diff --git a/src/Augmentation/ui/AugmentationsRoot.tsx b/src/Augmentation/ui/AugmentationsRoot.tsx
index 9f7ad401d..f3a64e6e3 100644
--- a/src/Augmentation/ui/AugmentationsRoot.tsx
+++ b/src/Augmentation/ui/AugmentationsRoot.tsx
@@ -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 ? (
+
+ NeuroFlux Governor - Level {level}
+ {Augmentations[AugmentationNames.NeuroFluxGovernor].stats}
+
+ ) : (
+ <>>
+ );
+};
+
+interface EntropyDisplayProps {
+ player: IPlayer;
+}
+
+const EntropyDisplay = ({ player }: EntropyDisplayProps): React.ReactElement => {
+ return player.entropy > 0 ? (
+
+
+ Entropy Virus - Level {player.entropy}
+
+
+ All multipliers decreased by: {formatNumber((1 - CONSTANTS.EntropyEffect ** player.entropy) * 100, 3)}%
+ (multiplicative)
+
+
+ ) : (
+ <>>
+ );
+};
interface IProps {
exportGameFn: () => void;
@@ -55,81 +100,112 @@ export function AugmentationsRoot(props: IProps): React.ReactElement {
}
return (
- <>
+
Augmentations
-
-
- Below is a list of all Augmentations you have purchased but not yet installed. Click the button below to
- install them.
-
- WARNING: Installing your Augmentations resets most of your progress, including:
-
- - Stats/Skill levels and Experience
- - Money
- - Scripts on every computer but your home computer
- - Purchased servers
- - Hacknet Nodes
- - Faction/Company reputation
- - Stocks
-
-
- 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)
-
+
+
+
+ Purchased Augmentations
+
+
+ Below is a list of all Augmentations you have purchased but not yet installed. Click the button
+ below to install them.
+
+
+ WARNING: Installing your Augmentations resets most of your progress, including:
+
+
+ - Stats/Skill levels and Experience
+ - Money
+ - Scripts on every computer but your home computer
+ - Purchased servers
+ - Hacknet Nodes
+ - Faction/Company reputation
+ - Stocks
+
+
+ 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)
+
+ >
+ }
+ >
+
+
+
+ setInstallOpen(false)}
+ onConfirm={props.installAugmentationsFn}
+ confirmationText={
+ <>
+ Installing will reset
+
+
- money
+
- skill / experience
+
- every server except home
+
- factions and reputation
+
+
+ You will keep:
+
+
- All scripts on home
+
- home ram and cores
+
+
+ It is recommended to install several Augmentations at once. Preferably everything from any faction of
+ your choosing.
+ >
+ }
+ />
+
+ 'I never asked for this'}>
+
+
+
+
+ It's always a good idea to backup/export your save!}>
+
+
+
+
+ {player.queuedAugmentations.length > 0 ? (
+
+
+
+
+ ) : (
+
+ No Augmentations have been purchased yet
+
+ )}
-
- Purchased Augmentations
-
-
- 'I never asked for this'}>
-
-
-
-
- setInstallOpen(false)}
- onConfirm={props.installAugmentationsFn}
- confirmationText={
- <>
- Installing will reset
-
-
- money
-
- skill / experience
-
- every server except home
-
- factions and reputation
-
-
- You will keep:
-
-
- All scripts on home
-
- home ram and cores
-
-
- It is recommended to install several Augmentations at once. Preferably everything from any faction of your
- choosing.
- >
- }
- />
- It's always a good idea to backup/export your save!}>
-
-
-
+
+ e.name === AugmentationNames.NeuroFluxGovernor)?.level ?? 0) > 0) +
+ +!!(player.entropy > 0)
+ }, 1fr)`,
+ }}
+ >
+
+
- Installed Augmentations
-
-
- List of all Augmentations that have been installed. You have gained the effects of these.
-
+
+
-
-
- >
+
+
);
}
diff --git a/src/Augmentation/ui/InstalledAugmentations.tsx b/src/Augmentation/ui/InstalledAugmentations.tsx
index eccfd94ec..6f208789f 100644
--- a/src/Augmentation/ui/InstalledAugmentations.tsx
+++ b/src/Augmentation/ui/InstalledAugmentations.tsx
@@ -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 (
- <>
-
-
-
-
-
-
-
- {player.entropy > 0 &&
- (() => {
- const [open, setOpen] = useState(false);
+
+
+ Installed Augmentations
+
+
+
+
+
+
+
+
+
+ {sourceAugs.length > 0 ? (
+
+
+
+ {sourceAugs
+ .filter((aug) => aug.name !== AugmentationNames.NeuroFluxGovernor)
+ .map((k, i) => (
+ setSelectedAug(k)} selected={selectedAug === k}>
+ {k.name}
+
+ ))}
+
+
+
+
+ {selectedAug.name}
+
+
+ {(() => {
+ const aug = Augmentations[selectedAug.name];
- return (
-
- setOpen((old) => !old)}>
-
- Entropy Virus - Level {player.entropy}
-
- }
- />
- {open ? (
-
- ) : (
-
- )}
-
-
-
-
- All multipliers decreased by:{" "}
- {formatNumber((1 - CONSTANTS.EntropyEffect ** player.entropy) * 100, 3)}% (multiplicative)
-
-
-
-
- );
- })()}
-
- {sourceAugs.map((e) => {
- const aug = Augmentations[e.name];
-
- let level = null;
- if (e.name === AugmentationNames.NeuroFluxGovernor) {
- level = e.level;
- }
-
- return ;
- })}
-
- >
+ const info = typeof aug.info === "string" ? {aug.info} : aug.info;
+ const tooltip = (
+ <>
+ {info}
+
+
+ {aug.stats}
+ >
+ );
+ return tooltip;
+ })()}
+
+
+
+ ) : (
+
+ No Augmentations have been installed yet
+
+ )}
+
);
}
diff --git a/src/Augmentation/ui/PlayerMultipliers.tsx b/src/Augmentation/ui/PlayerMultipliers.tsx
index be2c1bf47..d866bb340 100644
--- a/src/Augmentation/ui/PlayerMultipliers.tsx
+++ b/src/Augmentation/ui/PlayerMultipliers.tsx
@@ -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 (
- <>
-
- {"=>"}
-
-
-
- {numeralWrapper.formatPercentage(r)}
-
-
- >
- );
- }
- 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 {numeralWrapper.formatPercentage(props.base)};
-function MultiplierTable({ rows }: { rows: [string, number, number, number][] }): React.ReactElement {
return (
-
-
- {rows.map((r: any) => (
-
-
- {r[0]} multiplier:
-
-
-
- {numeralWrapper.formatPercentage(r[1])}
-
-
-
-
- ))}
-
-
+
+ {numeralWrapper.formatPercentage(props.base)}{" "}
+ {numeralWrapper.formatPercentage(props.base * props.mult)}
+
+ );
+}
+
+interface MultListProps {
+ rows: (string | number)[][];
+ color: string;
+}
+
+function MultiplierList(props: MultListProps): React.ReactElement {
+ return (
+
+ {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 (
+
+
+ {mult}
+
+ }
+ secondary={
+
+
+
+
+
+ }
+ disableTypography
+ />
+
+ );
+ }
+ return <>>;
+ })}
+
);
}
@@ -82,7 +89,7 @@ export function PlayerMultipliers(): React.ReactElement {
if (!Player.canAccessBladeburner()) return <>>;
return (
<>
-
>
@@ -116,20 +124,21 @@ export function PlayerMultipliers(): React.ReactElement {
}
return (
- <>
- Multipliers
-
-
+ Multipliers
+
+
-
-
-
-
-
-
-
-
-
- >
+
);
}
diff --git a/src/Augmentation/ui/PurchasedAugmentations.tsx b/src/Augmentation/ui/PurchasedAugmentations.tsx
index a8aa13b55..6b0402b5e 100644
--- a/src/Augmentation/ui/PurchasedAugmentations.tsx
+++ b/src/Augmentation/ui/PurchasedAugmentations.tsx
@@ -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();
}
- return {augs}
;
+ return (
+
+ {augs}
+
+ );
}
diff --git a/src/Augmentation/ui/SourceFiles.tsx b/src/Augmentation/ui/SourceFiles.tsx
index 1293f2298..ec9da77dd 100644
--- a/src/Augmentation/ui/SourceFiles.tsx
+++ b/src/Augmentation/ui/SourceFiles.tsx
@@ -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.
+
+
+ It increases all of the player's multipliers by 0.1%
+
+
+ You have found the following exploits:
+
+
+ {Player.exploits.map((c: Exploit) => (
+
+ * {ExploitName(c)}
+
+
+ ))}
+ >
+ ),
+ 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(sourceSfs[0]);
-export function SourceFiles(): React.ReactElement {
return (
- <>
- Source Files
-
-
-
-
-
-
- >
+
+
+ Source Files
+
+ {sourceSfs.length > 0 ? (
+
+
+
+ {exploits.length > 0 && (
+ setSelectedSf({ n: -1, lvl: exploits.length })}
+ selected={selectedSf.n === -1}
+ sx={{ py: 0 }}
+ >
+ Source-File -1: Exploits in the BitNodes}
+ secondary={
+
+ Level {exploits.length} / {Object.keys(Exploit).length}
+
+ }
+ />
+
+ )}
+
+ {sourceSfs.map((e, i) => {
+ const sfObj = safeGetSf(e.n);
+ const maxLevel = sfObj?.n === 12 ? "∞" : "3";
+
+ return (
+ setSelectedSf(e)}
+ selected={selectedSf === e}
+ sx={{ py: 0 }}
+ >
+ {sfObj?.name}}
+ secondary={
+
+ Level {selectedSf.lvl} / {maxLevel}
+
+ }
+ />
+
+ );
+ })}
+
+
+
+
+ {safeGetSf(selectedSf.n)?.name}
+
+
+ {(() => {
+ 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}
+
+
+ {sfObj?.info}
+ >
+ );
+ })()}
+
+
+
+ ) : (
+ <>>
+ )}
+
);
}