No more player/router context

This commit is contained in:
Snarling 2022-09-12 18:00:09 -04:00
parent 83d357e758
commit a21b1029d7
56 changed files with 418 additions and 527 deletions

@ -2,7 +2,7 @@ import React, { useState } from "react";
import { BBCabinetRoot } from "./BBCabinet";
import Button from "@mui/material/Button";
import { use } from "../../ui/Context";
import { Player } from "../../Player";
import { AlertEvents } from "../../ui/React/AlertManager";
enum Page {
@ -11,11 +11,10 @@ enum Page {
}
export function ArcadeRoot(): React.ReactElement {
const player = use.Player();
const [page, setPage] = useState(Page.None);
function mbBurner2000(): void {
if (player.sourceFileLvl(1) === 0) {
if (Player.sourceFileLvl(1) === 0) {
AlertEvents.emit("This machine is broken.");
} else {
setPage(Page.Megabyteburner2000);

@ -1,6 +1,6 @@
import React, { useEffect } from "react";
import Typography from "@mui/material/Typography";
import { use } from "../../ui/Context";
import { Player } from "../../Player";
import { Exploit } from "../../Exploits/Exploit";
const metaBB = "https://bitburner-official.github.io/bitburner-legacy/";
@ -12,11 +12,10 @@ const style = {
};
export function BBCabinetRoot(): React.ReactElement {
const player = use.Player();
useEffect(() => {
window.addEventListener("message", function (this: Window, ev: MessageEvent<boolean>) {
if (ev.isTrusted && ev.origin == "https://bitburner-official.github.io" && ev.data) {
player.giveExploit(Exploit.TrueRecursion);
Player.giveExploit(Exploit.TrueRecursion);
}
});
});

@ -10,8 +10,6 @@ import { PurchasedAugmentations } from "./PurchasedAugmentations";
import { SourceFilesElement } from "./SourceFiles";
import { canGetBonus } from "../../ExportBonus";
import { use } from "../../ui/Context";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import Tooltip from "@mui/material/Tooltip";
@ -86,7 +84,6 @@ interface IProps {
export function AugmentationsRoot(props: IProps): React.ReactElement {
const [installOpen, setInstallOpen] = useState(false);
const player = use.Player();
const setRerender = useState(false)[1];
function rerender(): void {
setRerender((o) => !o);
@ -179,7 +176,7 @@ export function AugmentationsRoot(props: IProps): React.ReactElement {
<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}>
<Button sx={{ width: "100%" }} disabled={Player.queuedAugmentations.length === 0} onClick={doInstall}>
Install Augmentations
</Button>
</span>
@ -191,7 +188,7 @@ export function AugmentationsRoot(props: IProps): React.ReactElement {
</Tooltip>
</Box>
</Paper>
{player.queuedAugmentations.length > 0 ? (
{Player.queuedAugmentations.length > 0 ? (
<Box sx={{ display: "grid", gridTemplateColumns: "1fr 3fr" }}>
<PurchasedAugmentations />
<PlayerMultipliers />
@ -208,8 +205,8 @@ export function AugmentationsRoot(props: IProps): React.ReactElement {
my: 1,
display: "grid",
gridTemplateColumns: `repeat(${
+!!((player.augmentations.find((e) => e.name === AugmentationNames.NeuroFluxGovernor)?.level ?? 0) > 0) +
+!!(player.entropy > 0)
+!!((Player.augmentations.find((e) => e.name === AugmentationNames.NeuroFluxGovernor)?.level ?? 0) > 0) +
+!!(Player.entropy > 0)
}, 1fr)`,
gap: 1,
}}

@ -12,14 +12,13 @@ import Tooltip from "@mui/material/Tooltip";
import React, { useState } from "react";
import { OwnedAugmentationsOrderSetting } from "../../Settings/SettingEnums";
import { Settings } from "../../Settings/Settings";
import { use } from "../../ui/Context";
import { Player } from "../../Player";
import { StaticAugmentations } from "../StaticAugmentations";
import { AugmentationNames } from "../data/AugmentationNames";
export function InstalledAugmentations(): React.ReactElement {
const setRerender = useState(true)[1];
const player = use.Player();
const sourceAugs = player.augmentations.slice().filter((aug) => aug.name !== AugmentationNames.NeuroFluxGovernor);
const sourceAugs = Player.augmentations.slice().filter((aug) => aug.name !== AugmentationNames.NeuroFluxGovernor);
const [selectedAug, setSelectedAug] = useState(sourceAugs[0]);

@ -6,7 +6,7 @@ import { purchaseAugmentation } from "../../Faction/FactionHelpers";
import { isRepeatableAug } from "../AugmentationHelpers";
import { Money } from "../../ui/React/Money";
import { Modal } from "../../ui/React/Modal";
import { use } from "../../ui/Context";
import { Player } from "../../Player";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
@ -22,10 +22,8 @@ export function PurchaseAugmentationModal(props: IProps): React.ReactElement {
return <></>;
}
const player = use.Player();
function buy(): void {
if (!isRepeatableAug(props.aug as Augmentation) && player.hasAugmentation(props.aug as Augmentation)) {
if (!isRepeatableAug(props.aug as Augmentation) && Player.hasAugmentation(props.aug as Augmentation)) {
return;
}

@ -1,6 +1,6 @@
import React, { useState, useEffect } from "react";
import { Modal } from "../../ui/React/Modal";
import { use } from "../../ui/Context";
import { Router } from "../../ui/GameRoot";
import { EventEmitter } from "../../utils/EventEmitter";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
@ -8,10 +8,9 @@ import Button from "@mui/material/Button";
export const BitFlumeEvent = new EventEmitter<[]>();
export function BitFlumeModal(): React.ReactElement {
const router = use.Router();
const [open, setOpen] = useState(false);
function flume(): void {
router.toBitVerse(true, false);
Router.toBitVerse(true, false);
setOpen(false);
}

@ -5,7 +5,7 @@ import { uniqueId } from "lodash";
import React from "react";
import { SpecialServers } from "../../Server/data/SpecialServers";
import { Settings } from "../../Settings/Settings";
import { use } from "../../ui/Context";
import { Player } from "../../ui/Player";
import { StatsRow } from "../../ui/React/StatsRow";
import { defaultMultipliers, getBitNodeMultipliers } from "../BitNode";
import { IBitNodeMultipliers } from "../BitNodeMultipliers";
@ -33,13 +33,12 @@ export function BitnodeMultiplierDescription({ n, level }: IProps): React.ReactE
}
export const BitNodeMultipliersDisplay = ({ n, level }: IProps): React.ReactElement => {
const player = use.Player();
// If a level argument has been provided, use that as the multiplier level
// If not, then we have to assume that we want the next level up from the
// current node's source file, so we get the min of that, the SF's max level,
// or if it's BN12, ∞
const maxSfLevel = n === 12 ? Infinity : 3;
const mults = getBitNodeMultipliers(n, level ?? Math.min(player.sourceFileLvl(n) + 1, maxSfLevel));
const mults = getBitNodeMultipliers(n, level ?? Math.min(Player.sourceFileLvl(n) + 1, maxSfLevel));
return (
<Box sx={{ columnCount: 2, columnGap: 1, mb: -2 }}>
@ -277,8 +276,7 @@ function InfiltrationMults({ mults }: IMultsProps): React.ReactElement {
}
function BladeburnerMults({ mults }: IMultsProps): React.ReactElement {
const player = use.Player();
if (!player.canAccessBladeburner()) return <></>;
if (!Player.canAccessBladeburner()) return <></>;
if (mults.BladeburnerRank === 0) {
const rows: IBNMultRows = {
@ -297,8 +295,7 @@ function BladeburnerMults({ mults }: IMultsProps): React.ReactElement {
}
function StanekMults({ mults }: IMultsProps): React.ReactElement {
const player = use.Player();
if (!player.canAccessCotMG()) return <></>;
if (!Player.canAccessCotMG()) return <></>;
const extraSize = mults.StaneksGiftExtraSize.toFixed(3);
const rows: IBNMultRows = {
@ -313,8 +310,7 @@ function StanekMults({ mults }: IMultsProps): React.ReactElement {
}
function GangMults({ mults }: IMultsProps): React.ReactElement {
const player = use.Player();
if (player.bitNodeN !== 2 && player.sourceFileLvl(2) <= 0) return <></>;
if (Player.bitNodeN !== 2 && Player.sourceFileLvl(2) <= 0) return <></>;
const rows: IBNMultRows = {
GangSoftcap: {
@ -328,8 +324,7 @@ function GangMults({ mults }: IMultsProps): React.ReactElement {
}
function CorporationMults({ mults }: IMultsProps): React.ReactElement {
const player = use.Player();
if (!player.canAccessCorporation()) return <></>;
if (!Player.canAccessCorporation()) return <></>;
if (mults.CorporationSoftcap < 0.15) {
const rows: IBNMultRows = {

@ -1,10 +1,8 @@
import React, { useState } from "react";
import { IRouter } from "../../ui/Router";
import { BitNodes } from "../BitNode";
import { enterBitNode } from "../../RedPill";
import { PortalModal } from "./PortalModal";
import { CinematicText } from "../../ui/React/CinematicText";
import { use } from "../../ui/Context";
import { Player } from "../../Player";
import makeStyles from "@mui/styles/makeStyles";
import createStyles from "@mui/styles/createStyles";
import IconButton from "@mui/material/IconButton";
@ -46,7 +44,6 @@ interface IPortalProps {
level: number;
destroyedBitNode: number;
flume: boolean;
enter: (router: IRouter, flume: boolean, destroyedBitNode: number, newBitNode: number) => void;
}
function BitNodePortal(props: IPortalProps): React.ReactElement {
const [portalOpen, setPortalOpen] = useState(false);
@ -105,7 +102,6 @@ function BitNodePortal(props: IPortalProps): React.ReactElement {
onClose={() => setPortalOpen(false)}
n={props.n}
level={props.level}
enter={props.enter}
destroyedBitNode={props.destroyedBitNode}
flume={props.flume}
/>
@ -118,13 +114,10 @@ function BitNodePortal(props: IPortalProps): React.ReactElement {
interface IProps {
flume: boolean;
quick: boolean;
enter: (router: IRouter, flume: boolean, destroyedBitNode: number, newBitNode: number) => void;
}
export function BitverseRoot(props: IProps): React.ReactElement {
const player = use.Player();
const enter = enterBitNode;
const destroyed = player.bitNodeN;
const destroyed = Player.bitNodeN;
const [destroySequence, setDestroySequence] = useState(!props.quick);
if (destroySequence) {
@ -158,7 +151,7 @@ export function BitverseRoot(props: IProps): React.ReactElement {
}
const nextSourceFileLvl = (n: number): number => {
const lvl = player.sourceFileLvl(n);
const lvl = Player.sourceFileLvl(n);
if (n !== destroyed) {
return lvl;
}
@ -181,7 +174,6 @@ export function BitverseRoot(props: IProps): React.ReactElement {
key={node.number}
n={node.number}
level={nextSourceFileLvl(node.number)}
enter={enter}
flume={props.flume}
destroyedBitNode={destroyed}
/>
@ -234,19 +226,19 @@ export function BitverseRoot(props: IProps): React.ReactElement {
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}>O | | | \| | O / _/ | / O | |/ | | | O</Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}>| | | |O / | | O / | O O | | \ O| | | |</Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}>| | |/ \/ / __| | |/ \ | \ | |__ \ \/ \| | |</Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> \| O | |_/ |\| \ <BitNodePortal n={13} level={n(13)} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> \__| \_| | O |/ </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> \| O | |_/ |\| \ <BitNodePortal n={13} level={n(13)} flume={props.flume} destroyedBitNode={destroyed} /> \__| \_| | O |/ </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> | | |_/ | | \| / | \_| | | </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> \| / \| | / / \ |/ </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> | <BitNodePortal n={10} level={n(10)} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> | | / | <BitNodePortal n={11} level={n(11)} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> | </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> <BitNodePortal n={9} level={n(9)} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> | | | | | | | <BitNodePortal n={12} level={n(12)} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> | <BitNodePortal n={10} level={n(10)} flume={props.flume} destroyedBitNode={destroyed} /> | | / | <BitNodePortal n={11} level={n(11)} flume={props.flume} destroyedBitNode={destroyed} /> | </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> <BitNodePortal n={9} level={n(9)} flume={props.flume} destroyedBitNode={destroyed} /> | | | | | | | <BitNodePortal n={12} level={n(12)} flume={props.flume} destroyedBitNode={destroyed} /> </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> | | | / / \ \ | | | </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> \| | / <BitNodePortal n={7} level={n(7)} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> / \ <BitNodePortal n={8} level={n(8)} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> \ | |/ </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> \| | / <BitNodePortal n={7} level={n(7)} flume={props.flume} destroyedBitNode={destroyed} /> / \ <BitNodePortal n={8} level={n(8)} flume={props.flume} destroyedBitNode={destroyed} /> \ | |/ </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> \ | / / | | \ \ | / </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> \ \JUMP <BitNodePortal n={5} level={n(5)} enter={enter} flume={props.flume} destroyedBitNode={destroyed} />3R | | | | | | R3<BitNodePortal n={6} level={n(6)} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> PMUJ/ / </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> \ \JUMP <BitNodePortal n={5} level={n(5)} flume={props.flume} destroyedBitNode={destroyed} />3R | | | | | | R3<BitNodePortal n={6} level={n(6)} flume={props.flume} destroyedBitNode={destroyed} /> PMUJ/ / </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> \|| | | | | | | | | ||/ </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> \| \_ | | | | | | _/ |/ </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> \ \| / \ / \ |/ / </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> <BitNodePortal n={1} level={n(1)} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> |/ <BitNodePortal n={2} level={n(2)} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> | | <BitNodePortal n={3} level={n(3)} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> \| <BitNodePortal n={4} level={n(4)} enter={enter} flume={props.flume} destroyedBitNode={destroyed} /> </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> <BitNodePortal n={1} level={n(1)} flume={props.flume} destroyedBitNode={destroyed} /> |/ <BitNodePortal n={2} level={n(2)} flume={props.flume} destroyedBitNode={destroyed} /> | | <BitNodePortal n={3} level={n(3)} flume={props.flume} destroyedBitNode={destroyed} /> \| <BitNodePortal n={4} level={n(4)} flume={props.flume} destroyedBitNode={destroyed} /> </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> | | | | | | | | </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> \JUMP3R|JUMP|3R| |R3|PMUJ|R3PMUJ/ </Typography>
<br />

@ -1,8 +1,7 @@
import React from "react";
import { enterBitNode } from "../../RedPill";
import { BitNodes } from "../BitNode";
import { IRouter } from "../../ui/Router";
import { use } from "../../ui/Context";
import { Modal } from "../../ui/React/Modal";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
@ -15,11 +14,9 @@ interface IProps {
level: number;
destroyedBitNode: number;
flume: boolean;
enter: (router: IRouter, flume: boolean, destroyedBitNode: number, newBitNode: number) => void;
}
export function PortalModal(props: IProps): React.ReactElement {
const router = use.Router();
const bitNodeKey = "BitNode" + props.n;
const bitNode = BitNodes[bitNodeKey];
if (bitNode == null) throw new Error(`Could not find BitNode object for number: ${props.n}`);
@ -48,7 +45,7 @@ export function PortalModal(props: IProps): React.ReactElement {
aria-label={`enter-bitnode-${bitNode.number.toString()}`}
autoFocus={true}
onClick={() => {
props.enter(router, props.flume, props.destroyedBitNode, props.n);
enterBitNode(props.flume, props.destroyedBitNode, props.n);
props.onClose();
}}
>

@ -2,7 +2,6 @@ import React from "react";
import { IAction } from "../IAction";
import { IBladeburner } from "../IBladeburner";
import { BladeburnerConstants } from "../data/Constants";
import { use } from "../../ui/Context";
import Typography from "@mui/material/Typography";
import Tooltip from "@mui/material/Tooltip";
@ -19,8 +18,6 @@ interface IProps {
}
export function ActionLevel({ action, isActive, bladeburner, rerender }: IProps): React.ReactElement {
const player = use.Player();
const canIncrease = action.level < action.maxLevel;
const canDecrease = action.level > 1;

@ -3,7 +3,7 @@ import { BlackOpList } from "./BlackOpList";
import { IBladeburner } from "../IBladeburner";
import Typography from "@mui/material/Typography";
import { FactionNames } from "../../Faction/data/FactionNames";
import { use } from "../../ui/Context";
import { Router } from "../../ui/GameRoot";
import { BlackOperationNames } from "../data/BlackOperationNames";
import { Button } from "@mui/material";
import { CorruptableText } from "../../ui/React/CorruptableText";
@ -13,7 +13,6 @@ interface IProps {
}
export function BlackOpPage(props: IProps): React.ReactElement {
const router = use.Router();
return (
<>
<Typography>
@ -31,7 +30,7 @@ export function BlackOpPage(props: IProps): React.ReactElement {
losses.
</Typography>
{props.bladeburner.blackops[BlackOperationNames.OperationDaedalus] ? (
<Button sx={{ my: 1, p: 1 }} onClick={() => router.toBitVerse(false, false)}>
<Button sx={{ my: 1, p: 1 }} onClick={() => Router.toBitVerse(false, false)}>
<CorruptableText content="Destroy w0rld_d34mon"></CorruptableText>
</Button>
) : (

@ -1,11 +1,10 @@
import React from "react";
import { FactionNames } from "../../Faction/data/FactionNames";
import { use } from "../../ui/Context";
import { Router } from "../../ui/GameRoot";
import { CinematicText } from "../../ui/React/CinematicText";
import { dialogBoxCreate } from "../../ui/React/DialogBox";
export function BladeburnerCinematic(): React.ReactElement {
const router = use.Router();
return (
<CinematicText
lines={[
@ -32,7 +31,7 @@ export function BladeburnerCinematic(): React.ReactElement {
"investigating and dealing with Synthoid threats.",
]}
onDone={() => {
router.toTerminal();
Router.toTerminal();
dialogBoxCreate(
`Visit the National Security Agency (NSA) to apply for their ${FactionNames.Bladeburners} ` +
"division! You will need 100 of each combat stat before doing this.",

@ -3,12 +3,10 @@ import { Stats } from "./Stats";
import { Console } from "./Console";
import { AllPages } from "./AllPages";
import { use } from "../../ui/Context";
import { Player } from "../../Player";
import Box from "@mui/material/Box";
export function BladeburnerRoot(): React.ReactElement {
const player = use.Player();
const router = use.Router();
const setRerender = useState(false)[1];
function rerender(): void {
setRerender((old) => !old);
@ -19,8 +17,8 @@ export function BladeburnerRoot(): React.ReactElement {
return () => clearInterval(id);
}, []);
const bladeburner = player.bladeburner;
if (bladeburner === null) return <></>;
const bladeburner = Player.bladeburner;
if (!bladeburner) return <></>;
return (
<Box display="flex" flexDirection="column">
<Box sx={{ display: "grid", gridTemplateColumns: "4fr 8fr", p: 1 }}>

@ -2,7 +2,7 @@ import React from "react";
import { IBladeburner } from "../IBladeburner";
import { BlackOperation } from "../BlackOperation";
import { use } from "../../ui/Context";
import { Player } from "../../Player";
import Button from "@mui/material/Button";
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
@ -13,7 +13,6 @@ interface IProps {
rerender: () => void;
}
export function StartButton(props: IProps): React.ReactElement {
const player = use.Player();
const action = props.bladeburner.getActionObject({ name: props.name, type: props.type });
if (action == null) {
throw new Error("Failed to get Operation Object for: " + props.name);
@ -33,7 +32,7 @@ export function StartButton(props: IProps): React.ReactElement {
if (disabled) return;
props.bladeburner.action.type = props.type;
props.bladeburner.action.name = props.name;
if (!player.hasAugmentation(AugmentationNames.BladesSimulacrum, true)) player.finishWork(true);
if (!Player.hasAugmentation(AugmentationNames.BladesSimulacrum, true)) Player.finishWork(true);
props.bladeburner.startAction(props.bladeburner.action);
props.rerender();
}

@ -1,6 +1,6 @@
import React from "react";
import { Company } from "../Company";
import { use } from "../../ui/Context";
import { Player } from "../../Player";
import { Modal } from "../../ui/React/Modal";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
@ -14,9 +14,8 @@ interface IProps {
}
export function QuitJobModal(props: IProps): React.ReactElement {
const player = use.Player();
function quit(): void {
player.quitJob(props.locName);
Player.quitJob(props.locName);
props.onQuit();
props.onClose();
}

@ -1,5 +1,4 @@
import { Industry } from "./Industry";
import { IPlayer } from "../PersonObjects/IPlayer";
import { CorporationUnlockUpgrade } from "./data/CorporationUnlockUpgrades";
import { CorporationUpgrade } from "./data/CorporationUpgrades";
import { CorporationState } from "./CorporationState";
@ -36,7 +35,7 @@ export interface ICorporation {
addFunds(amt: number): void;
getState(): string;
storeCycles(numCycles: number): void;
process(player: IPlayer): void;
process(): void;
determineValuation(): void;
determineCycleValuation(): number;
getTargetSharePrice(): number;
@ -56,7 +55,7 @@ export interface ICorporation {
getEmployeeEffMultiplier(): number;
getSalesMultiplier(): number;
getScientificResearchMultiplier(): number;
getStarterGuide(player: IPlayer): void;
getStarterGuide(): void;
updateDividendTax(): void;
getCycleDividends(): number;
toJSON(): IReviverValue;

@ -6,7 +6,7 @@ import { IIndustry } from "../IIndustry";
import { MainPanel } from "./MainPanel";
import { Industries } from "../IndustryData";
import { ExpandIndustryTab } from "./ExpandIndustryTab";
import { use } from "../../ui/Context";
import { Player } from "../../Player";
import { Context } from "./Context";
import { Overview } from "./Overview";
@ -14,8 +14,7 @@ import Tabs from "@mui/material/Tabs";
import Tab from "@mui/material/Tab";
export function CorporationRoot(): React.ReactElement {
const player = use.Player();
const corporation = player.corporation;
const corporation = Player.corporation;
if (corporation === null) return <></>;
const setRerender = useState(false)[1];
function rerender(): void {

@ -7,7 +7,6 @@ import { IndustryOverview } from "./IndustryOverview";
import { IndustryWarehouse } from "./IndustryWarehouse";
import { Warehouse } from "../Warehouse";
import { OfficeSpace } from "../OfficeSpace";
import { use } from "../../ui/Context";
import { useCorporation, useDivision } from "./Context";
import Box from "@mui/material/Box";
@ -19,7 +18,6 @@ interface IProps {
}
export function Industry(props: IProps): React.ReactElement {
const player = use.Player();
const corp = useCorporation();
const division = useDivision();
return (

@ -21,7 +21,7 @@ import { convertTimeMsToTimeElapsedString } from "../../utils/StringHelperFuncti
import { Money } from "../../ui/React/Money";
import { MoneyRate } from "../../ui/React/MoneyRate";
import { StatsTable } from "../../ui/React/StatsTable";
import { use } from "../../ui/Context";
import { Player } from "../../Player";
import { useCorporation } from "./Context";
import Typography from "@mui/material/Typography";
import Tooltip from "@mui/material/Tooltip";
@ -34,7 +34,6 @@ interface IProps {
rerender: () => void;
}
export function Overview({ rerender }: IProps): React.ReactElement {
const player = use.Player();
const corp = useCorporation();
const profit: number = corp.revenue - corp.expenses;
@ -100,7 +99,7 @@ export function Overview({ rerender }: IProps): React.ReactElement {
</Typography>
}
>
<Button onClick={() => corp.getStarterGuide(player)}>Getting Started Guide</Button>
<Button onClick={() => corp.getStarterGuide()}>Getting Started Guide</Button>
</Tooltip>
{corp.public ? <PublicButtons rerender={rerender} /> : <PrivateButtons rerender={rerender} />}
<BribeButton />
@ -240,12 +239,11 @@ function PublicButtons({ rerender }: IPublicButtonsProps): React.ReactElement {
}
function BribeButton(): React.ReactElement {
const player = use.Player();
const corp = useCorporation();
const [open, setOpen] = useState(false);
const canBribe =
corp.valuation >= CorporationConstants.BribeThreshold &&
player.factions.filter((f) => Factions[f].getInfo().offersWork()).length > 0;
Player.factions.filter((f) => Factions[f].getInfo().offersWork()).length > 0;
function openBribe(): void {
if (!canBribe) return;

@ -4,7 +4,7 @@ import { CorporationConstants } from "../../data/Constants";
import { numeralWrapper } from "../../../ui/numeralFormat";
import { dialogBoxCreate } from "../../../ui/React/DialogBox";
import { Modal } from "../../../ui/React/Modal";
import { use } from "../../../ui/Context";
import { Player } from "../../../Player";
import { useCorporation } from "../Context";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
@ -19,11 +19,10 @@ interface IProps {
}
export function BribeFactionModal(props: IProps): React.ReactElement {
const player = use.Player();
const factions = player.factions.filter((name: string) => {
const factions = Player.factions.filter((name: string) => {
const info = Factions[name].getInfo();
if (!info.offersWork()) return false;
if (player.hasGangWith(name)) return false;
if (Player.hasGangWith(name)) return false;
return true;
});
const corp = useCorporation();
@ -77,7 +76,7 @@ export function BribeFactionModal(props: IProps): React.ReactElement {
{factions.map((name: string) => {
const info = Factions[name].getInfo();
if (!info.offersWork()) return;
if (player.hasGangWith(name)) return;
if (Player.hasGangWith(name)) return;
return (
<MenuItem key={name} value={name}>
{name}

@ -1,7 +1,7 @@
import React, { useState } from "react";
import { Modal } from "../../../ui/React/Modal";
import { numeralWrapper } from "../../../ui/numeralFormat";
import { use } from "../../../ui/Context";
import { Player } from "../../../Player";
import { useCorporation } from "../Context";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
@ -19,7 +19,6 @@ interface IProps {
// Create a popup that lets the player buyback shares
// This is created when the player clicks the "Buyback Shares" button in the overview panel
export function BuybackSharesModal(props: IProps): React.ReactElement {
const player = use.Player();
const corp = useCorporation();
const [shares, setShares] = useState<number>(NaN);
@ -30,7 +29,7 @@ export function BuybackSharesModal(props: IProps): React.ReactElement {
isNaN(shares) ||
shares <= 0 ||
shares > corp.issuedShares ||
shares * buybackPrice > player.money;
shares * buybackPrice > Player.money;
function buy(): void {
if (disabled) return;

@ -2,7 +2,8 @@ import React, { useState } from "react";
import { Money } from "../../../ui/React/Money";
import { Modal } from "../../../ui/React/Modal";
import { use } from "../../../ui/Context";
import { Router } from "../../../ui/GameRoot";
import { Player } from "../../../Player";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import TextField from "@mui/material/TextField";
@ -13,10 +14,8 @@ interface IProps {
}
export function CreateCorporationModal(props: IProps): React.ReactElement {
const player = use.Player();
const router = use.Router();
const canSelfFund = player.canAfford(150e9);
if (!player.canAccessCorporation() || player.hasCorporation()) {
const canSelfFund = Player.canAfford(150e9);
if (!Player.canAccessCorporation() || Player.hasCorporation()) {
props.onClose();
return <></>;
}
@ -35,11 +34,11 @@ export function CreateCorporationModal(props: IProps): React.ReactElement {
return;
}
player.startCorporation(name);
player.loseMoney(150e9, "corporation");
Player.startCorporation(name);
Player.loseMoney(150e9, "corporation");
props.onClose();
router.toCorporation();
Router.toCorporation();
}
function seed(): void {
@ -47,17 +46,17 @@ export function CreateCorporationModal(props: IProps): React.ReactElement {
return;
}
player.startCorporation(name, 500e6);
Player.startCorporation(name, 500e6);
props.onClose();
router.toCorporation();
Router.toCorporation();
}
return (
<Modal open={props.open} onClose={props.onClose}>
<Typography>
Would you like to start a corporation? This will require $150b for registration and initial funding.{" "}
{player.bitNodeN === 3 &&
{Player.bitNodeN === 3 &&
`This $150b
can either be self-funded, or you can obtain the seed money from the government in exchange for 500 million
shares`}
@ -66,7 +65,7 @@ export function CreateCorporationModal(props: IProps): React.ReactElement {
If you would like to start one, please enter a name for your corporation below:
</Typography>
<TextField autoFocus={true} placeholder="Corporation Name" onChange={onChange} value={name} />
{player.bitNodeN === 3 && (
{Player.bitNodeN === 3 && (
<Button onClick={seed} disabled={name == ""}>
Use seed money
</Button>

@ -2,7 +2,6 @@ import React, { useState } from "react";
import { numeralWrapper } from "../../../ui/numeralFormat";
import { dialogBoxCreate } from "../../../ui/React/DialogBox";
import { Modal } from "../../../ui/React/Modal";
import { use } from "../../../ui/Context";
import { useCorporation } from "../Context";
import { ICorporation } from "../../ICorporation";
import Typography from "@mui/material/Typography";
@ -20,7 +19,6 @@ interface IProps {
// Create a popup that lets the player sell Corporation shares
// This is created when the player clicks the "Sell Shares" button in the overview panel
export function SellSharesModal(props: IProps): React.ReactElement {
const player = use.Player();
const corp = useCorporation();
const [shares, setShares] = useState<number>(NaN);

@ -1,5 +1,5 @@
import { CONSTANTS } from "../Constants";
import { IPlayer } from "../PersonObjects/IPlayer";
import { Player } from "../Player";
import { IPerson } from "../PersonObjects/IPerson";
import { WorkerScript } from "../Netscript/WorkerScript";
import { CrimeType } from "../utils/WorkType";
@ -101,11 +101,11 @@ export class Crime {
this.kills = params.kills ? params.kills : 0;
}
commit(p: IPlayer, div = 1, workerScript: WorkerScript | null = null): number {
commit(div = 1, workerScript: WorkerScript | null = null): number {
if (div <= 0) {
div = 1;
}
p.startWork(
Player.startWork(
new CrimeWork({
crimeType: this.type,
singularity: workerScript !== null,

@ -1,16 +1,15 @@
import React from "react";
import { use } from "../ui/Context";
import { Player } from "../Player";
import { Exploit } from "./Exploit";
const getComputedStyle = window.getComputedStyle;
export function Unclickable(): React.ReactElement {
const player = use.Player();
function unclickable(event: React.MouseEvent<HTMLDivElement>): void {
if (!event.target || !(event.target instanceof Element)) return;
const display = getComputedStyle(event.target).display;
const visibility = getComputedStyle(event.target).visibility;
if (display === "none" && visibility === "hidden" && event.isTrusted) player.giveExploit(Exploit.Unclickable);
if (display === "none" && visibility === "hidden" && event.isTrusted) Player.giveExploit(Exploit.Unclickable);
}
return (

@ -1,7 +1,7 @@
import React from "react";
import { IMap } from "../types";
import { FactionNames } from "./data/FactionNames";
import { use } from "../ui/Context";
import { Router } from "../ui/GameRoot";
import { Option } from "./ui/Option";
import { Typography } from "@mui/material";
@ -449,12 +449,11 @@ export const FactionInfos: IMap<FactionInfo> = {
special: true,
assignment: (): React.ReactElement => {
const router = use.Router();
return (
<Option
buttonText={"Open Bladeburner headquarters"}
infoText={"You can gain reputation with bladeburner by completing contracts and operations."}
onClick={() => router.toBladeburner()}
onClick={() => Router.toBladeburner()}
/>
);
},
@ -499,7 +498,6 @@ export const FactionInfos: IMap<FactionInfo> = {
special: true,
keepOnInstall: true,
assignment: (): React.ReactElement => {
const router = use.Router();
return (
<Option
buttonText={"Open Staneks Gift"}
@ -507,7 +505,7 @@ export const FactionInfos: IMap<FactionInfo> = {
"Stanek's Gift is a powerful augmentation that powers up the stat you chose to boost." +
"Gaining reputation with the Church of the Machine God can only be done by charging the gift."
}
onClick={() => router.toStaneksGift()}
onClick={() => Router.toStaneksGift()}
/>
);
},

@ -3,7 +3,8 @@
*/
import React from "react";
import { Modal } from "../../ui/React/Modal";
import { use } from "../../ui/Context";
import { Router } from "../../ui/GameRoot";
import { Player } from "../../Player";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import { KEY } from "../../utils/helpers/keyCodes";
@ -16,8 +17,6 @@ interface IProps {
}
export function CreateGangModal(props: IProps): React.ReactElement {
const player = use.Player();
const router = use.Router();
const combatGangText =
"This is a COMBAT gang. Members in this gang will have different tasks than HACKING gangs. " +
"Compared to hacking gangs, progression with combat gangs can be more difficult as territory management " +
@ -33,9 +32,9 @@ export function CreateGangModal(props: IProps): React.ReactElement {
}
function createGang(): void {
player.startGang(props.facName, isHacking());
Player.startGang(props.facName, isHacking());
props.onClose();
router.toGang();
Router.toGang();
}
function onKeyUp(event: React.KeyboardEvent): void {

@ -1,7 +1,8 @@
import { Button, Typography, Box, Paper, Tooltip } from "@mui/material";
import React, { useState } from "react";
import { GangConstants } from "../../Gang/data/Constants";
import { use } from "../../ui/Context";
import { Router } from "../../ui/GameRoot";
import { Player } from "../../Player";
import { Faction } from "../Faction";
import { CreateGangModal } from "./CreateGangModal";
@ -10,14 +11,12 @@ type IProps = {
};
export function GangButton({ faction }: IProps): React.ReactElement {
const player = use.Player();
const router = use.Router();
const [gangOpen, setGangOpen] = useState(false);
if (
!GangConstants.Names.includes(faction.name) || // not even a gang
!player.isAwareOfGang() || // doesn't know about gang
(player.inGang() && player.getGangName() !== faction.name) // already in another gang
!Player.isAwareOfGang() || // doesn't know about gang
(Player.inGang() && Player.getGangName() !== faction.name) // already in another gang
) {
return <></>;
}
@ -29,7 +28,7 @@ export function GangButton({ faction }: IProps): React.ReactElement {
description: "",
};
if (player.inGang()) {
if (Player.inGang()) {
data = {
enabled: true,
title: "Manage Gang",
@ -38,9 +37,9 @@ export function GangButton({ faction }: IProps): React.ReactElement {
};
} else {
data = {
enabled: player.canAccessGang(),
enabled: Player.canAccessGang(),
title: "Create Gang",
tooltip: !player.canAccessGang() ? (
tooltip: !Player.canAccessGang() ? (
<Typography>Unlocked when reaching {GangConstants.GangKarmaRequirement} karma</Typography>
) : (
""
@ -51,8 +50,8 @@ export function GangButton({ faction }: IProps): React.ReactElement {
const manageGang = (): void => {
// If player already has a gang, just go to the gang UI
if (player.inGang()) {
return router.toGang();
if (Player.inGang()) {
return Router.toGang();
}
setGangOpen(true);

@ -2,7 +2,7 @@ import React, { useState, useEffect } from "react";
import { joinFaction } from "../FactionHelpers";
import { Faction } from "../Faction";
import { Modal } from "../../ui/React/Modal";
import { use } from "../../ui/Context";
import { Player } from "../../Player";
import { EventEmitter } from "../../utils/EventEmitter";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
@ -11,11 +11,10 @@ export const InvitationEvent = new EventEmitter<[Faction]>();
export function InvitationModal(): React.ReactElement {
const [faction, setFaction] = useState<Faction | null>(null);
const player = use.Player();
function join(): void {
if (faction === null) return;
//Remove from invited factions
const i = player.factionInvitations.findIndex((facName) => facName === faction.name);
const i = Player.factionInvitations.findIndex((facName) => facName === faction.name);
if (i === -1) {
console.error("Could not find faction in Player.factionInvitations");
}

@ -2,10 +2,9 @@ import React from "react";
import { OptionSwitch } from "../../ui/React/OptionSwitch";
import { Settings } from "../../Settings/Settings";
import { GameOptionsPage } from "./GameOptionsPage";
import { use } from "../../ui/Context";
import { Player } from "../../Player";
export const GameplayPage = (): React.ReactElement => {
const player = use.Player();
return (
<GameOptionsPage title="Gameplay">
<OptionSwitch
@ -53,7 +52,7 @@ export const GameplayPage = (): React.ReactElement => {
text="Suppress TIX messages"
tooltip={<>If this is set, the stock market will never create any popup.</>}
/>
{player.bladeburner && (
{Player.bladeburner && (
<OptionSwitch
checked={Settings.SuppressBladeburnerPopup}
onChange={(newValue) => (Settings.SuppressBladeburnerPopup = newValue)}

@ -3,7 +3,7 @@ import { GangMemberTasks } from "./GangMemberTasks";
import { GangMemberUpgrade } from "./GangMemberUpgrade";
import { GangMemberUpgrades } from "./GangMemberUpgrades";
import { IAscensionResult } from "./IAscensionResult";
import { IPlayer } from "../PersonObjects/IPlayer";
import { Player } from "../Player";
import { IGang } from "./IGang";
import { Generic_fromJSON, Generic_toJSON, IReviverValue, Reviver } from "../utils/JSONReviver";
import {
@ -302,12 +302,14 @@ export class GangMember {
if (upg.mults.hack != null) this.hack_mult *= upg.mults.hack;
}
buyUpgrade(upg: GangMemberUpgrade, player: IPlayer, gang: IGang): boolean {
buyUpgrade(upg: GangMemberUpgrade): boolean {
if (!Player.gang) throw new Error("Tried to buy a gang member upgrade when no gang was present");
// Prevent purchasing of already-owned upgrades
if (this.augmentations.includes(upg.name) || this.upgrades.includes(upg.name)) return false;
if (player.money < gang.getUpgradeCost(upg)) return false;
player.loseMoney(gang.getUpgradeCost(upg), "gang");
if (Player.money < Player.gang.getUpgradeCost(upg)) return false;
Player.loseMoney(Player.gang.getUpgradeCost(upg), "gang");
if (upg.type === "g") {
this.augmentations.push(upg.name);
} else {

@ -19,7 +19,7 @@ import { GangMemberUpgrade } from "../GangMemberUpgrade";
import { Money } from "../../ui/React/Money";
import { GangMember } from "../GangMember";
import { UpgradeType } from "../data/upgrades";
import { use } from "../../ui/Context";
import { Player } from "../../Player";
import { Settings } from "../../Settings/Settings";
import { StatsRow } from "../../ui/React/StatsRow";
@ -30,11 +30,10 @@ interface INextRevealProps {
function NextReveal(props: INextRevealProps): React.ReactElement {
const gang = useGang();
const player = use.Player();
const upgrades = Object.keys(GangMemberUpgrades)
.filter((upgName: string) => {
const upg = GangMemberUpgrades[upgName];
if (player.money > gang.getUpgradeCost(upg)) return false;
if (Player.money > gang.getUpgradeCost(upg)) return false;
if (upg.type !== props.type) return false;
if (props.upgrades.includes(upgName)) return false;
return true;
@ -68,9 +67,8 @@ interface IUpgradeButtonProps {
function UpgradeButton(props: IUpgradeButtonProps): React.ReactElement {
const gang = useGang();
const player = use.Player();
function onClick(): void {
props.member.buyUpgrade(props.upg, player, gang);
props.member.buyUpgrade(props.upg);
props.rerender();
}
return (
@ -91,7 +89,6 @@ interface IPanelProps {
function GangMemberUpgradePanel(props: IPanelProps): React.ReactElement {
const gang = useGang();
const player = use.Player();
const setRerender = useState(false)[1];
const [currentCategory, setCurrentCategory] = useState("Weapons");
@ -103,7 +100,7 @@ function GangMemberUpgradePanel(props: IPanelProps): React.ReactElement {
return Object.keys(GangMemberUpgrades)
.filter((upgName: string) => {
const upg = GangMemberUpgrades[upgName];
if (player.money < gang.getUpgradeCost(upg)) return false;
if (Player.money < gang.getUpgradeCost(upg)) return false;
if (upg.type !== type) return false;
if (list.includes(upgName)) return false;
return true;

@ -5,17 +5,16 @@ import React, { useState, useEffect } from "react";
import { ManagementSubpage } from "./ManagementSubpage";
import { TerritorySubpage } from "./TerritorySubpage";
import { EquipmentsSubpage } from "./EquipmentsSubpage";
import { use } from "../../ui/Context";
import { Player } from "../../Player";
import { Context } from "./Context";
import Tabs from "@mui/material/Tabs";
import Tab from "@mui/material/Tab";
export function GangRoot(): React.ReactElement {
const player = use.Player();
const gang = (function () {
if (player.gang === null) throw new Error("Gang should not be null");
return player.gang;
if (Player.gang === null) throw new Error("Gang should not be null");
return Player.gang;
})();
const [value, setValue] = React.useState(0);

@ -1,7 +1,8 @@
import { Button, Container, Paper, Typography } from "@mui/material";
import React, { useState } from "react";
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
import { use } from "../../ui/Context";
import { Router } from "../../ui/GameRoot";
import { Player } from "../../Player";
import { BackwardGame } from "./BackwardGame";
import { BracketGame } from "./BracketGame";
import { BribeGame } from "./BribeGame";
@ -39,8 +40,6 @@ const minigames = [
];
export function Game(props: IProps): React.ReactElement {
const player = use.Player();
const router = use.Router();
const [level, setLevel] = useState(1);
const [stage, setStage] = useState(Stage.Countdown);
const [results, setResults] = useState("");
@ -91,17 +90,17 @@ export function Game(props: IProps): React.ReactElement {
// Kill the player immediately if they use automation, so
// it's clear they're not meant to
const damage = options?.automated
? player.hp.current
: props.StartingDifficulty * 3 * (player.hasAugmentation(AugmentationNames.WKSharmonizer, true) ? 0.5 : 1);
if (player.takeDamage(damage)) {
router.toCity();
? Player.hp.current
: props.StartingDifficulty * 3 * (Player.hasAugmentation(AugmentationNames.WKSharmonizer, true) ? 0.5 : 1);
if (Player.takeDamage(damage)) {
Router.toCity();
return;
}
setupNextGame();
}
function cancel(): void {
router.toCity();
Router.toCity();
return;
}

@ -1,7 +1,7 @@
import { Paper } from "@mui/material";
import React, { useEffect, useState } from "react";
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
import { use } from "../../ui/Context";
import { Player } from "../../Player";
import { ProgressBar } from "../../ui/React/Progress";
interface IProps {
@ -11,9 +11,8 @@ interface IProps {
}
export function GameTimer(props: IProps): React.ReactElement {
const player = use.Player();
const [v, setV] = useState(100);
const totalMillis = (player.hasAugmentation(AugmentationNames.WKSharmonizer, true) ? 1.3 : 1) * props.millis;
const totalMillis = (Player.hasAugmentation(AugmentationNames.WKSharmonizer, true) ? 1.3 : 1) * props.millis;
const tick = 200;
useEffect(() => {

@ -1,6 +1,7 @@
import React, { useState } from "react";
import { Location } from "../../Locations/Location";
import { use } from "../../ui/Context";
import { Router } from "../../ui/GameRoot";
import { Player } from "../../Player";
import { calculateDifficulty, calculateReward } from "../formulas/game";
import { Game } from "./Game";
import { Intro } from "./Intro";
@ -9,17 +10,15 @@ interface IProps {
}
export function InfiltrationRoot(props: IProps): React.ReactElement {
const player = use.Player();
const router = use.Router();
const [start, setStart] = useState(false);
if (props.location.infiltrationData === undefined) throw new Error("Trying to do infiltration on invalid location.");
const startingSecurityLevel = props.location.infiltrationData.startingSecurityLevel;
const difficulty = calculateDifficulty(player, startingSecurityLevel);
const reward = calculateReward(player, startingSecurityLevel);
const difficulty = calculateDifficulty(Player, startingSecurityLevel);
const reward = calculateReward(Player, startingSecurityLevel);
function cancel(): void {
router.toCity();
Router.toCity();
}
return (

@ -3,7 +3,8 @@ import React, { useState } from "react";
import { FactionNames } from "../../Faction/data/FactionNames";
import { inviteToFaction } from "../../Faction/FactionHelpers";
import { Factions } from "../../Faction/Factions";
import { use } from "../../ui/Context";
import { Router } from "../../ui/GameRoot";
import { Player } from "../../Player";
import { Money } from "../../ui/React/Money";
import { Reputation } from "../../ui/React/Reputation";
import { formatNumber } from "../../utils/StringHelperFunctions";
@ -21,25 +22,23 @@ interface IProps {
}
export function Victory(props: IProps): React.ReactElement {
const player = use.Player();
const router = use.Router();
const [faction, setFaction] = useState("none");
function quitInfiltration(): void {
handleInfiltrators();
router.toCity();
Router.toCity();
}
const soa = Factions[FactionNames.ShadowsOfAnarchy];
const repGain = calculateTradeInformationRepReward(player, props.Reward, props.MaxLevel, props.StartingDifficulty);
const moneyGain = calculateSellInformationCashReward(player, props.Reward, props.MaxLevel, props.StartingDifficulty);
const infiltrationRepGain = calculateInfiltratorsRepReward(player, soa, props.StartingDifficulty);
const repGain = calculateTradeInformationRepReward(Player, props.Reward, props.MaxLevel, props.StartingDifficulty);
const moneyGain = calculateSellInformationCashReward(Player, props.Reward, props.MaxLevel, props.StartingDifficulty);
const infiltrationRepGain = calculateInfiltratorsRepReward(Player, soa, props.StartingDifficulty);
const isMemberOfInfiltrators = player.factions.includes(FactionNames.ShadowsOfAnarchy);
const isMemberOfInfiltrators = Player.factions.includes(FactionNames.ShadowsOfAnarchy);
function sell(): void {
handleInfiltrators();
player.gainMoney(moneyGain, "infiltration");
Player.gainMoney(moneyGain, "infiltration");
quitInfiltration();
}
@ -81,7 +80,7 @@ export function Victory(props: IProps): React.ReactElement {
<MenuItem key={"none"} value={"none"}>
{"none"}
</MenuItem>
{player.factions
{Player.factions
.filter((f) => Factions[f].getInfo().offersWork())
.map((f) => (
<MenuItem key={f} value={f}>

@ -7,7 +7,7 @@ import { Company } from "../../Company/Company";
import { CompanyPosition } from "../../Company/CompanyPosition";
import { getJobRequirementText } from "../../Company/GetJobRequirementText";
import { use } from "../../ui/Context";
import { Player } from "../../Player";
import Button from "@mui/material/Button";
import Tooltip from "@mui/material/Tooltip";
@ -19,10 +19,8 @@ type IProps = {
};
export function ApplyToJobButton(props: IProps): React.ReactElement {
const player = use.Player();
function getJobRequirementTooltip(): string {
const pos = player.getNextCompanyPosition(props.company, props.entryPosType);
const pos = Player.getNextCompanyPosition(props.company, props.entryPosType);
if (pos == null) {
return "";
}

@ -12,8 +12,8 @@ import { Locations } from "../Locations";
import { Location } from "../Location";
import { Settings } from "../../Settings/Settings";
import { use } from "../../ui/Context";
import { IRouter } from "../../ui/Router";
import { Player } from "../../Player";
import { Router } from "../../ui/GameRoot";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import { LocationType } from "../LocationTypeEnum";
@ -37,19 +37,18 @@ const useStyles = makeStyles((theme: Theme) =>
}),
);
function toLocation(router: IRouter, location: Location): void {
function toLocation(location: Location): void {
if (location.name === LocationName.TravelAgency) {
router.toTravel();
Router.toTravel();
} else if (location.name === LocationName.WorldStockExchange) {
router.toStockMarket();
Router.toStockMarket();
} else {
router.toLocation(location);
Router.toLocation(location);
}
}
function LocationLetter(location: Location): React.ReactElement {
location.types;
const router = use.Router();
const classes = useStyles();
let L = "X";
if (location.types.includes(LocationType.Company)) L = "C";
@ -68,7 +67,7 @@ function LocationLetter(location: Location): React.ReactElement {
aria-label={location.name}
key={location.name}
className={classes.location}
onClick={() => toLocation(router, location)}
onClick={() => toLocation(location)}
>
<b>{L}</b>
</span>
@ -147,11 +146,10 @@ function ASCIICity(props: IProps): React.ReactElement {
}
function ListCity(props: IProps): React.ReactElement {
const router = use.Router();
const locationButtons = props.city.locations.map((locName) => {
return (
<React.Fragment key={locName}>
<Button onClick={() => toLocation(router, Locations[locName])}>{locName}</Button>
<Button onClick={() => toLocation(Locations[locName])}>{locName}</Button>
<br />
</React.Fragment>
);
@ -161,8 +159,7 @@ function ListCity(props: IProps): React.ReactElement {
}
export function LocationCity(): React.ReactElement {
const player = use.Player();
const city = Cities[player.city];
const city = Cities[Player.city];
return (
<>
<Typography>{city.name}</Typography>

@ -21,7 +21,8 @@ import * as posNames from "../../Company/data/companypositionnames";
import { Reputation } from "../../ui/React/Reputation";
import { Favor } from "../../ui/React/Favor";
import { use } from "../../ui/Context";
import { Router } from "../../ui/GameRoot";
import { Player } from "../../Player";
import { QuitJobModal } from "../../Company/ui/QuitJobModal";
import { CompanyWork } from "../../Work/CompanyWork";
@ -30,8 +31,6 @@ type IProps = {
};
export function CompanyLocation(props: IProps): React.ReactElement {
const p = use.Player();
const router = use.Router();
const [quitOpen, setQuitOpen] = useState(false);
const setRerender = useState(false)[1];
function rerender(): void {
@ -60,7 +59,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
/**
* Name of company position that player holds, if applicable
*/
const jobTitle = p.jobs[props.locName] ? p.jobs[props.locName] : null;
const jobTitle = Player.jobs[props.locName] ? Player.jobs[props.locName] : null;
/**
* CompanyPosition object for the job that the player holds at this company
@ -68,13 +67,13 @@ export function CompanyLocation(props: IProps): React.ReactElement {
*/
const companyPosition = jobTitle ? CompanyPositions[jobTitle] : null;
p.location = props.locName;
Player.location = props.locName;
function applyForAgentJob(e: React.MouseEvent<HTMLElement>): void {
if (!e.isTrusted) {
return;
}
p.applyForAgentJob();
Player.applyForAgentJob();
rerender();
}
@ -82,7 +81,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
if (!e.isTrusted) {
return;
}
p.applyForBusinessConsultantJob();
Player.applyForBusinessConsultantJob();
rerender();
}
@ -90,7 +89,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
if (!e.isTrusted) {
return;
}
p.applyForBusinessJob();
Player.applyForBusinessJob();
rerender();
}
@ -98,7 +97,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
if (!e.isTrusted) {
return;
}
p.applyForEmployeeJob();
Player.applyForEmployeeJob();
rerender();
}
@ -106,7 +105,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
if (!e.isTrusted) {
return;
}
p.applyForItJob();
Player.applyForItJob();
rerender();
}
@ -114,7 +113,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
if (!e.isTrusted) {
return;
}
p.applyForPartTimeEmployeeJob();
Player.applyForPartTimeEmployeeJob();
rerender();
}
@ -122,7 +121,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
if (!e.isTrusted) {
return;
}
p.applyForPartTimeWaiterJob();
Player.applyForPartTimeWaiterJob();
rerender();
}
@ -130,7 +129,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
if (!e.isTrusted) {
return;
}
p.applyForSecurityJob();
Player.applyForSecurityJob();
rerender();
}
@ -138,7 +137,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
if (!e.isTrusted) {
return;
}
p.applyForSoftwareConsultantJob();
Player.applyForSoftwareConsultantJob();
rerender();
}
@ -146,7 +145,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
if (!e.isTrusted) {
return;
}
p.applyForSoftwareJob();
Player.applyForSoftwareJob();
rerender();
}
@ -154,7 +153,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
if (!e.isTrusted) {
return;
}
p.applyForWaiterJob();
Player.applyForWaiterJob();
rerender();
}
@ -166,7 +165,7 @@ export function CompanyLocation(props: IProps): React.ReactElement {
if (!loc.infiltrationData)
throw new Error(`trying to start infiltration at ${props.locName} but the infiltrationData is null`);
router.toInfiltration(loc);
Router.toInfiltration(loc);
}
function work(e: React.MouseEvent<HTMLElement>): void {
@ -176,14 +175,14 @@ export function CompanyLocation(props: IProps): React.ReactElement {
const pos = companyPosition;
if (pos instanceof CompanyPosition) {
p.startWork(
Player.startWork(
new CompanyWork({
singularity: false,
companyName: props.locName,
}),
);
p.startFocusing();
router.toWork();
Player.startFocusing();
Router.toWork();
}
}

@ -6,7 +6,7 @@ import { purchaseServer } from "../../Server/ServerPurchases";
import { numeralWrapper } from "../../ui/numeralFormat";
import { Money } from "../../ui/React/Money";
import { Modal } from "../../ui/React/Modal";
import { use } from "../../ui/Context";
import { Player } from "../../Player";
import Typography from "@mui/material/Typography";
import TextField from "@mui/material/TextField";
import Button from "@mui/material/Button";
@ -21,7 +21,6 @@ interface IProps {
}
export function PurchaseServerModal(props: IProps): React.ReactElement {
const player = use.Player();
const [hostname, setHostname] = useState("");
function tryToPurchaseServer(): void {
@ -56,7 +55,7 @@ export function PurchaseServerModal(props: IProps): React.ReactElement {
placeholder="Unique Hostname"
InputProps={{
endAdornment: (
<Button onClick={tryToPurchaseServer} disabled={!player.canAfford(props.cost) || hostname === ""}>
<Button onClick={tryToPurchaseServer} disabled={!Player.canAfford(props.cost) || hostname === ""}>
Buy
</Button>
),

@ -10,132 +10,131 @@ import Tooltip from "@mui/material/Tooltip";
import { Crimes } from "../../Crime/Crimes";
import { numeralWrapper } from "../../ui/numeralFormat";
import { use } from "../../ui/Context";
import { Router } from "../../ui/GameRoot";
import { Player } from "../../Player";
import { Box } from "@mui/material";
export function SlumsLocation(): React.ReactElement {
const player = use.Player();
const router = use.Router();
function shoplift(e: React.MouseEvent<HTMLElement>): void {
if (!e.isTrusted) {
return;
}
Crimes.Shoplift.commit(player);
router.toWork();
player.focus = true;
Crimes.Shoplift.commit();
Router.toWork();
Player.focus = true;
}
function robStore(e: React.MouseEvent<HTMLElement>): void {
if (!e.isTrusted) {
return;
}
Crimes.RobStore.commit(player);
router.toWork();
player.focus = true;
Crimes.RobStore.commit();
Router.toWork();
Player.focus = true;
}
function mug(e: React.MouseEvent<HTMLElement>): void {
if (!e.isTrusted) {
return;
}
Crimes.Mug.commit(player);
router.toWork();
player.focus = true;
Crimes.Mug.commit();
Router.toWork();
Player.focus = true;
}
function larceny(e: React.MouseEvent<HTMLElement>): void {
if (!e.isTrusted) {
return;
}
Crimes.Larceny.commit(player);
router.toWork();
player.focus = true;
Crimes.Larceny.commit();
Router.toWork();
Player.focus = true;
}
function dealDrugs(e: React.MouseEvent<HTMLElement>): void {
if (!e.isTrusted) {
return;
}
Crimes.DealDrugs.commit(player);
router.toWork();
player.focus = true;
Crimes.DealDrugs.commit();
Router.toWork();
Player.focus = true;
}
function bondForgery(e: React.MouseEvent<HTMLElement>): void {
if (!e.isTrusted) {
return;
}
Crimes.BondForgery.commit(player);
router.toWork();
player.focus = true;
Crimes.BondForgery.commit();
Router.toWork();
Player.focus = true;
}
function traffickArms(e: React.MouseEvent<HTMLElement>): void {
if (!e.isTrusted) {
return;
}
Crimes.TraffickArms.commit(player);
router.toWork();
player.focus = true;
Crimes.TraffickArms.commit();
Router.toWork();
Player.focus = true;
}
function homicide(e: React.MouseEvent<HTMLElement>): void {
if (!e.isTrusted) {
return;
}
Crimes.Homicide.commit(player);
router.toWork();
player.focus = true;
Crimes.Homicide.commit();
Router.toWork();
Player.focus = true;
}
function grandTheftAuto(e: React.MouseEvent<HTMLElement>): void {
if (!e.isTrusted) {
return;
}
Crimes.GrandTheftAuto.commit(player);
router.toWork();
player.focus = true;
Crimes.GrandTheftAuto.commit();
Router.toWork();
Player.focus = true;
}
function kidnap(e: React.MouseEvent<HTMLElement>): void {
if (!e.isTrusted) {
return;
}
Crimes.Kidnap.commit(player);
router.toWork();
player.focus = true;
Crimes.Kidnap.commit();
Router.toWork();
Player.focus = true;
}
function assassinate(e: React.MouseEvent<HTMLElement>): void {
if (!e.isTrusted) {
return;
}
Crimes.Assassination.commit(player);
router.toWork();
player.focus = true;
Crimes.Assassination.commit();
Router.toWork();
Player.focus = true;
}
function heist(e: React.MouseEvent<HTMLElement>): void {
if (!e.isTrusted) {
return;
}
Crimes.Heist.commit(player);
router.toWork();
player.focus = true;
Crimes.Heist.commit();
Router.toWork();
Player.focus = true;
}
const shopliftChance = Crimes.Shoplift.successRate(player);
const robStoreChance = Crimes.RobStore.successRate(player);
const mugChance = Crimes.Mug.successRate(player);
const larcenyChance = Crimes.Larceny.successRate(player);
const drugsChance = Crimes.DealDrugs.successRate(player);
const bondChance = Crimes.BondForgery.successRate(player);
const armsChance = Crimes.TraffickArms.successRate(player);
const homicideChance = Crimes.Homicide.successRate(player);
const gtaChance = Crimes.GrandTheftAuto.successRate(player);
const kidnapChance = Crimes.Kidnap.successRate(player);
const assassinateChance = Crimes.Assassination.successRate(player);
const heistChance = Crimes.Heist.successRate(player);
const shopliftChance = Crimes.Shoplift.successRate(Player);
const robStoreChance = Crimes.RobStore.successRate(Player);
const mugChance = Crimes.Mug.successRate(Player);
const larcenyChance = Crimes.Larceny.successRate(Player);
const drugsChance = Crimes.DealDrugs.successRate(Player);
const bondChance = Crimes.BondForgery.successRate(Player);
const armsChance = Crimes.TraffickArms.successRate(Player);
const homicideChance = Crimes.Homicide.successRate(Player);
const gtaChance = Crimes.GrandTheftAuto.successRate(Player);
const kidnapChance = Crimes.Kidnap.successRate(Player);
const assassinateChance = Crimes.Assassination.successRate(Player);
const heistChance = Crimes.Heist.successRate(Player);
return (
<Box sx={{ display: "grid", width: "fit-content" }}>

@ -21,7 +21,8 @@ import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
import { Factions } from "../../Faction/Factions";
import { joinFaction } from "../../Faction/FactionHelpers";
import { use } from "../../ui/Context";
import { Router } from "../../ui/GameRoot";
import { Player } from "../../Player";
import { dialogBoxCreate } from "../../ui/React/DialogBox";
import { SnackbarEvents, ToastVariant } from "../../ui/React/Snackbar";
@ -41,27 +42,24 @@ type IProps = {
};
export function SpecialLocation(props: IProps): React.ReactElement {
const player = use.Player();
const router = use.Router();
const setRerender = useState(false)[1];
const inBladeburner = player.inBladeburner();
const inBladeburner = Player.inBladeburner();
/**
* Click handler for Bladeburner button at Sector-12 NSA
*/
function handleBladeburner(): void {
const p = player;
if (p.inBladeburner()) {
if (Player.inBladeburner()) {
// Enter Bladeburner division
router.toBladeburner();
Router.toBladeburner();
} else if (
p.skills.strength >= 100 &&
p.skills.defense >= 100 &&
p.skills.dexterity >= 100 &&
p.skills.agility >= 100
Player.skills.strength >= 100 &&
Player.skills.defense >= 100 &&
Player.skills.dexterity >= 100 &&
Player.skills.agility >= 100
) {
// Apply for Bladeburner division
p.startBladeburner();
Player.startBladeburner();
dialogBoxCreate("You have been accepted into the Bladeburner division!");
setRerender((old) => !old);
@ -79,11 +77,11 @@ export function SpecialLocation(props: IProps): React.ReactElement {
* Click handler for Resleeving button at New Tokyo VitaLife
*/
function handleGrafting(): void {
router.toGrafting();
Router.toGrafting();
}
function renderBladeburner(): React.ReactElement {
if (!player.canAccessBladeburner() || BitNodeMultipliers.BladeburnerRank === 0) {
if (!Player.canAccessBladeburner() || BitNodeMultipliers.BladeburnerRank === 0) {
return <></>;
}
const text = inBladeburner ? "Enter Bladeburner Headquarters" : "Apply to Bladeburner Division";
@ -99,32 +97,32 @@ export function SpecialLocation(props: IProps): React.ReactElement {
function EatNoodles(): void {
SnackbarEvents.emit("You ate some delicious noodles and feel refreshed", ToastVariant.SUCCESS, 2000);
N00dles(); // This is the true power of the noodles.
if (player.sourceFiles.length > 0) player.giveExploit(Exploit.N00dles);
if (player.sourceFileLvl(5) > 0 || player.bitNodeN === 5) {
player.exp.intelligence *= 1.0000000000000002;
if (Player.sourceFiles.length > 0) Player.giveExploit(Exploit.N00dles);
if (Player.sourceFileLvl(5) > 0 || Player.bitNodeN === 5) {
Player.exp.intelligence *= 1.0000000000000002;
}
player.exp.hacking *= 1.0000000000000002;
player.exp.strength *= 1.0000000000000002;
player.exp.defense *= 1.0000000000000002;
player.exp.agility *= 1.0000000000000002;
player.exp.dexterity *= 1.0000000000000002;
player.exp.charisma *= 1.0000000000000002;
for (const node of player.hacknetNodes) {
Player.exp.hacking *= 1.0000000000000002;
Player.exp.strength *= 1.0000000000000002;
Player.exp.defense *= 1.0000000000000002;
Player.exp.agility *= 1.0000000000000002;
Player.exp.dexterity *= 1.0000000000000002;
Player.exp.charisma *= 1.0000000000000002;
for (const node of Player.hacknetNodes) {
if (node instanceof HacknetNode) {
player.gainMoney(node.moneyGainRatePerSecond * 0.001, "other");
Player.gainMoney(node.moneyGainRatePerSecond * 0.001, "other");
} else {
const server = GetServer(node);
if (!(server instanceof HacknetServer)) throw new Error(`Server ${node} is not a hacknet server.`);
player.hashManager.storeHashes(server.hashRate * 0.001);
Player.hashManager.storeHashes(server.hashRate * 0.001);
}
}
if (player.bladeburner) {
player.bladeburner.rank += 0.00001;
if (Player.bladeburner) {
Player.bladeburner.rank += 0.00001;
}
if (player.corporation) {
player.corporation.funds += player.corporation.revenue * 0.01;
if (Player.corporation) {
Player.corporation.funds += Player.corporation.revenue * 0.01;
}
}
@ -138,7 +136,7 @@ export function SpecialLocation(props: IProps): React.ReactElement {
function CreateCorporation(): React.ReactElement {
const [open, setOpen] = useState(false);
if (!player.canAccessCorporation()) {
if (!Player.canAccessCorporation()) {
return (
<>
<Typography>
@ -149,7 +147,7 @@ export function SpecialLocation(props: IProps): React.ReactElement {
}
return (
<>
<Button disabled={!player.canAccessCorporation() || player.hasCorporation()} onClick={() => setOpen(true)}>
<Button disabled={!Player.canAccessCorporation() || Player.hasCorporation()} onClick={() => setOpen(true)}>
Create a Corporation
</Button>
<CreateCorporationModal open={open} onClose={() => setOpen(false)} />
@ -158,7 +156,7 @@ export function SpecialLocation(props: IProps): React.ReactElement {
}
function renderGrafting(): React.ReactElement {
if (!player.canAccessGrafting()) {
if (!Player.canAccessGrafting()) {
return <></>;
}
return (
@ -170,21 +168,21 @@ export function SpecialLocation(props: IProps): React.ReactElement {
function handleCotMG(): void {
const faction = Factions[FactionNames.ChurchOfTheMachineGod];
if (!player.factions.includes(FactionNames.ChurchOfTheMachineGod)) {
if (!Player.factions.includes(FactionNames.ChurchOfTheMachineGod)) {
joinFaction(faction);
}
if (
!player.augmentations.some((a) => a.name === AugmentationNames.StaneksGift1) &&
!player.queuedAugmentations.some((a) => a.name === AugmentationNames.StaneksGift1)
!Player.augmentations.some((a) => a.name === AugmentationNames.StaneksGift1) &&
!Player.queuedAugmentations.some((a) => a.name === AugmentationNames.StaneksGift1)
) {
applyAugmentation({ name: AugmentationNames.StaneksGift1, level: 1 });
}
router.toStaneksGift();
Router.toStaneksGift();
}
function renderCotMG(): React.ReactElement {
const toStanek = <Button onClick={() => router.toStaneksGift()}>Open Stanek's Gift</Button>;
const toStanek = <Button onClick={() => Router.toStaneksGift()}>Open Stanek's Gift</Button>;
// prettier-ignore
const symbol = <Typography sx={{ lineHeight: '1em', whiteSpace: 'pre' }}>
{" `` "}<br />
@ -215,7 +213,7 @@ export function SpecialLocation(props: IProps): React.ReactElement {
{" sNNo-.`.-omNy` "}<br />
{" -smNNNNmdo- "}<br />
{" `..` "}</Typography>
if (player.hasAugmentation(AugmentationNames.StaneksGift3, true)) {
if (Player.hasAugmentation(AugmentationNames.StaneksGift3, true)) {
return (
<>
<Typography>
@ -232,7 +230,7 @@ export function SpecialLocation(props: IProps): React.ReactElement {
</>
);
}
if (player.hasAugmentation(AugmentationNames.StaneksGift2, true)) {
if (Player.hasAugmentation(AugmentationNames.StaneksGift2, true)) {
return (
<>
<Typography>
@ -249,7 +247,7 @@ export function SpecialLocation(props: IProps): React.ReactElement {
</>
);
}
if (player.factions.includes(FactionNames.ChurchOfTheMachineGod)) {
if (Player.factions.includes(FactionNames.ChurchOfTheMachineGod)) {
return (
<>
<Typography>
@ -263,7 +261,7 @@ export function SpecialLocation(props: IProps): React.ReactElement {
);
}
if (!player.canAccessCotMG()) {
if (!Player.canAccessCotMG()) {
return (
<>
<Typography>
@ -278,8 +276,8 @@ export function SpecialLocation(props: IProps): React.ReactElement {
}
if (
player.augmentations.filter((a) => a.name !== AugmentationNames.NeuroFluxGovernor).length > 0 ||
player.queuedAugmentations.filter((a) => a.name !== AugmentationNames.NeuroFluxGovernor).length > 0
Player.augmentations.filter((a) => a.name !== AugmentationNames.NeuroFluxGovernor).length > 0 ||
Player.queuedAugmentations.filter((a) => a.name !== AugmentationNames.NeuroFluxGovernor).length > 0
) {
return (
<>

@ -2,7 +2,6 @@ import React from "react";
import { CONSTANTS } from "../../Constants";
import { Money } from "../../ui/React/Money";
import { Modal } from "../../ui/React/Modal";
import { use } from "../../ui/Context";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
@ -15,7 +14,6 @@ interface IProps {
}
export function TravelConfirmationModal(props: IProps): React.ReactElement {
const player = use.Player();
const cost = CONSTANTS.TravelCost;
function travel(): void {
props.travel();

@ -10,7 +10,8 @@ import Button from "@mui/material/Button";
import { Location } from "../Location";
import { Money } from "../../ui/React/Money";
import { use } from "../../ui/Context";
import { Router } from "../../ui/GameRoot";
import { Player } from "../../Player";
import { Box } from "@mui/material";
import { ClassWork, ClassType, Classes } from "../../Work/ClassWork";
@ -21,19 +22,16 @@ type IProps = {
};
export function UniversityLocation(props: IProps): React.ReactElement {
const player = use.Player();
const router = use.Router();
function take(classType: ClassType): void {
player.startWork(
Player.startWork(
new ClassWork({
classType: classType,
location: props.loc.name,
singularity: false,
}),
);
player.startFocusing();
router.toWork();
Player.startFocusing();
Router.toWork();
}
const dataStructuresCost = calculateCost(Classes[ClassType.DataStructures], props.loc);

@ -274,7 +274,7 @@ export function NetscriptGang(): InternalAPI<IGang> {
const member = getGangMember(ctx, memberName);
const equipment = GangMemberUpgrades[equipName];
if (!equipment) return false;
const res = member.buyUpgrade(equipment, player, gang);
const res = member.buyUpgrade(equipment);
if (res) {
ctx.workerScript.log(
"gang.purchaseEquipment",

@ -1178,7 +1178,7 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
throw helpers.makeRuntimeErrorMsg(ctx, `Invalid crime: '${crimeRoughName}'`);
}
helpers.log(ctx, () => `Attempting to commit ${crime.name}...`);
const crimeTime = crime.commit(Player, 1, ctx.workerScript);
const crimeTime = crime.commit(1, ctx.workerScript);
if (focus) {
Player.startFocusing();
Router.toWork();
@ -1275,7 +1275,7 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
const nextBN = helpers.number(ctx, "nextBN", _nextBN);
const callbackScript = helpers.string(ctx, "callbackScript", _callbackScript);
helpers.checkSingularityAccess(ctx);
enterBitNode(Router, true, Player.bitNodeN, nextBN);
enterBitNode(true, Player.bitNodeN, nextBN);
if (callbackScript)
setTimeout(() => {
runAfterReset(callbackScript);
@ -1308,7 +1308,7 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
wd.backdoorInstalled = true;
calculateAchievements();
enterBitNode(Router, false, Player.bitNodeN, nextBN);
enterBitNode(false, Player.bitNodeN, nextBN);
if (callbackScript)
setTimeout(() => {
runAfterReset(callbackScript);

@ -11,7 +11,7 @@ import { BaseCostPerSleeve, MaxSleevesFromCovenant } from "../SleeveCovenantPurc
import { Money } from "../../../ui/React/Money";
import { Modal } from "../../../ui/React/Modal";
import { use } from "../../../ui/Context";
import { Player } from "../../../Player";
import { dialogBoxCreate } from "../../../ui/React/DialogBox";
import Typography from "@mui/material/Typography";
@ -24,14 +24,13 @@ interface IProps {
}
export function CovenantPurchasesRoot(props: IProps): React.ReactElement {
const player = use.Player();
const [update, setUpdate] = useState(0);
/**
* Get the cost to purchase a new Duplicate Sleeve
*/
function purchaseCost(): number {
return Math.pow(10, player.sleevesFromCovenant) * BaseCostPerSleeve;
return Math.pow(10, Player.sleevesFromCovenant) * BaseCostPerSleeve;
}
/**
@ -43,20 +42,20 @@ export function CovenantPurchasesRoot(props: IProps): React.ReactElement {
// Purchasing a new Duplicate Sleeve
let purchaseDisabled = false;
if (!player.canAfford(purchaseCost())) {
if (!Player.canAfford(purchaseCost())) {
purchaseDisabled = true;
}
if (player.sleevesFromCovenant >= MaxSleevesFromCovenant) {
if (Player.sleevesFromCovenant >= MaxSleevesFromCovenant) {
purchaseDisabled = true;
}
function purchaseOnClick(): void {
if (player.sleevesFromCovenant >= MaxSleevesFromCovenant) return;
if (Player.sleevesFromCovenant >= MaxSleevesFromCovenant) return;
if (player.canAfford(purchaseCost())) {
player.loseMoney(purchaseCost(), "sleeves");
player.sleevesFromCovenant += 1;
player.sleeves.push(new Sleeve());
if (Player.canAfford(purchaseCost())) {
Player.loseMoney(purchaseCost(), "sleeves");
Player.sleevesFromCovenant += 1;
Player.sleeves.push(new Sleeve());
rerender();
} else {
dialogBoxCreate(`You cannot afford to purchase a Duplicate Sleeve`);
@ -65,15 +64,15 @@ export function CovenantPurchasesRoot(props: IProps): React.ReactElement {
// Purchasing Upgrades for Sleeves
const upgradePanels = [];
for (let i = 0; i < player.sleeves.length; ++i) {
const sleeve = player.sleeves[i];
for (let i = 0; i < Player.sleeves.length; ++i) {
const sleeve = Player.sleeves[i];
upgradePanels.push(<CovenantSleeveMemoryUpgrade index={i} rerender={rerender} sleeve={sleeve} />);
}
return (
<Modal open={props.open} onClose={props.onClose}>
<>
{player.sleevesFromCovenant < MaxSleevesFromCovenant && (
{Player.sleevesFromCovenant < MaxSleevesFromCovenant && (
<>
<Typography>
Purchase an additional Sleeves. These Duplicate Sleeves are permanent (they persist through BitNodes). You

@ -2,13 +2,12 @@ import React, { useState, useEffect } from "react";
import { Box, Typography, Button, Container } from "@mui/material";
import { use } from "../../../ui/Context";
import { Player } from "../../../Player";
import { SleeveElem } from "./SleeveElem";
import { FAQModal } from "./FAQModal";
export function SleeveRoot(): React.ReactElement {
const player = use.Player();
const [FAQOpen, setFAQOpen] = useState(false);
const setRerender = useState(false)[1];
function rerender(): void {
@ -43,7 +42,7 @@ export function SleeveRoot(): React.ReactElement {
Wiki Documentation
</Button>
<Box display="grid" sx={{ gridTemplateColumns: "repeat(2, 1fr)", mt: 1 }}>
{player.sleeves.map((sleeve, i) => (
{Player.sleeves.map((sleeve, i) => (
<SleeveElem key={i} rerender={rerender} sleeve={sleeve} />
))}
</Box>

@ -8,7 +8,7 @@ import { PlayerOwnedSourceFile } from "./SourceFile/PlayerOwnedSourceFile";
import { SourceFiles } from "./SourceFile/SourceFiles";
import { dialogBoxCreate } from "./ui/React/DialogBox";
import { IRouter } from "./ui/Router";
import { Router } from "./ui/GameRoot";
function giveSourceFile(bitNodeNumber: number): void {
const sourceFileKey = "SourceFile" + bitNodeNumber.toString();
@ -65,7 +65,7 @@ function giveSourceFile(bitNodeNumber: number): void {
}
}
export function enterBitNode(router: IRouter, flume: boolean, destroyedBitNode: number, newBitNode: number): void {
export function enterBitNode(flume: boolean, destroyedBitNode: number, newBitNode: number): void {
if (!flume) {
giveSourceFile(destroyedBitNode);
} else if (Player.sourceFileLvl(5) === 0 && newBitNode !== 5) {
@ -79,9 +79,9 @@ export function enterBitNode(router: IRouter, flume: boolean, destroyedBitNode:
Player.bitNodeN = newBitNode;
if (newBitNode === 6) {
router.toBladeburnerCinematic();
Router.toBladeburnerCinematic();
} else {
router.toTerminal();
Router.toTerminal();
}
prestigeSourceFile(flume);
}

@ -6,7 +6,7 @@ import * as React from "react";
import { Money } from "../React/Money";
import { MoneyRate } from "../React/MoneyRate";
import { use } from "../Context";
import { Player } from "../../Player";
import Typography from "@mui/material/Typography";
@ -32,9 +32,8 @@ const useStyles = makeStyles((theme: Theme) =>
}),
);
export function ScriptProduction(): React.ReactElement {
const player = use.Player();
const classes = useStyles();
const prodRateSinceLastAug = player.scriptProdSinceLastAug / (player.playtimeSinceLastAug / 1000);
const prodRateSinceLastAug = Player.scriptProdSinceLastAug / (Player.playtimeSinceLastAug / 1000);
return (
<Table size="small" classes={{ root: classes.size }}>
@ -45,7 +44,7 @@ export function ScriptProduction(): React.ReactElement {
</TableCell>
<TableCell align="left" classes={{ root: classes.cell }}>
<Typography variant="body2">
<Money money={player.scriptProdSinceLastAug} />
<Money money={Player.scriptProdSinceLastAug} />
</Typography>
</TableCell>
<TableCell align="left" classes={{ root: classes.cell }}>

@ -9,7 +9,7 @@ import { getPurchaseServerLimit } from "../Server/ServerPurchases";
import { Settings } from "../Settings/Settings";
import { MoneySourceTracker } from "../utils/MoneySourceTracker";
import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions";
import { use } from "./Context";
import { Player } from "../Player";
import { numeralWrapper } from "./numeralFormat";
import { Modal } from "./React/Modal";
import { Money } from "./React/Money";
@ -23,13 +23,12 @@ interface EmployersModalProps {
}
const EmployersModal = ({ open, onClose }: EmployersModalProps): React.ReactElement => {
const player = use.Player();
return (
<Modal open={open} onClose={onClose}>
<>
<Typography variant="h5">All Employers</Typography>
<ul>
{Object.keys(player.jobs).map((j) => (
{Object.keys(Player.jobs).map((j) => (
<Typography key={j}>* {j}</Typography>
))}
</ul>
@ -59,14 +58,13 @@ interface MultTableProps {
}
function MultiplierTable(props: MultTableProps): React.ReactElement {
const player = use.Player();
return (
<Table sx={{ display: "table", width: "100%", mb: (props.noMargin ?? false) === true ? 0 : 2 }}>
<TableBody>
{props.rows.map((data) => {
const { mult, value, effValue = null, color = props.color } = data;
if (effValue !== null && effValue !== value && player.sourceFileLvl(5) > 0) {
if (effValue !== null && effValue !== value && Player.sourceFileLvl(5) > 0) {
return (
<StatsRow key={mult} name={mult} color={color} data={{}}>
<>
@ -88,14 +86,13 @@ function MultiplierTable(props: MultTableProps): React.ReactElement {
}
function CurrentBitNode(): React.ReactElement {
const player = use.Player();
if (player.sourceFiles.length > 0) {
const index = "BitNode" + player.bitNodeN;
const lvl = Math.min(player.sourceFileLvl(player.bitNodeN) + 1, player.bitNodeN === 12 ? Infinity : 3);
if (Player.sourceFiles.length > 0) {
const index = "BitNode" + Player.bitNodeN;
const lvl = Math.min(Player.sourceFileLvl(Player.bitNodeN) + 1, Player.bitNodeN === 12 ? Infinity : 3);
return (
<Paper sx={{ mb: 1, p: 1 }}>
<Typography variant="h5">
BitNode {player.bitNodeN}: {BitNodes[index].name} (Level {lvl})
BitNode {Player.bitNodeN}: {BitNodes[index].name} (Level {lvl})
</Typography>
<Typography sx={{ whiteSpace: "pre-wrap", overflowWrap: "break-word" }}>{BitNodes[index].info}</Typography>
</Paper>
@ -111,7 +108,6 @@ interface IMoneyModalProps {
}
function MoneyModal({ open, onClose }: IMoneyModalProps): React.ReactElement {
const player = use.Player();
function convertMoneySourceTrackerToString(src: MoneySourceTracker): React.ReactElement {
const parts: [string, JSX.Element][] = [[`Total:`, <Money money={src.total} />]];
if (src.augmentations) {
@ -178,10 +174,10 @@ function MoneyModal({ open, onClose }: IMoneyModalProps): React.ReactElement {
Money earned since you last installed Augmentations
</Typography>
<br />
{convertMoneySourceTrackerToString(player.moneySourceA)}
{convertMoneySourceTrackerToString(Player.moneySourceA)}
</>
);
if (player.sourceFiles.length !== 0) {
if (Player.sourceFiles.length !== 0) {
content = (
<>
{content}
@ -191,7 +187,7 @@ function MoneyModal({ open, onClose }: IMoneyModalProps): React.ReactElement {
Money earned in this BitNode
</Typography>
<br />
{convertMoneySourceTrackerToString(player.moneySourceB)}
{convertMoneySourceTrackerToString(Player.moneySourceB)}
</>
);
}
@ -204,7 +200,6 @@ function MoneyModal({ open, onClose }: IMoneyModalProps): React.ReactElement {
}
export function CharacterStats(): React.ReactElement {
const player = use.Player();
const [moneyOpen, setMoneyOpen] = useState(false);
const [employersOpen, setEmployersOpen] = useState(false);
const setRerender = useState(false)[1];
@ -218,18 +213,18 @@ export function CharacterStats(): React.ReactElement {
}, []);
const timeRows = [
["Since last Augmentation installation", convertTimeMsToTimeElapsedString(player.playtimeSinceLastAug)],
["Since last Augmentation installation", convertTimeMsToTimeElapsedString(Player.playtimeSinceLastAug)],
];
if (player.sourceFiles.length > 0) {
timeRows.push(["Since last Bitnode destroyed", convertTimeMsToTimeElapsedString(player.playtimeSinceLastBitnode)]);
if (Player.sourceFiles.length > 0) {
timeRows.push(["Since last Bitnode destroyed", convertTimeMsToTimeElapsedString(Player.playtimeSinceLastBitnode)]);
}
timeRows.push(["Total", convertTimeMsToTimeElapsedString(player.totalPlaytime)]);
timeRows.push(["Total", convertTimeMsToTimeElapsedString(Player.totalPlaytime)]);
let showBitNodeMults = false;
if (player.sourceFileLvl(5) > 0) {
const n = player.bitNodeN;
if (Player.sourceFileLvl(5) > 0) {
const n = Player.bitNodeN;
const maxSfLevel = n === 12 ? Infinity : 3;
const mults = getBitNodeMultipliers(n, Math.min(player.sourceFileLvl(n) + 1, maxSfLevel));
const mults = getBitNodeMultipliers(n, Math.min(Player.sourceFileLvl(n) + 1, maxSfLevel));
showBitNodeMults = !isEqual(mults, defaultMultipliers);
}
return (
@ -240,20 +235,20 @@ export function CharacterStats(): React.ReactElement {
<Typography variant="h5">General</Typography>
<Table>
<TableBody>
<StatsRow name="Current City" color={Settings.theme.primary} data={{ content: player.city }} />
<StatsRow name="Current City" color={Settings.theme.primary} data={{ content: Player.city }} />
<StatsRow name="Money" color={Settings.theme.money} data={{}}>
<>
<Money money={player.money} />
<Money money={Player.money} />
<IconButton onClick={() => setMoneyOpen(true)} sx={{ p: 0 }}>
<MoreHoriz color="info" />
</IconButton>
</>
</StatsRow>
{player.jobs && Object.keys(player.jobs).length !== 0 ? (
{Player.jobs && Object.keys(Player.jobs).length !== 0 ? (
<StatsRow name="All Employers" color={Settings.theme.primary} data={{}}>
<>
<span style={{ color: Settings.theme.primary }}>{Object.keys(player.jobs).length} total</span>
<span style={{ color: Settings.theme.primary }}>{Object.keys(Player.jobs).length} total</span>
<IconButton onClick={() => setEmployersOpen(true)} sx={{ p: 0 }}>
<MoreHoriz color="info" />
</IconButton>
@ -265,14 +260,14 @@ export function CharacterStats(): React.ReactElement {
<StatsRow
name="Servers Owned"
color={Settings.theme.primary}
data={{ content: `${player.purchasedServers.length} / ${getPurchaseServerLimit()}` }}
data={{ content: `${Player.purchasedServers.length} / ${getPurchaseServerLimit()}` }}
/>
<StatsRow
name={`Hacknet ${player.bitNodeN === 9 || player.sourceFileLvl(9) > 0 ? "Servers" : "Nodes"} owned`}
name={`Hacknet ${Player.bitNodeN === 9 || Player.sourceFileLvl(9) > 0 ? "Servers" : "Nodes"} owned`}
color={Settings.theme.primary}
data={{
content: `${player.hacknetNodes.length}${
player.bitNodeN === 9 || player.sourceFileLvl(9) > 0
content: `${Player.hacknetNodes.length}${
Player.bitNodeN === 9 || Player.sourceFileLvl(9) > 0
? ` / ${HacknetServerConstants.MaxServers}`
: ""
}`,
@ -281,7 +276,7 @@ export function CharacterStats(): React.ReactElement {
<StatsRow
name="Augmentations Installed"
color={Settings.theme.primary}
data={{ content: String(player.augmentations.length) }}
data={{ content: String(Player.augmentations.length) }}
/>
</TableBody>
</Table>
@ -293,38 +288,38 @@ export function CharacterStats(): React.ReactElement {
<StatsRow
name="Hacking"
color={Settings.theme.hack}
data={{ level: player.skills.hacking, exp: player.exp.hacking }}
data={{ level: Player.skills.hacking, exp: Player.exp.hacking }}
/>
<StatsRow
name="Strength"
color={Settings.theme.combat}
data={{ level: player.skills.strength, exp: player.exp.strength }}
data={{ level: Player.skills.strength, exp: Player.exp.strength }}
/>
<StatsRow
name="Defense"
color={Settings.theme.combat}
data={{ level: player.skills.defense, exp: player.exp.defense }}
data={{ level: Player.skills.defense, exp: Player.exp.defense }}
/>
<StatsRow
name="Dexterity"
color={Settings.theme.combat}
data={{ level: player.skills.dexterity, exp: player.exp.dexterity }}
data={{ level: Player.skills.dexterity, exp: Player.exp.dexterity }}
/>
<StatsRow
name="Agility"
color={Settings.theme.combat}
data={{ level: player.skills.agility, exp: player.exp.agility }}
data={{ level: Player.skills.agility, exp: Player.exp.agility }}
/>
<StatsRow
name="Charisma"
color={Settings.theme.cha}
data={{ level: player.skills.charisma, exp: player.exp.charisma }}
data={{ level: Player.skills.charisma, exp: Player.exp.charisma }}
/>
{player.skills.intelligence > 0 && (player.bitNodeN === 5 || player.sourceFileLvl(5) > 0) && (
{Player.skills.intelligence > 0 && (Player.bitNodeN === 5 || Player.sourceFileLvl(5) > 0) && (
<StatsRow
name="Intelligence"
color={Settings.theme.int}
data={{ level: player.skills.intelligence, exp: player.exp.intelligence }}
data={{ level: Player.skills.intelligence, exp: Player.exp.intelligence }}
/>
)}
</TableBody>
@ -335,7 +330,7 @@ export function CharacterStats(): React.ReactElement {
<Paper sx={{ p: 1, mb: 1 }}>
<Typography variant="h5" color="primary" sx={{ display: "flex", alignItems: "center", flexWrap: "wrap" }}>
Multipliers
{player.sourceFileLvl(5) > 0 && (
{Player.sourceFileLvl(5) > 0 && (
<Tooltip
title={
<Typography>
@ -361,21 +356,21 @@ export function CharacterStats(): React.ReactElement {
rows={[
{
mult: "Hacking Chance",
value: player.mults.hacking_chance,
value: Player.mults.hacking_chance,
},
{
mult: "Hacking Speed",
value: player.mults.hacking_speed,
value: Player.mults.hacking_speed,
},
{
mult: "Hacking Money",
value: player.mults.hacking_money,
effValue: player.mults.hacking_money * BitNodeMultipliers.ScriptHackMoney,
value: Player.mults.hacking_money,
effValue: Player.mults.hacking_money * BitNodeMultipliers.ScriptHackMoney,
},
{
mult: "Hacking Growth",
value: player.mults.hacking_grow,
effValue: player.mults.hacking_grow * BitNodeMultipliers.ServerGrowthRate,
value: Player.mults.hacking_grow,
effValue: Player.mults.hacking_grow * BitNodeMultipliers.ServerGrowthRate,
},
]}
color={Settings.theme.hack}
@ -384,13 +379,13 @@ export function CharacterStats(): React.ReactElement {
rows={[
{
mult: "Hacking Level",
value: player.mults.hacking,
effValue: player.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier,
value: Player.mults.hacking,
effValue: Player.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier,
},
{
mult: "Hacking Experience",
value: player.mults.hacking_exp,
effValue: player.mults.hacking_exp * BitNodeMultipliers.HackExpGain,
value: Player.mults.hacking_exp,
effValue: Player.mults.hacking_exp * BitNodeMultipliers.HackExpGain,
},
]}
color={Settings.theme.hack}
@ -399,12 +394,12 @@ export function CharacterStats(): React.ReactElement {
rows={[
{
mult: "Strength Level",
value: player.mults.strength,
effValue: player.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier,
value: Player.mults.strength,
effValue: Player.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier,
},
{
mult: "Strength Experience",
value: player.mults.strength_exp,
value: Player.mults.strength_exp,
},
]}
color={Settings.theme.combat}
@ -413,12 +408,12 @@ export function CharacterStats(): React.ReactElement {
rows={[
{
mult: "Defense Level",
value: player.mults.defense,
effValue: player.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier,
value: Player.mults.defense,
effValue: Player.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier,
},
{
mult: "Defense Experience",
value: player.mults.defense_exp,
value: Player.mults.defense_exp,
},
]}
color={Settings.theme.combat}
@ -427,12 +422,12 @@ export function CharacterStats(): React.ReactElement {
rows={[
{
mult: "Dexterity Level",
value: player.mults.dexterity,
effValue: player.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier,
value: Player.mults.dexterity,
effValue: Player.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier,
},
{
mult: "Dexterity Experience",
value: player.mults.dexterity_exp,
value: Player.mults.dexterity_exp,
},
]}
color={Settings.theme.combat}
@ -441,12 +436,12 @@ export function CharacterStats(): React.ReactElement {
rows={[
{
mult: "Agility Level",
value: player.mults.agility,
effValue: player.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier,
value: Player.mults.agility,
effValue: Player.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier,
},
{
mult: "Agility Experience",
value: player.mults.agility_exp,
value: Player.mults.agility_exp,
},
]}
color={Settings.theme.combat}
@ -455,12 +450,12 @@ export function CharacterStats(): React.ReactElement {
rows={[
{
mult: "Charisma Level",
value: player.mults.charisma,
effValue: player.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier,
value: Player.mults.charisma,
effValue: Player.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier,
},
{
mult: "Charisma Experience",
value: player.mults.charisma_exp,
value: Player.mults.charisma_exp,
},
]}
color={Settings.theme.cha}
@ -473,24 +468,24 @@ export function CharacterStats(): React.ReactElement {
rows={[
{
mult: "Hacknet Node Production",
value: player.mults.hacknet_node_money,
effValue: player.mults.hacknet_node_money * BitNodeMultipliers.HacknetNodeMoney,
value: Player.mults.hacknet_node_money,
effValue: Player.mults.hacknet_node_money * BitNodeMultipliers.HacknetNodeMoney,
},
{
mult: "Hacknet Node Purchase Cost",
value: player.mults.hacknet_node_purchase_cost,
value: Player.mults.hacknet_node_purchase_cost,
},
{
mult: "Hacknet Node RAM Upgrade Cost",
value: player.mults.hacknet_node_ram_cost,
value: Player.mults.hacknet_node_ram_cost,
},
{
mult: "Hacknet Node Core Purchase Cost",
value: player.mults.hacknet_node_core_cost,
value: Player.mults.hacknet_node_core_cost,
},
{
mult: "Hacknet Node Level Upgrade Cost",
value: player.mults.hacknet_node_level_cost,
value: Player.mults.hacknet_node_level_cost,
},
]}
color={Settings.theme.primary}
@ -499,19 +494,19 @@ export function CharacterStats(): React.ReactElement {
rows={[
{
mult: "Company Reputation Gain",
value: player.mults.company_rep,
value: Player.mults.company_rep,
color: Settings.theme.rep,
},
{
mult: "Faction Reputation Gain",
value: player.mults.faction_rep,
effValue: player.mults.faction_rep * BitNodeMultipliers.FactionWorkRepGain,
value: Player.mults.faction_rep,
effValue: Player.mults.faction_rep * BitNodeMultipliers.FactionWorkRepGain,
color: Settings.theme.rep,
},
{
mult: "Salary",
value: player.mults.work_money,
effValue: player.mults.work_money * BitNodeMultipliers.CompanyWorkMoney,
value: Player.mults.work_money,
effValue: Player.mults.work_money * BitNodeMultipliers.CompanyWorkMoney,
color: Settings.theme.money,
},
]}
@ -521,35 +516,35 @@ export function CharacterStats(): React.ReactElement {
rows={[
{
mult: "Crime Success Chance",
value: player.mults.crime_success,
value: Player.mults.crime_success,
},
{
mult: "Crime Money",
value: player.mults.crime_money,
effValue: player.mults.crime_money * BitNodeMultipliers.CrimeMoney,
value: Player.mults.crime_money,
effValue: Player.mults.crime_money * BitNodeMultipliers.CrimeMoney,
color: Settings.theme.money,
},
]}
color={Settings.theme.combat}
/>
{player.canAccessBladeburner() && BitNodeMultipliers.BladeburnerRank > 0 && (
{Player.canAccessBladeburner() && BitNodeMultipliers.BladeburnerRank > 0 && (
<MultiplierTable
rows={[
{
mult: "Bladeburner Success Chance",
value: player.mults.bladeburner_success_chance,
value: Player.mults.bladeburner_success_chance,
},
{
mult: "Bladeburner Max Stamina",
value: player.mults.bladeburner_max_stamina,
value: Player.mults.bladeburner_max_stamina,
},
{
mult: "Bladeburner Stamina Gain",
value: player.mults.bladeburner_stamina_gain,
value: Player.mults.bladeburner_stamina_gain,
},
{
mult: "Bladeburner Field Analysis",
value: player.mults.bladeburner_analysis,
value: Player.mults.bladeburner_analysis,
},
]}
color={Settings.theme.primary}
@ -576,7 +571,7 @@ export function CharacterStats(): React.ReactElement {
{showBitNodeMults && (
<Paper sx={{ p: 1, mb: 1 }}>
<Typography variant="h5">BitNode Multipliers</Typography>
<BitNodeMultipliersDisplay n={player.bitNodeN} />
<BitNodeMultipliersDisplay n={Player.bitNodeN} />
</Paper>
)}

@ -1,19 +0,0 @@
import React, { useContext } from "react";
import { IPlayer } from "../PersonObjects/IPlayer";
import { IRouter } from "./Router";
export const Context: {
Player: React.Context<IPlayer>;
Router: React.Context<IRouter>;
} = {
Player: React.createContext<IPlayer>({} as IPlayer),
Router: React.createContext<IRouter>({} as IRouter),
};
export const use: {
Player: () => IPlayer;
Router: () => IRouter;
} = {
Player: () => useContext(Context.Player),
Router: () => useContext(Context.Router),
};

@ -64,8 +64,6 @@ import { PromptManager } from "./React/PromptManager";
import { InvitationModal } from "../Faction/ui/InvitationModal";
import { calculateAchievements } from "../Achievements/Achievements";
import { enterBitNode } from "../RedPill";
import { Context } from "./Context";
import { RecoveryMode, RecoveryRoot } from "./React/RecoveryRoot";
import { AchievementsRoot } from "../Achievements/AchievementsRoot";
import { ErrorBoundary } from "./ErrorBoundary";
@ -316,7 +314,7 @@ export function GameRoot(): React.ReactElement {
break;
}
case Page.BitVerse: {
mainPage = <BitverseRoot flume={flume} enter={enterBitNode} quick={quick} />;
mainPage = <BitverseRoot flume={flume} quick={quick} />;
withSidebar = false;
withPopups = false;
break;

@ -20,7 +20,8 @@ import SaveIcon from "@mui/icons-material/Save";
import ClearAllIcon from "@mui/icons-material/ClearAll";
import { Settings } from "../../Settings/Settings";
import { use } from "../Context";
import { Router } from "../GameRoot";
import { Player } from "../../Player";
import { StatsProgressOverviewCell } from "./StatsProgressBar";
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
@ -42,10 +43,9 @@ interface IProps {
function Intelligence(): React.ReactElement {
const theme = useTheme();
const player = use.Player();
const classes = useStyles();
if (player.skills.intelligence === 0) return <></>;
const progress = player.calculateSkillProgress(player.exp.intelligence);
if (Player.skills.intelligence === 0) return <></>;
const progress = Player.calculateSkillProgress(Player.exp.intelligence);
return (
<>
@ -55,7 +55,7 @@ function Intelligence(): React.ReactElement {
</TableCell>
<TableCell align="right" classes={{ root: classes.cell }}>
<Typography classes={{ root: classes.int }}>
{numeralWrapper.formatSkill(player.skills.intelligence)}
{numeralWrapper.formatSkill(Player.skills.intelligence)}
</Typography>
</TableCell>
<TableCell align="right" classes={{ root: classes.cell }}>
@ -75,9 +75,8 @@ function Intelligence(): React.ReactElement {
}
function Bladeburner(): React.ReactElement {
const player = use.Player();
const classes = useStyles();
const bladeburner = player.bladeburner;
const bladeburner = Player.bladeburner;
if (bladeburner === null) return <></>;
const action = bladeburner.getTypeAndNameFromActionId(bladeburner.action);
if (action.type === "Idle") return <></>;
@ -141,32 +140,30 @@ function WorkInProgressOverview({
}
function Work(): React.ReactElement {
const player = use.Player();
const router = use.Router();
const onClickFocus = (): void => {
player.startFocusing();
router.toWork();
Player.startFocusing();
Router.toWork();
};
if (player.currentWork === null || player.focus) return <></>;
if (Player.currentWork === null || Player.focus) return <></>;
let details = <></>;
let header = <></>;
let innerText = <></>;
if (isCrimeWork(player.currentWork)) {
const crime = player.currentWork.getCrime();
const perc = (player.currentWork.unitCompleted / crime.time) * 100;
if (isCrimeWork(Player.currentWork)) {
const crime = Player.currentWork.getCrime();
const perc = (Player.currentWork.unitCompleted / crime.time) * 100;
details = <>{player.currentWork.crimeType}</>;
header = <>You are attempting to {player.currentWork.crimeType}</>;
details = <>{Player.currentWork.crimeType}</>;
header = <>You are attempting to {Player.currentWork.crimeType}</>;
innerText = <>{perc.toFixed(2)}%</>;
}
if (isClassWork(player.currentWork)) {
details = <>{player.currentWork.getClass().youAreCurrently}</>;
header = <>You are {player.currentWork.getClass().youAreCurrently}</>;
innerText = <>{convertTimeMsToTimeElapsedString(player.currentWork.cyclesWorked * CONSTANTS._idleSpeed)}</>;
if (isClassWork(Player.currentWork)) {
details = <>{Player.currentWork.getClass().youAreCurrently}</>;
header = <>You are {Player.currentWork.getClass().youAreCurrently}</>;
innerText = <>{convertTimeMsToTimeElapsedString(Player.currentWork.cyclesWorked * CONSTANTS._idleSpeed)}</>;
}
if (isCreateProgramWork(player.currentWork)) {
const create = player.currentWork;
if (isCreateProgramWork(Player.currentWork)) {
const create = Player.currentWork;
details = <>Coding {create.programName}</>;
header = <>Creating a program</>;
innerText = (
@ -175,8 +172,8 @@ function Work(): React.ReactElement {
</>
);
}
if (isGraftingWork(player.currentWork)) {
const graft = player.currentWork;
if (isGraftingWork(Player.currentWork)) {
const graft = Player.currentWork;
details = <>Grafting {graft.augmentation}</>;
header = <>Grafting an Augmentation</>;
innerText = (
@ -186,8 +183,8 @@ function Work(): React.ReactElement {
);
}
if (isFactionWork(player.currentWork)) {
const factionWork = player.currentWork;
if (isFactionWork(Player.currentWork)) {
const factionWork = Player.currentWork;
header = (
<>
Working for <strong>{factionWork.factionName}</strong>
@ -201,11 +198,11 @@ function Work(): React.ReactElement {
</>
);
}
if (isCompanyWork(player.currentWork)) {
const companyWork = player.currentWork;
if (isCompanyWork(Player.currentWork)) {
const companyWork = Player.currentWork;
details = (
<>
{player.jobs[companyWork.companyName]} at <strong>{companyWork.companyName}</strong>
{Player.jobs[companyWork.companyName]} at <strong>{companyWork.companyName}</strong>
</>
);
header = (
@ -215,7 +212,7 @@ function Work(): React.ReactElement {
);
innerText = (
<>
<Reputation reputation={companyWork.getCompany().playerReputation} /> rep
<Reputation reputation={companyWork.getCompany().PlayerReputation} /> rep
<br />(
<ReputationRate reputation={companyWork.getGainRates().reputation * (1000 / CONSTANTS._idleSpeed)} />)
</>
@ -281,41 +278,37 @@ export { useStyles as characterOverviewStyles };
export function CharacterOverview({ save, killScripts }: IProps): React.ReactElement {
const [killOpen, setKillOpen] = useState(false);
const player = use.Player();
const setRerender = useState(false)[1];
useEffect(() => {
const id = setInterval(() => setRerender((old) => !old), 600);
return () => clearInterval(id);
}, []);
const classes = useStyles();
const theme = useTheme();
const hackingProgress = player.calculateSkillProgress(
player.exp.hacking,
player.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier,
const hackingProgress = Player.calculateSkillProgress(
Player.exp.hacking,
Player.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier,
);
const strengthProgress = player.calculateSkillProgress(
player.exp.strength,
player.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier,
const strengthProgress = Player.calculateSkillProgress(
Player.exp.strength,
Player.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier,
);
const defenseProgress = player.calculateSkillProgress(
player.exp.defense,
player.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier,
const defenseProgress = Player.calculateSkillProgress(
Player.exp.defense,
Player.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier,
);
const dexterityProgress = player.calculateSkillProgress(
player.exp.dexterity,
player.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier,
const dexterityProgress = Player.calculateSkillProgress(
Player.exp.dexterity,
Player.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier,
);
const agilityProgress = player.calculateSkillProgress(
player.exp.agility,
player.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier,
const agilityProgress = Player.calculateSkillProgress(
Player.exp.agility,
Player.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier,
);
const charismaProgress = player.calculateSkillProgress(
player.exp.charisma,
player.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier,
const charismaProgress = Player.calculateSkillProgress(
Player.exp.charisma,
Player.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier,
);
return (
@ -328,7 +321,7 @@ export function CharacterOverview({ save, killScripts }: IProps): React.ReactEle
</TableCell>
<TableCell align="right" classes={{ root: classes.cellNone }}>
<Typography classes={{ root: classes.hp }}>
{numeralWrapper.formatHp(player.hp.current)}&nbsp;/&nbsp;{numeralWrapper.formatHp(player.hp.max)}
{numeralWrapper.formatHp(Player.hp.current)}&nbsp;/&nbsp;{numeralWrapper.formatHp(Player.hp.max)}
</Typography>
</TableCell>
<TableCell align="right" classes={{ root: classes.cellNone }}>
@ -343,7 +336,7 @@ export function CharacterOverview({ save, killScripts }: IProps): React.ReactEle
<Typography classes={{ root: classes.money }}>Money&nbsp;</Typography>
</TableCell>
<TableCell align="right" classes={{ root: classes.cellNone }}>
<Typography classes={{ root: classes.money }}>{numeralWrapper.formatMoney(player.money)}</Typography>
<Typography classes={{ root: classes.money }}>{numeralWrapper.formatMoney(Player.money)}</Typography>
</TableCell>
<TableCell align="right" classes={{ root: classes.cellNone }}>
<Typography id="overview-money-hook" classes={{ root: classes.money }}>
@ -358,7 +351,7 @@ export function CharacterOverview({ save, killScripts }: IProps): React.ReactEle
</TableCell>
<TableCell align="right" classes={{ root: classes.cellNone }}>
<Typography classes={{ root: classes.hack }}>
{numeralWrapper.formatSkill(player.skills.hacking)}
{numeralWrapper.formatSkill(Player.skills.hacking)}
</Typography>
</TableCell>
</TableRow>
@ -384,7 +377,7 @@ export function CharacterOverview({ save, killScripts }: IProps): React.ReactEle
</TableCell>
<TableCell align="right" classes={{ root: classes.cellNone }}>
<Typography classes={{ root: classes.combat }}>
{numeralWrapper.formatSkill(player.skills.strength)}
{numeralWrapper.formatSkill(Player.skills.strength)}
</Typography>
</TableCell>
<TableCell align="right" classes={{ root: classes.cellNone }}>
@ -405,7 +398,7 @@ export function CharacterOverview({ save, killScripts }: IProps): React.ReactEle
</TableCell>
<TableCell align="right" classes={{ root: classes.cellNone }}>
<Typography classes={{ root: classes.combat }}>
{numeralWrapper.formatSkill(player.skills.defense)}
{numeralWrapper.formatSkill(Player.skills.defense)}
</Typography>
</TableCell>
<TableCell align="right" classes={{ root: classes.cellNone }}>
@ -426,7 +419,7 @@ export function CharacterOverview({ save, killScripts }: IProps): React.ReactEle
</TableCell>
<TableCell align="right" classes={{ root: classes.cellNone }}>
<Typography classes={{ root: classes.combat }}>
{numeralWrapper.formatSkill(player.skills.dexterity)}
{numeralWrapper.formatSkill(Player.skills.dexterity)}
</Typography>
</TableCell>
<TableCell align="right" classes={{ root: classes.cellNone }}>
@ -447,7 +440,7 @@ export function CharacterOverview({ save, killScripts }: IProps): React.ReactEle
</TableCell>
<TableCell align="right" classes={{ root: classes.cell }}>
<Typography classes={{ root: classes.combat }}>
{numeralWrapper.formatSkill(player.skills.agility)}
{numeralWrapper.formatSkill(Player.skills.agility)}
</Typography>
</TableCell>
<TableCell align="right" classes={{ root: classes.cell }}>
@ -468,7 +461,7 @@ export function CharacterOverview({ save, killScripts }: IProps): React.ReactEle
</TableCell>
<TableCell align="right" classes={{ root: classes.cellNone }}>
<Typography classes={{ root: classes.cha }}>
{numeralWrapper.formatSkill(player.skills.charisma)}
{numeralWrapper.formatSkill(Player.skills.charisma)}
</Typography>
</TableCell>
<TableCell align="right" classes={{ root: classes.cellNone }}>

@ -7,7 +7,7 @@ import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp";
import EqualizerIcon from "@mui/icons-material/Equalizer";
import SchoolIcon from "@mui/icons-material/School";
import { use } from "../Context";
import { Router } from "../GameRoot";
import { Page } from "../Router";
import { Settings } from "../../Settings/Settings";
import { Box, Button, Typography } from "@mui/material";
@ -69,7 +69,6 @@ export function Overview({ children, mode }: IProps): React.ReactElement {
const [x, setX] = useState(Settings.overview.x);
const [y, setY] = useState(Settings.overview.y);
const classes = useStyles();
const router = use.Router();
const CurrentIcon = open ? KeyboardArrowUpIcon : KeyboardArrowDownIcon;
const LeftIcon = mode === "tutorial" ? SchoolIcon : EqualizerIcon;
@ -113,7 +112,7 @@ export function Overview({ children, mode }: IProps): React.ReactElement {
node.dispatchEvent(clickEvent);
};
if (router.page() === Page.BitVerse || router.page() === Page.Loading || router.page() === Page.Recovery)
if (Router.page() === Page.BitVerse || Router.page() === Page.Loading || Router.page() === Page.Recovery)
return <></>;
return (
<Draggable handle=".drag" bounds="body" onStop={handleStop} defaultPosition={{ x, y }}>