build dev

This commit is contained in:
Olivier Gagnon
2021-09-18 03:00:07 -04:00
parent eb2a44e213
commit bdfa4be71f
10 changed files with 1099 additions and 1132 deletions

533
dist/engine.bundle.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1074
dist/vendor.bundle.js vendored

File diff suppressed because one or more lines are too long

View File

@ -76,9 +76,7 @@ export class GenericLocation extends React.Component<IProps, any> {
} }
if (this.props.loc.types.includes(LocationType.Special)) { if (this.props.loc.types.includes(LocationType.Special)) {
content.push( content.push(<SpecialLocation key={"speciallocation"} loc={this.props.loc} />);
<SpecialLocation engine={this.props.engine} key={"speciallocation"} loc={this.props.loc} p={this.props.p} />,
);
} }
if (this.props.loc.types.includes(LocationType.TechVendor)) { if (this.props.loc.types.includes(LocationType.TechVendor)) {

View File

@ -98,7 +98,8 @@ export class LocationRoot extends React.Component<IProps, IState> {
} }
if (loc.types.includes(LocationType.StockMarket)) { if (loc.types.includes(LocationType.StockMarket)) {
this.props.engine.loadStockMarketContent(); setTimeout(() => this.props.router.toStockMarket(), 50);
return <></>;
} }
return ( return (

View File

@ -10,7 +10,7 @@
* This subcomponent creates all of the buttons for interacting with those special * This subcomponent creates all of the buttons for interacting with those special
* properties * properties
*/ */
import * as React from "react"; import React, { useState } from "react";
import { Location } from "../Location"; import { Location } from "../Location";
import { CreateCorporationPopup } from "../../Corporation/ui/CreateCorporationPopup"; import { CreateCorporationPopup } from "../../Corporation/ui/CreateCorporationPopup";
@ -19,6 +19,7 @@ import { LocationName } from "../data/LocationNames";
import { IEngine } from "../../IEngine"; import { IEngine } from "../../IEngine";
import { IPlayer } from "../../PersonObjects/IPlayer"; import { IPlayer } from "../../PersonObjects/IPlayer";
import { use } from "../../ui/Context";
import { AutoupdatingStdButton } from "../../ui/React/AutoupdatingStdButton"; import { AutoupdatingStdButton } from "../../ui/React/AutoupdatingStdButton";
import { StdButton } from "../../ui/React/StdButton"; import { StdButton } from "../../ui/React/StdButton";
@ -26,43 +27,25 @@ import { StdButton } from "../../ui/React/StdButton";
import { dialogBoxCreate } from "../../../utils/DialogBox"; import { dialogBoxCreate } from "../../../utils/DialogBox";
type IProps = { type IProps = {
engine: IEngine;
loc: Location; loc: Location;
p: IPlayer;
}; };
type IState = { type IState = {
inBladeburner: boolean; inBladeburner: boolean;
}; };
export class SpecialLocation extends React.Component<IProps, IState> { export function SpecialLocation(props: IProps): React.ReactElement {
/** const player = use.Player();
* Stores button styling that sets them all to block display const router = use.Router();
*/ const [rerender, setRerender] = useState(false);
btnStyle: any; const inBladeburner = player.inBladeburner();
constructor(props: IProps) {
super(props);
this.btnStyle = { display: "block" };
this.renderNoodleBar = this.renderNoodleBar.bind(this);
this.createCorporationPopup = this.createCorporationPopup.bind(this);
this.handleBladeburner = this.handleBladeburner.bind(this);
this.handleResleeving = this.handleResleeving.bind(this);
this.state = {
inBladeburner: this.props.p.inBladeburner(),
};
}
/** /**
* Click handler for "Create Corporation" button at Sector-12 City Hall * Click handler for "Create Corporation" button at Sector-12 City Hall
*/ */
createCorporationPopup(): void { function createCorporationPopup(): void {
const popupId = `create-start-corporation-popup`; const popupId = `create-start-corporation-popup`;
createPopup(popupId, CreateCorporationPopup, { createPopup(popupId, CreateCorporationPopup, {
player: this.props.p, player: player,
popupId: popupId, popupId: popupId,
}); });
} }
@ -70,19 +53,17 @@ export class SpecialLocation extends React.Component<IProps, IState> {
/** /**
* Click handler for Bladeburner button at Sector-12 NSA * Click handler for Bladeburner button at Sector-12 NSA
*/ */
handleBladeburner(): void { function handleBladeburner(): void {
const p = this.props.p; const p = player;
if (p.inBladeburner()) { if (p.inBladeburner()) {
// Enter Bladeburner division // Enter Bladeburner division
this.props.engine.loadBladeburnerContent(); router.toBladeburner();
} else { } else {
// Apply for Bladeburner division // Apply for Bladeburner division
if (p.strength >= 100 && p.defense >= 100 && p.dexterity >= 100 && p.agility >= 100) { if (p.strength >= 100 && p.defense >= 100 && p.dexterity >= 100 && p.agility >= 100) {
p.startBladeburner({ new: true }); p.startBladeburner({ new: true });
dialogBoxCreate("You have been accepted into the Bladeburner division!"); dialogBoxCreate("You have been accepted into the Bladeburner division!");
this.setState({ setRerender((old) => !old);
inBladeburner: true,
});
const worldHeader = document.getElementById("world-menu-header"); const worldHeader = document.getElementById("world-menu-header");
if (worldHeader instanceof HTMLElement) { if (worldHeader instanceof HTMLElement) {
@ -98,28 +79,28 @@ export class SpecialLocation extends React.Component<IProps, IState> {
/** /**
* Click handler for Resleeving button at New Tokyo VitaLife * Click handler for Resleeving button at New Tokyo VitaLife
*/ */
handleResleeving(): void { function handleResleeving(): void {
this.props.engine.loadResleevingContent(); router.toResleeves();
} }
renderBladeburner(): React.ReactNode { function renderBladeburner(): React.ReactElement {
if (!this.props.p.canAccessBladeburner()) { if (!player.canAccessBladeburner()) {
return null; return <></>;
} }
const text = this.state.inBladeburner ? "Enter Bladeburner Headquarters" : "Apply to Bladeburner Division"; const text = inBladeburner ? "Enter Bladeburner Headquarters" : "Apply to Bladeburner Division";
return <StdButton onClick={this.handleBladeburner} style={this.btnStyle} text={text} />; return <StdButton onClick={handleBladeburner} style={{ display: "block" }} text={text} />;
} }
renderNoodleBar(): React.ReactNode { function renderNoodleBar(): React.ReactElement {
function EatNoodles(): void { function EatNoodles(): void {
dialogBoxCreate(<>You ate some delicious noodles and feel refreshed.</>); dialogBoxCreate(<>You ate some delicious noodles and feel refreshed.</>);
} }
return <StdButton onClick={EatNoodles} style={this.btnStyle} text={"Eat noodles"} />; return <StdButton onClick={EatNoodles} style={{ display: "block" }} text={"Eat noodles"} />;
} }
renderCreateCorporation(): React.ReactNode { function renderCreateCorporation(): React.ReactElement {
if (!this.props.p.canAccessCorporation()) { if (!player.canAccessCorporation()) {
return ( return (
<> <>
<p> <p>
@ -130,38 +111,36 @@ export class SpecialLocation extends React.Component<IProps, IState> {
} }
return ( return (
<AutoupdatingStdButton <AutoupdatingStdButton
disabled={!this.props.p.canAccessCorporation() || this.props.p.hasCorporation()} disabled={!player.canAccessCorporation() || player.hasCorporation()}
onClick={this.createCorporationPopup} onClick={createCorporationPopup}
style={this.btnStyle} style={{ display: "block" }}
text={"Create a Corporation"} text={"Create a Corporation"}
/> />
); );
} }
renderResleeving(): React.ReactNode { function renderResleeving(): React.ReactElement {
if (!this.props.p.canAccessResleeving()) { if (!player.canAccessResleeving()) {
return null; return <></>;
} }
return <StdButton onClick={this.handleResleeving} style={this.btnStyle} text={"Re-Sleeve"} />; return <StdButton onClick={handleResleeving} style={{ display: "block" }} text={"Re-Sleeve"} />;
} }
render(): React.ReactNode { switch (props.loc.name) {
switch (this.props.loc.name) { case LocationName.NewTokyoVitaLife: {
case LocationName.NewTokyoVitaLife: { return renderResleeving();
return this.renderResleeving();
}
case LocationName.Sector12CityHall: {
return this.renderCreateCorporation();
}
case LocationName.Sector12NSA: {
return this.renderBladeburner();
}
case LocationName.NewTokyoNoodleBar: {
return this.renderNoodleBar();
}
default:
console.error(`Location ${this.props.loc.name} doesn't have any special properties`);
break;
} }
case LocationName.Sector12CityHall: {
return renderCreateCorporation();
}
case LocationName.Sector12NSA: {
return renderBladeburner();
}
case LocationName.NewTokyoNoodleBar: {
return renderNoodleBar();
}
default:
console.error(`Location ${props.loc.name} doesn't have any special properties`);
return <></>;
} }
} }

View File

@ -17,6 +17,7 @@ import { WorkerScriptStartStopEventEmitter } from "../../Netscript/WorkerScriptS
import { getServer } from "../../Server/ServerHelpers"; import { getServer } from "../../Server/ServerHelpers";
import { BaseServer } from "../../Server/BaseServer"; import { BaseServer } from "../../Server/BaseServer";
import { TablePaginationActionsAll } from "../React/TablePaginationActionsAll"; import { TablePaginationActionsAll } from "../React/TablePaginationActionsAll";
import SearchIcon from "@mui/icons-material/Search";
// Map of server hostname -> all workerscripts on that server for all active scripts // Map of server hostname -> all workerscripts on that server for all active scripts
interface IServerData { interface IServerData {
@ -100,7 +101,7 @@ export function ServerAccordions(props: IProps): React.ReactElement {
autoFocus autoFocus
variant="standard" variant="standard"
InputProps={{ InputProps={{
startAdornment: <Typography m={1}>Filter:</Typography>, startAdornment: <SearchIcon />,
spellCheck: false, spellCheck: false,
}} }}
/> />

View File

@ -12,12 +12,158 @@ import { getPurchaseServerLimit } from "../Server/ServerPurchases";
import { HacknetServerConstants } from "../Hacknet/data/Constants"; import { HacknetServerConstants } from "../Hacknet/data/Constants";
import { StatsTable } from "./React/StatsTable"; import { StatsTable } from "./React/StatsTable";
import { Money } from "./React/Money"; import { Money } from "./React/Money";
import { use } from "./Context";
interface IProps { function LastEmployer(): React.ReactElement {
player: IPlayer; const player = use.Player();
if (player.companyName) {
return (
<>
<span>Employer at which you last worked: {player.companyName}</span>
<br />
</>
);
}
return <></>;
} }
export function CharacterInfo(props: IProps): React.ReactElement { function LastJob(): React.ReactElement {
const player = use.Player();
if (player.companyName !== "") {
return (
<>
<span>Job you last worked: {player.jobs[player.companyName]}</span>
<br />
</>
);
}
return <></>;
}
function Employers(): React.ReactElement {
const player = use.Player();
if (player.jobs && Object.keys(player.jobs).length !== 0)
return (
<>
<span>All Employers:</span>
<br />
<ul>
{Object.keys(player.jobs).map((j) => (
<li key={j}> * {j}</li>
))}
</ul>
<br />
<br />
</>
);
return <></>;
}
function Hacknet(): React.ReactElement {
const player = use.Player();
// Can't import HacknetHelpers for some reason.
if (!(player.bitNodeN === 9 || SourceFileFlags[9] > 0)) {
return (
<>
<span>{`Hacknet Nodes owned: ${player.hacknetNodes.length}`}</span>
<br />
</>
);
} else {
return (
<>
<span>{`Hacknet Servers owned: ${player.hacknetNodes.length} / ${HacknetServerConstants.MaxServers}`}</span>
<br />
</>
);
}
}
function Intelligence(): React.ReactElement {
const player = use.Player();
if (player.intelligence > 0 && (player.bitNodeN === 5 || SourceFileFlags[5] > 0)) {
return (
<tr key="5">
<td>Intelligence:</td>
<td style={{ textAlign: "right" }}>{numeralWrapper.formatSkill(player.intelligence)}</td>
</tr>
);
}
return <></>;
}
function MultiplierTable(props: any): React.ReactElement {
function bn5Stat(r: any): JSX.Element {
if (SourceFileFlags[5] > 0 && r.length > 2 && r[1] != r[2]) {
return (
<td key="2" style={{ textAlign: "right" }}>
{" "}
({numeralWrapper.formatPercentage(r[2])})
</td>
);
}
return <></>;
}
return (
<>
<table>
<tbody>
{props.rows.map((r: any) => (
<tr key={r[0]}>
<td key="0">{`${r[0]} multiplier:`}</td>
<td key="1" style={{ textAlign: "right", paddingLeft: "5px" }}>
{numeralWrapper.formatPercentage(r[1])}
</td>
{bn5Stat(r)}
</tr>
))}
</tbody>
</table>
</>
);
}
function BladeburnerMults(): React.ReactElement {
const player = use.Player();
if (!player.canAccessBladeburner()) return <></>;
return (
<>
<MultiplierTable
rows={[
["Bladeburner Success Chance", player.bladeburner_max_stamina_mult],
["Bladeburner Max Stamina", player.bladeburner_stamina_gain_mult],
["Bladeburner Stamina Gain", player.bladeburner_analysis_mult],
["Bladeburner Field Analysis", player.bladeburner_success_chance_mult],
]}
/>
<br />
</>
);
}
function CurrentBitNode(): React.ReactElement {
const player = use.Player();
if (player.sourceFiles.length > 0) {
const index = "BitNode" + player.bitNodeN;
return (
<>
<span>
Current BitNode: {player.bitNodeN} ({BitNodes[index].name})
</span>
<br />
<br />
<div style={{ width: "60%", fontSize: "13px", marginLeft: "2%" }}>
<span style={{ whiteSpace: "pre-wrap", overflowWrap: "break-word" }}>{BitNodes[index].info}</span>
</div>
</>
);
}
return <></>;
}
export function CharacterInfo(): React.ReactElement {
const player = use.Player();
const setRerender = useState(false)[1]; const setRerender = useState(false)[1];
function rerender(): void { function rerender(): void {
setRerender((old) => !old); setRerender((old) => !old);
@ -28,65 +174,6 @@ export function CharacterInfo(props: IProps): React.ReactElement {
return () => clearInterval(id); return () => clearInterval(id);
}, []); }, []);
function LastEmployer(): React.ReactElement {
if (props.player.companyName) {
return (
<>
<span>Employer at which you last worked: {props.player.companyName}</span>
<br />
</>
);
}
return <></>;
}
function LastJob(): React.ReactElement {
if (props.player.companyName !== "") {
return (
<>
<span>Job you last worked: {props.player.jobs[props.player.companyName]}</span>
<br />
</>
);
}
return <></>;
}
function Employers(): React.ReactElement {
if (props.player.jobs && Object.keys(props.player.jobs).length !== 0)
return (
<>
<span>All Employers:</span>
<br />
<ul>
{Object.keys(props.player.jobs).map((j) => (
<li key={j}> * {j}</li>
))}
</ul>
<br />
<br />
</>
);
return <></>;
}
function Hacknet(): React.ReactElement {
// Can't import HacknetHelpers for some reason.
if (!(props.player.bitNodeN === 9 || SourceFileFlags[9] > 0)) {
return (
<>
<span>{`Hacknet Nodes owned: ${props.player.hacknetNodes.length}`}</span>
<br />
</>
);
} else {
return (
<>
<span>{`Hacknet Servers owned: ${props.player.hacknetNodes.length} / ${HacknetServerConstants.MaxServers}`}</span>
<br />
</>
);
}
}
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) {
@ -140,10 +227,10 @@ export function CharacterInfo(props: IProps): React.ReactElement {
<> <>
<u>Money earned since you last installed Augmentations:</u> <u>Money earned since you last installed Augmentations:</u>
<br /> <br />
{convertMoneySourceTrackerToString(props.player.moneySourceA)} {convertMoneySourceTrackerToString(player.moneySourceA)}
</> </>
); );
if (props.player.sourceFiles.length !== 0) { if (player.sourceFiles.length !== 0) {
content = ( content = (
<> <>
{content} {content}
@ -151,7 +238,7 @@ export function CharacterInfo(props: IProps): React.ReactElement {
<br /> <br />
<u>Money earned in this BitNode:</u> <u>Money earned in this BitNode:</u>
<br /> <br />
{convertMoneySourceTrackerToString(props.player.moneySourceB)} {convertMoneySourceTrackerToString(player.moneySourceB)}
</> </>
); );
} }
@ -159,96 +246,16 @@ export function CharacterInfo(props: IProps): React.ReactElement {
dialogBoxCreate(content, false); dialogBoxCreate(content, false);
} }
function Intelligence(): React.ReactElement {
if (props.player.intelligence > 0 && (props.player.bitNodeN === 5 || SourceFileFlags[5] > 0)) {
return (
<tr key="5">
<td>Intelligence:</td>
<td style={{ textAlign: "right" }}>{numeralWrapper.formatSkill(props.player.intelligence)}</td>
</tr>
);
}
return <></>;
}
function MultiplierTable(props: any): React.ReactElement {
function bn5Stat(r: any): JSX.Element {
if (SourceFileFlags[5] > 0 && r.length > 2 && r[1] != r[2]) {
return (
<td key="2" style={{ textAlign: "right" }}>
{" "}
({numeralWrapper.formatPercentage(r[2])})
</td>
);
}
return <></>;
}
return (
<>
<table>
<tbody>
{props.rows.map((r: any) => (
<tr key={r[0]}>
<td key="0">{`${r[0]} multiplier:`}</td>
<td key="1" style={{ textAlign: "right", paddingLeft: "5px" }}>
{numeralWrapper.formatPercentage(r[1])}
</td>
{bn5Stat(r)}
</tr>
))}
</tbody>
</table>
</>
);
}
function BladeburnerMults(): React.ReactElement {
if (!props.player.canAccessBladeburner()) return <></>;
return (
<>
<MultiplierTable
rows={[
["Bladeburner Success Chance", props.player.bladeburner_max_stamina_mult],
["Bladeburner Max Stamina", props.player.bladeburner_stamina_gain_mult],
["Bladeburner Stamina Gain", props.player.bladeburner_analysis_mult],
["Bladeburner Field Analysis", props.player.bladeburner_success_chance_mult],
]}
/>
<br />
</>
);
}
function CurrentBitNode(): React.ReactElement {
if (props.player.sourceFiles.length > 0) {
const index = "BitNode" + props.player.bitNodeN;
return (
<>
<span>
Current BitNode: {props.player.bitNodeN} ({BitNodes[index].name})
</span>
<br />
<br />
<div style={{ width: "60%", fontSize: "13px", marginLeft: "2%" }}>
<span style={{ whiteSpace: "pre-wrap", overflowWrap: "break-word" }}>{BitNodes[index].info}</span>
</div>
</>
);
}
return <></>;
}
const timeRows = [ const timeRows = [
["Time played since last Augmentation:", convertTimeMsToTimeElapsedString(props.player.playtimeSinceLastAug)], ["Time played since last Augmentation:", convertTimeMsToTimeElapsedString(player.playtimeSinceLastAug)],
]; ];
if (props.player.sourceFiles.length > 0) { if (player.sourceFiles.length > 0) {
timeRows.push([ timeRows.push([
"Time played since last Bitnode destroyed:", "Time played since last Bitnode destroyed:",
convertTimeMsToTimeElapsedString(props.player.playtimeSinceLastBitnode), convertTimeMsToTimeElapsedString(player.playtimeSinceLastBitnode),
]); ]);
} }
timeRows.push(["Total Time played:", convertTimeMsToTimeElapsedString(props.player.totalPlaytime)]); timeRows.push(["Total Time played:", convertTimeMsToTimeElapsedString(player.totalPlaytime)]);
return ( return (
<> <>
@ -256,13 +263,13 @@ export function CharacterInfo(props: IProps): React.ReactElement {
<b>General</b> <b>General</b>
<br /> <br />
<br /> <br />
<span>Current City: {props.player.city}</span> <span>Current City: {player.city}</span>
<br /> <br />
<LastEmployer /> <LastEmployer />
<LastJob /> <LastJob />
<Employers /> <Employers />
<span> <span>
Money: <Money money={props.player.money.toNumber()} /> Money: <Money money={player.money.toNumber()} />
</span> </span>
<button <button
className="popup-box-button" className="popup-box-button"
@ -279,55 +286,55 @@ export function CharacterInfo(props: IProps): React.ReactElement {
<tr key="0"> <tr key="0">
<td key="0">Hacking:</td> <td key="0">Hacking:</td>
<td key="1" style={{ textAlign: "right" }}> <td key="1" style={{ textAlign: "right" }}>
{numeralWrapper.formatSkill(props.player.hacking_skill)} {numeralWrapper.formatSkill(player.hacking_skill)}
</td> </td>
<td key="2" style={{ textAlign: "right" }}> <td key="2" style={{ textAlign: "right" }}>
({numeralWrapper.formatExp(props.player.hacking_exp)} exp) ({numeralWrapper.formatExp(player.hacking_exp)} exp)
</td> </td>
</tr> </tr>
<tr key="1"> <tr key="1">
<td key="0">Strength:</td> <td key="0">Strength:</td>
<td key="1" style={{ textAlign: "right" }}> <td key="1" style={{ textAlign: "right" }}>
{numeralWrapper.formatSkill(props.player.strength)} {numeralWrapper.formatSkill(player.strength)}
</td> </td>
<td key="2" style={{ textAlign: "right" }}> <td key="2" style={{ textAlign: "right" }}>
({numeralWrapper.formatExp(props.player.strength_exp)} exp) ({numeralWrapper.formatExp(player.strength_exp)} exp)
</td> </td>
</tr> </tr>
<tr key="2"> <tr key="2">
<td key="0">Defense:</td> <td key="0">Defense:</td>
<td key="1" style={{ textAlign: "right" }}> <td key="1" style={{ textAlign: "right" }}>
{numeralWrapper.formatSkill(props.player.defense)} {numeralWrapper.formatSkill(player.defense)}
</td> </td>
<td key="2" style={{ textAlign: "right" }}> <td key="2" style={{ textAlign: "right" }}>
({numeralWrapper.formatExp(props.player.defense_exp)} exp) ({numeralWrapper.formatExp(player.defense_exp)} exp)
</td> </td>
</tr> </tr>
<tr key="3"> <tr key="3">
<td key="0">Dexterity:</td> <td key="0">Dexterity:</td>
<td key="1" style={{ textAlign: "right" }}> <td key="1" style={{ textAlign: "right" }}>
{numeralWrapper.formatSkill(props.player.dexterity)} {numeralWrapper.formatSkill(player.dexterity)}
</td> </td>
<td key="2" style={{ textAlign: "right" }}> <td key="2" style={{ textAlign: "right" }}>
({numeralWrapper.formatExp(props.player.dexterity_exp)} exp) ({numeralWrapper.formatExp(player.dexterity_exp)} exp)
</td> </td>
</tr> </tr>
<tr key="4"> <tr key="4">
<td key="0">Agility:</td> <td key="0">Agility:</td>
<td key="1" style={{ textAlign: "right" }}> <td key="1" style={{ textAlign: "right" }}>
{numeralWrapper.formatSkill(props.player.agility)} {numeralWrapper.formatSkill(player.agility)}
</td> </td>
<td key="2" style={{ textAlign: "right" }}> <td key="2" style={{ textAlign: "right" }}>
({numeralWrapper.formatExp(props.player.agility_exp)} exp) ({numeralWrapper.formatExp(player.agility_exp)} exp)
</td> </td>
</tr> </tr>
<tr key="5"> <tr key="5">
<td key="0">Charisma:</td> <td key="0">Charisma:</td>
<td key="1" style={{ textAlign: "right" }}> <td key="1" style={{ textAlign: "right" }}>
{numeralWrapper.formatSkill(props.player.charisma)} {numeralWrapper.formatSkill(player.charisma)}
</td> </td>
<td key="2" style={{ textAlign: "right" }}> <td key="2" style={{ textAlign: "right" }}>
({numeralWrapper.formatExp(props.player.charisma_exp)} exp) ({numeralWrapper.formatExp(player.charisma_exp)} exp)
</td> </td>
</tr> </tr>
<Intelligence /> <Intelligence />
@ -336,57 +343,41 @@ export function CharacterInfo(props: IProps): React.ReactElement {
<br /> <br />
<MultiplierTable <MultiplierTable
rows={[ rows={[
["Hacking Chance", props.player.hacking_chance_mult], ["Hacking Chance", player.hacking_chance_mult],
["Hacking Speed", props.player.hacking_speed_mult], ["Hacking Speed", player.hacking_speed_mult],
[ [
"Hacking Money", "Hacking Money",
props.player.hacking_money_mult, player.hacking_money_mult,
props.player.hacking_money_mult * BitNodeMultipliers.ScriptHackMoney, player.hacking_money_mult * BitNodeMultipliers.ScriptHackMoney,
], ],
[ [
"Hacking Growth", "Hacking Growth",
props.player.hacking_grow_mult, player.hacking_grow_mult,
props.player.hacking_grow_mult * BitNodeMultipliers.ServerGrowthRate, player.hacking_grow_mult * BitNodeMultipliers.ServerGrowthRate,
], ],
]} ]}
/> />
<br /> <br />
<MultiplierTable <MultiplierTable
rows={[ rows={[
[ ["Hacking Level", player.hacking_mult, player.hacking_mult * BitNodeMultipliers.HackingLevelMultiplier],
"Hacking Level", ["Hacking Experience", player.hacking_exp_mult, player.hacking_exp_mult * BitNodeMultipliers.HackExpGain],
props.player.hacking_mult,
props.player.hacking_mult * BitNodeMultipliers.HackingLevelMultiplier,
],
[
"Hacking Experience",
props.player.hacking_exp_mult,
props.player.hacking_exp_mult * BitNodeMultipliers.HackExpGain,
],
]} ]}
/> />
<br /> <br />
<MultiplierTable <MultiplierTable
rows={[ rows={[
[ ["Strength Level", player.strength_mult, player.strength_mult * BitNodeMultipliers.StrengthLevelMultiplier],
"Strength Level", ["Strength Experience", player.strength_exp_mult],
props.player.strength_mult,
props.player.strength_mult * BitNodeMultipliers.StrengthLevelMultiplier,
],
["Strength Experience", props.player.strength_exp_mult],
]} ]}
/> />
<br /> <br />
<MultiplierTable <MultiplierTable
rows={[ rows={[
[ ["Defense Level", player.defense_mult, player.defense_mult * BitNodeMultipliers.DefenseLevelMultiplier],
"Defense Level", ["Defense Experience", player.defense_exp_mult],
props.player.defense_mult,
props.player.defense_mult * BitNodeMultipliers.DefenseLevelMultiplier,
],
["Defense Experience", props.player.defense_exp_mult],
]} ]}
/> />
<br /> <br />
@ -395,34 +386,26 @@ export function CharacterInfo(props: IProps): React.ReactElement {
rows={[ rows={[
[ [
"Dexterity Level", "Dexterity Level",
props.player.dexterity_mult, player.dexterity_mult,
props.player.dexterity_mult * BitNodeMultipliers.DexterityLevelMultiplier, player.dexterity_mult * BitNodeMultipliers.DexterityLevelMultiplier,
], ],
["Dexterity Experience", props.player.dexterity_exp_mult], ["Dexterity Experience", player.dexterity_exp_mult],
]} ]}
/> />
<br /> <br />
<MultiplierTable <MultiplierTable
rows={[ rows={[
[ ["Agility Level", player.agility_mult, player.agility_mult * BitNodeMultipliers.AgilityLevelMultiplier],
"Agility Level", ["Agility Experience", player.agility_exp_mult],
props.player.agility_mult,
props.player.agility_mult * BitNodeMultipliers.AgilityLevelMultiplier,
],
["Agility Experience", props.player.agility_exp_mult],
]} ]}
/> />
<br /> <br />
<MultiplierTable <MultiplierTable
rows={[ rows={[
[ ["Charisma Level", player.charisma_mult, player.charisma_mult * BitNodeMultipliers.CharismaLevelMultiplier],
"Charisma Level", ["Charisma Experience", player.charisma_exp_mult],
props.player.charisma_mult,
props.player.charisma_mult * BitNodeMultipliers.CharismaLevelMultiplier,
],
["Charisma Experience", props.player.charisma_exp_mult],
]} ]}
/> />
<br /> <br />
@ -431,42 +414,34 @@ export function CharacterInfo(props: IProps): React.ReactElement {
rows={[ rows={[
[ [
"Hacknet Node production", "Hacknet Node production",
props.player.hacknet_node_money_mult, player.hacknet_node_money_mult,
props.player.hacknet_node_money_mult * BitNodeMultipliers.HacknetNodeMoney, player.hacknet_node_money_mult * BitNodeMultipliers.HacknetNodeMoney,
], ],
["Hacknet Node purchase cost", props.player.hacknet_node_purchase_cost_mult], ["Hacknet Node purchase cost", player.hacknet_node_purchase_cost_mult],
["Hacknet Node RAM upgrade cost", props.player.hacknet_node_ram_cost_mult], ["Hacknet Node RAM upgrade cost", player.hacknet_node_ram_cost_mult],
["Hacknet Node Core purchase cost", props.player.hacknet_node_core_cost_mult], ["Hacknet Node Core purchase cost", player.hacknet_node_core_cost_mult],
["Hacknet Node level upgrade cost", props.player.hacknet_node_level_cost_mult], ["Hacknet Node level upgrade cost", player.hacknet_node_level_cost_mult],
]} ]}
/> />
<br /> <br />
<MultiplierTable <MultiplierTable
rows={[ rows={[
["Company reputation gain", props.player.company_rep_mult], ["Company reputation gain", player.company_rep_mult],
[ [
"Faction reputation gain", "Faction reputation gain",
props.player.faction_rep_mult, player.faction_rep_mult,
props.player.faction_rep_mult * BitNodeMultipliers.FactionWorkRepGain, player.faction_rep_mult * BitNodeMultipliers.FactionWorkRepGain,
],
[
"Salary",
props.player.work_money_mult,
props.player.work_money_mult * BitNodeMultipliers.CompanyWorkMoney,
], ],
["Salary", player.work_money_mult, player.work_money_mult * BitNodeMultipliers.CompanyWorkMoney],
]} ]}
/> />
<br /> <br />
<MultiplierTable <MultiplierTable
rows={[ rows={[
["Crime success", props.player.crime_success_mult], ["Crime success", player.crime_success_mult],
[ ["Crime money", player.crime_money_mult, player.crime_money_mult * BitNodeMultipliers.CrimeMoney],
"Crime money",
props.player.crime_money_mult,
props.player.crime_money_mult * BitNodeMultipliers.CrimeMoney,
],
]} ]}
/> />
<br /> <br />
@ -477,10 +452,10 @@ export function CharacterInfo(props: IProps): React.ReactElement {
<b>Misc.</b> <b>Misc.</b>
<br /> <br />
<br /> <br />
<span>{`Servers owned: ${props.player.purchasedServers.length} / ${getPurchaseServerLimit()}`}</span> <span>{`Servers owned: ${player.purchasedServers.length} / ${getPurchaseServerLimit()}`}</span>
<br /> <br />
<Hacknet /> <Hacknet />
<span>{`Augmentations installed: ${props.player.augmentations.length}`}</span> <span>{`Augmentations installed: ${player.augmentations.length}`}</span>
<br /> <br />
<br /> <br />
{StatsTable(timeRows)} {StatsTable(timeRows)}

View File

@ -274,7 +274,7 @@ export function GameRoot({ player, engine, terminal }: IProps): React.ReactEleme
) : page === Page.Sleeves ? ( ) : page === Page.Sleeves ? (
<SleeveRoot player={player} /> <SleeveRoot player={player} />
) : page === Page.Stats ? ( ) : page === Page.Stats ? (
<CharacterInfo player={player} /> <CharacterInfo />
) : page === Page.CreateScript ? ( ) : page === Page.CreateScript ? (
<ScriptEditorRoot filename={filename} code={code} player={player} router={Router} /> <ScriptEditorRoot filename={filename} code={code} player={player} router={Router} />
) : page === Page.ActiveScripts ? ( ) : page === Page.ActiveScripts ? (

View File

@ -233,8 +233,8 @@ export function CharacterOverview({ save }: IProps): React.ReactElement {
</Paper> </Paper>
</Collapse> </Collapse>
<Box display="flex" justifyContent="flex-end"> <Box display="flex" justifyContent="flex-end">
<Fab classes={{ root: classes.nobackground }} color="secondary" onClick={() => setOpen((old) => !old)}> <Fab classes={{ root: classes.nobackground }} onClick={() => setOpen((old) => !old)}>
<VisibilityOffIcon /> <VisibilityOffIcon color="primary" />
</Fab> </Fab>
</Box> </Box>
</Box> </Box>