import { Paper, Table, TableBody, Box, IconButton, Typography, Container, Tooltip } from "@mui/material";
import { MoreHoriz, Info } from "@mui/icons-material";
import React, { useEffect, useState } from "react";
import { BitNodes, defaultMultipliers, getBitNodeMultipliers } from "../BitNode/BitNode";
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
import { BitNodeMultipliersDisplay } from "../BitNode/ui/BitnodeMultipliersDescription";
import { HacknetServerConstants } from "../Hacknet/data/Constants";
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 { numeralWrapper } from "./numeralFormat";
import { Modal } from "./React/Modal";
import { Money } from "./React/Money";
import { StatsRow } from "./React/StatsRow";
import { StatsTable } from "./React/StatsTable";
import { isEqual } from "lodash";
interface EmployersModalProps {
open: boolean;
onClose: () => void;
}
const EmployersModal = ({ open, onClose }: EmployersModalProps): React.ReactElement => {
const player = use.Player();
return (
<>
All Employers
{Object.keys(player.jobs).map((j) => (
* {j}
))}
>
);
};
interface IMultRow {
// The name of the multiplier
mult: string;
// The player's raw multiplier value
value: number;
// The player's effective multiplier value, affected by BitNode mults
effValue?: number;
// The text color for the row
color?: string;
}
interface MultTableProps {
rows: IMultRow[];
color: string;
noMargin?: boolean;
}
function MultiplierTable(props: MultTableProps): React.ReactElement {
const player = use.Player();
return (
{props.rows.map((data) => {
const { mult, value, effValue = null, color = props.color } = data;
if (effValue !== null && effValue !== value && player.sourceFileLvl(5) > 0) {
return (
<>
{numeralWrapper.formatPercentage(value)}{" "}
{numeralWrapper.formatPercentage(effValue)}
>
);
}
return (
);
})}
);
}
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);
return (
BitNode {player.bitNodeN}: {BitNodes[index].name} (Level {lvl})
{BitNodes[index].info}
);
}
return <>>;
}
interface IMoneyModalProps {
open: boolean;
onClose: () => void;
}
function MoneyModal({ open, onClose }: IMoneyModalProps): React.ReactElement {
const player = use.Player();
function convertMoneySourceTrackerToString(src: MoneySourceTracker): React.ReactElement {
const parts: any[][] = [[`Total:`, ]];
if (src.augmentations) {
parts.push([`Augmentations:`, ]);
}
if (src.bladeburner) {
parts.push([`Bladeburner:`, ]);
}
if (src.casino) {
parts.push([`Casino:`, ]);
}
if (src.codingcontract) {
parts.push([`Coding Contracts:`, ]);
}
if (src.work) {
parts.push([`Company Work:`, ]);
}
if (src.class) {
parts.push([`Class:`, ]);
}
if (src.corporation) {
parts.push([`Corporation:`, ]);
}
if (src.crime) {
parts.push([`Crimes:`, ]);
}
if (src.gang) {
parts.push([`Gang:`, ]);
}
if (src.hacking) {
parts.push([`Hacking:`, ]);
}
if (src.hacknet) {
parts.push([`Hacknet Nodes:`, ]);
}
if (src.hacknet_expenses) {
parts.push([`Hacknet Nodes Expenses:`, ]);
}
if (src.hospitalization) {
parts.push([`Hospitalization:`, ]);
}
if (src.infiltration) {
parts.push([`Infiltration:`, ]);
}
if (src.servers) {
parts.push([`Servers:`, ]);
}
if (src.stock) {
parts.push([`Stock Market:`, ]);
}
if (src.sleeves) {
parts.push([`Sleeves:`, ]);
}
if (src.other) {
parts.push([`Other:`, ]);
}
return ;
}
let content = (
<>
Money earned since you last installed Augmentations
{convertMoneySourceTrackerToString(player.moneySourceA)}
>
);
if (player.sourceFiles.length !== 0) {
content = (
<>
{content}
Money earned in this BitNode
{convertMoneySourceTrackerToString(player.moneySourceB)}
>
);
}
return (
{content}
);
}
export function CharacterStats(): React.ReactElement {
const player = use.Player();
const [moneyOpen, setMoneyOpen] = useState(false);
const [employersOpen, setEmployersOpen] = useState(false);
const setRerender = useState(false)[1];
function rerender(): void {
setRerender((old) => !old);
}
useEffect(() => {
const id = setInterval(rerender, 200);
return () => clearInterval(id);
}, []);
const timeRows = [
["Since last Augmentation installation", convertTimeMsToTimeElapsedString(player.playtimeSinceLastAug)],
];
if (player.sourceFiles.length > 0) {
timeRows.push(["Since last Bitnode destroyed", convertTimeMsToTimeElapsedString(player.playtimeSinceLastBitnode)]);
}
timeRows.push(["Total", convertTimeMsToTimeElapsedString(player.totalPlaytime)]);
let showBitNodeMults = false;
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));
showBitNodeMults = !isEqual(mults, defaultMultipliers);
}
return (
Stats
General
<>
setMoneyOpen(true)} sx={{ p: 0 }}>
>
{player.companyName ? (
<>
>
) : (
<>>
)}
{player.jobs && Object.keys(player.jobs).length !== 0 ? (
<>
{Object.keys(player.jobs).length} total
setEmployersOpen(true)} sx={{ p: 0 }}>
>
) : (
<>>
)}
0 ? "Servers" : "Nodes"} owned`}
color={Settings.theme.primary}
data={{
content: `${player.hacknetNodes.length}${
player.bitNodeN === 9 || player.sourceFileLvl(9) > 0
? ` / ${HacknetServerConstants.MaxServers}`
: ""
}`,
}}
/>
Skills
{player.intelligence > 0 && (player.bitNodeN === 5 || player.sourceFileLvl(5) > 0) && (
)}
Multipliers
{player.sourceFileLvl(5) > 0 && (
Displays your current multipliers.
When there is a dim number next to a multiplier, that means that the multiplier in question is being
affected by BitNode multipliers.
The dim number is the raw multiplier, and the undimmed number is the effective multiplier, as dictated
by the BitNode.
}
>
)}
{player.canAccessBladeburner() && (
)}
Time Played
{timeRows.map(([name, content]) => (
))}
{showBitNodeMults && (
BitNode Multipliers
)}
setMoneyOpen(false)} />
setEmployersOpen(false)} />
);
}