build dev

This commit is contained in:
Olivier Gagnon 2021-09-18 13:29:01 -04:00
parent e087420519
commit e5abf014b2
8 changed files with 310 additions and 253 deletions

@ -147,12 +147,14 @@ export function Stats(props: IProps): React.ReactElement {
</p> </p>
<p>Skill Points: {formatNumber(props.bladeburner.skillPoints, 0)}</p> <p>Skill Points: {formatNumber(props.bladeburner.skillPoints, 0)}</p>
<br /> <br />
{StatsTable([ <StatsTable
rows={[
["Aug. Success Chance mult: ", formatNumber(props.player.bladeburner_success_chance_mult * 100, 1) + "%"], ["Aug. Success Chance mult: ", formatNumber(props.player.bladeburner_success_chance_mult * 100, 1) + "%"],
["Aug. Max Stamina mult: ", formatNumber(props.player.bladeburner_max_stamina_mult * 100, 1) + "%"], ["Aug. Max Stamina mult: ", formatNumber(props.player.bladeburner_max_stamina_mult * 100, 1) + "%"],
["Aug. Stamina Gain mult: ", formatNumber(props.player.bladeburner_stamina_gain_mult * 100, 1) + "%"], ["Aug. Stamina Gain mult: ", formatNumber(props.player.bladeburner_stamina_gain_mult * 100, 1) + "%"],
["Aug. Field Analysis mult: ", formatNumber(props.player.bladeburner_analysis_mult * 100, 1) + "%"], ["Aug. Field Analysis mult: ", formatNumber(props.player.bladeburner_analysis_mult * 100, 1) + "%"],
])} ]}
/>
<br /> <br />
<a onClick={openTravel} className="a-link-button" style={{ display: "inline-block" }}> <a onClick={openTravel} className="a-link-button" style={{ display: "inline-block" }}>
Travel Travel

@ -46,7 +46,9 @@ export function TaskSelector(props: IProps): React.ReactElement {
</option> </option>
))} ))}
</select> </select>
<div>{StatsTable(data)}</div> <div>
<StatsTable rows={data} />
</div>
</> </>
); );
} }

@ -11,8 +11,8 @@ interface IProps {
export function MoreEarningsContent(props: IProps): React.ReactElement { export function MoreEarningsContent(props: IProps): React.ReactElement {
return ( return (
<> <>
{StatsTable( <StatsTable
[ rows={[
["Money ", <Money money={props.sleeve.earningsForTask.money} />], ["Money ", <Money money={props.sleeve.earningsForTask.money} />],
["Hacking Exp ", numeralWrapper.formatExp(props.sleeve.earningsForTask.hack)], ["Hacking Exp ", numeralWrapper.formatExp(props.sleeve.earningsForTask.hack)],
["Strength Exp ", numeralWrapper.formatExp(props.sleeve.earningsForTask.str)], ["Strength Exp ", numeralWrapper.formatExp(props.sleeve.earningsForTask.str)],
@ -20,12 +20,12 @@ export function MoreEarningsContent(props: IProps): React.ReactElement {
["Dexterity Exp ", numeralWrapper.formatExp(props.sleeve.earningsForTask.dex)], ["Dexterity Exp ", numeralWrapper.formatExp(props.sleeve.earningsForTask.dex)],
["Agility Exp ", numeralWrapper.formatExp(props.sleeve.earningsForTask.agi)], ["Agility Exp ", numeralWrapper.formatExp(props.sleeve.earningsForTask.agi)],
["Charisma Exp ", numeralWrapper.formatExp(props.sleeve.earningsForTask.cha)], ["Charisma Exp ", numeralWrapper.formatExp(props.sleeve.earningsForTask.cha)],
], ]}
"Earnings for Current Task:", title="Earnings for Current Task:"
)} />
<br /> <br />
{StatsTable( <StatsTable
[ rows={[
["Money: ", <Money money={props.sleeve.earningsForPlayer.money} />], ["Money: ", <Money money={props.sleeve.earningsForPlayer.money} />],
["Hacking Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForPlayer.hack)], ["Hacking Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForPlayer.hack)],
["Strength Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForPlayer.str)], ["Strength Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForPlayer.str)],
@ -33,12 +33,12 @@ export function MoreEarningsContent(props: IProps): React.ReactElement {
["Dexterity Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForPlayer.dex)], ["Dexterity Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForPlayer.dex)],
["Agility Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForPlayer.agi)], ["Agility Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForPlayer.agi)],
["Charisma Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForPlayer.cha)], ["Charisma Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForPlayer.cha)],
], ]}
"Total Earnings for Host Consciousness:", title="Total Earnings for Host Consciousness:"
)} />
<br /> <br />
{StatsTable( <StatsTable
[ rows={[
["Money: ", <Money money={props.sleeve.earningsForSleeves.money} />], ["Money: ", <Money money={props.sleeve.earningsForSleeves.money} />],
["Hacking Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForSleeves.hack)], ["Hacking Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForSleeves.hack)],
["Strength Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForSleeves.str)], ["Strength Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForSleeves.str)],
@ -46,9 +46,9 @@ export function MoreEarningsContent(props: IProps): React.ReactElement {
["Dexterity Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForSleeves.dex)], ["Dexterity Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForSleeves.dex)],
["Agility Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForSleeves.agi)], ["Agility Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForSleeves.agi)],
["Charisma Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForSleeves.cha)], ["Charisma Exp: ", numeralWrapper.formatExp(props.sleeve.earningsForSleeves.cha)],
], ]}
"Total Earnings for Other Sleeves:", title="Total Earnings for Other Sleeves:"
)} />
<br /> <br />
</> </>
); );

@ -10,20 +10,20 @@ interface IProps {
export function MoreStatsContent(props: IProps): React.ReactElement { export function MoreStatsContent(props: IProps): React.ReactElement {
return ( return (
<> <>
{StatsTable( <StatsTable
[ rows={[
["Hacking: ", props.sleeve.hacking_skill, `(${numeralWrapper.formatExp(props.sleeve.hacking_exp)} exp)`], ["Hacking: ", props.sleeve.hacking_skill, `(${numeralWrapper.formatExp(props.sleeve.hacking_exp)} exp)`],
["Strength: ", props.sleeve.strength, `(${numeralWrapper.formatExp(props.sleeve.strength_exp)} exp)`], ["Strength: ", props.sleeve.strength, `(${numeralWrapper.formatExp(props.sleeve.strength_exp)} exp)`],
["Defense: ", props.sleeve.defense, `(${numeralWrapper.formatExp(props.sleeve.defense_exp)} exp)`], ["Defense: ", props.sleeve.defense, `(${numeralWrapper.formatExp(props.sleeve.defense_exp)} exp)`],
["Dexterity: ", props.sleeve.dexterity, `(${numeralWrapper.formatExp(props.sleeve.dexterity_exp)} exp)`], ["Dexterity: ", props.sleeve.dexterity, `(${numeralWrapper.formatExp(props.sleeve.dexterity_exp)} exp)`],
["Agility: ", props.sleeve.agility, `(${numeralWrapper.formatExp(props.sleeve.agility_exp)} exp)`], ["Agility: ", props.sleeve.agility, `(${numeralWrapper.formatExp(props.sleeve.agility_exp)} exp)`],
["Charisma: ", props.sleeve.charisma, `(${numeralWrapper.formatExp(props.sleeve.charisma_exp)} exp)`], ["Charisma: ", props.sleeve.charisma, `(${numeralWrapper.formatExp(props.sleeve.charisma_exp)} exp)`],
], ]}
"Stats:", title="Stats:"
)} />
<br /> <br />
{StatsTable( <StatsTable
[ rows={[
["Hacking Level multiplier: ", numeralWrapper.formatPercentage(props.sleeve.hacking_mult)], ["Hacking Level multiplier: ", numeralWrapper.formatPercentage(props.sleeve.hacking_mult)],
["Hacking Experience multiplier: ", numeralWrapper.formatPercentage(props.sleeve.hacking_exp_mult)], ["Hacking Experience multiplier: ", numeralWrapper.formatPercentage(props.sleeve.hacking_exp_mult)],
["Strength Level multiplier: ", numeralWrapper.formatPercentage(props.sleeve.strength_mult)], ["Strength Level multiplier: ", numeralWrapper.formatPercentage(props.sleeve.strength_mult)],
@ -41,9 +41,9 @@ export function MoreStatsContent(props: IProps): React.ReactElement {
["Salary multiplier: ", numeralWrapper.formatPercentage(props.sleeve.work_money_mult)], ["Salary multiplier: ", numeralWrapper.formatPercentage(props.sleeve.work_money_mult)],
["Crime Money multiplier: ", numeralWrapper.formatPercentage(props.sleeve.crime_money_mult)], ["Crime Money multiplier: ", numeralWrapper.formatPercentage(props.sleeve.crime_money_mult)],
["Crime Success multiplier: ", numeralWrapper.formatPercentage(props.sleeve.crime_success_mult)], ["Crime Success multiplier: ", numeralWrapper.formatPercentage(props.sleeve.crime_success_mult)],
], ]}
"Multipliers:", title="Multipliers:"
)} />
</> </>
); );
} }

@ -15,16 +15,19 @@ import { Money } from "./React/Money";
import { use } from "./Context"; import { use } from "./Context";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import Box from "@mui/material/Box";
import IconButton from "@mui/material/IconButton";
import MoreHorizIcon from "@mui/icons-material/MoreHoriz";
import { Modal } from "./React/Modal";
import TableBody from "@mui/material/TableBody";
import { Table, TableCell } from "./React/Table";
import TableRow from "@mui/material/TableRow";
function LastEmployer(): React.ReactElement { function LastEmployer(): React.ReactElement {
const player = use.Player(); const player = use.Player();
if (player.companyName) { if (player.companyName) {
return ( return <Typography>Employer at which you last worked: {player.companyName}</Typography>;
<>
<span>Employer at which you last worked: {player.companyName}</span>
<br />
</>
);
} }
return <></>; return <></>;
} }
@ -32,12 +35,7 @@ function LastEmployer(): React.ReactElement {
function LastJob(): React.ReactElement { function LastJob(): React.ReactElement {
const player = use.Player(); const player = use.Player();
if (player.companyName !== "") { if (player.companyName !== "") {
return ( return <Typography>Job you last worked: {player.jobs[player.companyName]}</Typography>;
<>
<span>Job you last worked: {player.jobs[player.companyName]}</span>
<br />
</>
);
} }
return <></>; return <></>;
} }
@ -47,15 +45,13 @@ function Employers(): React.ReactElement {
if (player.jobs && Object.keys(player.jobs).length !== 0) if (player.jobs && Object.keys(player.jobs).length !== 0)
return ( return (
<> <>
<span>All Employers:</span> <Typography>All Employers:</Typography>
<br />
<ul> <ul>
{Object.keys(player.jobs).map((j) => ( {Object.keys(player.jobs).map((j) => (
<li key={j}> * {j}</li> <Typography key={j}> * {j}</Typography>
))} ))}
</ul> </ul>
<br />
<br />
</> </>
); );
return <></>; return <></>;
@ -67,14 +63,14 @@ function Hacknet(): React.ReactElement {
if (!(player.bitNodeN === 9 || SourceFileFlags[9] > 0)) { if (!(player.bitNodeN === 9 || SourceFileFlags[9] > 0)) {
return ( return (
<> <>
<span>{`Hacknet Nodes owned: ${player.hacknetNodes.length}`}</span> <Typography>{`Hacknet Nodes owned: ${player.hacknetNodes.length}`}</Typography>
<br /> <br />
</> </>
); );
} else { } else {
return ( return (
<> <>
<span>{`Hacknet Servers owned: ${player.hacknetNodes.length} / ${HacknetServerConstants.MaxServers}`}</span> <Typography>{`Hacknet Servers owned: ${player.hacknetNodes.length} / ${HacknetServerConstants.MaxServers}`}</Typography>
<br /> <br />
</> </>
); );
@ -85,10 +81,14 @@ function Intelligence(): React.ReactElement {
const player = use.Player(); const player = use.Player();
if (player.intelligence > 0 && (player.bitNodeN === 5 || SourceFileFlags[5] > 0)) { if (player.intelligence > 0 && (player.bitNodeN === 5 || SourceFileFlags[5] > 0)) {
return ( return (
<tr key="5"> <TableRow>
<td>Intelligence:</td> <TableCell>
<td style={{ textAlign: "right" }}>{numeralWrapper.formatSkill(player.intelligence)}</td> <Typography>Intelligence:&nbsp;</Typography>
</tr> </TableCell>
<TableCell align="right">
<Typography>{numeralWrapper.formatSkill(player.intelligence)}&nbsp;</Typography>
</TableCell>
</TableRow>
); );
} }
return <></>; return <></>;
@ -98,29 +98,30 @@ function MultiplierTable(props: any): React.ReactElement {
function bn5Stat(r: any): JSX.Element { function bn5Stat(r: any): JSX.Element {
if (SourceFileFlags[5] > 0 && r.length > 2 && r[1] != r[2]) { if (SourceFileFlags[5] > 0 && r.length > 2 && r[1] != r[2]) {
return ( return (
<td key="2" style={{ textAlign: "right" }}> <TableCell key="2" align="right">
{" "} <Typography noWrap>({numeralWrapper.formatPercentage(r[2])})</Typography>
({numeralWrapper.formatPercentage(r[2])}) </TableCell>
</td>
); );
} }
return <></>; return <></>;
} }
return ( return (
<> <>
<table> <Table size="small" padding="none">
<tbody> <TableBody>
{props.rows.map((r: any) => ( {props.rows.map((r: any) => (
<tr key={r[0]}> <TableRow key={r[0]}>
<td key="0">{`${r[0]} multiplier:`}</td> <TableCell key="0">
<td key="1" style={{ textAlign: "right", paddingLeft: "5px" }}> <Typography noWrap>{`${r[0]} multiplier:`}&nbsp;</Typography>
{numeralWrapper.formatPercentage(r[1])} </TableCell>
</td> <TableCell key="1" align="right">
<Typography noWrap>{numeralWrapper.formatPercentage(r[1])}</Typography>
</TableCell>
{bn5Stat(r)} {bn5Stat(r)}
</tr> </TableRow>
))} ))}
</tbody> </TableBody>
</table> </Table>
</> </>
); );
} }
@ -129,7 +130,6 @@ function BladeburnerMults(): React.ReactElement {
const player = use.Player(); const player = use.Player();
if (!player.canAccessBladeburner()) return <></>; if (!player.canAccessBladeburner()) return <></>;
return ( return (
<>
<MultiplierTable <MultiplierTable
rows={[ rows={[
["Bladeburner Success Chance", player.bladeburner_max_stamina_mult], ["Bladeburner Success Chance", player.bladeburner_max_stamina_mult],
@ -138,8 +138,6 @@ function BladeburnerMults(): React.ReactElement {
["Bladeburner Field Analysis", player.bladeburner_success_chance_mult], ["Bladeburner Field Analysis", player.bladeburner_success_chance_mult],
]} ]}
/> />
<br />
</>
); );
} }
@ -149,14 +147,12 @@ function CurrentBitNode(): React.ReactElement {
const index = "BitNode" + player.bitNodeN; const index = "BitNode" + player.bitNodeN;
return ( return (
<> <>
<span> <Typography variant="h5" color="primary">
Current BitNode: {player.bitNodeN} ({BitNodes[index].name}) BitNode-{player.bitNodeN}: {BitNodes[index].name}
</span> </Typography>
<br /> <Typography sx={{ mx: 2 }} style={{ whiteSpace: "pre-wrap", overflowWrap: "break-word" }}>
<br /> {BitNodes[index].info}
<div style={{ width: "60%", fontSize: "13px", marginLeft: "2%" }}> </Typography>
<span style={{ whiteSpace: "pre-wrap", overflowWrap: "break-word" }}>{BitNodes[index].info}</span>
</div>
</> </>
); );
} }
@ -164,18 +160,13 @@ function CurrentBitNode(): React.ReactElement {
return <></>; return <></>;
} }
export function CharacterStats(): React.ReactElement { interface IMoneyModalProps {
open: boolean;
onClose: () => void;
}
function MoneyModal({ open, onClose }: IMoneyModalProps): React.ReactElement {
const player = use.Player(); const player = use.Player();
const setRerender = useState(false)[1];
function rerender(): void {
setRerender((old) => !old);
}
useEffect(() => {
const id = setInterval(rerender, 20);
return () => clearInterval(id);
}, []);
function convertMoneySourceTrackerToString(src: MoneySourceTracker): React.ReactElement { function convertMoneySourceTrackerToString(src: MoneySourceTracker): React.ReactElement {
const parts: any[][] = [[`Total:`, <Money money={src.total} />]]; const parts: any[][] = [[`Total:`, <Money money={src.total} />]];
if (src.bladeburner) { if (src.bladeburner) {
@ -221,13 +212,14 @@ export function CharacterStats(): React.ReactElement {
parts.push([`Sleeves:`, <Money money={src.sleeves} />]); parts.push([`Sleeves:`, <Money money={src.sleeves} />]);
} }
return StatsTable(parts); return <StatsTable rows={parts} wide />;
} }
function openMoneyModal(): void {
let content = ( let content = (
<> <>
<u>Money earned since you last installed Augmentations:</u> <Typography variant="h6" color="primary">
Money earned since you last installed Augmentations
</Typography>
<br /> <br />
{convertMoneySourceTrackerToString(player.moneySourceA)} {convertMoneySourceTrackerToString(player.moneySourceA)}
</> </>
@ -238,16 +230,35 @@ export function CharacterStats(): React.ReactElement {
{content} {content}
<br /> <br />
<br /> <br />
<u>Money earned in this BitNode:</u> <Typography variant="h6" color="primary">
Money earned in this BitNode
</Typography>
<br /> <br />
{convertMoneySourceTrackerToString(player.moneySourceB)} {convertMoneySourceTrackerToString(player.moneySourceB)}
</> </>
); );
} }
dialogBoxCreate(content, false); return (
<Modal open={open} onClose={onClose}>
{content}
</Modal>
);
}
export function CharacterStats(): React.ReactElement {
const player = use.Player();
const [moneyOpen, setMoneyOpen] = useState(false);
const setRerender = useState(false)[1];
function rerender(): void {
setRerender((old) => !old);
} }
useEffect(() => {
const id = setInterval(rerender, 20);
return () => clearInterval(id);
}, []);
const timeRows = [ const timeRows = [
["Time played since last Augmentation:", convertTimeMsToTimeElapsedString(player.playtimeSinceLastAug)], ["Time played since last Augmentation:", convertTimeMsToTimeElapsedString(player.playtimeSinceLastAug)],
]; ];
@ -261,88 +272,105 @@ export function CharacterStats(): React.ReactElement {
return ( return (
<> <>
<pre> <Typography variant="h5" color="primary">
<b>General</b> General
<br /> </Typography>
<br /> <Box sx={{ mx: 2 }}>
<span>Current City: {player.city}</span> <Typography>Current City: {player.city}</Typography>
<br />
<LastEmployer /> <LastEmployer />
<LastJob /> <LastJob />
<Employers /> <Employers />
<span>
<Typography>
Money: <Money money={player.money.toNumber()} /> Money: <Money money={player.money.toNumber()} />
</span> <IconButton onClick={() => setMoneyOpen(true)}>
<button <MoreHorizIcon color="info" />
className="popup-box-button" </IconButton>
style={{ display: "inline-block", float: "none" }} </Typography>
onClick={openMoneyModal} </Box>
>
Money Statistics & Breakdown
</button>
<br /> <br />
<br /> <Typography variant="h5" color="primary">
<b>Stats</b> Stats
<table> </Typography>
<tbody> <Box sx={{ mx: 2 }}>
<tr key="0"> <Table size="small" padding="none">
<td key="0">Hacking:</td> <TableBody>
<td key="1" style={{ textAlign: "right" }}> <TableRow>
{numeralWrapper.formatSkill(player.hacking_skill)} <TableCell>
</td> <Typography noWrap>Hacking:&nbsp;</Typography>
<td key="2" style={{ textAlign: "right" }}> </TableCell>
({numeralWrapper.formatExp(player.hacking_exp)} exp) <TableCell align="right">
</td> <Typography noWrap>{numeralWrapper.formatSkill(player.hacking_skill)}&nbsp;</Typography>
</tr> </TableCell>
<tr key="1"> <TableCell align="right">
<td key="0">Strength:</td> <Typography noWrap>({numeralWrapper.formatExp(player.hacking_exp)} exp)</Typography>
<td key="1" style={{ textAlign: "right" }}> </TableCell>
{numeralWrapper.formatSkill(player.strength)} </TableRow>
</td> <TableRow>
<td key="2" style={{ textAlign: "right" }}> <TableCell>
({numeralWrapper.formatExp(player.strength_exp)} exp) <Typography noWrap>Strength:&nbsp;</Typography>
</td> </TableCell>
</tr> <TableCell align="right">
<tr key="2"> <Typography noWrap>{numeralWrapper.formatSkill(player.strength)}&nbsp;</Typography>
<td key="0">Defense:</td> </TableCell>
<td key="1" style={{ textAlign: "right" }}> <TableCell align="right">
{numeralWrapper.formatSkill(player.defense)} <Typography noWrap>({numeralWrapper.formatExp(player.strength_exp)} exp)</Typography>
</td> </TableCell>
<td key="2" style={{ textAlign: "right" }}> </TableRow>
({numeralWrapper.formatExp(player.defense_exp)} exp) <TableRow>
</td> <TableCell>
</tr> <Typography noWrap>Defense:&nbsp;</Typography>
<tr key="3"> </TableCell>
<td key="0">Dexterity:</td> <TableCell align="right">
<td key="1" style={{ textAlign: "right" }}> <Typography noWrap>{numeralWrapper.formatSkill(player.defense)}&nbsp;</Typography>
{numeralWrapper.formatSkill(player.dexterity)} </TableCell>
</td> <TableCell align="right">
<td key="2" style={{ textAlign: "right" }}> <Typography noWrap>({numeralWrapper.formatExp(player.defense_exp)} exp)</Typography>
({numeralWrapper.formatExp(player.dexterity_exp)} exp) </TableCell>
</td> </TableRow>
</tr> <TableRow>
<tr key="4"> <TableCell>
<td key="0">Agility:</td> <Typography noWrap>Dexterity:&nbsp;</Typography>
<td key="1" style={{ textAlign: "right" }}> </TableCell>
{numeralWrapper.formatSkill(player.agility)} <TableCell align="right">
</td> <Typography noWrap>{numeralWrapper.formatSkill(player.dexterity)}&nbsp;</Typography>
<td key="2" style={{ textAlign: "right" }}> </TableCell>
({numeralWrapper.formatExp(player.agility_exp)} exp) <TableCell align="right">
</td> <Typography noWrap>({numeralWrapper.formatExp(player.dexterity_exp)} exp)</Typography>
</tr> </TableCell>
<tr key="5"> </TableRow>
<td key="0">Charisma:</td> <TableRow>
<td key="1" style={{ textAlign: "right" }}> <TableCell>
{numeralWrapper.formatSkill(player.charisma)} <Typography noWrap>Agility:&nbsp;</Typography>
</td> </TableCell>
<td key="2" style={{ textAlign: "right" }}> <TableCell align="right">
({numeralWrapper.formatExp(player.charisma_exp)} exp) <Typography noWrap>{numeralWrapper.formatSkill(player.agility)}&nbsp;</Typography>
</td> </TableCell>
</tr> <TableCell align="right">
<Typography noWrap>({numeralWrapper.formatExp(player.agility_exp)} exp)</Typography>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
<Typography noWrap>Charisma:&nbsp;</Typography>
</TableCell>
<TableCell align="right">
<Typography noWrap>{numeralWrapper.formatSkill(player.charisma)}&nbsp;</Typography>
</TableCell>
<TableCell align="right">
<Typography noWrap>({numeralWrapper.formatExp(player.charisma_exp)} exp)</Typography>
</TableCell>
</TableRow>
<Intelligence /> <Intelligence />
</tbody> </TableBody>
</table> </Table>
<br /> <br />
</Box>
<br />
<Typography variant="h5" color="primary">
Multipliers
</Typography>
<Box sx={{ mx: 2 }}>
<MultiplierTable <MultiplierTable
rows={[ rows={[
["Hacking Chance", player.hacking_chance_mult], ["Hacking Chance", player.hacking_chance_mult],
@ -447,23 +475,22 @@ export function CharacterStats(): React.ReactElement {
]} ]}
/> />
<br /> <br />
<BladeburnerMults /> <BladeburnerMults />
</Box>
<br /> <br />
<b>Misc.</b> <Typography variant="h5" color="primary">
<br /> Misc
<br /> </Typography>
<span>{`Servers owned: ${player.purchasedServers.length} / ${getPurchaseServerLimit()}`}</span> <Box sx={{ mx: 2 }}>
<br /> <Typography>{`Servers owned: ${player.purchasedServers.length} / ${getPurchaseServerLimit()}`}</Typography>
<Hacknet /> <Hacknet />
<span>{`Augmentations installed: ${player.augmentations.length}`}</span> <Typography>{`Augmentations installed: ${player.augmentations.length}`}</Typography>
<br /> <StatsTable rows={timeRows} />
<br /> </Box>
{StatsTable(timeRows)}
<br /> <br />
<CurrentBitNode /> <CurrentBitNode />
</pre> <MoneyModal open={moneyOpen} onClose={() => setMoneyOpen(false)} />
</> </>
); );
} }

@ -3,8 +3,8 @@ import { Theme } from "@mui/material";
import makeStyles from "@mui/styles/makeStyles"; import makeStyles from "@mui/styles/makeStyles";
import createStyles from "@mui/styles/createStyles"; import createStyles from "@mui/styles/createStyles";
import M from "@mui/material/Modal"; import M from "@mui/material/Modal";
import Backdrop from "@mui/material/Backdrop";
import Fade from "@mui/material/Fade"; import Fade from "@mui/material/Fade";
import Box from "@mui/material/Box";
const useStyles = makeStyles((theme: Theme) => const useStyles = makeStyles((theme: Theme) =>
createStyles({ createStyles({
@ -39,18 +39,11 @@ interface IProps {
export const Modal = (props: IProps): React.ReactElement => { export const Modal = (props: IProps): React.ReactElement => {
const classes = useStyles(); const classes = useStyles();
return ( return (
<M <M open={props.open} onClose={props.onClose} closeAfterTransition className={classes.modal}>
open={props.open}
onClose={props.onClose}
closeAfterTransition
className={classes.modal}
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 100,
}}
>
<Fade in={props.open}> <Fade in={props.open}>
<div className={classes.paper}>{props.children}</div> <div className={classes.paper}>
<Box sx={{ m: 2 }}>{props.children}</Box>
</div>
</Fade> </Fade>
</M> </M>
); );

@ -1,39 +1,35 @@
import * as React from "react"; import React from "react";
export function StatsTable(rows: any[][], title?: string): React.ReactElement { import { Table, TableCell } from "./Table";
let titleElem = <></>; import TableBody from "@mui/material/TableBody";
if (title) { import { Table as MuiTable } from "@mui/material";
titleElem = ( import TableRow from "@mui/material/TableRow";
<> import Typography from "@mui/material/Typography";
<h2>
<u>{title}</u> interface IProps {
</h2> rows: any[][];
<br /> title?: string;
</> wide?: boolean;
); }
}
export function StatsTable({ rows, title, wide }: IProps): React.ReactElement {
const T = wide ? MuiTable : Table;
return ( return (
<> <>
{titleElem} {title && <Typography>{title}</Typography>}
<table> <T size="small" padding="none">
<tbody> <TableBody>
{rows.map((row: any[]) => { {rows.map((row: any[]) => (
return ( <TableRow key={row[0]}>
<tr key={row[0]}> {row.map((elem: any, i: number) => (
{row.map((elem: any, i: number) => { <TableCell key={i} align={i !== 0 ? "right" : "left"}>
let style = {}; <Typography noWrap>{elem}</Typography>
if (i !== 0) style = { textAlign: "right", paddingLeft: ".25em" }; </TableCell>
return ( ))}
<td key={i} style={style}> </TableRow>
{elem} ))}
</td> </TableBody>
); </T>
})}
</tr>
);
})}
</tbody>
</table>
</> </>
); );
} }

37
src/ui/React/Table.tsx Normal file

@ -0,0 +1,37 @@
import React from "react";
import { TableCell as MuiTableCell, TableCellProps, Table as MuiTable, TableProps } from "@mui/material";
import makeStyles from "@mui/styles/makeStyles";
const useStyles = makeStyles({
root: {
borderBottom: "none",
},
small: {
width: "1px",
},
});
export const TableCell: React.FC<TableCellProps> = (props: TableCellProps) => {
return (
<MuiTableCell
{...props}
classes={{
root: useStyles().root,
...props.classes,
}}
/>
);
};
export const Table: React.FC<TableProps> = (props: TableProps) => {
return (
<MuiTable
{...props}
classes={{
root: useStyles().small,
...props.classes,
}}
/>
);
};