From 05078ffb0820ebc79bb08eb2d3197362f5773add Mon Sep 17 00:00:00 2001 From: nickofolas Date: Mon, 2 May 2022 15:36:21 -0500 Subject: [PATCH 01/10] Move `ProgressBar` component --- src/Infiltration/ui/GameTimer.tsx | 20 ++++---------------- src/ui/React/Progress.tsx | 13 +++++++++++++ 2 files changed, 17 insertions(+), 16 deletions(-) create mode 100644 src/ui/React/Progress.tsx diff --git a/src/Infiltration/ui/GameTimer.tsx b/src/Infiltration/ui/GameTimer.tsx index c6ea60f44..6af6351f3 100644 --- a/src/Infiltration/ui/GameTimer.tsx +++ b/src/Infiltration/ui/GameTimer.tsx @@ -1,20 +1,8 @@ -import LinearProgress from "@mui/material/LinearProgress"; -import React, { useState, useEffect } from "react"; -import withStyles from "@mui/styles/withStyles"; -import { Theme } from "@mui/material/styles"; import Grid from "@mui/material/Grid"; -import { use } from "../../ui/Context"; +import React, { useEffect, useState } from "react"; import { AugmentationNames } from "../../Augmentation/data/AugmentationNames"; - -const TimerProgress = withStyles((theme: Theme) => ({ - root: { - backgroundColor: theme.palette.background.paper, - }, - bar: { - transition: "none", - backgroundColor: theme.palette.primary.main, - }, -}))(LinearProgress); +import { use } from "../../ui/Context"; +import { ProgressBar } from "../../ui/React/Progress"; interface IProps { millis: number; @@ -44,7 +32,7 @@ export function GameTimer(props: IProps): React.ReactElement { // bar physically reaches the end return ( - + ); } 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); From 35fa6dcca116d89c538691349ce6c6805ce9ed59 Mon Sep 17 00:00:00 2001 From: nickofolas Date: Mon, 2 May 2022 16:34:17 -0500 Subject: [PATCH 02/10] Basic `WorkInfo` implementation --- src/ui/WorkInProgressRoot.tsx | 67 +++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/src/ui/WorkInProgressRoot.tsx b/src/ui/WorkInProgressRoot.tsx index cce3a056c..13fc2b919 100644 --- a/src/ui/WorkInProgressRoot.tsx +++ b/src/ui/WorkInProgressRoot.tsx @@ -21,6 +21,24 @@ import { createProgressBarText } from "../utils/helpers/createProgressBarText"; 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; + percentage?: number; + }; + + stopText: string; + stopTooltip?: string | React.ReactElement; +} + export function WorkInProgressRoot(): React.ReactElement { const setRerender = useState(false)[1]; function rerender(): void { @@ -527,7 +545,52 @@ export function WorkInProgressRoot(): React.ReactElement { ); } - if (!player.workType) router.toTerminal(); + return ( + + + {workInfo.title} + {workInfo.description} + + + {workInfo.progress !== undefined && ( + + + {workInfo.progress.elapsed !== undefined && ( + {convertTimeMsToTimeElapsedString(workInfo.progress.elapsed)} elapsed + )} + {workInfo.progress.percentage !== undefined && ( + {workInfo.progress.percentage.toFixed(2)}% done + )} + + {workInfo.progress.percentage !== undefined && ( + + )} + + )} - return <>; + + {workInfo.stopTooltip ? ( + + + + ) : ( + + )} + {workInfo.buttons.unfocus && ( + + )} + + + + ); } From 4c15b77d21e7cfa02d972999bdab81d777089605 Mon Sep 17 00:00:00 2001 From: nickofolas Date: Mon, 2 May 2022 17:05:25 -0500 Subject: [PATCH 03/10] Update `StatsRow` --- src/ui/React/StatsRow.tsx | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) 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 ( From e859759ebd224eeee3a1d2c2a6d8b97292f77221 Mon Sep 17 00:00:00 2001 From: nickofolas Date: Mon, 2 May 2022 17:31:40 -0500 Subject: [PATCH 04/10] First pass on work in progress root --- src/ui/WorkInProgressRoot.tsx | 763 ++++++++++++++++------------------ 1 file changed, 355 insertions(+), 408 deletions(-) diff --git a/src/ui/WorkInProgressRoot.tsx b/src/ui/WorkInProgressRoot.tsx index 13fc2b919..db5b9e721 100644 --- a/src/ui/WorkInProgressRoot.tsx +++ b/src/ui/WorkInProgressRoot.tsx @@ -1,23 +1,24 @@ -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; @@ -32,6 +33,7 @@ interface IWorkInfo { gains?: (string | React.ReactElement)[]; progress?: { elapsed?: number; + remaining?: number; percentage?: number; }; @@ -53,18 +55,102 @@ export function WorkInProgressRoot(): React.ReactElement { const player = use.Player(); const router = use.Router(); + const expGains = [ + player.workHackExpGained > 0 ? ( + + ) : ( + <> + ), + player.workStrExpGained > 0 ? ( + + ) : ( + <> + ), + player.workDefExpGained > 0 ? ( + + ) : ( + <> + ), + player.workDexExpGained > 0 ? ( + + ) : ( + <> + ), + player.workAgiExpGained > 0 ? ( + + ) : ( + <> + ), + player.workChaExpGained > 0 ? ( + + ) : ( + <> + ), + ]; + + let workInfo: IWorkInfo | null; + 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 - - - - ); + 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", + + stopText: "Back to Factions", + }; } function cancel(): void { @@ -75,81 +161,45 @@ export function WorkInProgressRoot(): React.ReactElement { 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. -
-
- - - - -
- ); - } - const className = player.className; - if (player.className !== "") { + workInfo = { + buttons: { + cancel: cancel, + unfocus: unfocus, + }, + title: ( + <> + You are currently {player.currentWorkFactionDescription} for your faction {faction.name} + + ), + + description: ( + <> + Current Faction Reputation: + + ), + gains: [ + + + () + + , + + + ( + ) + + , + ...expGains, + ], + progress: { + elapsed: player.timeWorked, + }, + + stopText: "Stop Faction work", + }; + } else if (player.className !== "") { + const className = player.className; function cancel(): void { player.finishClass(true); router.toCity(); @@ -172,79 +222,44 @@ export function WorkInProgressRoot(): React.ReactElement { stopText = "Stop taking course"; } - 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 -
-
- - - - -
- ); - } + workInfo = { + buttons: { + cancel: cancel, + unfocus: unfocus, + }, + title: ( + <> + You are currently {className} + + ), - if (player.workType == CONSTANTS.WorkTypeCompany) { + gains: [ + + + () + + , + ...expGains, + ], + progress: { + elapsed: player.timeWorked, + }, + + stopText: stopText, + }; + } else 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 - - - - ); + 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; @@ -263,84 +278,47 @@ export function WorkInProgressRoot(): React.ReactElement { 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) { + 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.`, + }; + } else if (player.workType == CONSTANTS.WorkTypeCompanyPartTime) { function cancel(): void { player.finishWorkPartTime(true); router.toJob(); @@ -357,126 +335,67 @@ export function WorkInProgressRoot(): React.ReactElement { companyRep = comp.playerReputation; const position = player.jobs[player.companyName]; - return ( - - + + workInfo = { + buttons: { + cancel: cancel, + unfocus: unfocus, + }, + title: ( + <> + You are currently working as a {position} at {player.companyName} + + ), + + description: ( + <> + Current Company Reputation: + + ), + gains: [ + + + () + + , + - 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. + )
-
- - - - -
- ); - } +
, + ...expGains, + ], + progress: { + elapsed: player.timeWorked, + }, - 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 }); + 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.", + }; + } else if (player.crimeType !== "") { + const completion = Math.round((player.timeWorked / player.timeNeededToCompleteWork) * 100); - return ( - - - - You are attempting to {player.crimeType}. -
+ workInfo = { + buttons: { + cancel: () => { + router.toLocation(Locations[LocationName.Slums]); + player.finishCrime(true); + }, + }, + title: `You are attempting to ${player.crimeType}`, - - Time remaining: {convertTimeMsToTimeElapsedString(player.timeNeededToCompleteWork - player.timeWorked)} - + progress: { + elapsed: player.timeWorked, + remaining: player.timeNeededToCompleteWork - player.timeWorked, + percentage: completion, + }, -
-
{progressBar}
-
-
- - - -
- ); - } - - if (player.createProgramName !== "") { + stopText: "Cancel crime", + }; + } else if (player.createProgramName !== "") { function cancel(): void { player.finishCreateProgramWork(true); router.toTerminal(); @@ -485,31 +404,29 @@ export function WorkInProgressRoot(): React.ReactElement { 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 (player.graftAugmentationName !== "") { + 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.", + }; + } else if (player.graftAugmentationName !== "") { function cancel(): void { player.finishGraftAugmentationWork(true); router.toTerminal(); @@ -518,33 +435,50 @@ export function WorkInProgressRoot(): React.ReactElement { 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 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, you work will not be saved, and the money you spent will not be returned + + ), + }; + } else if (!player.workType) { + router.toTerminal(); + workInfo = null; + } else { + workInfo = null; } + if (workInfo === null) { + return <>; + } + + const tooltipInfo = + typeof workInfo?.stopTooltip === "string" ? ( + {workInfo.stopTooltip} + ) : ( + workInfo.stopTooltip || <> + ); + return ( {workInfo.title} {workInfo.description} + {workInfo.gains && ( + + + {workInfo.gains.map((row) => ( + {row} + ))} + +
+ )} {workInfo.progress !== undefined && ( @@ -563,11 +506,15 @@ export function WorkInProgressRoot(): React.ReactElement { gridTemplateColumns: `repeat(${Object.keys(workInfo.progress).length}, 1fr)`, width: "100%", justifyItems: "center", + textAlign: "center", }} > {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 )} From 57673ae2815a3dd61bd5ab1fe3a04316cb9c5ade Mon Sep 17 00:00:00 2001 From: nickofolas Date: Mon, 2 May 2022 17:48:49 -0500 Subject: [PATCH 05/10] Add new progress bar to sleeve UI --- src/PersonObjects/Sleeve/ui/SleeveElem.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/PersonObjects/Sleeve/ui/SleeveElem.tsx b/src/PersonObjects/Sleeve/ui/SleeveElem.tsx index ec43ce05d..6ec55dea1 100644 --- a/src/PersonObjects/Sleeve/ui/SleeveElem.tsx +++ b/src/PersonObjects/Sleeve/ui/SleeveElem.tsx @@ -176,12 +176,14 @@ export function SleeveElem(props: IProps): React.ReactElement { {desc} - {props.sleeve.currentTask === SleeveTaskType.Crime && - createProgressBarText({ - progress: props.sleeve.currentTaskTime / props.sleeve.currentTaskMaxTime, - totalTicks: 25, - })} - + {props.sleeve.currentTask === SleeveTaskType.Crime && ( + + )} + setStatsOpen(false)} sleeve={props.sleeve} /> From d942d27a8573f70a11d5fd0bd9416ee1549d5314 Mon Sep 17 00:00:00 2001 From: nickofolas Date: Mon, 2 May 2022 17:49:10 -0500 Subject: [PATCH 06/10] Reduce component usage in sleeve element --- src/PersonObjects/Sleeve/ui/SleeveElem.tsx | 138 ++++++++++----------- 1 file changed, 64 insertions(+), 74 deletions(-) diff --git a/src/PersonObjects/Sleeve/ui/SleeveElem.tsx b/src/PersonObjects/Sleeve/ui/SleeveElem.tsx index 6ec55dea1..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,51 +127,47 @@ 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} - + + + + + + {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} - /> - - - + + + setStatsOpen(false)} sleeve={props.sleeve} /> + setEarningsOpen(false)} sleeve={props.sleeve} /> + setTravelOpen(false)} + sleeve={props.sleeve} + rerender={props.rerender} + /> + setAugmentationsOpen(false)} + sleeve={props.sleeve} + /> + ); } From 73d08973f9d2cb31be4ce6d8f032df4478e3a54e Mon Sep 17 00:00:00 2001 From: nickofolas Date: Mon, 2 May 2022 17:56:02 -0500 Subject: [PATCH 07/10] Render faction money gain conditionally --- src/ui/WorkInProgressRoot.tsx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/ui/WorkInProgressRoot.tsx b/src/ui/WorkInProgressRoot.tsx index db5b9e721..3dcb3c92a 100644 --- a/src/ui/WorkInProgressRoot.tsx +++ b/src/ui/WorkInProgressRoot.tsx @@ -179,11 +179,15 @@ export function WorkInProgressRoot(): React.ReactElement { ), gains: [ - - - () - - , + player.workMoneyGained > 0 ? ( + + + () + + + ) : ( + <> + ), ( From e8a08424af6b296f722a0b7c9d84e2656a357e5f Mon Sep 17 00:00:00 2001 From: nickofolas Date: Mon, 2 May 2022 17:57:50 -0500 Subject: [PATCH 08/10] Fix typo --- src/ui/WorkInProgressRoot.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/WorkInProgressRoot.tsx b/src/ui/WorkInProgressRoot.tsx index 3dcb3c92a..f14cc5ef5 100644 --- a/src/ui/WorkInProgressRoot.tsx +++ b/src/ui/WorkInProgressRoot.tsx @@ -461,7 +461,7 @@ export function WorkInProgressRoot(): React.ReactElement { stopText: "Stop grafting", stopTooltip: ( <> - If you cancel, you work will not be saved, and the money you spent will not be returned + If you cancel, your work will not be saved, and the money you spent will not be returned ), }; From b8cb5f09915e9ae27625fedc34c90ee106c17c49 Mon Sep 17 00:00:00 2001 From: nickofolas Date: Tue, 3 May 2022 15:27:41 -0500 Subject: [PATCH 09/10] Remove elapsed from crime WIP --- src/ui/WorkInProgressRoot.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ui/WorkInProgressRoot.tsx b/src/ui/WorkInProgressRoot.tsx index f14cc5ef5..c10cb152e 100644 --- a/src/ui/WorkInProgressRoot.tsx +++ b/src/ui/WorkInProgressRoot.tsx @@ -392,7 +392,6 @@ export function WorkInProgressRoot(): React.ReactElement { title: `You are attempting to ${player.crimeType}`, progress: { - elapsed: player.timeWorked, remaining: player.timeNeededToCompleteWork - player.timeWorked, percentage: completion, }, From cc5e89208efdaee3f001d86a1dea29b8a372f90f Mon Sep 17 00:00:00 2001 From: nickofolas Date: Wed, 4 May 2022 12:44:48 -0500 Subject: [PATCH 10/10] Convert WIP root to use switch statement --- src/ui/WorkInProgressRoot.tsx | 611 ++++++++++++++++++---------------- 1 file changed, 320 insertions(+), 291 deletions(-) diff --git a/src/ui/WorkInProgressRoot.tsx b/src/ui/WorkInProgressRoot.tsx index c10cb152e..bc266c22d 100644 --- a/src/ui/WorkInProgressRoot.tsx +++ b/src/ui/WorkInProgressRoot.tsx @@ -138,337 +138,366 @@ export function WorkInProgressRoot(): React.ReactElement { let workInfo: IWorkInfo | null; - if (player.workType == CONSTANTS.WorkTypeFaction) { - const faction = Factions[player.currentWorkFactionName]; - if (!faction) { + 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", + + stopText: "Back to Factions", + }; + } + + function cancel(): void { + router.toFaction(faction); + player.finishFactionWork(true); + } + function unfocus(): void { + router.toFaction(faction); + player.stopFocusing(); + } + workInfo = { buttons: { - cancel: () => router.toFactions(), + cancel: cancel, + unfocus: unfocus, }, - title: - `You have not joined ${player.currentWorkFactionName || "(Faction not found)"} at this time,` + - " please try again if you think this should have worked", + title: ( + <> + You are currently {player.currentWorkFactionDescription} for your faction {faction.name} + + ), - stopText: "Back to Factions", + description: ( + <> + Current Faction Reputation: + + ), + gains: [ + player.workMoneyGained > 0 ? ( + + + ( + ) + + + ) : ( + <> + ), + + + ( + ) + + , + ...expGains, + ], + progress: { + elapsed: player.timeWorked, + }, + + stopText: "Stop Faction work", }; + + break; } - function cancel(): void { - router.toFaction(faction); - player.finishFactionWork(true); - } - function unfocus(): void { - router.toFaction(faction); - player.stopFocusing(); + 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; } - workInfo = { - buttons: { - cancel: cancel, - unfocus: unfocus, - }, - title: ( - <> - You are currently {player.currentWorkFactionDescription} for your faction {faction.name} - - ), + 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", - description: ( - <> - Current Faction Reputation: - - ), - gains: [ - player.workMoneyGained > 0 ? ( + 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, - }, + , + + + ( + ) + + , + ...expGains, + ], + progress: { + elapsed: player.timeWorked, + }, - stopText: "Stop Faction work", - }; - } else if (player.className !== "") { - const className = player.className; - function cancel(): void { - player.finishClass(true); - router.toCity(); + 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; } - function unfocus(): void { - router.toCity(); - player.stopFocusing(); - } + 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; - 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"; - } + const position = player.jobs[player.companyName]; - workInfo = { - buttons: { - cancel: cancel, - unfocus: unfocus, - }, - title: ( - <> - You are currently {className} - - ), - - gains: [ - - - () - - , - ...expGains, - ], - progress: { - elapsed: player.timeWorked, - }, - - stopText: stopText, - }; - } else if (player.workType == CONSTANTS.WorkTypeCompany) { - const comp = Companies[player.companyName]; - if (comp == null || !(comp instanceof Company)) { workInfo = { buttons: { - cancel: () => router.toTerminal(), + cancel: cancel, + unfocus: unfocus, }, - title: - `You cannot work for ${player.companyName || "(Company not found)"} at this time,` + - " please try again if you think this should have worked", + title: ( + <> + You are currently working as a {position} at {player.companyName} + + ), - stopText: "Back to Terminal", + 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; } - const companyRep = comp.playerReputation; + case CONSTANTS.WorkTypeCrime: { + const completion = Math.round((player.timeWorked / player.timeNeededToCompleteWork) * 100); - 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.`, - }; - } else 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]; - - 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.", - }; - } else if (player.crimeType !== "") { - const completion = Math.round((player.timeWorked / player.timeNeededToCompleteWork) * 100); - - workInfo = { - buttons: { - cancel: () => { - router.toLocation(Locations[LocationName.Slums]); - player.finishCrime(true); + workInfo = { + buttons: { + cancel: () => { + router.toLocation(Locations[LocationName.Slums]); + player.finishCrime(true); + }, }, - }, - title: `You are attempting to ${player.crimeType}`, + title: `You are attempting to ${player.crimeType}`, - progress: { - remaining: player.timeNeededToCompleteWork - player.timeWorked, - percentage: completion, - }, + progress: { + remaining: player.timeNeededToCompleteWork - player.timeWorked, + percentage: completion, + }, - stopText: "Cancel crime", - }; - } else if (player.createProgramName !== "") { - function cancel(): void { - player.finishCreateProgramWork(true); - router.toTerminal(); - } - function unfocus(): void { - router.toTerminal(); - player.stopFocusing(); + stopText: "Cancel crime", + }; + + break; } - const completion = (player.timeWorkedCreateProgram / player.timeNeededToCompleteWork) * 100; + case CONSTANTS.WorkTypeCreateProgram: { + function cancel(): void { + player.finishCreateProgramWork(true); + router.toTerminal(); + } + function unfocus(): void { + router.toTerminal(); + player.stopFocusing(); + } - workInfo = { - buttons: { - cancel: cancel, - unfocus: unfocus, - }, - title: ( - <> - You are currently working on coding {player.createProgramName} - - ), + const completion = (player.timeWorkedCreateProgram / player.timeNeededToCompleteWork) * 100; - progress: { - elapsed: player.timeWorked, - percentage: completion, - }, + workInfo = { + buttons: { + cancel: cancel, + unfocus: unfocus, + }, + title: ( + <> + You are currently working on coding {player.createProgramName} + + ), - stopText: "Stop creating program", - stopTooltip: "Your work will be saved and you can return to complete the program later.", - }; - } else if (player.graftAugmentationName !== "") { - function cancel(): void { - player.finishGraftAugmentationWork(true); - router.toTerminal(); - } - function unfocus(): void { - router.toTerminal(); - player.stopFocusing(); + 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; } - const completion = (player.timeWorkedGraftAugmentation / player.timeNeededToCompleteWork) * 100; + case CONSTANTS.WorkTypeGraftAugmentation: { + function cancel(): void { + player.finishGraftAugmentationWork(true); + router.toTerminal(); + } + function unfocus(): void { + router.toTerminal(); + player.stopFocusing(); + } - workInfo = { - buttons: { - cancel: cancel, - unfocus: unfocus, - }, - title: ( - <> - You are currently working on grafting {player.graftAugmentationName} - - ), + const completion = (player.timeWorkedGraftAugmentation / player.timeNeededToCompleteWork) * 100; - progress: { - elapsed: player.timeWorked, - percentage: completion, - }, + workInfo = { + buttons: { + cancel: cancel, + unfocus: unfocus, + }, + title: ( + <> + You are currently working on grafting {player.graftAugmentationName} + + ), - stopText: "Stop grafting", - stopTooltip: ( - <> - If you cancel, your work will not be saved, and the money you spent will not be returned - - ), - }; - } else if (!player.workType) { - router.toTerminal(); - workInfo = null; - } else { - workInfo = null; + 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 (workInfo === null) {