diff --git a/src/Infiltration/ui/GameTimer.tsx b/src/Infiltration/ui/GameTimer.tsx
index 7bd25e563..335fe4925 100644
--- a/src/Infiltration/ui/GameTimer.tsx
+++ b/src/Infiltration/ui/GameTimer.tsx
@@ -1,19 +1,8 @@
-import { LinearProgress, Paper } from "@mui/material";
-import { Theme } from "@mui/material/styles";
-import withStyles from "@mui/styles/withStyles";
+import { Paper } from "@mui/material";
import React, { useEffect, useState } from "react";
import { AugmentationNames } from "../../Augmentation/data/AugmentationNames";
import { use } from "../../ui/Context";
-
-const TimerProgress = withStyles((theme: Theme) => ({
- root: {
- backgroundColor: theme.palette.background.paper,
- },
- bar: {
- transition: "none",
- backgroundColor: theme.palette.primary.main,
- },
-}))(LinearProgress);
+import { ProgressBar } from "../../ui/React/Progress";
interface IProps {
millis: number;
@@ -43,10 +32,10 @@ export function GameTimer(props: IProps): React.ReactElement {
// TODO(hydroflame): there's like a bug where it triggers the end before the
// bar physically reaches the end
return props.noPaper ? (
-
+
) : (
-
+
);
}
diff --git a/src/PersonObjects/Sleeve/ui/SleeveElem.tsx b/src/PersonObjects/Sleeve/ui/SleeveElem.tsx
index ec43ce05d..82a98a706 100644
--- a/src/PersonObjects/Sleeve/ui/SleeveElem.tsx
+++ b/src/PersonObjects/Sleeve/ui/SleeveElem.tsx
@@ -1,23 +1,19 @@
+import { Box, Button, Paper, Tooltip, Typography } from "@mui/material";
import React, { useState } from "react";
-
-import { Box, Paper, Typography, Button, Tooltip } from "@mui/material";
-
import { CONSTANTS } from "../../../Constants";
import { Crimes } from "../../../Crime/Crimes";
-import { numeralWrapper } from "../../../ui/numeralFormat";
-import { createProgressBarText } from "../../../utils/helpers/createProgressBarText";
-import { use } from "../../../ui/Context";
import { FactionWorkType } from "../../../Faction/FactionWorkTypeEnum";
-
+import { use } from "../../../ui/Context";
+import { numeralWrapper } from "../../../ui/numeralFormat";
+import { ProgressBar } from "../../../ui/React/Progress";
import { Sleeve } from "../Sleeve";
import { SleeveTaskType } from "../SleeveTaskTypesEnum";
-
-import { SleeveAugmentationsModal } from "./SleeveAugmentationsModal";
-import { TravelModal } from "./TravelModal";
-import { StatsElement, EarningsElement } from "./StatsElement";
-import { MoreStatsModal } from "./MoreStatsModal";
import { MoreEarningsModal } from "./MoreEarningsModal";
+import { MoreStatsModal } from "./MoreStatsModal";
+import { SleeveAugmentationsModal } from "./SleeveAugmentationsModal";
+import { EarningsElement, StatsElement } from "./StatsElement";
import { TaskSelector } from "./TaskSelector";
+import { TravelModal } from "./TravelModal";
interface IProps {
sleeve: Sleeve;
@@ -131,74 +127,70 @@ export function SleeveElem(props: IProps): React.ReactElement {
}
return (
-
-
-
-
-
-
-
-
- Insufficient funds : ""}>
-
-
-
-
- Unlocked when sleeve has fully recovered : ""
- }
- >
-
-
-
-
-
+ <>
+
+
+
+
+
+
+ Insufficient funds : ""}>
+
+
+
+
+ Unlocked when sleeve has fully recovered : ""}
+ >
+
+
+
+
-
-
-
-
-
- {desc}
-
- {props.sleeve.currentTask === SleeveTaskType.Crime &&
- createProgressBarText({
- progress: props.sleeve.currentTaskTime / props.sleeve.currentTaskMaxTime,
- totalTicks: 25,
- })}
-
-
-
- setStatsOpen(false)} sleeve={props.sleeve} />
- setEarningsOpen(false)} sleeve={props.sleeve} />
- setTravelOpen(false)}
- sleeve={props.sleeve}
- rerender={props.rerender}
- />
- setAugmentationsOpen(false)}
- sleeve={props.sleeve}
- />
-
-
-
+
+
+
+
+
+ {desc}
+
+ {props.sleeve.currentTask === SleeveTaskType.Crime && (
+
+ )}
+
+
+
+ setStatsOpen(false)} sleeve={props.sleeve} />
+ setEarningsOpen(false)} sleeve={props.sleeve} />
+ setTravelOpen(false)}
+ sleeve={props.sleeve}
+ rerender={props.rerender}
+ />
+ setAugmentationsOpen(false)}
+ sleeve={props.sleeve}
+ />
+ >
);
}
diff --git a/src/ui/React/Progress.tsx b/src/ui/React/Progress.tsx
new file mode 100644
index 000000000..0a29ae311
--- /dev/null
+++ b/src/ui/React/Progress.tsx
@@ -0,0 +1,13 @@
+import LinearProgress from "@mui/material/LinearProgress";
+import { Theme } from "@mui/material/styles";
+import withStyles from "@mui/styles/withStyles";
+
+export const ProgressBar = withStyles((theme: Theme) => ({
+ root: {
+ backgroundColor: theme.palette.background.paper,
+ },
+ bar: {
+ transition: "none",
+ backgroundColor: theme.palette.primary.main,
+ },
+}))(LinearProgress);
diff --git a/src/ui/React/StatsRow.tsx b/src/ui/React/StatsRow.tsx
index 405abcc26..030670791 100644
--- a/src/ui/React/StatsRow.tsx
+++ b/src/ui/React/StatsRow.tsx
@@ -16,19 +16,21 @@ interface IProps {
name: string;
color: string;
classes?: any;
- data: ITableRowData;
+ data?: ITableRowData;
children?: React.ReactElement;
}
export const StatsRow = ({ name, color, classes = useStyles(), children, data }: IProps): React.ReactElement => {
- let content;
+ let content = "";
- if (data.content !== undefined) {
- content = data.content;
- } else if (data.level !== undefined && data.exp !== undefined) {
- content = `${formatNumber(data.level, 0)} (${numeralWrapper.formatExp(data.exp)} exp)`;
- } else if (data.level !== undefined && data.exp === undefined) {
- content = `${formatNumber(data.level, 0)}`;
+ if (data) {
+ if (data.content !== undefined) {
+ content = data.content;
+ } else if (data.level !== undefined && data.exp !== undefined) {
+ content = `${formatNumber(data.level, 0)} (${numeralWrapper.formatExp(data.exp)} exp)`;
+ } else if (data.level !== undefined && data.exp === undefined) {
+ content = `${formatNumber(data.level, 0)}`;
+ }
}
return (
diff --git a/src/ui/WorkInProgressRoot.tsx b/src/ui/WorkInProgressRoot.tsx
index cce3a056c..bc266c22d 100644
--- a/src/ui/WorkInProgressRoot.tsx
+++ b/src/ui/WorkInProgressRoot.tsx
@@ -1,26 +1,46 @@
-import React, { useState, useEffect } from "react";
-import { use } from "./Context";
+import { Box, Container, Paper, Table, TableBody, Tooltip } from "@mui/material";
+import Button from "@mui/material/Button";
+import Typography from "@mui/material/Typography";
+import { uniqueId } from "lodash";
+import React, { useEffect, useState } from "react";
+import { Companies } from "../Company/Companies";
+import { Company } from "../Company/Company";
import { CONSTANTS } from "../Constants";
+import { Factions } from "../Faction/Factions";
+import { LocationName } from "../Locations/data/LocationNames";
+import { Locations } from "../Locations/Locations";
+import { Settings } from "../Settings/Settings";
+import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions";
+import { use } from "./Context";
import { numeralWrapper } from "./numeralFormat";
+import { Money } from "./React/Money";
+import { MoneyRate } from "./React/MoneyRate";
+import { ProgressBar } from "./React/Progress";
import { Reputation } from "./React/Reputation";
import { ReputationRate } from "./React/ReputationRate";
-import { MoneyRate } from "./React/MoneyRate";
-import { Money } from "./React/Money";
-import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions";
-import { Factions } from "../Faction/Factions";
-import { Company } from "../Company/Company";
-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";
+import { StatsRow } from "./React/StatsRow";
const CYCLES_PER_SEC = 1000 / CONSTANTS.MilliPerCycle;
+interface IWorkInfo {
+ buttons: {
+ cancel: () => void;
+ unfocus?: () => void;
+ };
+ title: string | React.ReactElement;
+
+ description?: string | React.ReactElement;
+ gains?: (string | React.ReactElement)[];
+ progress?: {
+ elapsed?: number;
+ remaining?: number;
+ percentage?: number;
+ };
+
+ stopText: string;
+ stopTooltip?: string | React.ReactElement;
+}
+
export function WorkInProgressRoot(): React.ReactElement {
const setRerender = useState(false)[1];
function rerender(): void {
@@ -35,499 +55,521 @@ export function WorkInProgressRoot(): React.ReactElement {
const player = use.Player();
const router = use.Router();
- if (player.workType == CONSTANTS.WorkTypeFaction) {
- const faction = Factions[player.currentWorkFactionName];
- if (!faction) {
- return (
- <>
-
- 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
-
-
- >
- );
- }
+ const expGains = [
+ player.workHackExpGained > 0 ? (
+
+ ) : (
+ <>>
+ ),
+ player.workStrExpGained > 0 ? (
+
+ ) : (
+ <>>
+ ),
+ player.workDefExpGained > 0 ? (
+
+ ) : (
+ <>>
+ ),
+ player.workDexExpGained > 0 ? (
+
+ ) : (
+ <>>
+ ),
+ player.workAgiExpGained > 0 ? (
+
+ ) : (
+ <>>
+ ),
+ player.workChaExpGained > 0 ? (
+
+ ) : (
+ <>>
+ ),
+ ];
- function cancel(): void {
- router.toFaction(faction);
- player.finishFactionWork(true);
- }
- function unfocus(): void {
- router.toFaction(faction);
- player.stopFocusing();
- }
- return (
-
-
-
- You are currently {player.currentWorkFactionDescription} for your faction {faction.name}
-
- (Current Faction Reputation:
- ).
- You have been doing this for {convertTimeMsToTimeElapsedString(player.timeWorked)}
-
-
- You have earned:
-
- (){" "}
-
-
- (
- ) reputation for this faction
-
- {player.workHackExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workHackExpGained)} (
- {numeralWrapper.formatExp(player.workHackExpGainRate * CYCLES_PER_SEC)} / sec) hacking exp
- >
- )}
-
- {player.workStrExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workStrExpGained)} (
- {numeralWrapper.formatExp(player.workStrExpGainRate * CYCLES_PER_SEC)} / sec) strength exp
- >
- )}
- {player.workDefExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workDefExpGained)} (
- {numeralWrapper.formatExp(player.workDefExpGainRate * CYCLES_PER_SEC)} / sec) defense exp
- >
- )}
- {player.workDexExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workDexExpGained)} (
- {numeralWrapper.formatExp(player.workDexExpGainRate * CYCLES_PER_SEC)} / sec) dexterity exp
- >
- )}
- {player.workAgiExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workAgiExpGained)} (
- {numeralWrapper.formatExp(player.workAgiExpGainRate * CYCLES_PER_SEC)} / sec) agility exp
- >
- )}
-
- {player.workChaExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workChaExpGained)} (
- {numeralWrapper.formatExp(player.workChaExpGainRate * CYCLES_PER_SEC)} / sec) charisma exp
- >
- )}
-
- You will automatically finish after working for 20 hours. You can cancel earlier if you wish.
-
- There is no penalty for cancelling earlier.
-
-
-
-
-
-
-
- );
- }
+ let workInfo: IWorkInfo | null;
- const className = player.className;
- if (player.className !== "") {
- function cancel(): void {
- player.finishClass(true);
- router.toCity();
- }
+ switch (player.workType) {
+ case CONSTANTS.WorkTypeFaction: {
+ const faction = Factions[player.currentWorkFactionName];
+ if (!faction) {
+ workInfo = {
+ buttons: {
+ cancel: () => router.toFactions(),
+ },
+ title:
+ `You have not joined ${player.currentWorkFactionName || "(Faction not found)"} at this time,` +
+ " please try again if you think this should have worked",
- function unfocus(): void {
- router.toCity();
- player.stopFocusing();
- }
+ stopText: "Back to Factions",
+ };
+ }
- 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";
- }
+ function cancel(): void {
+ router.toFaction(faction);
+ player.finishFactionWork(true);
+ }
+ function unfocus(): void {
+ router.toFaction(faction);
+ player.stopFocusing();
+ }
- return (
-
-
-
- You have been {className} for {convertTimeMsToTimeElapsedString(player.timeWorked)}
-
-
- This has cost you:
- (){" "}
-
-
- You have gained:
- {player.workHackExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workHackExpGained)} (
- {numeralWrapper.formatExp(player.workHackExpGainRate * CYCLES_PER_SEC)} / sec) hacking exp
- >
- )}
- {player.workStrExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workStrExpGained)} (
- {numeralWrapper.formatExp(player.workStrExpGainRate * CYCLES_PER_SEC)} / sec) strength exp
- >
- )}
- {player.workDefExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workDefExpGained)} (
- {numeralWrapper.formatExp(player.workDefExpGainRate * CYCLES_PER_SEC)} / sec) defense exp
- >
- )}
- {player.workDexExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workDexExpGained)} (
- {numeralWrapper.formatExp(player.workDexExpGainRate * CYCLES_PER_SEC)} / sec) dexterity exp
- >
- )}
- {player.workAgiExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workAgiExpGained)} (
- {numeralWrapper.formatExp(player.workAgiExpGainRate * CYCLES_PER_SEC)} / sec) agility exp
- >
- )}
- {player.workChaExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workChaExpGained)} (
- {numeralWrapper.formatExp(player.workChaExpGainRate * CYCLES_PER_SEC)} / sec) charisma exp
- >
- )}
- You may cancel at any time
-
-
-
-
-
-
-
- );
- }
-
- if (player.workType == CONSTANTS.WorkTypeCompany) {
- const comp = Companies[player.companyName];
- if (comp == null || !(comp instanceof Company)) {
- return (
- <>
-
- You cannot work for {player.companyName || "(Company not found)"} at this time, please try again if you
- think this should have worked
-
-
- >
- );
- }
-
- const companyRep = comp.playerReputation;
-
- function cancel(): void {
- player.finishWork(true);
- router.toJob();
- }
- function unfocus(): void {
- player.stopFocusing();
- router.toJob();
- }
-
- const position = player.jobs[player.companyName];
-
- const penalty = player.cancelationPenalty();
-
- const penaltyString = penalty === 0.5 ? "half" : "three-quarters";
- return (
-
-
-
- You are currently working as a {position} at {player.companyName} (Current Company Reputation:{" "}
- )
-
- You have been working for {convertTimeMsToTimeElapsedString(player.timeWorked)}
-
-
- You have earned:
-
- (){" "}
-
-
- (
- ) reputation for this company
-
- {player.workHackExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workHackExpGained)} (
- {`${numeralWrapper.formatExp(player.workHackExpGainRate * CYCLES_PER_SEC)} / sec`}
- ) hacking exp
- >
- )}
-
- {player.workStrExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workStrExpGained)} (
- {`${numeralWrapper.formatExp(player.workStrExpGainRate * CYCLES_PER_SEC)} / sec`}
- ) strength exp
- >
- )}
- {player.workDefExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workDefExpGained)} (
- {`${numeralWrapper.formatExp(player.workDefExpGainRate * CYCLES_PER_SEC)} / sec`}
- ) defense exp
- >
- )}
- {player.workDexExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workDexExpGained)} (
- {`${numeralWrapper.formatExp(player.workDexExpGainRate * CYCLES_PER_SEC)} / sec`}
- ) dexterity exp
- >
- )}
- {player.workAgiExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workAgiExpGained)} (
- {`${numeralWrapper.formatExp(player.workAgiExpGainRate * CYCLES_PER_SEC)} / sec`}
- ) agility exp
- >
- )}
-
- {player.workChaExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workChaExpGained)} (
- {`${numeralWrapper.formatExp(player.workChaExpGainRate * CYCLES_PER_SEC)} / sec`}
- ) charisma exp
- >
- )}
-
- 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.
-
-
-
-
-
-
-
- );
- }
-
- if (player.workType == CONSTANTS.WorkTypeCompanyPartTime) {
- function cancel(): void {
- player.finishWorkPartTime(true);
- router.toJob();
- }
- function unfocus(): void {
- player.stopFocusing();
- router.toJob();
- }
- 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 (
-
-
-
- You are currently working as a {position} at {player.companyName} (Current Company Reputation:{" "}
- )
-
- You have been working for {convertTimeMsToTimeElapsedString(player.timeWorked)}
-
-
- You have earned:
-
- (){" "}
-
-
- (
-
- ) reputation for this company
-
- {player.workHackExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workHackExpGained)} (
- {`${numeralWrapper.formatExp(player.workHackExpGainRate * CYCLES_PER_SEC)} / sec`}
- ) hacking exp
- >
- )}
-
- {player.workStrExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workStrExpGained)} (
- {`${numeralWrapper.formatExp(player.workStrExpGainRate * CYCLES_PER_SEC)} / sec`}
- ) strength exp
- >
- )}
- {player.workDefExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workDefExpGained)} (
- {`${numeralWrapper.formatExp(player.workDefExpGainRate * CYCLES_PER_SEC)} / sec`}
- ) defense exp
- >
- )}
- {player.workDexExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workDexExpGained)} (
- {`${numeralWrapper.formatExp(player.workDexExpGainRate * CYCLES_PER_SEC)} / sec`}
- ) dexterity exp
- >
- )}
- {player.workAgiExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workAgiExpGained)} (
- {`${numeralWrapper.formatExp(player.workAgiExpGainRate * CYCLES_PER_SEC)} / sec`}
- ) agility exp
- >
- )}
-
- {player.workChaExpGained > 0 && (
- <>
- {numeralWrapper.formatExp(player.workChaExpGained)} (
- {`${numeralWrapper.formatExp(player.workChaExpGainRate * CYCLES_PER_SEC)} / sec`}
- ) charisma exp
- >
- )}
-
- 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.
-
-
-
-
-
-
-
- );
- }
-
- 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 (
-
-
-
- You are attempting to {player.crimeType}.
-
+ workInfo = {
+ buttons: {
+ cancel: cancel,
+ unfocus: unfocus,
+ },
+ title: (
+ <>
+ You are currently {player.currentWorkFactionDescription} for your faction {faction.name}
+ >
+ ),
+ description: (
+ <>
+ Current Faction Reputation:
+ >
+ ),
+ gains: [
+ player.workMoneyGained > 0 ? (
+
+
+ (
+ )
+
+
+ ) : (
+ <>>
+ ),
+
- Time remaining: {convertTimeMsToTimeElapsedString(player.timeNeededToCompleteWork - player.timeWorked)}
+ (
+ )
+ ,
+ ...expGains,
+ ],
+ progress: {
+ elapsed: player.timeWorked,
+ },
-
- {progressBar}
-
-
-
-
-
-
- );
+ stopText: "Stop Faction work",
+ };
+
+ break;
+ }
+
+ case CONSTANTS.WorkTypeStudyClass: {
+ const className = player.className;
+ function cancel(): void {
+ player.finishClass(true);
+ router.toCity();
+ }
+
+ function unfocus(): void {
+ router.toCity();
+ player.stopFocusing();
+ }
+
+ 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";
+ }
+
+ workInfo = {
+ buttons: {
+ cancel: cancel,
+ unfocus: unfocus,
+ },
+ title: (
+ <>
+ You are currently {className}
+ >
+ ),
+
+ gains: [
+
+
+ (
+ )
+
+ ,
+ ...expGains,
+ ],
+ progress: {
+ elapsed: player.timeWorked,
+ },
+
+ stopText: stopText,
+ };
+
+ break;
+ }
+
+ case CONSTANTS.WorkTypeCompany: {
+ const comp = Companies[player.companyName];
+ if (comp == null || !(comp instanceof Company)) {
+ workInfo = {
+ buttons: {
+ cancel: () => router.toTerminal(),
+ },
+ title:
+ `You cannot work for ${player.companyName || "(Company not found)"} at this time,` +
+ " please try again if you think this should have worked",
+
+ stopText: "Back to Terminal",
+ };
+ }
+
+ const companyRep = comp.playerReputation;
+
+ function cancel(): void {
+ player.finishWork(true);
+ router.toJob();
+ }
+ function unfocus(): void {
+ player.stopFocusing();
+ router.toJob();
+ }
+
+ const position = player.jobs[player.companyName];
+
+ const penalty = player.cancelationPenalty();
+
+ const penaltyString = penalty === 0.5 ? "half" : "three-quarters";
+
+ workInfo = {
+ buttons: {
+ cancel: cancel,
+ unfocus: unfocus,
+ },
+ title: (
+ <>
+ You are currently working as a {position} at {player.companyName}
+ >
+ ),
+
+ description: (
+ <>
+ Current Company Reputation:
+ >
+ ),
+ gains: [
+
+
+ ()
+
+ ,
+
+
+ (
+ )
+
+ ,
+ ...expGains,
+ ],
+ progress: {
+ elapsed: player.timeWorked,
+ },
+
+ stopText: "Stop working",
+ stopTooltip:
+ "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.`,
+ };
+
+ break;
+ }
+
+ case CONSTANTS.WorkTypeCompanyPartTime: {
+ function cancel(): void {
+ player.finishWorkPartTime(true);
+ router.toJob();
+ }
+ function unfocus(): void {
+ player.stopFocusing();
+ router.toJob();
+ }
+ 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];
+
+ workInfo = {
+ buttons: {
+ cancel: cancel,
+ unfocus: unfocus,
+ },
+ title: (
+ <>
+ You are currently working as a {position} at {player.companyName}
+ >
+ ),
+
+ description: (
+ <>
+ Current Company Reputation:
+ >
+ ),
+ gains: [
+
+
+ ()
+
+ ,
+
+
+ (
+ )
+
+ ,
+ ...expGains,
+ ],
+ progress: {
+ elapsed: player.timeWorked,
+ },
+
+ stopText: "Stop working",
+ stopTooltip:
+ "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.",
+ };
+
+ break;
+ }
+
+ case CONSTANTS.WorkTypeCrime: {
+ const completion = Math.round((player.timeWorked / player.timeNeededToCompleteWork) * 100);
+
+ workInfo = {
+ buttons: {
+ cancel: () => {
+ router.toLocation(Locations[LocationName.Slums]);
+ player.finishCrime(true);
+ },
+ },
+ title: `You are attempting to ${player.crimeType}`,
+
+ progress: {
+ remaining: player.timeNeededToCompleteWork - player.timeWorked,
+ percentage: completion,
+ },
+
+ stopText: "Cancel crime",
+ };
+
+ break;
+ }
+
+ case CONSTANTS.WorkTypeCreateProgram: {
+ function cancel(): void {
+ player.finishCreateProgramWork(true);
+ router.toTerminal();
+ }
+ function unfocus(): void {
+ router.toTerminal();
+ player.stopFocusing();
+ }
+
+ const completion = (player.timeWorkedCreateProgram / player.timeNeededToCompleteWork) * 100;
+
+ workInfo = {
+ buttons: {
+ cancel: cancel,
+ unfocus: unfocus,
+ },
+ title: (
+ <>
+ You are currently working on coding {player.createProgramName}
+ >
+ ),
+
+ progress: {
+ elapsed: player.timeWorked,
+ percentage: completion,
+ },
+
+ stopText: "Stop creating program",
+ stopTooltip: "Your work will be saved and you can return to complete the program later.",
+ };
+
+ break;
+ }
+
+ case CONSTANTS.WorkTypeGraftAugmentation: {
+ function cancel(): void {
+ player.finishGraftAugmentationWork(true);
+ router.toTerminal();
+ }
+ function unfocus(): void {
+ router.toTerminal();
+ player.stopFocusing();
+ }
+
+ const completion = (player.timeWorkedGraftAugmentation / player.timeNeededToCompleteWork) * 100;
+
+ workInfo = {
+ buttons: {
+ cancel: cancel,
+ unfocus: unfocus,
+ },
+ title: (
+ <>
+ You are currently working on grafting {player.graftAugmentationName}
+ >
+ ),
+
+ progress: {
+ elapsed: player.timeWorked,
+ percentage: completion,
+ },
+
+ stopText: "Stop grafting",
+ stopTooltip: (
+ <>
+ If you cancel, your work will not be saved, and the money you spent will not be returned
+ >
+ ),
+ };
+
+ break;
+ }
+
+ default:
+ router.toTerminal();
+ workInfo = null;
}
- if (player.createProgramName !== "") {
- function cancel(): void {
- player.finishCreateProgramWork(true);
- router.toTerminal();
- }
- function unfocus(): void {
- router.toTerminal();
- player.stopFocusing();
- }
- return (
-
-
-
- You are currently working on coding {player.createProgramName}.
-
- You have been working for {convertTimeMsToTimeElapsedString(player.timeWorked)}
-
-
- The program is {((player.timeWorkedCreateProgram / player.timeNeededToCompleteWork) * 100).toFixed(2)}
- % complete.
- If you cancel, your work will be saved and you can come back to complete the program later.
-
-
-
-
-
-
-
- );
+ if (workInfo === null) {
+ return <>>;
}
- if (player.graftAugmentationName !== "") {
- function cancel(): void {
- player.finishGraftAugmentationWork(true);
- router.toTerminal();
- }
- function unfocus(): void {
- router.toTerminal();
- player.stopFocusing();
- }
- return (
-
-
-
- You are currently working on grafting {player.graftAugmentationName}.
-
-
- You have been working for {convertTimeMsToTimeElapsedString(player.timeWorked)}
-
-
- The augmentation is{" "}
- {((player.timeWorkedGraftAugmentation / player.timeNeededToCompleteWork) * 100).toFixed(2)}% done being
- crafted.
-
- If you cancel, your work will not be saved, and the money you spent will not be returned.
-
-
-
-
-
-
-
+ const tooltipInfo =
+ typeof workInfo?.stopTooltip === "string" ? (
+ {workInfo.stopTooltip}
+ ) : (
+ workInfo.stopTooltip || <>>
);
- }
- if (!player.workType) router.toTerminal();
+ return (
+
+
+ {workInfo.title}
+ {workInfo.description}
+ {workInfo.gains && (
+
+
+ {workInfo.gains.map((row) => (
+ {row}
+ ))}
+
+
+ )}
+
+
+ {workInfo.progress !== undefined && (
+
+
+ {workInfo.progress.elapsed !== undefined && (
+ {convertTimeMsToTimeElapsedString(workInfo.progress.elapsed)} elapsed
+ )}
+ {workInfo.progress.remaining !== undefined && (
+ {convertTimeMsToTimeElapsedString(workInfo.progress.remaining)} remaining
+ )}
+ {workInfo.progress.percentage !== undefined && (
+ {workInfo.progress.percentage.toFixed(2)}% done
+ )}
+
+ {workInfo.progress.percentage !== undefined && (
+
+ )}
+
+ )}
- return <>>;
+
+ {workInfo.stopTooltip ? (
+
+
+
+ ) : (
+
+ )}
+ {workInfo.buttons.unfocus && (
+
+ )}
+
+
+
+ );
}