mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-30 01:47:33 +01:00
Initial aug page overhaul work
This commit is contained in:
parent
a9a31662ce
commit
c94b4f4fd3
@ -7,7 +7,7 @@ import React, { useState, useEffect } from "react";
|
||||
import { InstalledAugmentations } from "./InstalledAugmentations";
|
||||
import { PlayerMultipliers } from "./PlayerMultipliers";
|
||||
import { PurchasedAugmentations } from "./PurchasedAugmentations";
|
||||
import { SourceFiles } from "./SourceFiles";
|
||||
import { SourceFilesElement } from "./SourceFiles";
|
||||
|
||||
import { canGetBonus } from "../../ExportBonus";
|
||||
import { use } from "../../ui/Context";
|
||||
@ -16,8 +16,53 @@ import Typography from "@mui/material/Typography";
|
||||
import Button from "@mui/material/Button";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import Box from "@mui/material/Box";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import Container from "@mui/material/Container";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
import { ConfirmationModal } from "../../ui/React/ConfirmationModal";
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
import { AugmentationNames } from "../data/AugmentationNames";
|
||||
import { Augmentations } from "../Augmentations";
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { formatNumber } from "../../utils/StringHelperFunctions";
|
||||
import { Info } from "@mui/icons-material";
|
||||
|
||||
interface NFGDisplayProps {
|
||||
player: IPlayer;
|
||||
}
|
||||
|
||||
const NeuroFluxDisplay = ({ player }: NFGDisplayProps): React.ReactElement => {
|
||||
const level = player.augmentations.find((e) => e.name === AugmentationNames.NeuroFluxGovernor)?.level ?? 0;
|
||||
|
||||
return level > 0 ? (
|
||||
<Paper sx={{ p: 1 }}>
|
||||
<Typography variant="h5">NeuroFlux Governor - Level {level}</Typography>
|
||||
<Typography>{Augmentations[AugmentationNames.NeuroFluxGovernor].stats}</Typography>
|
||||
</Paper>
|
||||
) : (
|
||||
<></>
|
||||
);
|
||||
};
|
||||
|
||||
interface EntropyDisplayProps {
|
||||
player: IPlayer;
|
||||
}
|
||||
|
||||
const EntropyDisplay = ({ player }: EntropyDisplayProps): React.ReactElement => {
|
||||
return player.entropy > 0 ? (
|
||||
<Paper sx={{ p: 1 }}>
|
||||
<Typography variant="h5" color={Settings.theme.hp}>
|
||||
Entropy Virus - Level {player.entropy}
|
||||
</Typography>
|
||||
<Typography color={Settings.theme.hp}>
|
||||
<b>All multipliers decreased by:</b> {formatNumber((1 - CONSTANTS.EntropyEffect ** player.entropy) * 100, 3)}%
|
||||
(multiplicative)
|
||||
</Typography>
|
||||
</Paper>
|
||||
) : (
|
||||
<></>
|
||||
);
|
||||
};
|
||||
|
||||
interface IProps {
|
||||
exportGameFn: () => void;
|
||||
@ -55,81 +100,112 @@ export function AugmentationsRoot(props: IProps): React.ReactElement {
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Container disableGutters maxWidth="lg" sx={{ mx: 0 }}>
|
||||
<Typography variant="h4">Augmentations</Typography>
|
||||
<Box mx={2}>
|
||||
<Typography>
|
||||
Below is a list of all Augmentations you have purchased but not yet installed. Click the button below to
|
||||
install them.
|
||||
</Typography>
|
||||
<Typography>WARNING: Installing your Augmentations resets most of your progress, including:</Typography>
|
||||
<br />
|
||||
<Typography>- Stats/Skill levels and Experience</Typography>
|
||||
<Typography>- Money</Typography>
|
||||
<Typography>- Scripts on every computer but your home computer</Typography>
|
||||
<Typography>- Purchased servers</Typography>
|
||||
<Typography>- Hacknet Nodes</Typography>
|
||||
<Typography>- Faction/Company reputation</Typography>
|
||||
<Typography>- Stocks</Typography>
|
||||
<br />
|
||||
<Typography>
|
||||
Installing Augmentations lets you start over with the perks and benefits granted by all of the Augmentations
|
||||
you have ever installed. Also, you will keep any scripts and RAM/Core upgrades on your home computer (but you
|
||||
will lose all programs besides NUKE.exe)
|
||||
</Typography>
|
||||
<Box sx={{ mb: 1 }}>
|
||||
<Paper sx={{ p: 1 }}>
|
||||
<Typography variant="h5" color="primary" sx={{ display: "flex", alignItems: "center", flexWrap: "wrap" }}>
|
||||
Purchased Augmentations
|
||||
<Tooltip
|
||||
title={
|
||||
<>
|
||||
<Typography>
|
||||
Below is a list of all Augmentations you have purchased but not yet installed. Click the button
|
||||
below to install them.
|
||||
</Typography>
|
||||
<Typography>
|
||||
WARNING: Installing your Augmentations resets most of your progress, including:
|
||||
</Typography>
|
||||
<br />
|
||||
<Typography>- Stats/Skill levels and Experience</Typography>
|
||||
<Typography>- Money</Typography>
|
||||
<Typography>- Scripts on every computer but your home computer</Typography>
|
||||
<Typography>- Purchased servers</Typography>
|
||||
<Typography>- Hacknet Nodes</Typography>
|
||||
<Typography>- Faction/Company reputation</Typography>
|
||||
<Typography>- Stocks</Typography>
|
||||
<br />
|
||||
<Typography>
|
||||
Installing Augmentations lets you start over with the perks and benefits granted by all of the
|
||||
Augmentations you have ever installed. Also, you will keep any scripts and RAM/Core upgrades on your
|
||||
home computer (but you will lose all programs besides NUKE.exe)
|
||||
</Typography>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<Info sx={{ ml: 1, mb: 1 }} color="info" />
|
||||
</Tooltip>
|
||||
</Typography>
|
||||
<ConfirmationModal
|
||||
open={installOpen}
|
||||
onClose={() => setInstallOpen(false)}
|
||||
onConfirm={props.installAugmentationsFn}
|
||||
confirmationText={
|
||||
<>
|
||||
Installing will reset
|
||||
<br />
|
||||
<br />- money
|
||||
<br />- skill / experience
|
||||
<br />- every server except home
|
||||
<br />- factions and reputation
|
||||
<br />
|
||||
<br />
|
||||
You will keep:
|
||||
<br />
|
||||
<br />- All scripts on home
|
||||
<br />- home ram and cores
|
||||
<br />
|
||||
<br />
|
||||
It is recommended to install several Augmentations at once. Preferably everything from any faction of
|
||||
your choosing.
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Box sx={{ display: "grid", width: "100%", gridTemplateColumns: "1fr 1fr" }}>
|
||||
<Tooltip title={<Typography>'I never asked for this'</Typography>}>
|
||||
<span>
|
||||
<Button sx={{ width: "100%" }} disabled={player.queuedAugmentations.length === 0} onClick={doInstall}>
|
||||
Install Augmentations
|
||||
</Button>
|
||||
</span>
|
||||
</Tooltip>
|
||||
<Tooltip title={<Typography>It's always a good idea to backup/export your save!</Typography>}>
|
||||
<Button sx={{ width: "100%" }} onClick={doExport} color="error">
|
||||
Backup Save {exportBonusStr()}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
</Paper>
|
||||
{player.queuedAugmentations.length > 0 ? (
|
||||
<Box sx={{ display: "grid", gridTemplateColumns: "1fr 1fr" }}>
|
||||
<PurchasedAugmentations />
|
||||
<PlayerMultipliers />
|
||||
</Box>
|
||||
) : (
|
||||
<Paper sx={{ p: 1 }}>
|
||||
<Typography>No Augmentations have been purchased yet</Typography>
|
||||
</Paper>
|
||||
)}
|
||||
</Box>
|
||||
<Typography variant="h4" color="primary">
|
||||
Purchased Augmentations
|
||||
</Typography>
|
||||
<Box mx={2}>
|
||||
<Tooltip title={<Typography>'I never asked for this'</Typography>}>
|
||||
<span>
|
||||
<Button disabled={player.queuedAugmentations.length === 0} onClick={doInstall}>
|
||||
Install Augmentations
|
||||
</Button>
|
||||
</span>
|
||||
</Tooltip>
|
||||
<ConfirmationModal
|
||||
open={installOpen}
|
||||
onClose={() => setInstallOpen(false)}
|
||||
onConfirm={props.installAugmentationsFn}
|
||||
confirmationText={
|
||||
<>
|
||||
Installing will reset
|
||||
<br />
|
||||
<br />- money
|
||||
<br />- skill / experience
|
||||
<br />- every server except home
|
||||
<br />- factions and reputation
|
||||
<br />
|
||||
<br />
|
||||
You will keep:
|
||||
<br />
|
||||
<br />- All scripts on home
|
||||
<br />- home ram and cores
|
||||
<br />
|
||||
<br />
|
||||
It is recommended to install several Augmentations at once. Preferably everything from any faction of your
|
||||
choosing.
|
||||
</>
|
||||
}
|
||||
/>
|
||||
<Tooltip title={<Typography>It's always a good idea to backup/export your save!</Typography>}>
|
||||
<Button sx={{ mx: 2 }} onClick={doExport} color="error">
|
||||
Backup Save {exportBonusStr()}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<PurchasedAugmentations />
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
my: 1,
|
||||
display: "grid",
|
||||
gridTemplateColumns: `repeat(${
|
||||
+!!((player.augmentations.find((e) => e.name === AugmentationNames.NeuroFluxGovernor)?.level ?? 0) > 0) +
|
||||
+!!(player.entropy > 0)
|
||||
}, 1fr)`,
|
||||
}}
|
||||
>
|
||||
<NeuroFluxDisplay player={player} />
|
||||
<EntropyDisplay player={player} />
|
||||
</Box>
|
||||
<Typography variant="h4">Installed Augmentations</Typography>
|
||||
<Box mx={2}>
|
||||
<Typography>
|
||||
List of all Augmentations that have been installed. You have gained the effects of these.
|
||||
</Typography>
|
||||
|
||||
<Box>
|
||||
<InstalledAugmentations />
|
||||
</Box>
|
||||
<PlayerMultipliers />
|
||||
<SourceFiles />
|
||||
</>
|
||||
<SourceFilesElement />
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
@ -5,29 +5,24 @@
|
||||
* It also contains 'configuration' buttons that allow you to change how the
|
||||
* Augs/SF's are displayed
|
||||
*/
|
||||
import { Box, ListItemButton, Paper, Typography } from "@mui/material";
|
||||
import Button from "@mui/material/Button";
|
||||
import List from "@mui/material/List";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { AugmentationAccordion } from "../../ui/React/AugmentationAccordion";
|
||||
import { Augmentations } from "../Augmentations";
|
||||
import { AugmentationNames } from "../data/AugmentationNames";
|
||||
|
||||
import { OwnedAugmentationsOrderSetting } from "../../Settings/SettingEnums";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
import { use } from "../../ui/Context";
|
||||
import { OwnedAugmentationsOrderSetting } from "../../Settings/SettingEnums";
|
||||
import Button from "@mui/material/Button";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import List from "@mui/material/List";
|
||||
import { ExpandLess, ExpandMore } from "@mui/icons-material";
|
||||
import { Box, Paper, ListItemButton, ListItemText, Typography, Collapse } from "@mui/material";
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { formatNumber } from "../../utils/StringHelperFunctions";
|
||||
import { Augmentations } from "../Augmentations";
|
||||
import { AugmentationNames } from "../data/AugmentationNames";
|
||||
|
||||
export function InstalledAugmentations(): React.ReactElement {
|
||||
const setRerender = useState(true)[1];
|
||||
const player = use.Player();
|
||||
|
||||
const sourceAugs = player.augmentations.slice();
|
||||
|
||||
const [selectedAug, setSelectedAug] = useState(sourceAugs[0]);
|
||||
|
||||
if (Settings.OwnedAugmentationsOrder === OwnedAugmentationsOrderSetting.Alphabetically) {
|
||||
sourceAugs.sort((aug1, aug2) => {
|
||||
return aug1.name.localeCompare(aug2.name);
|
||||
@ -49,59 +44,62 @@ export function InstalledAugmentations(): React.ReactElement {
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Tooltip title={"Sorts the Augmentations alphabetically in numeral order"}>
|
||||
<Button onClick={sortInOrder}>Sort in Order</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={"Sorts the Augmentations based on when you acquired them (same as default)"}>
|
||||
<Button sx={{ mx: 2 }} onClick={sortByAcquirementTime}>
|
||||
Sort by Acquirement Time
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<List dense>
|
||||
{player.entropy > 0 &&
|
||||
(() => {
|
||||
const [open, setOpen] = useState(false);
|
||||
<Box sx={{ width: "100%" }}>
|
||||
<Paper sx={{ p: 1 }}>
|
||||
<Typography variant="h5">Installed Augmentations</Typography>
|
||||
<Box sx={{ display: "grid", gridTemplateColumns: "1fr 1fr" }}>
|
||||
<Tooltip title={"Sorts the Augmentations alphabetically in numeral order"}>
|
||||
<Button sx={{ width: "100%" }} onClick={sortInOrder}>
|
||||
Sort in Order
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip title={"Sorts the Augmentations based on when you acquired them (same as default)"}>
|
||||
<Button sx={{ width: "100%" }} onClick={sortByAcquirementTime}>
|
||||
Sort by Time of Acquirement
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
</Paper>
|
||||
{sourceAugs.length > 0 ? (
|
||||
<Paper sx={{ display: "grid", gridTemplateColumns: "1fr 3fr" }}>
|
||||
<Box>
|
||||
<List sx={{ maxHeight: 400, overflowY: "scroll", borderRight: `1px solid ${Settings.theme.welllight}` }}>
|
||||
{sourceAugs
|
||||
.filter((aug) => aug.name !== AugmentationNames.NeuroFluxGovernor)
|
||||
.map((k, i) => (
|
||||
<ListItemButton key={i + 1} onClick={() => setSelectedAug(k)} selected={selectedAug === k}>
|
||||
<Typography>{k.name}</Typography>
|
||||
</ListItemButton>
|
||||
))}
|
||||
</List>
|
||||
</Box>
|
||||
<Box sx={{ m: 1 }}>
|
||||
<Typography variant="h6" sx={{ display: "flex", alignItems: "center", flexWrap: "wrap" }}>
|
||||
{selectedAug.name}
|
||||
</Typography>
|
||||
<Typography sx={{ maxHeight: 305, overflowY: "scroll" }}>
|
||||
{(() => {
|
||||
const aug = Augmentations[selectedAug.name];
|
||||
|
||||
return (
|
||||
<Box component={Paper}>
|
||||
<ListItemButton onClick={() => setOpen((old) => !old)}>
|
||||
<ListItemText
|
||||
primary={
|
||||
<Typography color={Settings.theme.hp} style={{ whiteSpace: "pre-wrap" }}>
|
||||
Entropy Virus - Level {player.entropy}
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
{open ? (
|
||||
<ExpandLess sx={{ color: Settings.theme.hp }} />
|
||||
) : (
|
||||
<ExpandMore sx={{ color: Settings.theme.hp }} />
|
||||
)}
|
||||
</ListItemButton>
|
||||
<Collapse in={open} unmountOnExit>
|
||||
<Box m={4}>
|
||||
<Typography color={Settings.theme.hp}>
|
||||
<b>All multipliers decreased by:</b>{" "}
|
||||
{formatNumber((1 - CONSTANTS.EntropyEffect ** player.entropy) * 100, 3)}% (multiplicative)
|
||||
</Typography>
|
||||
</Box>
|
||||
</Collapse>
|
||||
</Box>
|
||||
);
|
||||
})()}
|
||||
|
||||
{sourceAugs.map((e) => {
|
||||
const aug = Augmentations[e.name];
|
||||
|
||||
let level = null;
|
||||
if (e.name === AugmentationNames.NeuroFluxGovernor) {
|
||||
level = e.level;
|
||||
}
|
||||
|
||||
return <AugmentationAccordion key={aug.name} aug={aug} level={level} />;
|
||||
})}
|
||||
</List>
|
||||
</>
|
||||
const info = typeof aug.info === "string" ? <span>{aug.info}</span> : aug.info;
|
||||
const tooltip = (
|
||||
<>
|
||||
{info}
|
||||
<br />
|
||||
<br />
|
||||
{aug.stats}
|
||||
</>
|
||||
);
|
||||
return tooltip;
|
||||
})()}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Paper>
|
||||
) : (
|
||||
<Paper sx={{ p: 1 }}>
|
||||
<Typography>No Augmentations have been installed yet</Typography>
|
||||
</Paper>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
@ -1,17 +1,14 @@
|
||||
/**
|
||||
* React component for displaying the player's multipliers on the Augmentation UI page
|
||||
*/
|
||||
import { Box, Typography, List, ListItemText, ListItem, Paper } from "@mui/material";
|
||||
import * as React from "react";
|
||||
|
||||
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||
import { Player } from "../../Player";
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { Augmentations } from "../Augmentations";
|
||||
import { Table, TableCell } from "../../ui/React/Table";
|
||||
import TableBody from "@mui/material/TableBody";
|
||||
import TableRow from "@mui/material/TableRow";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Box from "@mui/material/Box";
|
||||
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||
import { DoubleArrow } from "@mui/icons-material";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
|
||||
function calculateAugmentedStats(): any {
|
||||
const augP: any = {};
|
||||
@ -25,53 +22,63 @@ function calculateAugmentedStats(): any {
|
||||
return augP;
|
||||
}
|
||||
|
||||
function Improvements({ r, m }: { r: number; m: number }): React.ReactElement {
|
||||
if (r) {
|
||||
return (
|
||||
<>
|
||||
<TableCell key="2">
|
||||
<Typography> {"=>"} </Typography>
|
||||
</TableCell>
|
||||
<TableCell key="3">
|
||||
<Typography>
|
||||
{numeralWrapper.formatPercentage(r)} <BN5Stat base={r} mult={m} />
|
||||
</Typography>
|
||||
</TableCell>
|
||||
</>
|
||||
);
|
||||
}
|
||||
return <></>;
|
||||
}
|
||||
|
||||
interface IBN5StatsProps {
|
||||
interface BitNodeModifiedStatsProps {
|
||||
base: number;
|
||||
mult: number;
|
||||
color: string;
|
||||
}
|
||||
|
||||
function BN5Stat(props: IBN5StatsProps): React.ReactElement {
|
||||
if (props.mult === 1) return <></>;
|
||||
return <>({numeralWrapper.formatPercentage(props.base * props.mult)})</>;
|
||||
}
|
||||
function BitNodeModifiedStats(props: BitNodeModifiedStatsProps): React.ReactElement {
|
||||
if (props.mult === 1)
|
||||
return <Typography color={props.color}>{numeralWrapper.formatPercentage(props.base)}</Typography>;
|
||||
|
||||
function MultiplierTable({ rows }: { rows: [string, number, number, number][] }): React.ReactElement {
|
||||
return (
|
||||
<Table size="small" padding="none">
|
||||
<TableBody>
|
||||
{rows.map((r: any) => (
|
||||
<TableRow key={r[0]}>
|
||||
<TableCell key="0">
|
||||
<Typography noWrap>{r[0]} multiplier: </Typography>
|
||||
</TableCell>
|
||||
<TableCell key="1" style={{ textAlign: "right" }}>
|
||||
<Typography noWrap>
|
||||
{numeralWrapper.formatPercentage(r[1])} <BN5Stat base={r[1]} mult={r[3]} />
|
||||
</Typography>
|
||||
</TableCell>
|
||||
<Improvements r={r[2]} m={r[3]} />
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
<Typography color={props.color}>
|
||||
<span style={{ opacity: 0.5 }}>{numeralWrapper.formatPercentage(props.base)}</span>{" "}
|
||||
{numeralWrapper.formatPercentage(props.base * props.mult)}
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
interface MultListProps {
|
||||
rows: (string | number)[][];
|
||||
color: string;
|
||||
}
|
||||
|
||||
function MultiplierList(props: MultListProps): React.ReactElement {
|
||||
return (
|
||||
<List disablePadding>
|
||||
{props.rows.map((data) => {
|
||||
const mult = data[0] as string,
|
||||
value = data[1] as number,
|
||||
improved = data[2] as number | null,
|
||||
bnMult = data[3] as number;
|
||||
|
||||
if (improved) {
|
||||
return (
|
||||
<ListItem key={mult} disableGutters sx={{ py: 0 }}>
|
||||
<ListItemText
|
||||
sx={{ my: 0.1 }}
|
||||
primary={
|
||||
<Typography color={props.color}>
|
||||
<b>{mult}</b>
|
||||
</Typography>
|
||||
}
|
||||
secondary={
|
||||
<span style={{ display: "flex", alignItems: "center", flexWrap: "wrap" }}>
|
||||
<BitNodeModifiedStats base={value} mult={bnMult} color={props.color} />
|
||||
<DoubleArrow fontSize="small" color="success" sx={{ mb: 1, mx: 1 }} />
|
||||
<BitNodeModifiedStats base={improved} mult={bnMult} color={Settings.theme.success} />
|
||||
</span>
|
||||
}
|
||||
disableTypography
|
||||
/>
|
||||
</ListItem>
|
||||
);
|
||||
}
|
||||
return <></>;
|
||||
})}
|
||||
</List>
|
||||
);
|
||||
}
|
||||
|
||||
@ -82,7 +89,7 @@ export function PlayerMultipliers(): React.ReactElement {
|
||||
if (!Player.canAccessBladeburner()) return <></>;
|
||||
return (
|
||||
<>
|
||||
<MultiplierTable
|
||||
<MultiplierList
|
||||
rows={[
|
||||
[
|
||||
"Bladeburner Success Chance",
|
||||
@ -109,6 +116,7 @@ export function PlayerMultipliers(): React.ReactElement {
|
||||
1,
|
||||
],
|
||||
]}
|
||||
color={Settings.theme.primary}
|
||||
/>
|
||||
<br />
|
||||
</>
|
||||
@ -116,20 +124,21 @@ export function PlayerMultipliers(): React.ReactElement {
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Typography variant="h4">Multipliers</Typography>
|
||||
<Box mx={2}>
|
||||
<MultiplierTable
|
||||
<Paper sx={{ p: 1, maxHeight: 400, overflowY: "scroll" }}>
|
||||
<Typography variant="h6">Multipliers</Typography>
|
||||
<Box>
|
||||
<MultiplierList
|
||||
rows={[
|
||||
["Hacking Chance ", Player.hacking_chance_mult, Player.hacking_chance_mult * mults.hacking_chance_mult, 1],
|
||||
["Hacking Speed ", Player.hacking_speed_mult, Player.hacking_speed_mult * mults.hacking_speed_mult, 1],
|
||||
["Hacking Money ", Player.hacking_money_mult, Player.hacking_money_mult * mults.hacking_money_mult, 1],
|
||||
["Hacking Growth ", Player.hacking_grow_mult, Player.hacking_grow_mult * mults.hacking_grow_mult, 1],
|
||||
]}
|
||||
color={Settings.theme.hack}
|
||||
/>
|
||||
<br />
|
||||
|
||||
<MultiplierTable
|
||||
<MultiplierList
|
||||
rows={[
|
||||
[
|
||||
"Hacking Level ",
|
||||
@ -144,10 +153,11 @@ export function PlayerMultipliers(): React.ReactElement {
|
||||
BitNodeMultipliers.HackExpGain,
|
||||
],
|
||||
]}
|
||||
color={Settings.theme.hack}
|
||||
/>
|
||||
<br />
|
||||
|
||||
<MultiplierTable
|
||||
<MultiplierList
|
||||
rows={[
|
||||
[
|
||||
"Strength Level ",
|
||||
@ -157,10 +167,11 @@ export function PlayerMultipliers(): React.ReactElement {
|
||||
],
|
||||
["Strength Experience ", Player.strength_exp_mult, Player.strength_exp_mult * mults.strength_exp_mult, 1],
|
||||
]}
|
||||
color={Settings.theme.combat}
|
||||
/>
|
||||
<br />
|
||||
|
||||
<MultiplierTable
|
||||
<MultiplierList
|
||||
rows={[
|
||||
[
|
||||
"Defense Level ",
|
||||
@ -170,10 +181,11 @@ export function PlayerMultipliers(): React.ReactElement {
|
||||
],
|
||||
["Defense Experience ", Player.defense_exp_mult, Player.defense_exp_mult * mults.defense_exp_mult, 1],
|
||||
]}
|
||||
color={Settings.theme.combat}
|
||||
/>
|
||||
<br />
|
||||
|
||||
<MultiplierTable
|
||||
<MultiplierList
|
||||
rows={[
|
||||
[
|
||||
"Dexterity Level ",
|
||||
@ -188,10 +200,11 @@ export function PlayerMultipliers(): React.ReactElement {
|
||||
1,
|
||||
],
|
||||
]}
|
||||
color={Settings.theme.combat}
|
||||
/>
|
||||
<br />
|
||||
|
||||
<MultiplierTable
|
||||
<MultiplierList
|
||||
rows={[
|
||||
[
|
||||
"Agility Level ",
|
||||
@ -201,10 +214,11 @@ export function PlayerMultipliers(): React.ReactElement {
|
||||
],
|
||||
["Agility Experience ", Player.agility_exp_mult, Player.agility_exp_mult * mults.agility_exp_mult, 1],
|
||||
]}
|
||||
color={Settings.theme.combat}
|
||||
/>
|
||||
<br />
|
||||
|
||||
<MultiplierTable
|
||||
<MultiplierList
|
||||
rows={[
|
||||
[
|
||||
"Charisma Level ",
|
||||
@ -214,10 +228,11 @@ export function PlayerMultipliers(): React.ReactElement {
|
||||
],
|
||||
["Charisma Experience ", Player.charisma_exp_mult, Player.charisma_exp_mult * mults.charisma_exp_mult, 1],
|
||||
]}
|
||||
color={Settings.theme.cha}
|
||||
/>
|
||||
<br />
|
||||
|
||||
<MultiplierTable
|
||||
<MultiplierList
|
||||
rows={[
|
||||
[
|
||||
"Hacknet Node production ",
|
||||
@ -250,10 +265,11 @@ export function PlayerMultipliers(): React.ReactElement {
|
||||
1,
|
||||
],
|
||||
]}
|
||||
color={Settings.theme.primary}
|
||||
/>
|
||||
<br />
|
||||
|
||||
<MultiplierTable
|
||||
<MultiplierList
|
||||
rows={[
|
||||
["Company reputation gain ", Player.company_rep_mult, Player.company_rep_mult * mults.company_rep_mult, 1],
|
||||
[
|
||||
@ -269,10 +285,11 @@ export function PlayerMultipliers(): React.ReactElement {
|
||||
BitNodeMultipliers.CompanyWorkMoney,
|
||||
],
|
||||
]}
|
||||
color={Settings.theme.primary}
|
||||
/>
|
||||
<br />
|
||||
|
||||
<MultiplierTable
|
||||
<MultiplierList
|
||||
rows={[
|
||||
["Crime success ", Player.crime_success_mult, Player.crime_success_mult * mults.crime_success_mult, 1],
|
||||
[
|
||||
@ -282,11 +299,12 @@ export function PlayerMultipliers(): React.ReactElement {
|
||||
BitNodeMultipliers.CrimeMoney,
|
||||
],
|
||||
]}
|
||||
color={Settings.theme.combat}
|
||||
/>
|
||||
<br />
|
||||
|
||||
<BladeburnerMults />
|
||||
</Box>
|
||||
</>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ import { AugmentationNames } from "../data/AugmentationNames";
|
||||
import { Player } from "../../Player";
|
||||
|
||||
import { AugmentationAccordion } from "../../ui/React/AugmentationAccordion";
|
||||
import List from "@mui/material/List";
|
||||
import { List, Paper } from "@mui/material";
|
||||
|
||||
export function PurchasedAugmentations(): React.ReactElement {
|
||||
const augs: React.ReactElement[] = [];
|
||||
@ -32,5 +32,9 @@ export function PurchasedAugmentations(): React.ReactElement {
|
||||
augs.push(<AugmentationAccordion key={aug.name} aug={aug} level={level} />);
|
||||
}
|
||||
|
||||
return <List dense>{augs}</List>;
|
||||
return (
|
||||
<Paper sx={{ p: 1, maxHeight: 400, overflowY: "scroll" }}>
|
||||
<List dense>{augs}</List>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
@ -1,21 +1,161 @@
|
||||
import React from "react";
|
||||
import { SourceFileMinus1 } from "./SourceFileMinus1";
|
||||
import { OwnedSourceFiles } from "./OwnedSourceFiles";
|
||||
import List from "@mui/material/List";
|
||||
|
||||
import Typography from "@mui/material/Typography";
|
||||
import { ListItemButton, ListItemText, Paper } from "@mui/material";
|
||||
import Box from "@mui/material/Box";
|
||||
import List from "@mui/material/List";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import React, { useState } from "react";
|
||||
import { Exploit, ExploitName } from "../../Exploits/Exploit";
|
||||
import { Player } from "../../Player";
|
||||
import { OwnedAugmentationsOrderSetting } from "../../Settings/SettingEnums";
|
||||
import { Settings } from "../../Settings/Settings";
|
||||
import { SourceFile } from "../../SourceFile/SourceFile";
|
||||
import { SourceFiles } from "../../SourceFile/SourceFiles";
|
||||
|
||||
interface SfMinus1 {
|
||||
info: React.ReactElement;
|
||||
n: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
const safeGetSf = (sfNum: number): SourceFile | SfMinus1 | null => {
|
||||
if (sfNum === -1) {
|
||||
return {
|
||||
info: (
|
||||
<>
|
||||
This Source-File can only be acquired with obscure knowledge of the game, javascript, and the web ecosystem.
|
||||
<br />
|
||||
<br />
|
||||
It increases all of the player's multipliers by 0.1%
|
||||
<br />
|
||||
<br />
|
||||
You have found the following exploits:
|
||||
<br />
|
||||
<br />
|
||||
{Player.exploits.map((c: Exploit) => (
|
||||
<React.Fragment key={c}>
|
||||
* {ExploitName(c)}
|
||||
<br />
|
||||
</React.Fragment>
|
||||
))}
|
||||
</>
|
||||
),
|
||||
lvl: Player.exploits.length,
|
||||
n: -1,
|
||||
name: "Source-File -1: Exploits in the BitNodes",
|
||||
};
|
||||
}
|
||||
|
||||
const srcFileKey = "SourceFile" + sfNum;
|
||||
const sfObj = SourceFiles[srcFileKey];
|
||||
if (sfObj == null) {
|
||||
console.error(`Invalid source file number: ${sfNum}`);
|
||||
return null;
|
||||
}
|
||||
return sfObj;
|
||||
};
|
||||
|
||||
export function SourceFilesElement(): React.ReactElement {
|
||||
const sourceSfs = Player.sourceFiles.slice();
|
||||
const exploits = Player.exploits;
|
||||
|
||||
if (Settings.OwnedAugmentationsOrder === OwnedAugmentationsOrderSetting.Alphabetically) {
|
||||
sourceSfs.sort((sf1, sf2) => {
|
||||
return sf1.n - sf2.n;
|
||||
});
|
||||
}
|
||||
|
||||
const [selectedSf, setSelectedSf] = useState<any>(sourceSfs[0]);
|
||||
|
||||
export function SourceFiles(): React.ReactElement {
|
||||
return (
|
||||
<>
|
||||
<Typography variant="h4">Source Files</Typography>
|
||||
<Box mx={2}>
|
||||
<List dense>
|
||||
<SourceFileMinus1 />
|
||||
<OwnedSourceFiles />
|
||||
</List>
|
||||
</Box>
|
||||
</>
|
||||
<Box sx={{ width: "100%", mt: 1 }}>
|
||||
<Paper sx={{ p: 1 }}>
|
||||
<Typography variant="h5">Source Files</Typography>
|
||||
</Paper>
|
||||
{sourceSfs.length > 0 ? (
|
||||
<Paper sx={{ display: "grid", gridTemplateColumns: "1fr 3fr" }}>
|
||||
<Box>
|
||||
<List
|
||||
sx={{ maxHeight: 400, overflowY: "scroll", borderRight: `1px solid ${Settings.theme.welllight}` }}
|
||||
disablePadding
|
||||
>
|
||||
{exploits.length > 0 && (
|
||||
<ListItemButton
|
||||
key={-1}
|
||||
onClick={() => setSelectedSf({ n: -1, lvl: exploits.length })}
|
||||
selected={selectedSf.n === -1}
|
||||
sx={{ py: 0 }}
|
||||
>
|
||||
<ListItemText
|
||||
disableTypography
|
||||
primary={<Typography>Source-File -1: Exploits in the BitNodes</Typography>}
|
||||
secondary={
|
||||
<Typography>
|
||||
Level {exploits.length} / {Object.keys(Exploit).length}
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
</ListItemButton>
|
||||
)}
|
||||
|
||||
{sourceSfs.map((e, i) => {
|
||||
const sfObj = safeGetSf(e.n);
|
||||
const maxLevel = sfObj?.n === 12 ? "∞" : "3";
|
||||
|
||||
return (
|
||||
<ListItemButton
|
||||
key={i + 1}
|
||||
onClick={() => setSelectedSf(e)}
|
||||
selected={selectedSf === e}
|
||||
sx={{ py: 0 }}
|
||||
>
|
||||
<ListItemText
|
||||
disableTypography
|
||||
primary={<Typography>{sfObj?.name}</Typography>}
|
||||
secondary={
|
||||
<Typography>
|
||||
Level {selectedSf.lvl} / {maxLevel}
|
||||
</Typography>
|
||||
}
|
||||
/>
|
||||
</ListItemButton>
|
||||
);
|
||||
})}
|
||||
</List>
|
||||
</Box>
|
||||
<Box sx={{ m: 1 }}>
|
||||
<Typography variant="h6" sx={{ display: "flex", alignItems: "center", flexWrap: "wrap" }}>
|
||||
{safeGetSf(selectedSf.n)?.name}
|
||||
</Typography>
|
||||
<Typography sx={{ maxHeight: 305, overflowY: "scroll" }}>
|
||||
{(() => {
|
||||
const sfObj = safeGetSf(selectedSf.n);
|
||||
|
||||
let maxLevel;
|
||||
switch (sfObj?.n) {
|
||||
case 12:
|
||||
maxLevel = "∞";
|
||||
break;
|
||||
case -1:
|
||||
maxLevel = Object.keys(Exploit).length;
|
||||
break;
|
||||
default:
|
||||
maxLevel = "3";
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
Level {selectedSf.lvl} / {maxLevel}
|
||||
<br />
|
||||
<br />
|
||||
{sfObj?.info}
|
||||
</>
|
||||
);
|
||||
})()}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Paper>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user