removing some of the classes

This commit is contained in:
Olivier Gagnon
2021-10-01 13:08:37 -04:00
parent 97c04a1037
commit 4e8bb96f3f
58 changed files with 457 additions and 374 deletions

View File

@ -0,0 +1,33 @@
import React, { useState, useEffect } from "react";
import { Modal } from "../../ui/React/Modal";
import { use } from "../../ui/Context";
import { EventEmitter } from "../../utils/EventEmitter";
import Typography from "@mui/material/Typography";
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);
setOpen(false);
}
useEffect(() => BitFlumeEvent.subscribe(() => setOpen(true)), []);
return (
<Modal open={open} onClose={() => setOpen(false)}>
<Typography>
WARNING: USING THIS PROGRAM WILL CAUSE YOU TO LOSE ALL OF YOUR PROGRESS ON THE CURRENT BITNODE.
<br />
<br />
Do you want to travel to the BitNode Nexus? This allows you to reset the current BitNode and select a new one.
</Typography>
<br />
<br />
<Button onClick={flume}>Travel to the BitVerse</Button>
</Modal>
);
}

View File

@ -1,30 +0,0 @@
import React from "react";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { IRouter } from "../../ui/Router";
import { removePopup } from "../../ui/React/createPopup";
interface IProps {
player: IPlayer;
router: IRouter;
popupId: string;
}
export function BitFlumePopup(props: IProps): React.ReactElement {
function flume(): void {
props.router.toBitVerse(true, false);
removePopup(props.popupId);
}
return (
<>
WARNING: USING THIS PROGRAM WILL CAUSE YOU TO LOSE ALL OF YOUR PROGRESS ON THE CURRENT BITNODE.
<br />
<br />
Do you want to travel to the BitNode Nexus? This allows you to reset the current BitNode and select a new one.
<br />
<br />
<button className="std-button" onClick={flume}>
Travel to the BitVerse
</button>
</>
);
}

View File

@ -150,7 +150,7 @@ export function BitverseRoot(props: IProps): React.ReactElement {
return ( return (
// prettier-ignore // prettier-ignore
<div className="noselect"> <>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> O </Typography> <Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> O </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> | O O | O O | </Typography> <Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> | O O | O O | </Typography>
<Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> O | | / __| \ | | O </Typography> <Typography sx={{lineHeight: '1em',whiteSpace: 'pre'}}> O | | / __| \ | | O </Typography>
@ -203,7 +203,7 @@ export function BitverseRoot(props: IProps): React.ReactElement {
"> ", "> ",
"> (Enter a new BitNode using the image above)", "> (Enter a new BitNode using the image above)",
]} /> ]} />
</div> </>
); );
return <></>; return <></>;

View File

@ -307,9 +307,9 @@ export class Blackjack extends Game<Props, State> {
const dealerHandValues = this.getHandDisplayValues(dealerHand); const dealerHandValues = this.getHandDisplayValues(dealerHand);
return ( return (
<div> <>
{/* Wager input */} {/* Wager input */}
<div> <Box>
<TextField <TextField
value={betInput} value={betInput}
label={ label={
@ -336,32 +336,30 @@ export class Blackjack extends Game<Props, State> {
}} }}
/> />
<p> <Typography>
{"Total earnings this session: "} {"Total earnings this session: "}
<Money money={gains} /> <Money money={gains} />
</p> </Typography>
</div> </Box>
{/* Buttons */} {/* Buttons */}
{!gameInProgress ? ( {!gameInProgress ? (
<div> <Button onClick={this.startOnClick} disabled={wagerInvalid || !this.canStartGame()}>
<Button onClick={this.startOnClick} disabled={wagerInvalid || !this.canStartGame()}> Start
Start </Button>
</Button>
</div>
) : ( ) : (
<div> <>
<Button onClick={this.playerHit}>Hit</Button> <Button onClick={this.playerHit}>Hit</Button>
<Button color="secondary" onClick={this.playerStay}> <Button color="secondary" onClick={this.playerStay}>
Stay Stay
</Button> </Button>
</div> </>
)} )}
{/* Main game part. Displays both if the game is in progress OR if there's a result so you can see {/* Main game part. Displays both if the game is in progress OR if there's a result so you can see
* the cards that led to that result. */} * the cards that led to that result. */}
{(gameInProgress || result !== Result.Pending) && ( {(gameInProgress || result !== Result.Pending) && (
<div> <>
<Box display="flex"> <Box display="flex">
<Paper elevation={2}> <Paper elevation={2}>
<pre>Player</pre> <pre>Player</pre>
@ -396,28 +394,18 @@ export class Blackjack extends Game<Props, State> {
)} )}
</Paper> </Paper>
</Box> </Box>
</div> </>
)} )}
{/* Results from previous round */} {/* Results from previous round */}
{result !== Result.Pending && ( {result !== Result.Pending && (
<p> <Typography>
{result} {result}
{this.isPlayerWinResult(result) && ( {this.isPlayerWinResult(result) && <Money money={this.state.bet} />}
<> {result === Result.DealerWon && <Money money={this.state.bet} />}
{" You gained "} </Typography>
<Money money={this.state.bet} />
</>
)}
{result === Result.DealerWon && (
<>
{" You lost "}
<Money money={this.state.bet} />
</>
)}
</p>
)} )}
</div> </>
); );
} }
} }

View File

@ -1,8 +1,10 @@
import React, { FC } from "react"; import React, { FC } from "react";
import { Card, Suit } from "./Card"; import { Card, Suit } from "./Card";
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 Typography from "@mui/material/Typography";
import Paper from "@mui/material/Paper";
type Props = { type Props = {
card: Card; card: Card;
@ -56,11 +58,11 @@ export const ReactCard: FC<Props> = ({ card, hidden }) => {
throw new Error(`MissingCaseException: ${card.suit}`); throw new Error(`MissingCaseException: ${card.suit}`);
} }
return ( return (
<div className={`${classes.card} ${card.isRedSuit() ? classes.red : classes.black}`}> <Paper className={`${classes.card} ${card.isRedSuit() ? classes.red : classes.black}`}>
<> <>
<div className={classes.value}>{hidden ? " - " : card.formatValue()}</div> <span className={classes.value}>{hidden ? " - " : card.formatValue()}</span>
<div>{hidden ? " - " : suit}</div> <span>{hidden ? " - " : suit}</span>
</> </>
</div> </Paper>
); );
}; };

View File

@ -3,8 +3,7 @@ import { codingContractTypesMetadata, DescriptionFunc, GeneratorFunc, SolverFunc
import { IMap } from "./types"; import { IMap } from "./types";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "./utils/JSONReviver"; import { Generic_fromJSON, Generic_toJSON, Reviver } from "./utils/JSONReviver";
import { createPopup, removePopup } from "./ui/React/createPopup"; import { CodingContractEvent } from "./ui/React/CodingContractModal";
import { CodingContractPopup } from "./ui/React/CodingContractPopup";
/* tslint:disable:no-magic-numbers completed-docs max-classes-per-file no-console */ /* tslint:disable:no-magic-numbers completed-docs max-classes-per-file no-console */
@ -166,29 +165,21 @@ export class CodingContract {
* Creates a popup to prompt the player to solve the problem * Creates a popup to prompt the player to solve the problem
*/ */
async prompt(): Promise<CodingContractResult> { async prompt(): Promise<CodingContractResult> {
const popupId = `coding-contract-prompt-popup-${this.fn}`;
return new Promise<CodingContractResult>((resolve) => { return new Promise<CodingContractResult>((resolve) => {
createPopup( const props = {
popupId, c: this,
CodingContractPopup, onClose: () => {
{ resolve(CodingContractResult.Cancelled);
c: this,
popupId: popupId,
onClose: () => {
resolve(CodingContractResult.Cancelled);
removePopup(popupId);
},
onAttempt: (val: string) => {
if (this.isSolution(val)) {
resolve(CodingContractResult.Success);
} else {
resolve(CodingContractResult.Failure);
}
removePopup(popupId);
},
}, },
() => resolve(CodingContractResult.Cancelled), onAttempt: (val: string) => {
); if (this.isSolution(val)) {
resolve(CodingContractResult.Success);
} else {
resolve(CodingContractResult.Failure);
}
},
};
CodingContractEvent.emit(props);
}); });
} }

View File

@ -125,7 +125,7 @@ function Text(): React.ReactElement {
} }
return ( return (
<div> <>
<Typography> <Typography>
Industry: {division.type} (Corp Funds: <Money money={corp.funds.toNumber()} />) Industry: {division.type} (Corp Funds: <Money money={corp.funds.toNumber()} />)
</Typography> </Typography>
@ -218,7 +218,7 @@ function Text(): React.ReactElement {
Research Research
</Button> </Button>
</Box> </Box>
</div> </>
); );
} }

View File

@ -56,18 +56,6 @@ function WarehouseRoot(props: IProps): React.ReactElement {
props.rerender(); props.rerender();
} }
const ratioLines = [];
for (const matName in division.reqMats) {
if (division.reqMats.hasOwnProperty(matName)) {
const text = [" *", division.reqMats[matName], matName].join(" ");
ratioLines.push(
<div key={matName}>
<p>{text}</p>
</div>,
);
}
}
// Current State: // Current State:
let stateText; let stateText;
switch (division.state) { switch (division.state) {

View File

@ -50,7 +50,7 @@ export function ThrowPartyModal(props: IProps): React.ReactElement {
} }
function EffectText(): React.ReactElement { function EffectText(): React.ReactElement {
if (isNaN(cost) || cost < 0) return <p>Invalid value entered!</p>; if (isNaN(cost) || cost < 0) return <Typography>Invalid value entered!</Typography>;
return ( return (
<Typography> <Typography>
Throwing this party will cost a total of <Money money={totalCost} /> Throwing this party will cost a total of <Money money={totalCost} />

View File

@ -48,40 +48,38 @@ export function General(props: IProps): React.ReactElement {
<h2>General</h2> <h2>General</h2>
</AccordionSummary> </AccordionSummary>
<AccordionDetails> <AccordionDetails>
<div> <Button onClick={addMoney(1e6)}>
<Button onClick={addMoney(1e6)}> <pre>
<pre> + <Money money={1e6} />
+ <Money money={1e6} /> </pre>
</pre> </Button>
</Button> <Button onClick={addMoney(1e9)}>
<Button onClick={addMoney(1e9)}> <pre>
<pre> + <Money money={1e9} />
+ <Money money={1e9} /> </pre>
</pre> </Button>
</Button> <Button onClick={addMoney(1e12)}>
<Button onClick={addMoney(1e12)}> <pre>
<pre> + <Money money={1e12} />
+ <Money money={1e12} /> </pre>
</pre> </Button>
</Button> <Button onClick={addMoney(1e15)}>
<Button onClick={addMoney(1e15)}> <pre>
<pre> + <Money money={1000e12} />
+ <Money money={1000e12} /> </pre>
</pre> </Button>
</Button> <Button onClick={addMoney(Infinity)}>
<Button onClick={addMoney(Infinity)}> <pre>
<pre> + <Money money={Infinity} />
+ <Money money={Infinity} /> </pre>
</pre> </Button>
</Button> <Button onClick={upgradeRam}>+ RAM</Button>
<Button onClick={upgradeRam}>+ RAM</Button> <br />
</div>
<div> <Button onClick={quickB1tFlum3}>Quick b1t_flum3.exe</Button>
<Button onClick={quickB1tFlum3}>Quick b1t_flum3.exe</Button> <Button onClick={b1tflum3}>Run b1t_flum3.exe</Button>
<Button onClick={b1tflum3}>Run b1t_flum3.exe</Button> <Button onClick={quickHackW0r1dD43m0n}>Quick w0rld_d34m0n</Button>
<Button onClick={quickHackW0r1dD43m0n}>Quick w0rld_d34m0n</Button> <Button onClick={hackW0r1dD43m0n}>Hack w0rld_d34m0n</Button>
<Button onClick={hackW0r1dD43m0n}>Hack w0rld_d34m0n</Button>
</div>
</AccordionDetails> </AccordionDetails>
</Accordion> </Accordion>
); );

View File

@ -18,19 +18,13 @@ import {
import { SourceFileFlags } from "../SourceFile/SourceFileFlags"; import { SourceFileFlags } from "../SourceFile/SourceFileFlags";
import { dialogBoxCreate } from "../ui/React/DialogBox"; import { dialogBoxCreate } from "../ui/React/DialogBox";
import { createPopup } from "../ui/React/createPopup"; import { InvitationEvent } from "./ui/InvitationModal";
import { InvitationPopup } from "./ui/InvitationPopup";
export function inviteToFaction(faction: Faction): void { export function inviteToFaction(faction: Faction): void {
Player.factionInvitations.push(faction.name); Player.factionInvitations.push(faction.name);
faction.alreadyInvited = true; faction.alreadyInvited = true;
if (!Settings.SuppressFactionInvites) { if (!Settings.SuppressFactionInvites) {
const popupId = "faction-invitation"; InvitationEvent.emit(faction);
createPopup(popupId, InvitationPopup, {
player: Player,
faction: faction,
popupId: popupId,
});
} }
} }

View File

@ -57,7 +57,7 @@ export function DonateOption(props: IProps): React.ReactElement {
props.faction.playerReputation += repGain; props.faction.playerReputation += repGain;
dialogBoxCreate( dialogBoxCreate(
<> <>
You just donated <Money money={amt} /> to {fac.name} to gain {Reputation(repGain)} reputation. You just donated <Money money={amt} /> to {fac.name} to gain <Reputation reputation={repGain} /> reputation.
</>, </>,
); );
props.rerender(); props.rerender();
@ -71,7 +71,7 @@ export function DonateOption(props: IProps): React.ReactElement {
} }
return ( return (
<Typography> <Typography>
This donation will result in {Reputation(repFromDonation(donateAmt, props.p))} reputation gain This donation will result in <Reputation reputation={repFromDonation(donateAmt, props.p)} /> reputation gain
</Typography> </Typography>
); );
} }
@ -81,7 +81,7 @@ export function DonateOption(props: IProps): React.ReactElement {
<Status /> <Status />
{props.disabled ? ( {props.disabled ? (
<Typography> <Typography>
Unlock donations at {Favor(props.favorToDonate)} favor with {props.faction.name} Unlock donations at <Favor favor={props.favorToDonate} /> favor with {props.faction.name}
</Typography> </Typography>
) : ( ) : (
<> <>

View File

@ -54,7 +54,8 @@ export function Info(props: IProps): React.ReactElement {
title={ title={
<> <>
<Typography> <Typography>
You will have {Favor(props.faction.favor + favorGain)} faction favor after installing an Augmentation. You will have <Favor favor={props.faction.favor + favorGain} /> faction favor after installing an
Augmentation.
</Typography> </Typography>
<MathComponent tex={String.raw`\large{r = \text{total faction reputation}}`} /> <MathComponent tex={String.raw`\large{r = \text{total faction reputation}}`} />
<MathComponent <MathComponent
@ -63,7 +64,9 @@ export function Info(props: IProps): React.ReactElement {
</> </>
} }
> >
<Typography>Reputation: {Reputation(props.faction.playerReputation)}</Typography> <Typography>
Reputation: <Reputation reputation={props.faction.playerReputation} />
</Typography>
</Tooltip> </Tooltip>
</Box> </Box>
@ -83,7 +86,9 @@ export function Info(props: IProps): React.ReactElement {
</> </>
} }
> >
<Typography>Faction Favor: {Favor(props.faction.favor)}</Typography> <Typography>
Faction Favor: <Favor favor={props.faction.favor} />
</Typography>
</Tooltip> </Tooltip>
</Box> </Box>

View File

@ -0,0 +1,40 @@
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 { EventEmitter } from "../../utils/EventEmitter";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
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);
if (i === -1) {
console.error("Could not find faction in Player.factionInvitations");
}
joinFaction(faction);
setFaction(null);
}
useEffect(() => InvitationEvent.subscribe((faction) => setFaction(faction)), []);
return (
<Modal open={faction !== null} onClose={() => setFaction(null)}>
<Typography variant="h4">You have received a faction invitation.</Typography>
<Typography>
Would you like to join {(faction || { name: "" }).name}? <br />
<br />
Warning: Joining this faction may prevent you from joining other factions during this run!
</Typography>
<Button onClick={join}>Join!</Button>
<Button onClick={() => setFaction(null)}>Decide later</Button>
</Modal>
);
}

View File

@ -1,40 +0,0 @@
import React from "react";
import { joinFaction } from "../../Faction/FactionHelpers";
import { Faction } from "../../Faction/Faction";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { removePopup } from "../../ui/React/createPopup";
interface IProps {
player: IPlayer;
faction: Faction;
popupId: string;
}
export function InvitationPopup(props: IProps): React.ReactElement {
function join(): void {
//Remove from invited factions
const i = props.player.factionInvitations.findIndex((facName) => facName === props.faction.name);
if (i === -1) {
console.error("Could not find faction in Player.factionInvitations");
}
joinFaction(props.faction);
removePopup(props.popupId);
}
return (
<>
<h1>You have received a faction invitation.</h1>
<p>
Would you like to join {props.faction.name}? <br />
<br />
Warning: Joining this faction may prevent you from joining other factions during this run!
</p>
<button className="std-button" onClick={join}>
Join!
</button>
<button className="std-button" onClick={() => removePopup(props.popupId)}>
Decide later
</button>
</>
);
}

View File

@ -57,7 +57,7 @@ function Requirements(props: IReqProps): React.ReactElement {
</TableCell> </TableCell>
<TableCell key={2}> <TableCell key={2}>
<Typography color={props.hasRep ? "primary" : "error"}> <Typography color={props.hasRep ? "primary" : "error"}>
Requires {Reputation(props.rep)} faction reputation Requires <Reputation reputation={props.rep} /> faction reputation
</Typography> </Typography>
</TableCell> </TableCell>
</React.Fragment> </React.Fragment>

View File

@ -66,7 +66,7 @@ export function GangStats(props: IProps): React.ReactElement {
</p> </p>
<br /> <br />
<p style={{ display: "inline-block" }}> <p style={{ display: "inline-block" }}>
Faction reputation: {Reputation(Factions[props.gang.facName].playerReputation)} Faction reputation: <Reputation reputation={Factions[props.gang.facName].playerReputation} />
</p> </p>
<br /> <br />
<BonusTime gang={props.gang} /> <BonusTime gang={props.gang} />

View File

@ -183,7 +183,7 @@ export function HacknetServerElem(props: IProps): React.ReactElement {
</TableCell> </TableCell>
<TableCell colSpan={2}> <TableCell colSpan={2}>
<Typography> <Typography>
{Hashes(node.totalHashesGenerated)} ({HashRate(node.hashRate)}) <Hashes hashes={node.totalHashesGenerated} /> (<HashRate hashes={node.hashRate} />)
</Typography> </Typography>
</TableCell> </TableCell>
</TableRow> </TableRow>
@ -192,7 +192,9 @@ export function HacknetServerElem(props: IProps): React.ReactElement {
<Typography>Hash Capacity:</Typography> <Typography>Hash Capacity:</Typography>
</TableCell> </TableCell>
<TableCell colSpan={2}> <TableCell colSpan={2}>
<Typography>{Hashes(node.hashCapacity)}</Typography> <Typography>
<Hashes hashes={node.hashCapacity} />
</Typography>
</TableCell> </TableCell>
</TableRow> </TableRow>
<TableRow> <TableRow>

View File

@ -60,7 +60,7 @@ export function HacknetUpgradeElem(props: IProps): React.ReactElement {
<CopyableText value={upg.name} /> <CopyableText value={upg.name} />
</Typography> </Typography>
<Typography> <Typography>
Cost: {Hashes(cost)}, Bought: {level} times Cost: <Hashes hashes={cost} />, Bought: {level} times
</Typography> </Typography>
<Typography>{upg.desc}</Typography> <Typography>{upg.desc}</Typography>

View File

@ -6,8 +6,6 @@ import React, { useState, useEffect } from "react";
import { HashManager } from "../HashManager"; import { HashManager } from "../HashManager";
import { HashUpgrades } from "../HashUpgrades"; import { HashUpgrades } from "../HashUpgrades";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { Hashes } from "../../ui/React/Hashes"; import { Hashes } from "../../ui/React/Hashes";
import { HacknetUpgradeElem } from "./HacknetUpgradeElem"; import { HacknetUpgradeElem } from "./HacknetUpgradeElem";
import { Modal } from "../../ui/React/Modal"; import { Modal } from "../../ui/React/Modal";
@ -40,7 +38,9 @@ export function HashUpgradeModal(props: IProps): React.ReactElement {
<Modal open={props.open} onClose={props.onClose}> <Modal open={props.open} onClose={props.onClose}>
<> <>
<Typography>Spend your hashes on a variety of different upgrades</Typography> <Typography>Spend your hashes on a variety of different upgrades</Typography>
<Typography>Hashes: {Hashes(player.hashManager.hashes)}</Typography> <Typography>
Hashes: <Hashes hashes={player.hashManager.hashes} />
</Typography>
{Object.keys(HashUpgrades).map((upgName) => { {Object.keys(HashUpgrades).map((upgName) => {
const upg = HashUpgrades[upgName]; const upg = HashUpgrades[upgName];
return ( return (

View File

@ -9,14 +9,17 @@ import { PurchaseMultipliers } from "../data/Constants";
import Button from "@mui/material/Button"; import Button from "@mui/material/Button";
interface IMultiplierProps { interface IMultiplierProps {
className: string; disabled: boolean;
key: string;
onClick: () => void; onClick: () => void;
text: string; text: string;
} }
function MultiplierButton(props: IMultiplierProps): React.ReactElement { function MultiplierButton(props: IMultiplierProps): React.ReactElement {
return <Button onClick={props.onClick}>{props.text}</Button>; return (
<Button disabled={props.disabled} onClick={props.onClick}>
{props.text}
</Button>
);
} }
interface IProps { interface IProps {
@ -35,13 +38,12 @@ export function MultiplierButtons(props: IProps): React.ReactElement {
for (let i = 0; i < mults.length; ++i) { for (let i = 0; i < mults.length; ++i) {
const mult = mults[i]; const mult = mults[i];
const btnProps = { const btnProps = {
className: props.purchaseMultiplier === PurchaseMultipliers[mult] ? "std-button-disabled" : "std-button", disabled: props.purchaseMultiplier === PurchaseMultipliers[mult],
key: mult,
onClick: onClicks[i], onClick: onClicks[i],
text: mult, text: mult,
}; };
buttons.push(<MultiplierButton {...btnProps} />); buttons.push(<MultiplierButton key={mult} {...btnProps} />);
} }
return <>{buttons}</>; return <>{buttons}</>;

View File

@ -24,7 +24,7 @@ export function PlayerInfo(props: IProps): React.ReactElement {
let prod; let prod;
if (hasServers) { if (hasServers) {
prod = HashRate(props.totalProduction); prod = <HashRate hashes={props.totalProduction} />;
} else { } else {
prod = <MoneyRate money={props.totalProduction} />; prod = <MoneyRate money={props.totalProduction} />;
} }
@ -39,7 +39,8 @@ export function PlayerInfo(props: IProps): React.ReactElement {
{hasServers && ( {hasServers && (
<> <>
<Typography> <Typography>
Hashes: {Hashes(props.player.hashManager.hashes)} / {Hashes(props.player.hashManager.capacity)} Hashes: <Hashes hashes={props.player.hashManager.hashes} /> /{" "}
<Hashes hashes={props.player.hashManager.capacity} />
</Typography> </Typography>
</> </>
)} )}

View File

@ -18,14 +18,10 @@ interface IProps {
export function PurchaseButton(props: IProps): React.ReactElement { export function PurchaseButton(props: IProps): React.ReactElement {
const cost = props.cost; const cost = props.cost;
let className = Player.canAfford(cost) ? "std-button" : "std-button-disabled";
let text; let text;
let style = {};
if (hasHacknetServers(Player)) { if (hasHacknetServers(Player)) {
if (hasMaxNumberHacknetServers(Player)) { if (hasMaxNumberHacknetServers(Player)) {
className = "std-button-disabled";
text = <>Hacknet Server limit reached</>; text = <>Hacknet Server limit reached</>;
style = { color: "red" };
} else { } else {
text = ( text = (
<> <>
@ -43,5 +39,9 @@ export function PurchaseButton(props: IProps): React.ReactElement {
); );
} }
return <Button onClick={props.onClick}>{text}</Button>; return (
<Button disabled={!Player.canAfford(cost)} onClick={props.onClick}>
{text}
</Button>
);
} }

View File

@ -6,6 +6,7 @@ import { GameTimer } from "./GameTimer";
import { random } from "../utils"; import { random } from "../utils";
import { interpolate } from "./Difficulty"; import { interpolate } from "./Difficulty";
import { BlinkingCursor } from "./BlinkingCursor"; import { BlinkingCursor } from "./BlinkingCursor";
import Typography from "@mui/material/Typography";
interface Difficulty { interface Difficulty {
[key: string]: number; [key: string]: number;
@ -46,17 +47,17 @@ export function BackwardGame(props: IMinigameProps): React.ReactElement {
<Grid container spacing={3}> <Grid container spacing={3}>
<GameTimer millis={timer} onExpire={props.onFailure} /> <GameTimer millis={timer} onExpire={props.onFailure} />
<Grid item xs={12}> <Grid item xs={12}>
<h1 className={"noselect"}>Type it backward</h1> <Typography variant="h4">Type it backward</Typography>
<KeyHandler onKeyDown={press} onFailure={props.onFailure} /> <KeyHandler onKeyDown={press} onFailure={props.onFailure} />
</Grid> </Grid>
<Grid item xs={6}> <Grid item xs={6}>
<p style={{ transform: "scaleX(-1)" }}>{answer}</p> <Typography style={{ transform: "scaleX(-1)" }}>{answer}</Typography>
</Grid> </Grid>
<Grid item xs={6}> <Grid item xs={6}>
<p> <Typography>
{guess} {guess}
<BlinkingCursor /> <BlinkingCursor />
</p> </Typography>
</Grid> </Grid>
</Grid> </Grid>
); );

View File

@ -6,6 +6,7 @@ import { GameTimer } from "./GameTimer";
import { random } from "../utils"; import { random } from "../utils";
import { interpolate } from "./Difficulty"; import { interpolate } from "./Difficulty";
import { BlinkingCursor } from "./BlinkingCursor"; import { BlinkingCursor } from "./BlinkingCursor";
import Typography from "@mui/material/Typography";
interface Difficulty { interface Difficulty {
[key: string]: number; [key: string]: number;
@ -79,11 +80,11 @@ export function BracketGame(props: IMinigameProps): React.ReactElement {
<Grid container spacing={3}> <Grid container spacing={3}>
<GameTimer millis={timer} onExpire={props.onFailure} /> <GameTimer millis={timer} onExpire={props.onFailure} />
<Grid item xs={12}> <Grid item xs={12}>
<h1 className={"noselect"}>Close the brackets</h1> <Typography variant="h4">Close the brackets</Typography>
<p style={{ fontSize: "5em" }}> <Typography style={{ fontSize: "5em" }}>
{`${left}${right}`} {`${left}${right}`}
<BlinkingCursor /> <BlinkingCursor />
</p> </Typography>
<KeyHandler onKeyDown={press} onFailure={props.onFailure} /> <KeyHandler onKeyDown={press} onFailure={props.onFailure} />
</Grid> </Grid>
</Grid> </Grid>

View File

@ -4,6 +4,7 @@ import { IMinigameProps } from "./IMinigameProps";
import { KeyHandler } from "./KeyHandler"; import { KeyHandler } from "./KeyHandler";
import { GameTimer } from "./GameTimer"; import { GameTimer } from "./GameTimer";
import { interpolate } from "./Difficulty"; import { interpolate } from "./Difficulty";
import Typography from "@mui/material/Typography";
interface Difficulty { interface Difficulty {
[key: string]: number; [key: string]: number;
@ -51,13 +52,19 @@ export function BribeGame(props: IMinigameProps): React.ReactElement {
<Grid container spacing={3}> <Grid container spacing={3}>
<GameTimer millis={timer} onExpire={props.onFailure} /> <GameTimer millis={timer} onExpire={props.onFailure} />
<Grid item xs={12}> <Grid item xs={12}>
<h1>Say something nice about the guard.</h1> <Typography variant="h4">Say something nice about the guard.</Typography>
<KeyHandler onKeyDown={press} onFailure={props.onFailure} /> <KeyHandler onKeyDown={press} onFailure={props.onFailure} />
</Grid> </Grid>
<Grid item xs={6}> <Grid item xs={6}>
<h2 style={{ fontSize: "2em" }}></h2> <Typography variant="h5" color="primary">
<h2 style={{ fontSize: "2em" }}>{choices[index]}</h2>
<h2 style={{ fontSize: "2em" }}></h2> </Typography>
<Typography variant="h5" color="primary">
{choices[index]}
</Typography>
<Typography variant="h5" color="primary">
</Typography>
</Grid> </Grid>
</Grid> </Grid>
); );

View File

@ -5,6 +5,7 @@ import { KeyHandler } from "./KeyHandler";
import { GameTimer } from "./GameTimer"; import { GameTimer } from "./GameTimer";
import { random, getArrow } from "../utils"; import { random, getArrow } from "../utils";
import { interpolate } from "./Difficulty"; import { interpolate } from "./Difficulty";
import Typography from "@mui/material/Typography";
interface Difficulty { interface Difficulty {
[key: string]: number; [key: string]: number;
@ -46,8 +47,8 @@ export function CheatCodeGame(props: IMinigameProps): React.ReactElement {
<Grid container spacing={3}> <Grid container spacing={3}>
<GameTimer millis={timer} onExpire={props.onFailure} /> <GameTimer millis={timer} onExpire={props.onFailure} />
<Grid item xs={12}> <Grid item xs={12}>
<h1 className={"noselect"}>Enter the Code!</h1> <Typography variant="h4">Enter the Code!</Typography>
<p style={{ fontSize: "5em" }}>{code[index]}</p> <Typography variant="h4">{code[index]}</Typography>
<KeyHandler onKeyDown={press} onFailure={props.onFailure} /> <KeyHandler onKeyDown={press} onFailure={props.onFailure} />
</Grid> </Grid>
</Grid> </Grid>

View File

@ -1,6 +1,7 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import Grid from "@mui/material/Grid"; import Grid from "@mui/material/Grid";
import Typography from "@mui/material/Typography";
interface IProps { interface IProps {
onFinish: () => void; onFinish: () => void;
} }
@ -19,8 +20,8 @@ export function Countdown(props: IProps): React.ReactElement {
<> <>
<Grid container spacing={3}> <Grid container spacing={3}>
<Grid item xs={12}> <Grid item xs={12}>
<h1>Get Ready!</h1> <Typography variant="h4">Get Ready!</Typography>
<h1>{x}</h1> <Typography variant="h4">{x}</Typography>
</Grid> </Grid>
</Grid> </Grid>
</> </>

View File

@ -5,6 +5,7 @@ import { KeyHandler } from "./KeyHandler";
import { GameTimer } from "./GameTimer"; import { GameTimer } from "./GameTimer";
import { interpolate } from "./Difficulty"; import { interpolate } from "./Difficulty";
import { getArrow } from "../utils"; import { getArrow } from "../utils";
import Typography from "@mui/material/Typography";
interface Difficulty { interface Difficulty {
[key: string]: number; [key: string]: number;
@ -75,8 +76,8 @@ export function Cyberpunk2077Game(props: IMinigameProps): React.ReactElement {
<Grid container spacing={3}> <Grid container spacing={3}>
<GameTimer millis={timer} onExpire={props.onFailure} /> <GameTimer millis={timer} onExpire={props.onFailure} />
<Grid item xs={12}> <Grid item xs={12}>
<h1 className={"noselect"}>Match the symbols!</h1> <Typography variant="h4">Match the symbols!</Typography>
<h2 style={{ fontSize: fontSize }}> <Typography variant="h5" color="primary">
Targets:{" "} Targets:{" "}
{answer.map((a, i) => { {answer.map((a, i) => {
if (i == index) if (i == index)
@ -91,7 +92,7 @@ export function Cyberpunk2077Game(props: IMinigameProps): React.ReactElement {
</span> </span>
); );
})} })}
</h2> </Typography>
<br /> <br />
{grid.map((line, y) => ( {grid.map((line, y) => (
<div key={y}> <div key={y}>

View File

@ -11,6 +11,7 @@ import { Cyberpunk2077Game } from "./Cyberpunk2077Game";
import { MinesweeperGame } from "./MinesweeperGame"; import { MinesweeperGame } from "./MinesweeperGame";
import { WireCuttingGame } from "./WireCuttingGame"; import { WireCuttingGame } from "./WireCuttingGame";
import { Victory } from "./Victory"; import { Victory } from "./Victory";
import Typography from "@mui/material/Typography";
interface IProps { interface IProps {
StartingDifficulty: number; StartingDifficulty: number;
@ -130,9 +131,9 @@ export function Game(props: IProps): React.ReactElement {
<> <>
<Grid container spacing={3}> <Grid container spacing={3}>
<Grid item xs={3}> <Grid item xs={3}>
<h3> <Typography>
Level: {level}&nbsp;/&nbsp;{props.MaxLevel} Level: {level}&nbsp;/&nbsp;{props.MaxLevel}
</h3> </Typography>
<Progress /> <Progress />
</Grid> </Grid>

View File

@ -1,7 +1,8 @@
import React from "react"; import React from "react";
import { StdButton } from "../../ui/React/StdButton";
import { Location } from "../../Locations/Location"; import { Location } from "../../Locations/Location";
import Grid from "@mui/material/Grid"; import Grid from "@mui/material/Grid";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
interface IProps { interface IProps {
Location: Location; Location: Location;
@ -52,37 +53,45 @@ export function Intro(props: IProps): React.ReactElement {
<> <>
<Grid container spacing={3}> <Grid container spacing={3}>
<Grid item xs={10}> <Grid item xs={10}>
<h1>Infiltrating {props.Location.name}</h1> <Typography variant="h4">Infiltrating {props.Location.name}</Typography>
</Grid> </Grid>
<Grid item xs={10}> <Grid item xs={10}>
<h2>Maximum level: {props.MaxLevel}</h2> <Typography variant="h5" color="primary">
Maximum level: {props.MaxLevel}
</Typography>
</Grid> </Grid>
<Grid item xs={10}> <Grid item xs={10}>
<pre>[{coloredArrow(props.Difficulty)}]</pre> <Typography sx={{ lineHeight: "1em", whiteSpace: "pre" }}>[{coloredArrow(props.Difficulty)}]</Typography>
<pre>{` ^ ^ ^ ^`}</pre> <Typography
<pre>{` Trivial Normal Hard Impossible`}</pre> sx={{ lineHeight: "1em", whiteSpace: "pre" }}
>{` ^ ^ ^ ^`}</Typography>
<Typography
sx={{ lineHeight: "1em", whiteSpace: "pre" }}
>{` Trivial Normal Hard Impossible`}</Typography>
</Grid> </Grid>
<Grid item xs={10}> <Grid item xs={10}>
<p> <Typography>
Infiltration is a series of short minigames that get progressively harder. You take damage for failing them. Infiltration is a series of short minigames that get progressively harder. You take damage for failing them.
Reaching the maximum level rewards you with intel you can trade for money or reputation. Reaching the maximum level rewards you with intel you can trade for money or reputation.
</p> </Typography>
<br /> <br />
<p>The minigames you play are randomly selected. It might take you few tries to get used to them.</p> <Typography>
The minigames you play are randomly selected. It might take you few tries to get used to them.
</Typography>
<br /> <br />
<p>No game require use of the mouse.</p> <Typography>No game require use of the mouse.</Typography>
<br /> <br />
<p>Spacebar is the default action/confirm button.</p> <Typography>Spacebar is the default action/confirm button.</Typography>
<br /> <br />
<p>Everything that uses arrow can also use WASD</p> <Typography>Everything that uses arrow can also use WASD</Typography>
<br /> <br />
<p>Sometimes the rest of the keyboard is used.</p> <Typography>Sometimes the rest of the keyboard is used.</Typography>
</Grid> </Grid>
<Grid item xs={3}> <Grid item xs={3}>
<StdButton onClick={props.start} text={"Start"} /> <Button onClick={props.start}>Start</Button>
</Grid> </Grid>
<Grid item xs={3}> <Grid item xs={3}>
<StdButton onClick={props.cancel} text={"Cancel"} /> <Button onClick={props.cancel}>Cancel</Button>
</Grid> </Grid>
</Grid> </Grid>
</> </>

View File

@ -5,6 +5,7 @@ import { KeyHandler } from "./KeyHandler";
import { GameTimer } from "./GameTimer"; import { GameTimer } from "./GameTimer";
import { interpolate } from "./Difficulty"; import { interpolate } from "./Difficulty";
import { getArrow } from "../utils"; import { getArrow } from "../utils";
import Typography from "@mui/material/Typography";
interface Difficulty { interface Difficulty {
[key: string]: number; [key: string]: number;
@ -81,7 +82,7 @@ export function MinesweeperGame(props: IMinigameProps): React.ReactElement {
<Grid container spacing={3}> <Grid container spacing={3}>
<GameTimer millis={timer} onExpire={props.onFailure} /> <GameTimer millis={timer} onExpire={props.onFailure} />
<Grid item xs={12}> <Grid item xs={12}>
<h1 className={"noselect"}>{memoryPhase ? "Remember all the mines!" : "Mark all the mines!"}</h1> <Typography variant="h4">{memoryPhase ? "Remember all the mines!" : "Mark all the mines!"}</Typography>
{minefield.map((line, y) => ( {minefield.map((line, y) => (
<div key={y}> <div key={y}>
<pre> <pre>

View File

@ -4,6 +4,7 @@ import { IMinigameProps } from "./IMinigameProps";
import { KeyHandler } from "./KeyHandler"; import { KeyHandler } from "./KeyHandler";
import { GameTimer } from "./GameTimer"; import { GameTimer } from "./GameTimer";
import { interpolate } from "./Difficulty"; import { interpolate } from "./Difficulty";
import Typography from "@mui/material/Typography";
interface Difficulty { interface Difficulty {
[key: string]: number; [key: string]: number;
@ -53,8 +54,8 @@ export function SlashGame(props: IMinigameProps): React.ReactElement {
<Grid container spacing={3}> <Grid container spacing={3}>
<GameTimer millis={5000} onExpire={props.onFailure} /> <GameTimer millis={5000} onExpire={props.onFailure} />
<Grid item xs={12}> <Grid item xs={12}>
<h1 className={"noselect"}>Slash when his guard is down!</h1> <Typography variant="h4">Slash when his guard is down!</Typography>
<p style={{ fontSize: "5em" }}>{guarding ? "!Guarding!" : "!ATTACKING!"}</p> <Typography variant="h4">{guarding ? "!Guarding!" : "!ATTACKING!"}</Typography>
<KeyHandler onKeyDown={press} onFailure={props.onFailure} /> <KeyHandler onKeyDown={press} onFailure={props.onFailure} />
</Grid> </Grid>
</Grid> </Grid>

View File

@ -1,11 +1,14 @@
import { Factions } from "../../Faction/Factions"; import { Factions } from "../../Faction/Factions";
import React, { useState } from "react"; import React, { useState } from "react";
import { StdButton } from "../../ui/React/StdButton";
import Grid from "@mui/material/Grid"; import Grid from "@mui/material/Grid";
import { Money } from "../../ui/React/Money"; import { Money } from "../../ui/React/Money";
import { Reputation } from "../../ui/React/Reputation"; import { Reputation } from "../../ui/React/Reputation";
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
import { use } from "../../ui/Context"; import { use } from "../../ui/Context";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import MenuItem from "@mui/material/MenuItem";
import Select, { SelectChangeEvent } from "@mui/material/Select";
interface IProps { interface IProps {
StartingDifficulty: number; StartingDifficulty: number;
@ -50,7 +53,7 @@ export function Victory(props: IProps): React.ReactElement {
quitInfiltration(); quitInfiltration();
} }
function changeDropdown(event: React.ChangeEvent<HTMLSelectElement>): void { function changeDropdown(event: SelectChangeEvent<string>): void {
setFaction(event.target.value); setFaction(event.target.value);
} }
@ -58,46 +61,36 @@ export function Victory(props: IProps): React.ReactElement {
<> <>
<Grid container spacing={3}> <Grid container spacing={3}>
<Grid item xs={10}> <Grid item xs={10}>
<h1>Infiltration successful!</h1> <Typography variant="h4">Infiltration successful!</Typography>
</Grid> </Grid>
<Grid item xs={10}> <Grid item xs={10}>
<h2>You can trade the confidential information you found for money or reputation.</h2> <Typography variant="h5" color="primary">
<select className={"dropdown"} onChange={changeDropdown}> You can trade the confidential information you found for money or reputation.
<option key={"none"} value={"none"}> </Typography>
<Select value={faction} onChange={changeDropdown}>
<MenuItem key={"none"} value={"none"}>
{"none"} {"none"}
</option> </MenuItem>
{player.factions {player.factions
.filter((f) => Factions[f].getInfo().offersWork()) .filter((f) => Factions[f].getInfo().offersWork())
.map((f) => ( .map((f) => (
<option key={f} value={f}> <MenuItem key={f} value={f}>
{f} {f}
</option> </MenuItem>
))} ))}
</select> </Select>
<StdButton <Button onClick={trade}>
onClick={trade} Trade for <Reputation reputation={repGain} /> reputation
text={ </Button>
<>
{"Trade for "}
{Reputation(repGain)}
{" reputation"}
</>
}
/>
</Grid> </Grid>
<Grid item xs={3}> <Grid item xs={3}>
<StdButton <Button onClick={sell}>
onClick={sell} Sell for&nbsp;
text={ <Money money={moneyGain} />
<> </Button>
{"Sell for "}
<Money money={moneyGain} />
</>
}
/>
</Grid> </Grid>
<Grid item xs={3}> <Grid item xs={3}>
<StdButton onClick={quitInfiltration} text={"Quit"} /> <Button onClick={quitInfiltration}>Quit</Button>
</Grid> </Grid>
</Grid> </Grid>
</> </>

View File

@ -21,7 +21,6 @@ import * as posNames from "../../Company/data/companypositionnames";
import { Reputation } from "../../ui/React/Reputation"; import { Reputation } from "../../ui/React/Reputation";
import { Favor } from "../../ui/React/Favor"; import { Favor } from "../../ui/React/Favor";
import { createPopup } from "../../ui/React/createPopup";
import { use } from "../../ui/Context"; import { use } from "../../ui/Context";
import { QuitJobModal } from "../../Company/ui/QuitJobModal"; import { QuitJobModal } from "../../Company/ui/QuitJobModal";
@ -184,21 +183,23 @@ export function CompanyLocation(props: IProps): React.ReactElement {
const favorGain = company.getFavorGain(); const favorGain = company.getFavorGain();
return ( return (
<div> <>
{isEmployedHere && ( {isEmployedHere && (
<div> <>
<Typography>Job Title: {jobTitle}</Typography> <Typography>Job Title: {jobTitle}</Typography>
<Typography>-------------------------</Typography> <Typography>-------------------------</Typography>
<Box display="flex"> <Box display="flex">
<Tooltip <Tooltip
title={ title={
<> <>
You will have {Favor(company.favor + favorGain[0])} company favor upon resetting after installing You will have <Favor favor={company.favor + favorGain[0]} /> company favor upon resetting after
Augmentations installing Augmentations
</> </>
} }
> >
<Typography>Company reputation: {Reputation(company.playerReputation)}</Typography> <Typography>
Company reputation: <Reputation reputation={company.playerReputation} />
</Typography>
</Tooltip> </Tooltip>
</Box> </Box>
<Typography>-------------------------</Typography> <Typography>-------------------------</Typography>
@ -212,7 +213,9 @@ export function CompanyLocation(props: IProps): React.ReactElement {
</> </>
} }
> >
<Typography>Company Favor: {Favor(company.favor)}</Typography> <Typography>
Company Favor: <Favor favor={company.favor} />
</Typography>
</Tooltip> </Tooltip>
</Box> </Box>
<Typography>-------------------------</Typography> <Typography>-------------------------</Typography>
@ -227,8 +230,9 @@ export function CompanyLocation(props: IProps): React.ReactElement {
open={quitOpen} open={quitOpen}
onClose={() => setQuitOpen(false)} onClose={() => setQuitOpen(false)}
/> />
</div> </>
)} )}
<br />
{company.hasAgentPositions() && ( {company.hasAgentPositions() && (
<ApplyToJobButton <ApplyToJobButton
company={company} company={company}
@ -318,6 +322,6 @@ export function CompanyLocation(props: IProps): React.ReactElement {
/> />
)} )}
{location.infiltrationData != null && <Button onClick={startInfiltration}>Infiltrate Company</Button>} {location.infiltrationData != null && <Button onClick={startInfiltration}>Infiltrate Company</Button>}
</div> </>
); );
} }

View File

@ -113,7 +113,7 @@ export function SlumsLocation(): React.ReactElement {
const heistChance = Crimes.Heist.successRate(player); const heistChance = Crimes.Heist.successRate(player);
return ( return (
<div> <>
<Tooltip title={<>Attempt to shoplift from a low-end retailer</>}> <Tooltip title={<>Attempt to shoplift from a low-end retailer</>}>
<Button onClick={shoplift}> <Button onClick={shoplift}>
Shoplift ({numeralWrapper.formatPercentage(shopliftChance)} chance of success) Shoplift ({numeralWrapper.formatPercentage(shopliftChance)} chance of success)
@ -180,6 +180,6 @@ export function SlumsLocation(): React.ReactElement {
<Button onClick={heist}>Heist ({numeralWrapper.formatPercentage(heistChance)} chance of success)</Button> <Button onClick={heist}>Heist ({numeralWrapper.formatPercentage(heistChance)} chance of success)</Button>
</Tooltip> </Tooltip>
<br /> <br />
</div> </>
); );
} }

View File

@ -67,7 +67,7 @@ export function TechVendorLocation(props: IProps): React.ReactElement {
} }
return ( return (
<div> <>
{purchaseServerButtons} {purchaseServerButtons}
<br /> <br />
<Typography> <Typography>
@ -79,6 +79,6 @@ export function TechVendorLocation(props: IProps): React.ReactElement {
<RamButton p={player} rerender={rerender} /> <RamButton p={player} rerender={rerender} />
<br /> <br />
<CoresButton p={player} rerender={rerender} /> <CoresButton p={player} rerender={rerender} />
</div> </>
); );
} }

View File

@ -76,7 +76,7 @@ export function TravelAgencyRoot(props: IProps): React.ReactElement {
<Money money={CONSTANTS.TravelCost} player={props.p} />. <Money money={CONSTANTS.TravelCost} player={props.p} />.
</Typography> </Typography>
{Settings.DisableASCIIArt ? ( {Settings.DisableASCIIArt ? (
<div> <>
{Object.values(CityName) {Object.values(CityName)
.filter((city: string) => city != props.p.city) .filter((city: string) => city != props.p.city)
.map((city: string) => { .map((city: string) => {
@ -91,7 +91,7 @@ export function TravelAgencyRoot(props: IProps): React.ReactElement {
</React.Fragment> </React.Fragment>
); );
})} })}
</div> </>
) : ( ) : (
<WorldMap currentCity={props.p.city} onTravel={(city: CityName) => startTravel(city)} /> <WorldMap currentCity={props.p.city} onTravel={(city: CityName) => startTravel(city)} />
)} )}

View File

@ -626,7 +626,7 @@ export function finishWork(this: IPlayer, cancelled: boolean, sing = false): str
You earned a total of: <br /> You earned a total of: <br />
<Money money={this.workMoneyGained} /> <Money money={this.workMoneyGained} />
<br /> <br />
{Reputation(this.workRepGained)} reputation for the company <br /> <Reputation reputation={this.workRepGained} /> reputation for the company <br />
{numeralWrapper.formatExp(this.workHackExpGained)} hacking exp <br /> {numeralWrapper.formatExp(this.workHackExpGained)} hacking exp <br />
{numeralWrapper.formatExp(this.workStrExpGained)} strength exp <br /> {numeralWrapper.formatExp(this.workStrExpGained)} strength exp <br />
{numeralWrapper.formatExp(this.workDefExpGained)} defense exp <br /> {numeralWrapper.formatExp(this.workDefExpGained)} defense exp <br />
@ -747,7 +747,7 @@ export function finishWorkPartTime(this: IPlayer, sing = false): string {
You earned a total of: <br /> You earned a total of: <br />
<Money money={this.workMoneyGained} /> <Money money={this.workMoneyGained} />
<br /> <br />
{Reputation(this.workRepGained)} reputation for the company <br /> <Reputation reputation={this.workRepGained} /> reputation for the company <br />
{numeralWrapper.formatExp(this.workHackExpGained)} hacking exp <br /> {numeralWrapper.formatExp(this.workHackExpGained)} hacking exp <br />
{numeralWrapper.formatExp(this.workStrExpGained)} strength exp <br /> {numeralWrapper.formatExp(this.workStrExpGained)} strength exp <br />
{numeralWrapper.formatExp(this.workDefExpGained)} defense exp <br /> {numeralWrapper.formatExp(this.workDefExpGained)} defense exp <br />
@ -919,7 +919,7 @@ export function finishFactionWork(this: IPlayer, cancelled: boolean, sing = fals
You earned a total of: <br /> You earned a total of: <br />
<Money money={this.workMoneyGained} /> <Money money={this.workMoneyGained} />
<br /> <br />
{Reputation(this.workRepGained)} reputation for the faction <br /> <Reputation reputation={this.workRepGained} /> reputation for the faction <br />
{numeralWrapper.formatExp(this.workHackExpGained)} hacking exp <br /> {numeralWrapper.formatExp(this.workHackExpGained)} hacking exp <br />
{numeralWrapper.formatExp(this.workStrExpGained)} strength exp <br /> {numeralWrapper.formatExp(this.workStrExpGained)} strength exp <br />
{numeralWrapper.formatExp(this.workDefExpGained)} defense exp <br /> {numeralWrapper.formatExp(this.workDefExpGained)} defense exp <br />

View File

@ -161,7 +161,7 @@ export function SleeveElem(props: IProps): React.ReactElement {
]; ];
if (props.sleeve.currentTask === SleeveTaskType.Company || props.sleeve.currentTask === SleeveTaskType.Faction) { if (props.sleeve.currentTask === SleeveTaskType.Company || props.sleeve.currentTask === SleeveTaskType.Faction) {
const repGain: number = props.sleeve.getRepGain(player); const repGain: number = props.sleeve.getRepGain(player);
data.push([`Reputation:`, ReputationRate(5 * repGain)]); data.push([`Reputation:`, <ReputationRate reputation={5 * repGain} />]);
} }
} }

View File

@ -10,9 +10,7 @@ import { convertTimeMsToTimeElapsedString } from "../../utils/StringHelperFuncti
import { getServer } from "../../Server/ServerHelpers"; import { getServer } from "../../Server/ServerHelpers";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
import { createPopup } from "../../ui/React/createPopup"; import { BitFlumeEvent } from "../../BitNode/ui/BitFlumeModal";
import { BitFlumePopup } from "../../BitNode/ui/BitFlumePopup";
import { calculateHackingTime, calculateGrowTime, calculateWeakenTime } from "../../Hacking"; import { calculateHackingTime, calculateGrowTime, calculateWeakenTime } from "../../Hacking";
function requireHackingLevel(lvl: number) { function requireHackingLevel(lvl: number) {
@ -286,12 +284,7 @@ export const programsMetadata: IProgramCreationParams[] = [
time: CONSTANTS.MillisecondsPerFiveMinutes / 20, time: CONSTANTS.MillisecondsPerFiveMinutes / 20,
}, },
run: (router: IRouter, terminal: ITerminal, player: IPlayer): void => { run: (router: IRouter, terminal: ITerminal, player: IPlayer): void => {
const popupId = "bitflume-popup"; BitFlumeEvent.emit();
createPopup(popupId, BitFlumePopup, {
player: player,
router: router,
popupId: popupId,
});
}, },
}, },
{ {

View File

@ -307,7 +307,7 @@ export function Root(props: IProps): React.ReactElement {
<Editor <Editor
beforeMount={beforeMount} beforeMount={beforeMount}
onMount={onMount} onMount={onMount}
loading={<p>Loading script editor!</p>} loading={<Typography>Loading script editor!</Typography>}
height="90%" height="90%"
defaultLanguage="javascript" defaultLanguage="javascript"
defaultValue={code} defaultValue={code}

View File

@ -40,7 +40,7 @@ function DisplayModeButton(props: IProps): React.ReactElement {
export function StockTickersConfig(props: IProps): React.ReactElement { export function StockTickersConfig(props: IProps): React.ReactElement {
return ( return (
<div> <>
<DisplayModeButton {...props} /> <DisplayModeButton {...props} />
<br /> <br />
<TextField <TextField
@ -49,6 +49,6 @@ export function StockTickersConfig(props: IProps): React.ReactElement {
placeholder="Filter Stocks by symbol (comma-separated list)" placeholder="Filter Stocks by symbol (comma-separated list)"
type="text" type="text"
/> />
</div> </>
); );
} }

View File

@ -12,6 +12,9 @@ import { IRouter } from "../../ui/Router";
import { IPlayer } from "../../PersonObjects/IPlayer"; import { IPlayer } from "../../PersonObjects/IPlayer";
import { TerminalInput } from "./TerminalInput"; import { TerminalInput } from "./TerminalInput";
import { TerminalEvents, TerminalClearEvents } from "../TerminalEvents"; import { TerminalEvents, TerminalClearEvents } from "../TerminalEvents";
import { BitFlumeModal } from "../../BitNode/ui/BitFlumeModal";
import { CodingContractModal } from "../../ui/React/CodingContractModal";
import _ from "lodash"; import _ from "lodash";
interface IActionTimerProps { interface IActionTimerProps {
@ -118,6 +121,8 @@ export function TerminalRoot({ terminal, router, player }: IProps): React.ReactE
<Box position="sticky" bottom={0} width="100%" px={0}> <Box position="sticky" bottom={0} width="100%" px={0}>
<TerminalInput player={player} router={router} terminal={terminal} /> <TerminalInput player={player} router={router} terminal={terminal} />
</Box> </Box>
<BitFlumeModal />
<CodingContractModal />
</> </>
); );
} }

View File

@ -334,7 +334,9 @@ const Engine: {
// Hacknet Nodes offline progress // Hacknet Nodes offline progress
const offlineProductionFromHacknetNodes = processHacknetEarnings(Player, numCyclesOffline); const offlineProductionFromHacknetNodes = processHacknetEarnings(Player, numCyclesOffline);
const hacknetProdInfo = hasHacknetServers(Player) ? ( const hacknetProdInfo = hasHacknetServers(Player) ? (
<>{Hashes(offlineProductionFromHacknetNodes)} hashes</> <>
<Hashes hashes={offlineProductionFromHacknetNodes} /> hashes
</>
) : ( ) : (
<Money money={offlineProductionFromHacknetNodes} /> <Money money={offlineProductionFromHacknetNodes} />
); );
@ -405,7 +407,7 @@ const Engine: {
<> <>
Offline for {timeOfflineString}. While you were offline, your scripts generated{" "} Offline for {timeOfflineString}. While you were offline, your scripts generated{" "}
<Money money={offlineHackingIncome} />, your Hacknet Nodes generated {hacknetProdInfo} and you gained{" "} <Money money={offlineHackingIncome} />, your Hacknet Nodes generated {hacknetProdInfo} and you gained{" "}
{Reputation(offlineReputation)} divided amongst your factions. <Reputation reputation={offlineReputation} /> reputation divided amongst your factions.
</>, </>,
), ),
250, 250,

View File

@ -69,6 +69,7 @@ import { Unclickable } from "../Exploits/Unclickable";
import { Snackbar } from "./React/Snackbar"; import { Snackbar } from "./React/Snackbar";
import { LogBoxManager } from "./React/LogBoxManager"; import { LogBoxManager } from "./React/LogBoxManager";
import { AlertManager } from "./React/AlertManager"; import { AlertManager } from "./React/AlertManager";
import { InvitationModal } from "../Faction/ui/InvitationModal";
import { enterBitNode } from "../RedPill"; import { enterBitNode } from "../RedPill";
import { Context } from "./Context"; import { Context } from "./Context";
@ -398,6 +399,7 @@ export function GameRoot({ player, engine, terminal }: IProps): React.ReactEleme
<Snackbar /> <Snackbar />
<LogBoxManager /> <LogBoxManager />
<AlertManager /> <AlertManager />
<InvitationModal />
</Context.Router.Provider> </Context.Router.Provider>
</Context.Player.Provider> </Context.Player.Provider>
); );

View File

@ -1,9 +1,17 @@
import * as React from "react"; import * as React from "react";
import { Theme } from "@mui/material/styles";
import makeStyles from "@mui/styles/makeStyles";
import createStyles from "@mui/styles/createStyles";
const useStyles = makeStyles((theme: Theme) =>
createStyles({
aug: {
color: theme.colors.combat,
},
}),
);
export function Augmentation({ name }: { name: string }): JSX.Element { export function Augmentation({ name }: { name: string }): JSX.Element {
return ( const classes = useStyles();
<span className={"samefont"} style={{ color: "white" }}> return <span className={classes.aug}>{name}</span>;
{name}
</span>
);
} }

View File

@ -60,7 +60,9 @@ function Work(): React.ReactElement {
</TableRow> </TableRow>
<TableRow> <TableRow>
<TableCell component="th" scope="row" colSpan={2} classes={{ root: classes.cellNone }}> <TableCell component="th" scope="row" colSpan={2} classes={{ root: classes.cellNone }}>
<Typography>+{Reputation(player.workRepGained)} rep</Typography> <Typography>
+<Reputation reputation={player.workRepGained} /> rep
</Typography>
</TableCell> </TableCell>
</TableRow> </TableRow>
<TableRow> <TableRow>

View File

@ -24,12 +24,12 @@ export function CinematicText(props: IProps): React.ReactElement {
} }
return ( return (
<div> <>
{props.lines.slice(0, i).map((line, i) => ( {props.lines.slice(0, i).map((line, i) => (
<Typography key={i}>{line}</Typography> <Typography key={i}>{line}</Typography>
))} ))}
{props.lines.length > i && <CinematicLine key={i} text={props.lines[i]} onDone={advance} />} {props.lines.length > i && <CinematicLine key={i} text={props.lines[i]} onDone={advance} />}
{!props.auto && props.onDone && done && <Button onClick={props.onDone}>Continue ...</Button>} {!props.auto && props.onDone && done && <Button onClick={props.onDone}>Continue ...</Button>}
</div> </>
); );
} }

View File

@ -1,24 +1,37 @@
import React, { useState } from "react"; import React, { useState, useEffect } from "react";
import { KEY } from "../../utils/helpers/keyCodes"; import { KEY } from "../../utils/helpers/keyCodes";
import { CodingContract, CodingContractType, CodingContractTypes } from "../../CodingContracts"; import { CodingContract, CodingContractType, CodingContractTypes } from "../../CodingContracts";
import { ClickableTag, CopyableText } from "./CopyableText"; import { ClickableTag, CopyableText } from "./CopyableText";
import { Modal } from "./Modal";
import { EventEmitter } from "../../utils/EventEmitter";
import Typography from "@mui/material/Typography";
import TextField from "@mui/material/TextField";
import Button from "@mui/material/Button";
type IProps = { interface IProps {
c: CodingContract; c: CodingContract;
popupId: string;
onClose: () => void; onClose: () => void;
onAttempt: (answer: string) => void; onAttempt: (answer: string) => void;
}; }
export function CodingContractPopup(props: IProps): React.ReactElement { export const CodingContractEvent = new EventEmitter<[IProps]>();
export function CodingContractModal(): React.ReactElement {
const [props, setProps] = useState<IProps | null>(null);
const [answer, setAnswer] = useState(""); const [answer, setAnswer] = useState("");
useEffect(() => {
CodingContractEvent.subscribe((props) => setProps(props));
});
if (props === null) return <></>;
function onChange(event: React.ChangeEvent<HTMLInputElement>): void { function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
setAnswer(event.target.value); setAnswer(event.target.value);
} }
function onKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void { function onKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {
if (props === null) return;
// React just won't cooperate on this one. // React just won't cooperate on this one.
// "React.KeyboardEvent<HTMLInputElement>" seems like the right type but // "React.KeyboardEvent<HTMLInputElement>" seems like the right type but
// whatever ... // whatever ...
@ -30,34 +43,47 @@ export function CodingContractPopup(props: IProps): React.ReactElement {
} }
} }
function close(): void {
if (props === null) return;
props.onClose();
setProps(null);
}
const contractType: CodingContractType = CodingContractTypes[props.c.type]; const contractType: CodingContractType = CodingContractTypes[props.c.type];
const description = []; const description = [];
for (const [i, value] of contractType.desc(props.c.data).split("\n").entries()) for (const [i, value] of contractType.desc(props.c.data).split("\n").entries())
description.push(<span key={i} dangerouslySetInnerHTML={{ __html: value + "<br />" }}></span>); description.push(<span key={i} dangerouslySetInnerHTML={{ __html: value + "<br />" }}></span>);
return ( return (
<div> <Modal open={props !== null} onClose={close}>
<CopyableText value={props.c.type} tag={ClickableTag.Tag_h1} /> <Typography variant="h4">
<br /> <CopyableText value={props.c.type} />
<br /> </Typography>
<p> <Typography>
You are attempting to solve a Coding Contract. You have {props.c.getMaxNumTries() - props.c.tries} tries You are attempting to solve a Coding Contract. You have {props.c.getMaxNumTries() - props.c.tries} tries
remaining, after which the contract will self-destruct. remaining, after which the contract will self-destruct.
</p> </Typography>
<br /> <br />
<p>{description}</p> <Typography>{description}</Typography>
<br /> <br />
<input <TextField
className="text-input" autoFocus
style={{ width: "50%", marginTop: "8px" }}
autoFocus={true}
placeholder="Enter Solution here" placeholder="Enter Solution here"
value={answer} value={answer}
onChange={onChange} onChange={onChange}
onKeyDown={onKeyDown} onKeyDown={onKeyDown}
InputProps={{
endAdornment: (
<Button
onClick={() => {
props.onAttempt(answer);
close();
}}
>
Solve
</Button>
),
}}
/> />
<button className={"std-button"} onClick={() => props.onAttempt(answer)}> </Modal>
Solve
</button>
</div>
); );
} }

View File

@ -1,10 +1,18 @@
import * as React from "react"; import * as React from "react";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { Theme } from "@mui/material/styles";
import makeStyles from "@mui/styles/makeStyles";
import createStyles from "@mui/styles/createStyles";
export function Favor(favor: number | string): JSX.Element { const useStyles = makeStyles((theme: Theme) =>
return ( createStyles({
<span className={"light-yellow samefont"}> favor: {
{typeof favor === "number" ? numeralWrapper.formatFavor(favor) : favor} color: theme.colors.rep,
</span> },
); }),
);
export function Favor({ favor }: { favor: number | string }): React.ReactElement {
const classes = useStyles();
return <span className={classes.favor}>{typeof favor === "number" ? numeralWrapper.formatFavor(favor) : favor}</span>;
} }

View File

@ -1,6 +1,7 @@
import React from "react";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { Hashes } from "../../ui/React/Hashes"; import { Hashes } from "../../ui/React/Hashes";
export function HashRate(hashes: number): JSX.Element { export function HashRate({ hashes }: { hashes: number }): React.ReactElement {
return Hashes(`${numeralWrapper.formatHashes(hashes)} / sec`); return <Hashes hashes={`${numeralWrapper.formatHashes(hashes)} / sec`} />;
} }

View File

@ -1,10 +1,20 @@
import * as React from "react"; import * as React from "react";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { Theme } from "@mui/material/styles";
import makeStyles from "@mui/styles/makeStyles";
import createStyles from "@mui/styles/createStyles";
export function Hashes(hashes: number | string): JSX.Element { const useStyles = makeStyles((theme: Theme) =>
createStyles({
money: {
color: theme.colors.money,
},
}),
);
export function Hashes({ hashes }: { hashes: number | string }): React.ReactElement {
const classes = useStyles();
return ( return (
<span className={"money-gold samefont"}> <span className={classes.money}>{typeof hashes === "number" ? numeralWrapper.formatHashes(hashes) : hashes}</span>
{typeof hashes === "number" ? numeralWrapper.formatHashes(hashes) : hashes}
</span>
); );
} }

View File

@ -42,6 +42,8 @@ export const Modal = (props: IProps): React.ReactElement => {
<M <M
disableRestoreFocus disableRestoreFocus
disableScrollLock disableScrollLock
disableEnforceFocus
disableAutoFocus
open={props.open} open={props.open}
onClose={props.onClose} onClose={props.onClose}
closeAfterTransition closeAfterTransition

View File

@ -1,19 +1,34 @@
import * as React from "react"; import * as React from "react";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { IPlayer } from "../../PersonObjects/IPlayer"; import { IPlayer } from "../../PersonObjects/IPlayer";
import { Theme } from "@mui/material/styles";
import makeStyles from "@mui/styles/makeStyles";
import createStyles from "@mui/styles/createStyles";
const useStyles = makeStyles((theme: Theme) =>
createStyles({
unbuyable: {
color: theme.palette.action.disabled,
},
money: {
color: theme.colors.money,
},
}),
);
interface IProps { interface IProps {
money: number | string; money: number | string;
player?: IPlayer; player?: IPlayer;
} }
export function Money(props: IProps): JSX.Element { export function Money(props: IProps): React.ReactElement {
const classes = useStyles();
if (props.player !== undefined) { if (props.player !== undefined) {
if (typeof props.money !== "number") throw new Error("if player if provided, money should be number, contact dev"); if (typeof props.money !== "number") throw new Error("if player if provided, money should be number, contact dev");
if (!props.player.canAfford(props.money)) if (!props.player.canAfford(props.money))
return <span className={"unbuyable samefont"}>{numeralWrapper.formatMoney(props.money)}</span>; return <span className={classes.unbuyable}>{numeralWrapper.formatMoney(props.money)}</span>;
} }
return ( return (
<span className={"money-gold samefont"}> <span className={classes.money}>
{typeof props.money === "number" ? numeralWrapper.formatMoney(props.money) : props.money} {typeof props.money === "number" ? numeralWrapper.formatMoney(props.money) : props.money}
</span> </span>
); );

View File

@ -1,10 +1,22 @@
import * as React from "react"; import * as React from "react";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { Theme } from "@mui/material/styles";
import makeStyles from "@mui/styles/makeStyles";
import createStyles from "@mui/styles/createStyles";
export function Reputation(reputation: number | string): JSX.Element { const useStyles = makeStyles((theme: Theme) =>
createStyles({
reputation: {
color: theme.colors.rep,
},
}),
);
export function Reputation({ reputation }: { reputation: number | string }): React.ReactElement {
const classes = useStyles();
return ( return (
<span className={"reputation samefont"}> <span className={classes.reputation}>
{typeof reputation === "number" ? numeralWrapper.formatReputation(reputation) : reputation} {typeof reputation === "number" ? numeralWrapper.formatFavor(reputation) : reputation}
</span> </span>
); );
} }

View File

@ -1,6 +1,7 @@
import React from "react";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { Reputation } from "../../ui/React/Reputation"; import { Reputation } from "../../ui/React/Reputation";
export function ReputationRate(reputation: number): JSX.Element { export function ReputationRate({ reputation }: { reputation: number }): React.ReactElement {
return Reputation(`${numeralWrapper.formatReputation(reputation)} / sec`); return <Reputation reputation={`${numeralWrapper.formatReputation(reputation)} / sec`} />;
} }

View File

@ -49,7 +49,8 @@ export function WorkInProgressRoot(): React.ReactElement {
<Typography> <Typography>
You are currently {player.currentWorkFactionDescription} for your faction {faction.name} You are currently {player.currentWorkFactionDescription} for your faction {faction.name}
<br /> <br />
(Current Faction Reputation: {Reputation(faction.playerReputation)}). <br /> (Current Faction Reputation: <Reputation reputation={faction.playerReputation} />
). <br />
You have been doing this for {convertTimeMsToTimeElapsedString(player.timeWorked)} You have been doing this for {convertTimeMsToTimeElapsedString(player.timeWorked)}
<br /> <br />
<br /> <br />
@ -58,8 +59,8 @@ export function WorkInProgressRoot(): React.ReactElement {
<Money money={player.workMoneyGained} /> (<MoneyRate money={player.workMoneyGainRate * CYCLES_PER_SEC} />){" "} <Money money={player.workMoneyGained} /> (<MoneyRate money={player.workMoneyGainRate * CYCLES_PER_SEC} />){" "}
<br /> <br />
<br /> <br />
{Reputation(player.workRepGained)} ({ReputationRate(player.workRepGainRate * CYCLES_PER_SEC)}) reputation <Reputation reputation={player.workRepGained} /> (
for this faction <br /> <ReputationRate reputation={player.workRepGainRate * CYCLES_PER_SEC} />) reputation for this faction <br />
<br /> <br />
{numeralWrapper.formatExp(player.workHackExpGained)} ( {numeralWrapper.formatExp(player.workHackExpGained)} (
{numeralWrapper.formatExp(player.workHackExpGainRate * CYCLES_PER_SEC)} / sec) hacking exp <br /> {numeralWrapper.formatExp(player.workHackExpGainRate * CYCLES_PER_SEC)} / sec) hacking exp <br />
@ -171,7 +172,7 @@ export function WorkInProgressRoot(): React.ReactElement {
<Grid item> <Grid item>
<Typography> <Typography>
You are currently working as a {position} at {player.companyName} (Current Company Reputation:{" "} You are currently working as a {position} at {player.companyName} (Current Company Reputation:{" "}
{Reputation(companyRep)})<br /> <Reputation reputation={companyRep} />)<br />
<br /> <br />
You have been working for {convertTimeMsToTimeElapsedString(player.timeWorked)} You have been working for {convertTimeMsToTimeElapsedString(player.timeWorked)}
<br /> <br />
@ -181,8 +182,8 @@ export function WorkInProgressRoot(): React.ReactElement {
<Money money={player.workMoneyGained} /> (<MoneyRate money={player.workMoneyGainRate * CYCLES_PER_SEC} />){" "} <Money money={player.workMoneyGained} /> (<MoneyRate money={player.workMoneyGainRate * CYCLES_PER_SEC} />){" "}
<br /> <br />
<br /> <br />
{Reputation(player.workRepGained)} ({ReputationRate(player.workRepGainRate * CYCLES_PER_SEC)}) reputation <Reputation reputation={player.workRepGained} /> (
for this company <br /> <ReputationRate reputation={player.workRepGainRate * CYCLES_PER_SEC} />) reputation for this company <br />
<br /> <br />
{numeralWrapper.formatExp(player.workHackExpGained)} ( {numeralWrapper.formatExp(player.workHackExpGained)} (
{`${numeralWrapper.formatExp(player.workHackExpGainRate * CYCLES_PER_SEC)} / sec`} {`${numeralWrapper.formatExp(player.workHackExpGainRate * CYCLES_PER_SEC)} / sec`}
@ -241,7 +242,7 @@ export function WorkInProgressRoot(): React.ReactElement {
<Grid item> <Grid item>
<Typography> <Typography>
You are currently working as a {position} at {player.companyName} (Current Company Reputation:{" "} You are currently working as a {position} at {player.companyName} (Current Company Reputation:{" "}
{Reputation(companyRep)})<br /> <Reputation reputation={companyRep} />)<br />
<br /> <br />
You have been working for {convertTimeMsToTimeElapsedString(player.timeWorked)} You have been working for {convertTimeMsToTimeElapsedString(player.timeWorked)}
<br /> <br />
@ -251,8 +252,8 @@ export function WorkInProgressRoot(): React.ReactElement {
<Money money={player.workMoneyGained} /> (<MoneyRate money={player.workMoneyGainRate * CYCLES_PER_SEC} />){" "} <Money money={player.workMoneyGained} /> (<MoneyRate money={player.workMoneyGainRate * CYCLES_PER_SEC} />){" "}
<br /> <br />
<br /> <br />
{Reputation(player.workRepGained)} ( <Reputation reputation={player.workRepGained} /> (
{Reputation(`${numeralWrapper.formatExp(player.workRepGainRate * CYCLES_PER_SEC)} / sec`)} <ReputationRate reputation={player.workRepGainRate * CYCLES_PER_SEC} />
) reputation for this company <br /> ) reputation for this company <br />
<br /> <br />
{numeralWrapper.formatExp(player.workHackExpGained)} ( {numeralWrapper.formatExp(player.workHackExpGained)} (
@ -306,12 +307,12 @@ export function WorkInProgressRoot(): React.ReactElement {
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}> <Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
<Grid item> <Grid item>
<Typography> <Typography>
<p>You are attempting to {player.crimeType}.</p> <Typography>You are attempting to {player.crimeType}.</Typography>
<br /> <br />
<p> <Typography>
Time remaining: {convertTimeMsToTimeElapsedString(player.timeNeededToCompleteWork - player.timeWorked)} Time remaining: {convertTimeMsToTimeElapsedString(player.timeNeededToCompleteWork - player.timeWorked)}
</p> </Typography>
<br /> <br />
<pre>{progressBar}</pre> <pre>{progressBar}</pre>