Files
bitburner-src/src/BitNode/ui/PortalModal.tsx
T
2026-04-10 15:45:18 -07:00

135 lines
4.5 KiB
TypeScript

import React from "react";
import { Player } from "@player";
import { type BitNodeBooleanOptions } from "@nsdefs";
import { enterBitNode } from "../../RedPill";
import { BitNodes } from "../BitNode";
import { Modal } from "../../ui/React/Modal";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import { BitNodeMultiplierDescription } from "./BitnodeMultipliersDescription";
import { BitNodeAdvancedOptions } from "./BitNodeAdvancedOptions";
import { JSONMap } from "../../Types/Jsonable";
import { getBitNodeLevel } from "../BitNodeUtils";
interface IProps {
open: boolean;
onClose: () => void;
n: number;
level: number;
destroyedBitNode: number;
flume: boolean;
}
export function PortalModal(props: IProps): React.ReactElement {
const [sourceFileOverrides, setSourceFileOverrides] = React.useState<JSONMap<number, number>>(new JSONMap());
const [intelligenceOverride, setIntelligenceOverride] = React.useState<number | undefined>();
const [bitNodeBooleanOptions, setBitNodeBooleanOptions] = React.useState<BitNodeBooleanOptions>({
restrictHomePCUpgrade: false,
disableGang: false,
disableCorporation: false,
disableBladeburner: false,
disable4SData: false,
disableHacknetServer: false,
disableSleeveExpAndAugmentation: false,
});
const bitNodeKey = "BitNode" + props.n;
const bitNode = BitNodes[bitNodeKey];
if (bitNode == null) throw new Error(`Could not find BitNode object for number: ${props.n}`);
const maxSourceFileLevel = props.n === 12 ? "∞" : "3";
const newLevel = getBitNodeLevel(props.n, props.level);
let currentSourceFiles = new Map(Player.sourceFiles);
if (!props.flume) {
const currentSourceFileLevel = Player.sourceFileLvl(props.destroyedBitNode);
if (currentSourceFileLevel < 3 || props.destroyedBitNode === 12) {
currentSourceFiles.set(props.destroyedBitNode, currentSourceFileLevel + 1);
}
}
currentSourceFiles = new Map([...currentSourceFiles].sort((a, b) => a[0] - b[0]));
const callbacks = {
setSfOverrides: (value: JSONMap<number, number>) => {
setSourceFileOverrides(value);
},
setSfActiveLevel: (sfNumber: number, sfLevel: number) => {
setSourceFileOverrides((old) => {
const newValue = new JSONMap(old);
newValue.set(sfNumber, sfLevel);
return newValue;
});
},
setIntelligenceOverride: (value: number | undefined) => {
setIntelligenceOverride(value);
},
setBooleanOption: (key: keyof BitNodeBooleanOptions, value: boolean) => {
if (!(key in bitNodeBooleanOptions)) {
throw new Error(`Invalid key of booleanOptions: ${key}`);
}
setBitNodeBooleanOptions((old) => {
return {
...old,
[key]: value,
};
});
},
};
function onClose() {
setSourceFileOverrides(new JSONMap());
setIntelligenceOverride(undefined);
setBitNodeBooleanOptions({
restrictHomePCUpgrade: false,
disableGang: false,
disableCorporation: false,
disableBladeburner: false,
disable4SData: false,
disableHacknetServer: false,
disableSleeveExpAndAugmentation: false,
});
props.onClose();
}
return (
<Modal open={props.open} onClose={onClose}>
<Typography variant="h4">
BitNode-{props.n}: {bitNode.name}
</Typography>
<Typography variant="h5">{bitNode.tagline}</Typography>
<br />
<Typography>
Source-File Level: {props.level} / {maxSourceFileLevel}
</Typography>
<br />
<br />
<Typography component="div">{bitNode.info}</Typography>
<BitNodeMultiplierDescription n={props.n} level={newLevel} hideMultsIfCannotAccessFeature={false} />
<BitNodeAdvancedOptions
targetBitNode={props.n}
currentSourceFiles={currentSourceFiles}
sourceFileOverrides={sourceFileOverrides}
intelligenceOverride={intelligenceOverride}
bitNodeBooleanOptions={bitNodeBooleanOptions}
callbacks={callbacks}
></BitNodeAdvancedOptions>
<br />
<Button
aria-label={`enter-bitnode-${bitNode.number.toString()}`}
autoFocus={true}
onClick={() => {
const bitNodeOptions = {
sourceFileOverrides,
intelligenceOverride,
...bitNodeBooleanOptions,
};
enterBitNode(props.flume, props.destroyedBitNode, props.n, bitNodeOptions);
props.onClose();
}}
>
Enter BN{props.n}.{newLevel}
</Button>
</Modal>
);
}