bitburner-src/src/ui/WorkInProgressRoot.tsx

526 lines
19 KiB
TypeScript
Raw Normal View History

2021-09-18 01:43:08 +02:00
import React, { useState, useEffect } from "react";
import { use } from "./Context";
import { CONSTANTS } from "../Constants";
import { numeralWrapper } from "./numeralFormat";
import { Reputation } from "./React/Reputation";
import { ReputationRate } from "./React/ReputationRate";
import { MoneyRate } from "./React/MoneyRate";
import { Money } from "./React/Money";
2021-09-25 20:42:57 +02:00
import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions";
2021-09-18 01:43:08 +02:00
import { Factions } from "../Faction/Factions";
import { Company } from "../Company/Company";
import { Companies } from "../Company/Companies";
2021-09-18 10:01:07 +02:00
import { Locations } from "../Locations/Locations";
import { LocationName } from "../Locations/data/LocationNames";
2021-09-22 09:25:12 +02:00
import Typography from "@mui/material/Typography";
import Grid from "@mui/material/Grid";
import Button from "@mui/material/Button";
2021-09-25 20:42:57 +02:00
import { createProgressBarText } from "../utils/helpers/createProgressBarText";
2021-09-18 01:43:08 +02:00
const CYCLES_PER_SEC = 1000 / CONSTANTS.MilliPerCycle;
export function WorkInProgressRoot(): React.ReactElement {
const setRerender = useState(false)[1];
function rerender(): void {
setRerender((old) => !old);
}
useEffect(() => {
const id = setInterval(rerender, CONSTANTS.MilliPerCycle);
return () => clearInterval(id);
}, []);
2021-09-18 01:43:08 +02:00
const player = use.Player();
const router = use.Router();
2021-09-18 01:43:08 +02:00
if (player.workType == CONSTANTS.WorkTypeFaction) {
2022-03-11 05:05:35 +01:00
const faction = Factions[player.currentWorkFactionName];
if (!faction) {
return (
<>
<Typography variant="h4" color="primary">
2022-03-22 23:53:57 +01:00
You have not joined {player.currentWorkFactionName || "(Faction not found)"} yet or cannot work at this
time, please try again if you think this should have worked
2022-03-11 05:05:35 +01:00
</Typography>
<Button onClick={() => router.toFactions()}>Back to Factions</Button>
</>
);
}
2021-09-18 01:43:08 +02:00
function cancel(): void {
router.toFaction(faction);
2021-09-18 01:43:08 +02:00
player.finishFactionWork(true);
}
function unfocus(): void {
router.toFaction(faction);
2021-09-18 01:43:08 +02:00
player.stopFocusing();
}
return (
2021-09-22 09:25:12 +02:00
<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 />
2021-10-01 19:08:37 +02:00
(Current Faction Reputation: <Reputation reputation={faction.playerReputation} />
). <br />
2021-09-22 09:25:12 +02:00
You have been doing this for {convertTimeMsToTimeElapsedString(player.timeWorked)}
<br />
<br />
You have earned: <br />
<br />
<Money money={player.workMoneyGained} /> (<MoneyRate money={player.workMoneyGainRate * CYCLES_PER_SEC} />){" "}
<br />
<br />
2021-10-01 19:08:37 +02:00
<Reputation reputation={player.workRepGained} /> (
<ReputationRate reputation={player.workRepGainRate * CYCLES_PER_SEC} />) reputation for this faction <br />
2021-09-22 09:25:12 +02:00
<br />
2022-01-09 21:22:23 +01:00
{player.workHackExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workHackExpGained)} (
{numeralWrapper.formatExp(player.workHackExpGainRate * CYCLES_PER_SEC)} / sec) hacking exp <br />
</>
)}
<br />
{player.workStrExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workStrExpGained)} (
{numeralWrapper.formatExp(player.workStrExpGainRate * CYCLES_PER_SEC)} / sec) strength exp <br />
</>
)}
{player.workDefExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workDefExpGained)} (
{numeralWrapper.formatExp(player.workDefExpGainRate * CYCLES_PER_SEC)} / sec) defense exp <br />
</>
)}
{player.workDexExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workDexExpGained)} (
{numeralWrapper.formatExp(player.workDexExpGainRate * CYCLES_PER_SEC)} / sec) dexterity exp <br />
</>
)}
{player.workAgiExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workAgiExpGained)} (
{numeralWrapper.formatExp(player.workAgiExpGainRate * CYCLES_PER_SEC)} / sec) agility exp <br />
</>
)}
<br />
{player.workChaExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workChaExpGained)} (
{numeralWrapper.formatExp(player.workChaExpGainRate * CYCLES_PER_SEC)} / sec) charisma exp <br />
</>
)}
2021-09-22 09:25:12 +02:00
<br />
You will automatically finish after working for 20 hours. You can cancel earlier if you wish.
<br />
There is no penalty for cancelling earlier.
</Typography>
</Grid>
<Grid item>
<Button sx={{ mx: 2 }} onClick={cancel}>
Stop Faction Work
</Button>
<Button onClick={unfocus}>Do something else simultaneously</Button>
</Grid>
</Grid>
2021-09-18 01:43:08 +02:00
);
}
const className = player.className;
if (player.className !== "") {
function cancel(): void {
player.finishClass(true);
router.toCity();
2021-09-18 01:43:08 +02:00
}
2022-01-09 21:22:23 +01:00
function unfocus(): void {
router.toCity();
2022-01-09 21:22:23 +01:00
player.stopFocusing();
}
2021-09-18 01:43:08 +02:00
let stopText = "";
if (
className == CONSTANTS.ClassGymStrength ||
className == CONSTANTS.ClassGymDefense ||
className == CONSTANTS.ClassGymDexterity ||
className == CONSTANTS.ClassGymAgility
) {
stopText = "Stop training at gym";
} else {
stopText = "Stop taking course";
}
return (
2021-09-22 09:25:12 +02:00
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
<Grid item>
<Typography>
You have been {className} for {convertTimeMsToTimeElapsedString(player.timeWorked)}
<br />
<br />
This has cost you: <br />
<Money money={-player.workMoneyGained} /> (<MoneyRate money={player.workMoneyLossRate * CYCLES_PER_SEC} />){" "}
<br />
<br />
You have gained: <br />
2022-01-09 21:22:23 +01:00
{player.workHackExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workHackExpGained)} (
{numeralWrapper.formatExp(player.workHackExpGainRate * CYCLES_PER_SEC)} / sec) hacking exp <br />
</>
)}
{player.workStrExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workStrExpGained)} (
{numeralWrapper.formatExp(player.workStrExpGainRate * CYCLES_PER_SEC)} / sec) strength exp <br />
</>
)}
{player.workDefExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workDefExpGained)} (
{numeralWrapper.formatExp(player.workDefExpGainRate * CYCLES_PER_SEC)} / sec) defense exp <br />
</>
)}
{player.workDexExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workDexExpGained)} (
{numeralWrapper.formatExp(player.workDexExpGainRate * CYCLES_PER_SEC)} / sec) dexterity exp <br />
</>
)}
{player.workAgiExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workAgiExpGained)} (
{numeralWrapper.formatExp(player.workAgiExpGainRate * CYCLES_PER_SEC)} / sec) agility exp <br />
</>
)}
{player.workChaExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workChaExpGained)} (
{numeralWrapper.formatExp(player.workChaExpGainRate * CYCLES_PER_SEC)} / sec) charisma exp <br />
</>
)}
2021-09-22 09:25:12 +02:00
You may cancel at any time
</Typography>
</Grid>
<Grid item>
2022-01-09 21:22:23 +01:00
<Button sx={{ mx: 2 }} onClick={cancel}>
{stopText}
</Button>
<Button onClick={unfocus}>Do something else simultaneously</Button>
2021-09-22 09:25:12 +02:00
</Grid>
</Grid>
2021-09-18 01:43:08 +02:00
);
}
if (player.workType == CONSTANTS.WorkTypeCompany) {
const comp = Companies[player.companyName];
let companyRep = 0;
if (comp == null || !(comp instanceof Company)) {
throw new Error(`Could not find Company: ${player.companyName}`);
}
companyRep = comp.playerReputation;
function cancel(): void {
player.finishWork(true);
router.toJob();
2021-09-18 01:43:08 +02:00
}
function unfocus(): void {
player.stopFocusing();
router.toJob();
2021-09-18 01:43:08 +02:00
}
const position = player.jobs[player.companyName];
const penalty = player.cancelationPenalty();
const penaltyString = penalty === 0.5 ? "half" : "three-quarters";
return (
2021-09-22 09:25:12 +02:00
<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:{" "}
2021-10-01 19:08:37 +02:00
<Reputation reputation={companyRep} />)<br />
2021-09-22 09:25:12 +02:00
<br />
You have been working for {convertTimeMsToTimeElapsedString(player.timeWorked)}
<br />
<br />
You have earned: <br />
<br />
<Money money={player.workMoneyGained} /> (<MoneyRate money={player.workMoneyGainRate * CYCLES_PER_SEC} />){" "}
<br />
<br />
2021-10-01 19:08:37 +02:00
<Reputation reputation={player.workRepGained} /> (
<ReputationRate reputation={player.workRepGainRate * CYCLES_PER_SEC} />) reputation for this company <br />
2021-09-22 09:25:12 +02:00
<br />
2022-01-09 21:22:23 +01:00
{player.workHackExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workHackExpGained)} (
{`${numeralWrapper.formatExp(player.workHackExpGainRate * CYCLES_PER_SEC)} / sec`}
) hacking exp <br />
</>
)}
<br />
{player.workStrExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workStrExpGained)} (
{`${numeralWrapper.formatExp(player.workStrExpGainRate * CYCLES_PER_SEC)} / sec`}
) strength exp <br />
</>
)}
{player.workDefExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workDefExpGained)} (
{`${numeralWrapper.formatExp(player.workDefExpGainRate * CYCLES_PER_SEC)} / sec`}
) defense exp <br />
</>
)}
{player.workDexExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workDexExpGained)} (
{`${numeralWrapper.formatExp(player.workDexExpGainRate * CYCLES_PER_SEC)} / sec`}
) dexterity exp <br />
</>
)}
{player.workAgiExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workAgiExpGained)} (
{`${numeralWrapper.formatExp(player.workAgiExpGainRate * CYCLES_PER_SEC)} / sec`}
) agility exp <br />
</>
)}
<br />
{player.workChaExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workChaExpGained)} (
{`${numeralWrapper.formatExp(player.workChaExpGainRate * CYCLES_PER_SEC)} / sec`}
) charisma exp <br />
</>
)}
2021-09-22 09:25:12 +02:00
<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.
</Typography>
</Grid>
<Grid item>
<Button sx={{ mx: 2 }} onClick={cancel}>
Stop Working
</Button>
<Button onClick={unfocus}>Do something else simultaneously</Button>
</Grid>
</Grid>
2021-09-18 01:43:08 +02:00
);
}
if (player.workType == CONSTANTS.WorkTypeCompanyPartTime) {
function cancel(): void {
2021-10-22 21:21:10 +02:00
player.finishWorkPartTime(true);
router.toJob();
2021-09-18 01:43:08 +02:00
}
function unfocus(): void {
player.stopFocusing();
router.toJob();
2021-09-18 01:43:08 +02:00
}
const comp = Companies[player.companyName];
let companyRep = 0;
if (comp == null || !(comp instanceof Company)) {
throw new Error(`Could not find Company: ${player.companyName}`);
}
companyRep = comp.playerReputation;
const position = player.jobs[player.companyName];
return (
2021-09-22 09:25:12 +02:00
<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:{" "}
2021-10-01 19:08:37 +02:00
<Reputation reputation={companyRep} />)<br />
2021-09-22 09:25:12 +02:00
<br />
You have been working for {convertTimeMsToTimeElapsedString(player.timeWorked)}
<br />
<br />
You have earned: <br />
<br />
<Money money={player.workMoneyGained} /> (<MoneyRate money={player.workMoneyGainRate * CYCLES_PER_SEC} />){" "}
<br />
<br />
2021-10-01 19:08:37 +02:00
<Reputation reputation={player.workRepGained} /> (
<ReputationRate reputation={player.workRepGainRate * CYCLES_PER_SEC} />
2021-09-22 09:25:12 +02:00
) reputation for this company <br />
<br />
2022-01-09 21:22:23 +01:00
{player.workHackExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workHackExpGained)} (
{`${numeralWrapper.formatExp(player.workHackExpGainRate * CYCLES_PER_SEC)} / sec`}
) hacking exp <br />
</>
)}
<br />
{player.workStrExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workStrExpGained)} (
{`${numeralWrapper.formatExp(player.workStrExpGainRate * CYCLES_PER_SEC)} / sec`}
) strength exp <br />
</>
)}
{player.workDefExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workDefExpGained)} (
{`${numeralWrapper.formatExp(player.workDefExpGainRate * CYCLES_PER_SEC)} / sec`}
) defense exp <br />
</>
)}
{player.workDexExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workDexExpGained)} (
{`${numeralWrapper.formatExp(player.workDexExpGainRate * CYCLES_PER_SEC)} / sec`}
) dexterity exp <br />
</>
)}
{player.workAgiExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workAgiExpGained)} (
{`${numeralWrapper.formatExp(player.workAgiExpGainRate * CYCLES_PER_SEC)} / sec`}
) agility exp <br />
</>
)}
<br />
{player.workChaExpGained > 0 && (
<>
{numeralWrapper.formatExp(player.workChaExpGained)} (
{`${numeralWrapper.formatExp(player.workChaExpGainRate * CYCLES_PER_SEC)} / sec`}
) charisma exp <br />
</>
)}
2021-09-22 09:25:12 +02:00
<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.
</Typography>
</Grid>
<Grid item>
<Button sx={{ mx: 2 }} onClick={cancel}>
Stop Working
</Button>
<Button onClick={unfocus}>Do something else simultaneously</Button>
</Grid>
</Grid>
2021-09-18 01:43:08 +02:00
);
}
if (player.crimeType !== "") {
const percent = Math.round((player.timeWorked / player.timeNeededToCompleteWork) * 100);
let numBars = Math.round(percent / 5);
if (numBars < 0) {
numBars = 0;
}
if (numBars > 20) {
numBars = 20;
}
// const progressBar = "[" + Array(numBars + 1).join("|") + Array(20 - numBars + 1).join(" ") + "]";
const progressBar = createProgressBarText({ progress: (numBars + 1) / 20, totalTicks: 20 });
return (
2021-09-22 09:25:12 +02:00
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
<Grid item>
<Typography>
2021-10-01 19:08:37 +02:00
<Typography>You are attempting to {player.crimeType}.</Typography>
2021-09-22 09:25:12 +02:00
<br />
2021-09-18 01:43:08 +02:00
2021-10-01 19:08:37 +02:00
<Typography>
2021-09-22 09:25:12 +02:00
Time remaining: {convertTimeMsToTimeElapsedString(player.timeNeededToCompleteWork - player.timeWorked)}
2021-10-01 19:08:37 +02:00
</Typography>
2021-09-18 01:43:08 +02:00
2021-09-22 09:25:12 +02:00
<br />
<pre>{progressBar}</pre>
</Typography>
</Grid>
<Grid item>
<Button
onClick={() => {
router.toLocation(Locations[LocationName.Slums]);
player.finishCrime(true);
}}
>
Cancel crime
</Button>
</Grid>
</Grid>
2021-09-18 01:43:08 +02:00
);
}
if (player.createProgramName !== "") {
2022-01-09 21:22:23 +01:00
function cancel(): void {
player.finishCreateProgramWork(true);
router.toTerminal();
2022-01-09 21:22:23 +01:00
}
function unfocus(): void {
router.toTerminal();
2022-01-09 21:22:23 +01:00
player.stopFocusing();
}
2021-09-18 01:43:08 +02:00
return (
2021-09-22 09:25:12 +02:00
<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)}
<br />
<br />
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.
</Typography>
</Grid>
<Grid item>
2022-01-09 21:22:23 +01:00
<Button sx={{ mx: 2 }} onClick={cancel}>
2021-09-22 09:25:12 +02:00
Cancel work on creating program
</Button>
2022-01-09 21:22:23 +01:00
<Button onClick={unfocus}>Do something else simultaneously</Button>
2021-09-22 09:25:12 +02:00
</Grid>
</Grid>
2021-09-18 01:43:08 +02:00
);
}
2022-03-19 15:31:48 +01:00
if (player.craftAugmentationName !== "") {
function cancel(): void {
player.finishCraftAugmentationWork(true);
router.toTerminal();
}
function unfocus(): void {
router.toTerminal();
player.stopFocusing();
}
return (
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
<Grid item>
<Typography>
You are currently working on crafting {player.craftAugmentationName}.
2022-03-22 23:53:57 +01:00
<br />
<br />
2022-03-19 15:31:48 +01:00
You have been working for {convertTimeMsToTimeElapsedString(player.timeWorked)}
2022-03-22 23:53:57 +01:00
<br />
<br />
The augmentation is{" "}
{((player.timeWorkedCraftAugmentation / player.timeNeededToCompleteWork) * 100).toFixed(2)}% done being
crafted.
<br />
2022-03-19 15:31:48 +01:00
If you cancel, your work will <b>not</b> be saved, and the money you spent will <b>not</b> be returned.
</Typography>
</Grid>
<Grid item>
<Button sx={{ mx: 2 }} onClick={cancel}>
Cancel work on creating program
</Button>
<Button onClick={unfocus}>Do something else simultaneously</Button>
</Grid>
</Grid>
2022-03-22 23:53:57 +01:00
);
2022-03-19 15:31:48 +01:00
}
2021-10-16 21:43:28 +02:00
if (!player.workType) router.toTerminal();
2021-09-18 01:43:08 +02:00
return <></>;
}