Merge pull request #1356 from danielyxie/dev

can buy trp
This commit is contained in:
hydroflame 2021-09-22 11:00:31 -04:00 committed by GitHub
commit 1ba0332c53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 450 additions and 376 deletions

24
dist/vendor.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

File diff suppressed because one or more lines are too long

@ -13,6 +13,7 @@ export interface IConstructorParams {
expMultiplier: number;
salaryMultiplier: number;
jobStatReqOffset: number;
isMegacorp?: boolean;
}
const DefaultConstructorParams: IConstructorParams = {
@ -35,6 +36,11 @@ export class Company {
*/
info: string;
/**
* Has faction associated.
*/
isMegacorp: boolean;
/**
* Object that holds all available positions in this Company.
* Position names are held in keys.
@ -79,6 +85,8 @@ export class Company {
this.playerReputation = 1;
this.favor = 0;
this.rolloverRep = 0;
this.isMegacorp = false;
if (p.isMegacorp) this.isMegacorp = true;
}
hasPosition(pos: CompanyPosition | string): boolean {

@ -45,6 +45,11 @@ export class FactionInfo {
*/
offerSecurityWork: boolean;
/**
* Keep faction on install.
*/
keep: boolean;
constructor(
infoText: JSX.Element,
enemies: string[],
@ -52,6 +57,7 @@ export class FactionInfo {
offerHackingWork: boolean,
offerFieldWork: boolean,
offerSecurityWork: boolean,
keep: boolean,
) {
this.infoText = infoText;
this.enemies = enemies;
@ -63,6 +69,7 @@ export class FactionInfo {
// These are always all 1 for now.
this.augmentationPriceMult = 1;
this.augmentationRepRequirementMult = 1;
this.keep = keep;
}
offersWork(): boolean {
@ -88,6 +95,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
false,
false,
),
Daedalus: new FactionInfo(
@ -97,6 +105,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
false,
false,
),
"The Covenant": new FactionInfo(
@ -114,6 +123,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
false,
false,
),
// Megacorporations, each forms its own faction
@ -129,6 +139,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
true,
true,
),
MegaCorp: new FactionInfo(
@ -147,6 +158,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
true,
true,
),
"Bachman & Associates": new FactionInfo(
@ -163,9 +175,10 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
true,
true,
),
"Blade Industries": new FactionInfo(<>Augmentation is Salvation.</>, [], true, true, true, true),
"Blade Industries": new FactionInfo(<>Augmentation is Salvation.</>, [], true, true, true, true, true),
NWO: new FactionInfo(
(
@ -180,9 +193,10 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
true,
true,
),
"Clarke Incorporated": new FactionInfo(<>The Power of the Genome - Unlocked.</>, [], true, true, true, true),
"Clarke Incorporated": new FactionInfo(<>The Power of the Genome - Unlocked.</>, [], true, true, true, true, true),
"OmniTek Incorporated": new FactionInfo(
<>Simply put, our mission is to design and build robots that make a difference.</>,
@ -191,6 +205,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
true,
true,
),
"Four Sigma": new FactionInfo(
@ -205,9 +220,10 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
true,
true,
),
"KuaiGong International": new FactionInfo(<>Dream big. Work hard. Make history.</>, [], true, true, true, true),
"KuaiGong International": new FactionInfo(<>Dream big. Work hard. Make history.</>, [], true, true, true, true, true),
// Other Corporations
"Fulcrum Secret Technologies": new FactionInfo(
@ -222,6 +238,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
false,
true,
true,
),
// Hacker groups
@ -243,6 +260,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
false,
false,
false,
),
"The Black Hand": new FactionInfo(
@ -261,6 +279,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
false,
false,
),
// prettier-ignore
@ -305,6 +324,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
false,
false,
false,
),
// City factions, essentially governments
@ -315,8 +335,9 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
true,
false,
),
Chongqing: new FactionInfo(<>Serve the People.</>, ["Sector-12", "Aevum", "Volhaven"], true, true, true, true),
Chongqing: new FactionInfo(<>Serve the People.</>, ["Sector-12", "Aevum", "Volhaven"], true, true, true, true, false),
Ishima: new FactionInfo(
<>The East Asian Order of the Future.</>,
["Sector-12", "Aevum", "Volhaven"],
@ -324,8 +345,17 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
true,
false,
),
"New Tokyo": new FactionInfo(
<>Asia's World City.</>,
["Sector-12", "Aevum", "Volhaven"],
true,
true,
true,
true,
false,
),
"New Tokyo": new FactionInfo(<>Asia's World City.</>, ["Sector-12", "Aevum", "Volhaven"], true, true, true, true),
"Sector-12": new FactionInfo(
<>The City of the Future.</>,
["Chongqing", "New Tokyo", "Ishima", "Volhaven"],
@ -333,6 +363,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
true,
false,
),
Volhaven: new FactionInfo(
<>Benefit, Honor, and Glory.</>,
@ -341,6 +372,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
true,
false,
),
// Criminal Organizations/Gangs
@ -351,6 +383,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
true,
false,
),
"The Dark Army": new FactionInfo(
@ -360,9 +393,10 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
false,
false,
),
"The Syndicate": new FactionInfo(<>Honor holds you back.</>, [], true, true, true, true),
"The Syndicate": new FactionInfo(<>Honor holds you back.</>, [], true, true, true, true, false),
Silhouette: new FactionInfo(
(
@ -380,6 +414,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
true,
false,
false,
),
Tetrads: new FactionInfo(
@ -389,14 +424,15 @@ export const FactionInfos: IMap<FactionInfo> = {
false,
true,
true,
false,
),
"Slum Snakes": new FactionInfo(<>Slum Snakes rule!</>, [], false, false, true, true),
"Slum Snakes": new FactionInfo(<>Slum Snakes rule!</>, [], false, false, true, true, false),
// Earlygame factions - factions the player will prestige with early on that don't belong in other categories.
Netburners: new FactionInfo(<>{"~~//*>H4CK||3T 8URN3R5**>?>\\~~"}</>, [], true, true, false, false),
Netburners: new FactionInfo(<>{"~~//*>H4CK||3T 8URN3R5**>?>\\~~"}</>, [], true, true, false, false, false),
"Tian Di Hui": new FactionInfo(<>Obey Heaven and work righteously.</>, [], true, true, false, true),
"Tian Di Hui": new FactionInfo(<>Obey Heaven and work righteously.</>, [], true, true, false, true, false),
CyberSec: new FactionInfo(
(
@ -411,6 +447,7 @@ export const FactionInfos: IMap<FactionInfo> = {
true,
false,
false,
false,
),
// Special Factions
@ -429,5 +466,6 @@ export const FactionInfos: IMap<FactionInfo> = {
false,
false,
false,
false,
),
};

@ -10,6 +10,7 @@ import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
import { Faction } from "../../Faction/Faction";
import { PurchaseAugmentationsOrderSetting } from "../../Settings/SettingEnums";
import { Settings } from "../../Settings/Settings";
import { hasAugmentationPrereqs } from "../FactionHelpers";
import { StdButton } from "../../ui/React/StdButton";
import { use } from "../../ui/Context";
@ -59,6 +60,9 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
case PurchaseAugmentationsOrderSetting.Reputation: {
return getAugsSortedByReputation();
}
case PurchaseAugmentationsOrderSetting.Purchasable: {
return getAugsSortedByPurchasable();
}
default:
return getAugsSortedByDefault();
}
@ -79,6 +83,41 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
return augs;
}
function getAugsSortedByPurchasable(): string[] {
const augs = getAugs();
function canBuy(augName: string): boolean {
const aug = Augmentations[augName];
const moneyCost = aug.baseCost * props.faction.getInfo().augmentationPriceMult;
const repCost = aug.baseRepRequirement * props.faction.getInfo().augmentationRepRequirementMult;
const hasReq = props.faction.playerReputation >= repCost;
const hasRep = hasAugmentationPrereqs(aug);
const hasCost =
aug.baseCost !== 0 && player.money.gt(aug.baseCost * props.faction.getInfo().augmentationPriceMult);
return hasCost && hasReq && hasRep;
}
const buy = augs.filter(canBuy).sort((augName1, augName2) => {
const aug1 = Augmentations[augName1],
aug2 = Augmentations[augName2];
if (aug1 == null || aug2 == null) {
throw new Error("Invalid Augmentation Names");
}
return aug1.baseCost - aug2.baseCost;
});
const cantBuy = augs
.filter((aug) => !canBuy(aug))
.sort((augName1, augName2) => {
const aug1 = Augmentations[augName1],
aug2 = Augmentations[augName2];
if (aug1 == null || aug2 == null) {
throw new Error("Invalid Augmentation Names");
}
return aug1.baseRepRequirement - aug2.baseRepRequirement;
});
return buy.concat(cantBuy);
}
function getAugsSortedByReputation(): string[] {
const augs = getAugs();
augs.sort((augName1, augName2) => {
@ -148,6 +187,9 @@ export function AugmentationsPage(props: IProps): React.ReactElement {
<Button onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Cost)}>Sort by Cost</Button>
<Button onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Reputation)}>Sort by Reputation</Button>
<Button onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Default)}>Sort by Default Order</Button>
<Button onClick={() => switchSortOrder(PurchaseAugmentationsOrderSetting.Purchasable)}>
Sort by Purchasable
</Button>
<br />
<Table size="small" padding="none">

@ -55,12 +55,14 @@ function Requirements(props: IReqProps): React.ReactElement {
return (
<React.Fragment key="f">
<TableCell key={1}>
<Typography color={color}>
<Typography>
<Money money={props.cost} player={props.p} />
</Typography>
</TableCell>
<TableCell key={2}>
<Typography color={color}>Requires {Reputation(props.rep)} faction reputation</Typography>
<Typography color={props.hasRep ? "primary" : "error"}>
Requires {Reputation(props.rep)} faction reputation
</Typography>
</TableCell>
</React.Fragment>
);
@ -78,24 +80,6 @@ export function PurchaseableAugmentation(props: IProps): React.ReactElement {
const aug = Augmentations[props.augName];
if (aug == null) throw new Error(`aug ${props.augName} does not exists`);
function getMoneyCost(): number {
return aug.baseCost * props.faction.getInfo().augmentationPriceMult;
}
function getRepCost(): number {
return aug.baseRepRequirement * props.faction.getInfo().augmentationRepRequirementMult;
}
// Whether the player has the prerequisite Augmentations
function hasPrereqs(): boolean {
return hasAugmentationPrereqs(aug);
}
// Whether the player has enough rep for this Augmentation
function hasReputation(): boolean {
return props.faction.playerReputation >= getRepCost();
}
// Whether the player has this augmentations (purchased OR installed)
function owned(): boolean {
let owned = false;
@ -123,11 +107,11 @@ export function PurchaseableAugmentation(props: IProps): React.ReactElement {
return <></>;
}
const moneyCost = getMoneyCost();
const repCost = getRepCost();
const hasReq = hasPrereqs();
const hasRep = hasReputation();
const hasCost = aug.baseCost !== 0 && props.p.money.gt(aug.baseCost * props.faction.getInfo().augmentationPriceMult);
const moneyCost = aug.baseCost * props.faction.getInfo().augmentationPriceMult;
const repCost = aug.baseRepRequirement * props.faction.getInfo().augmentationRepRequirementMult;
const hasReq = hasAugmentationPrereqs(aug);
const hasRep = props.faction.playerReputation >= repCost;
const hasCost = aug.baseCost === 0 || props.p.money.gt(aug.baseCost * props.faction.getInfo().augmentationPriceMult);
// Determine UI properties
const color: "error" | "primary" = !hasReq || !hasRep || !hasCost ? "error" : "primary";

@ -3,6 +3,9 @@ import { Milestones } from "../Milestones";
import { Milestone } from "../Milestone";
import * as React from "react";
import Typography from "@mui/material/Typography";
import Box from "@mui/material/Box";
interface IProps {
player: IPlayer;
}
@ -21,25 +24,25 @@ export function MilestonesRoot(props: IProps): JSX.Element {
const milestones = Milestones.map((milestone: Milestone, i: number) => {
if (i <= n + 1) {
return (
<ul key={i}>
<p>
<Typography key={i}>
[{milestone.fulfilled(props.player) ? "x" : " "}] {milestone.title}
</p>
</ul>
</Typography>
);
}
});
return (
<div className="milestones-container">
<h1>Milestones</h1>
<p>
Milestones don't reward you for completing them. They are here to guide you if you're lost. They will reset when
you install Augmentations.
</p>
<>
<Typography variant="h4">Milestones</Typography>
<Box mx={2}>
<Typography>
Milestones don't reward you for completing them. They are here to guide you if you're lost. They will reset
when you install Augmentations.
</Typography>
<br />
<h2>Completing fl1ght.exe</h2>
<li>{milestones}</li>
</div>
<Typography>Completing fl1ght.exe</Typography>
{milestones}
</Box>
</>
);
}

@ -34,21 +34,8 @@ const BitNode8StartingMoney = 250e6;
function prestigeAugmentation() {
initBitNodeMultipliers(Player);
const megaCorpFactions = [
"ECorp",
"MegaCorp",
"Bachman & Associates",
"Blade Industries",
"NWO",
"Clarke Incorporated",
"OmniTek Incorporated",
"Four Sigma",
"KuaiGong International",
"Fulcrum Secret Technologies",
];
const maintainMembership = Player.factions.filter(function (faction) {
return megaCorpFactions.includes(faction);
return Factions[faction].getInfo().keep;
});
Player.prestigeAugmentation();

@ -96,6 +96,7 @@ export enum PurchaseAugmentationsOrderSetting {
Cost,
Default,
Reputation,
Purchasable,
}
/**

@ -1,99 +1,93 @@
import React from "react";
import Typography from "@mui/material/Typography";
import Link from "@mui/material/Link";
import Box from "@mui/material/Box";
export function TutorialRoot(): React.ReactElement {
return (
<>
<h1>Tutorial (AKA Links to Documentation)</h1>
<a
id="tutorial-getting-started-link"
className="a-link-button"
<Typography variant="h4">Tutorial (AKA Links to Documentation)</Typography>
<Box m={2}>
<Link
color="primary"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/guidesandtips/gettingstartedguideforbeginnerprogrammers.html"
>
Getting Started
</a>
<Typography>Getting Started</Typography>
</Link>
<br />
<br />
<a
className="a-link-button"
<Link
color="primary"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/servers.html"
>
Servers & Networking
</a>
<Typography>Servers & Networking</Typography>
</Link>
<br />
<br />
<a
className="a-link-button"
<Link
color="primary"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/hacking.html"
>
Hacking
</a>
<Typography>Hacking</Typography>
</Link>
<br />
<br />
<a
className="a-link-button"
<Link
color="primary"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/scripts.html"
>
Scripts
</a>
<Typography>Scripts</Typography>
</Link>
<br />
<Link color="primary" target="_blank" href="https://bitburner.readthedocs.io/en/latest/netscript.html">
<Typography>Netscript Programming Language</Typography>
</Link>
<br />
<a className="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/netscript.html">
Netscript Programming Language
</a>
<br />
<br />
<a
className="a-link-button"
<Link
color="primary"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/world.html"
>
Traveling
</a>
<Typography>Traveling</Typography>
</Link>
<br />
<br />
<a
className="a-link-button"
<Link
color="primary"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/companies.html"
>
Companies
</a>
<Typography>Companies</Typography>
</Link>
<br />
<br />
<a
className="a-link-button"
<Link
color="primary"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/infiltration.html"
>
Infiltration
</a>
<Typography>Infiltration</Typography>
</Link>
<br />
<br />
<a
className="a-link-button"
<Link
color="primary"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/factions.html"
>
Factions
</a>
<Typography>Factions</Typography>
</Link>
<br />
<br />
<a
className="a-link-button"
<Link
color="primary"
target="_blank"
href="https://bitburner.readthedocs.io/en/latest/basicgameplay/augmentations.html"
>
Augmentations
</a>
<Typography>Augmentations</Typography>
</Link>
<br />
<br />
<a className="a-link-button" target="_blank" href="https://bitburner.readthedocs.io/en/latest/shortcuts.html">
Keyboard Shortcuts
</a>
<Link color="primary" target="_blank" href="https://bitburner.readthedocs.io/en/latest/shortcuts.html">
<Typography>Keyboard Shortcuts</Typography>
</Link>
</Box>
</>
);
}

@ -13,6 +13,10 @@ import { Companies } from "../Company/Companies";
import { Locations } from "../Locations/Locations";
import { LocationName } from "../Locations/data/LocationNames";
import Typography from "@mui/material/Typography";
import Grid from "@mui/material/Grid";
import Button from "@mui/material/Button";
import { createProgressBarText } from "../../utils/helpers/createProgressBarText";
const CYCLES_PER_SEC = 1000 / CONSTANTS.MilliPerCycle;
@ -40,8 +44,9 @@ export function WorkInProgressRoot(): React.ReactElement {
player.stopFocusing();
}
return (
<div>
<p>
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
<Grid item>
<Typography>
You are currently {player.currentWorkFactionDescription} for your faction {faction.name}
<br />
(Current Faction Reputation: {Reputation(faction.playerReputation)}). <br />
@ -53,8 +58,8 @@ export function WorkInProgressRoot(): React.ReactElement {
<Money money={player.workMoneyGained} /> (<MoneyRate money={player.workMoneyGainRate * CYCLES_PER_SEC} />){" "}
<br />
<br />
{Reputation(player.workRepGained)} ({ReputationRate(player.workRepGainRate * CYCLES_PER_SEC)}) reputation for
this faction <br />
{Reputation(player.workRepGained)} ({ReputationRate(player.workRepGainRate * CYCLES_PER_SEC)}) reputation
for this faction <br />
<br />
{numeralWrapper.formatExp(player.workHackExpGained)} (
{numeralWrapper.formatExp(player.workHackExpGainRate * CYCLES_PER_SEC)} / sec) hacking exp <br />
@ -74,15 +79,15 @@ export function WorkInProgressRoot(): React.ReactElement {
You will automatically finish after working for 20 hours. You can cancel earlier if you wish.
<br />
There is no penalty for cancelling earlier.
</p>
<button onClick={cancel} className="work-button">
</Typography>
</Grid>
<Grid item>
<Button sx={{ mx: 2 }} onClick={cancel}>
Stop Faction Work
</button>
<button onClick={unfocus} className="work-button">
Do something else simultaneously
</button>
</div>
</Button>
<Button onClick={unfocus}>Do something else simultaneously</Button>
</Grid>
</Grid>
);
}
@ -110,8 +115,9 @@ export function WorkInProgressRoot(): React.ReactElement {
}
return (
<div>
<p>
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
<Grid item>
<Typography>
You have been {className} for {convertTimeMsToTimeElapsedString(player.timeWorked)}
<br />
<br />
@ -133,12 +139,12 @@ export function WorkInProgressRoot(): React.ReactElement {
{numeralWrapper.formatExp(player.workChaExpGained)} (
{numeralWrapper.formatExp(player.workChaExpGainRate * CYCLES_PER_SEC)} / sec) charisma exp <br />
You may cancel at any time
</p>
<button onClick={cancel} className="work-button">
{stopText}
</button>
</div>
</Typography>
</Grid>
<Grid item>
<Button onClick={cancel}>{stopText}</Button>
</Grid>
</Grid>
);
}
@ -165,8 +171,9 @@ export function WorkInProgressRoot(): React.ReactElement {
const penaltyString = penalty === 0.5 ? "half" : "three-quarters";
return (
<div>
<p>
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
<Grid item>
<Typography>
You are currently working as a {position} at {player.companyName} (Current Company Reputation:{" "}
{Reputation(companyRep)})<br />
<br />
@ -178,8 +185,8 @@ export function WorkInProgressRoot(): React.ReactElement {
<Money money={player.workMoneyGained} /> (<MoneyRate money={player.workMoneyGainRate * CYCLES_PER_SEC} />){" "}
<br />
<br />
{Reputation(player.workRepGained)} ({ReputationRate(player.workRepGainRate * CYCLES_PER_SEC)}) reputation for
this company <br />
{Reputation(player.workRepGained)} ({ReputationRate(player.workRepGainRate * CYCLES_PER_SEC)}) reputation
for this company <br />
<br />
{numeralWrapper.formatExp(player.workHackExpGained)} (
{`${numeralWrapper.formatExp(player.workHackExpGainRate * CYCLES_PER_SEC)} / sec`}
@ -202,17 +209,17 @@ export function WorkInProgressRoot(): React.ReactElement {
{`${numeralWrapper.formatExp(player.workChaExpGainRate * CYCLES_PER_SEC)} / sec`}
) charisma exp <br />
<br />
You will automatically finish after working for 8 hours. You can cancel earlier if you wish, but you will only
gain {penaltyString} of the reputation you've earned so far.
</p>
<button onClick={cancel} className="work-button">
You will automatically finish after working for 8 hours. You can cancel earlier if you wish, but you will
only gain {penaltyString} of the reputation you've earned so far.
</Typography>
</Grid>
<Grid item>
<Button sx={{ mx: 2 }} onClick={cancel}>
Stop Working
</button>
<button onClick={unfocus} className="work-button">
Do something else simultaneously
</button>
</div>
</Button>
<Button onClick={unfocus}>Do something else simultaneously</Button>
</Grid>
</Grid>
);
}
@ -234,8 +241,9 @@ export function WorkInProgressRoot(): React.ReactElement {
const position = player.jobs[player.companyName];
return (
<div>
<p>
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
<Grid item>
<Typography>
You are currently working as a {position} at {player.companyName} (Current Company Reputation:{" "}
{Reputation(companyRep)})<br />
<br />
@ -272,17 +280,17 @@ export function WorkInProgressRoot(): React.ReactElement {
{`${numeralWrapper.formatExp(player.workChaExpGainRate * CYCLES_PER_SEC)} / sec`}
) charisma exp <br />
<br />
You will automatically finish after working for 8 hours. You can cancel earlier if you wish, and there will be
no penalty because this is a part-time job.
</p>
<button onClick={cancel} className="work-button">
You will automatically finish after working for 8 hours. You can cancel earlier if you wish, and there will
be no penalty because this is a part-time job.
</Typography>
</Grid>
<Grid item>
<Button sx={{ mx: 2 }} onClick={cancel}>
Stop Working
</button>
<button onClick={unfocus} className="work-button">
Do something else simultaneously
</button>
</div>
</Button>
<Button onClick={unfocus}>Do something else simultaneously</Button>
</Grid>
</Grid>
);
}
@ -299,32 +307,39 @@ export function WorkInProgressRoot(): React.ReactElement {
const progressBar = createProgressBarText({ progress: (numBars + 1) / 20, totalTicks: 20 });
return (
<div>
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
<Grid item>
<Typography>
<p>You are attempting to {player.crimeType}.</p>
<br />
<p>Time remaining: {convertTimeMsToTimeElapsedString(player.timeNeededToCompleteWork - player.timeWorked)}</p>
<p>
Time remaining: {convertTimeMsToTimeElapsedString(player.timeNeededToCompleteWork - player.timeWorked)}
</p>
<br />
<pre>{progressBar}</pre>
<button
className="work-button"
</Typography>
</Grid>
<Grid item>
<Button
onClick={() => {
router.toLocation(Locations[LocationName.Slums]);
player.finishCrime(true);
}}
>
Cancel crime
</button>
</div>
</Button>
</Grid>
</Grid>
);
}
if (player.createProgramName !== "") {
return (
<div>
<p>
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
<Grid item>
<Typography>
You are currently working on coding {player.createProgramName}.<br />
<br />
You have been working for {convertTimeMsToTimeElapsedString(player.timeWorked)}
@ -333,17 +348,19 @@ export function WorkInProgressRoot(): React.ReactElement {
The program is {((player.timeWorkedCreateProgram / player.timeNeededToCompleteWork) * 100).toFixed(2)}
% complete. <br />
If you cancel, your work will be saved and you can come back to complete the program later.
</p>
<button
className="work-button"
</Typography>
</Grid>
<Grid item>
<Button
onClick={() => {
player.finishCreateProgramWork(true);
router.toTerminal();
}}
>
Cancel work on creating program
</button>
</div>
</Button>
</Grid>
</Grid>
);
}