mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-30 03:23:48 +01:00
Merge branch 'dev' of github.com:danielyxie/bitburner into fix/nfg-level-application
This commit is contained in:
commit
6d9dcfe81f
4
dist/main.bundle.js
vendored
4
dist/main.bundle.js
vendored
File diff suppressed because one or more lines are too long
2
dist/main.bundle.js.map
vendored
2
dist/main.bundle.js.map
vendored
File diff suppressed because one or more lines are too long
42
dist/vendor.bundle.js
vendored
42
dist/vendor.bundle.js
vendored
File diff suppressed because one or more lines are too long
2
dist/vendor.bundle.js.map
vendored
2
dist/vendor.bundle.js.map
vendored
File diff suppressed because one or more lines are too long
@ -24,6 +24,7 @@ import { IMap } from "../types";
|
||||
import * as data from "./AchievementData.json";
|
||||
import { FactionNames } from "../Faction/data/FactionNames";
|
||||
import { BlackOperationNames } from "../Bladeburner/data/BlackOperationNames";
|
||||
import { ClassType } from "../utils/WorkType";
|
||||
|
||||
// Unable to correctly cast the JSON data into AchievementDataJson type otherwise...
|
||||
const achievementData = (<AchievementDataJson>(<unknown>data)).achievements;
|
||||
@ -391,12 +392,9 @@ export const achievements: IMap<Achievement> = {
|
||||
...achievementData["WORKOUT"],
|
||||
Icon: "WORKOUT",
|
||||
Condition: () =>
|
||||
[
|
||||
CONSTANTS.ClassGymStrength,
|
||||
CONSTANTS.ClassGymDefense,
|
||||
CONSTANTS.ClassGymDexterity,
|
||||
CONSTANTS.ClassGymAgility,
|
||||
].includes(Player.className),
|
||||
[ClassType.GymStrength, ClassType.GymDefense, ClassType.GymDexterity, ClassType.GymAgility].includes(
|
||||
Player.className,
|
||||
),
|
||||
},
|
||||
TOR: {
|
||||
...achievementData["TOR"],
|
||||
|
@ -63,26 +63,6 @@ export const CONSTANTS: {
|
||||
GameCyclesPerQuarterHour: number;
|
||||
MillisecondsPerFiveMinutes: number;
|
||||
GameCyclesPerFiveMinutes: number;
|
||||
FactionWorkHacking: string;
|
||||
FactionWorkField: string;
|
||||
FactionWorkSecurity: string;
|
||||
WorkTypeCompany: string;
|
||||
WorkTypeCompanyPartTime: string;
|
||||
WorkTypeFaction: string;
|
||||
WorkTypeCreateProgram: string;
|
||||
WorkTypeStudyClass: string;
|
||||
WorkTypeCrime: string;
|
||||
WorkTypeGraftAugmentation: string;
|
||||
ClassStudyComputerScience: string;
|
||||
ClassDataStructures: string;
|
||||
ClassNetworks: string;
|
||||
ClassAlgorithms: string;
|
||||
ClassManagement: string;
|
||||
ClassLeadership: string;
|
||||
ClassGymStrength: string;
|
||||
ClassGymDefense: string;
|
||||
ClassGymDexterity: string;
|
||||
ClassGymAgility: string;
|
||||
ClassDataStructuresBaseCost: number;
|
||||
ClassNetworksBaseCost: number;
|
||||
ClassAlgorithmsBaseCost: number;
|
||||
@ -95,18 +75,6 @@ export const CONSTANTS: {
|
||||
ClassAlgorithmsBaseExp: number;
|
||||
ClassManagementBaseExp: number;
|
||||
ClassLeadershipBaseExp: number;
|
||||
CrimeShoplift: string;
|
||||
CrimeRobStore: string;
|
||||
CrimeMug: string;
|
||||
CrimeLarceny: string;
|
||||
CrimeDrugs: string;
|
||||
CrimeBondForgery: string;
|
||||
CrimeTraffickArms: string;
|
||||
CrimeHomicide: string;
|
||||
CrimeGrandTheftAuto: string;
|
||||
CrimeKidnap: string;
|
||||
CrimeAssassination: string;
|
||||
CrimeHeist: string;
|
||||
CodingContractBaseFactionRepGain: number;
|
||||
CodingContractBaseCompanyRepGain: number;
|
||||
CodingContractBaseMoneyGain: number;
|
||||
@ -223,28 +191,6 @@ export const CONSTANTS: {
|
||||
|
||||
// Player Work & Action
|
||||
BaseFocusBonus: 0.8,
|
||||
FactionWorkHacking: "Faction Hacking Work",
|
||||
FactionWorkField: "Faction Field Work",
|
||||
FactionWorkSecurity: "Faction Security Work",
|
||||
|
||||
WorkTypeCompany: "Working for Company",
|
||||
WorkTypeCompanyPartTime: "Working for Company part-time",
|
||||
WorkTypeFaction: "Working for Faction",
|
||||
WorkTypeCreateProgram: "Working on Create a Program",
|
||||
WorkTypeStudyClass: "Studying or Taking a class at university",
|
||||
WorkTypeCrime: "Committing a crime",
|
||||
WorkTypeGraftAugmentation: "Grafting an Augmentation",
|
||||
|
||||
ClassStudyComputerScience: "studying Computer Science",
|
||||
ClassDataStructures: "taking a Data Structures course",
|
||||
ClassNetworks: "taking a Networks course",
|
||||
ClassAlgorithms: "taking an Algorithms course",
|
||||
ClassManagement: "taking a Management course",
|
||||
ClassLeadership: "taking a Leadership course",
|
||||
ClassGymStrength: "training your strength at a gym",
|
||||
ClassGymDefense: "training your defense at a gym",
|
||||
ClassGymDexterity: "training your dexterity at a gym",
|
||||
ClassGymAgility: "training your agility at a gym",
|
||||
|
||||
ClassDataStructuresBaseCost: 40,
|
||||
ClassNetworksBaseCost: 80,
|
||||
@ -260,19 +206,6 @@ export const CONSTANTS: {
|
||||
ClassManagementBaseExp: 2,
|
||||
ClassLeadershipBaseExp: 4,
|
||||
|
||||
CrimeShoplift: "shoplift",
|
||||
CrimeRobStore: "rob a store",
|
||||
CrimeMug: "mug someone",
|
||||
CrimeLarceny: "commit larceny",
|
||||
CrimeDrugs: "deal drugs",
|
||||
CrimeBondForgery: "forge corporate bonds",
|
||||
CrimeTraffickArms: "traffick illegal arms",
|
||||
CrimeHomicide: "commit homicide",
|
||||
CrimeGrandTheftAuto: "commit grand theft auto",
|
||||
CrimeKidnap: "kidnap someone for ransom",
|
||||
CrimeAssassination: "assassinate a high-profile target",
|
||||
CrimeHeist: "pull off the ultimate heist",
|
||||
|
||||
// Coding Contract
|
||||
// TODO: Move this into Coding contract implementation?
|
||||
CodingContractBaseFactionRepGain: 2500,
|
||||
|
@ -3,6 +3,7 @@ import { IPlayer } from "../PersonObjects/IPlayer";
|
||||
import { IPlayerOrSleeve } from "../PersonObjects/IPlayerOrSleeve";
|
||||
import { IRouter } from "../ui/Router";
|
||||
import { WorkerScript } from "../Netscript/WorkerScript";
|
||||
import { CrimeType } from "../utils/WorkType";
|
||||
|
||||
interface IConstructorParams {
|
||||
hacking_success_weight?: number;
|
||||
@ -42,7 +43,7 @@ export class Crime {
|
||||
time = 0;
|
||||
|
||||
// Corresponding type in CONSTANTS. Contains a description for the crime activity
|
||||
type = "";
|
||||
type: CrimeType;
|
||||
|
||||
// Weighting factors that determine how stats affect the success rate of this crime
|
||||
hacking_success_weight = 0;
|
||||
@ -61,7 +62,15 @@ export class Crime {
|
||||
charisma_exp = 0;
|
||||
intelligence_exp = 0;
|
||||
|
||||
constructor(name = "", type = "", time = 0, money = 0, difficulty = 0, karma = 0, params: IConstructorParams = {}) {
|
||||
constructor(
|
||||
name = "",
|
||||
type: CrimeType,
|
||||
time = 0,
|
||||
money = 0,
|
||||
difficulty = 0,
|
||||
karma = 0,
|
||||
params: IConstructorParams = {},
|
||||
) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.time = time;
|
||||
|
@ -9,7 +9,7 @@ export function determineCrimeSuccess(p: IPlayer, type: string): boolean {
|
||||
let found = false;
|
||||
for (const i of Object.keys(Crimes)) {
|
||||
const crime = Crimes[i];
|
||||
if (crime.type == type) {
|
||||
if (crime.type === type) {
|
||||
chance = crime.successRate(p);
|
||||
found = true;
|
||||
break;
|
||||
|
@ -3,8 +3,10 @@ import { Crime } from "./Crime";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
import { IMap } from "../types";
|
||||
|
||||
import { CrimeType } from "../utils/WorkType";
|
||||
|
||||
export const Crimes: IMap<Crime> = {
|
||||
Shoplift: new Crime("Shoplift", CONSTANTS.CrimeShoplift, 2e3, 15e3, 1 / 20, 0.1, {
|
||||
Shoplift: new Crime("Shoplift", CrimeType.Shoplift, 2e3, 15e3, 1 / 20, 0.1, {
|
||||
dexterity_success_weight: 1,
|
||||
agility_success_weight: 1,
|
||||
|
||||
@ -12,7 +14,7 @@ export const Crimes: IMap<Crime> = {
|
||||
agility_exp: 2,
|
||||
}),
|
||||
|
||||
RobStore: new Crime("Rob Store", CONSTANTS.CrimeRobStore, 60e3, 400e3, 1 / 5, 0.5, {
|
||||
RobStore: new Crime("Rob Store", CrimeType.RobStore, 60e3, 400e3, 1 / 5, 0.5, {
|
||||
hacking_exp: 30,
|
||||
dexterity_exp: 45,
|
||||
agility_exp: 45,
|
||||
@ -24,7 +26,7 @@ export const Crimes: IMap<Crime> = {
|
||||
intelligence_exp: 7.5 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
}),
|
||||
|
||||
Mug: new Crime("Mug", CONSTANTS.CrimeMug, 4e3, 36e3, 1 / 5, 0.25, {
|
||||
Mug: new Crime("Mug", CrimeType.Mug, 4e3, 36e3, 1 / 5, 0.25, {
|
||||
strength_exp: 3,
|
||||
defense_exp: 3,
|
||||
dexterity_exp: 3,
|
||||
@ -36,7 +38,7 @@ export const Crimes: IMap<Crime> = {
|
||||
agility_success_weight: 0.5,
|
||||
}),
|
||||
|
||||
Larceny: new Crime("Larceny", CONSTANTS.CrimeLarceny, 90e3, 800e3, 1 / 3, 1.5, {
|
||||
Larceny: new Crime("Larceny", CrimeType.Larceny, 90e3, 800e3, 1 / 3, 1.5, {
|
||||
hacking_exp: 45,
|
||||
dexterity_exp: 60,
|
||||
agility_exp: 60,
|
||||
@ -48,7 +50,7 @@ export const Crimes: IMap<Crime> = {
|
||||
intelligence_exp: 15 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
}),
|
||||
|
||||
DealDrugs: new Crime("Deal Drugs", CONSTANTS.CrimeDrugs, 10e3, 120e3, 1, 0.5, {
|
||||
DealDrugs: new Crime("Deal Drugs", CrimeType.Drugs, 10e3, 120e3, 1, 0.5, {
|
||||
dexterity_exp: 5,
|
||||
agility_exp: 5,
|
||||
charisma_exp: 10,
|
||||
@ -58,7 +60,7 @@ export const Crimes: IMap<Crime> = {
|
||||
agility_success_weight: 1,
|
||||
}),
|
||||
|
||||
BondForgery: new Crime("Bond Forgery", CONSTANTS.CrimeBondForgery, 300e3, 4.5e6, 1 / 2, 0.1, {
|
||||
BondForgery: new Crime("Bond Forgery", CrimeType.BondForgery, 300e3, 4.5e6, 1 / 2, 0.1, {
|
||||
hacking_exp: 100,
|
||||
dexterity_exp: 150,
|
||||
charisma_exp: 15,
|
||||
@ -69,7 +71,7 @@ export const Crimes: IMap<Crime> = {
|
||||
intelligence_exp: 60 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
}),
|
||||
|
||||
TraffickArms: new Crime("Traffick Arms", CONSTANTS.CrimeTraffickArms, 40e3, 600e3, 2, 1, {
|
||||
TraffickArms: new Crime("Traffick Arms", CrimeType.TraffickArms, 40e3, 600e3, 2, 1, {
|
||||
strength_exp: 20,
|
||||
defense_exp: 20,
|
||||
dexterity_exp: 20,
|
||||
@ -83,7 +85,7 @@ export const Crimes: IMap<Crime> = {
|
||||
agility_success_weight: 1,
|
||||
}),
|
||||
|
||||
Homicide: new Crime("Homicide", CONSTANTS.CrimeHomicide, 3e3, 45e3, 1, 3, {
|
||||
Homicide: new Crime("Homicide", CrimeType.Homicide, 3e3, 45e3, 1, 3, {
|
||||
strength_exp: 2,
|
||||
defense_exp: 2,
|
||||
dexterity_exp: 2,
|
||||
@ -97,7 +99,7 @@ export const Crimes: IMap<Crime> = {
|
||||
kills: 1,
|
||||
}),
|
||||
|
||||
GrandTheftAuto: new Crime("Grand Theft Auto", CONSTANTS.CrimeGrandTheftAuto, 80e3, 1.6e6, 8, 5, {
|
||||
GrandTheftAuto: new Crime("Grand Theft Auto", CrimeType.GrandTheftAuto, 80e3, 1.6e6, 8, 5, {
|
||||
strength_exp: 20,
|
||||
defense_exp: 20,
|
||||
dexterity_exp: 20,
|
||||
@ -113,7 +115,7 @@ export const Crimes: IMap<Crime> = {
|
||||
intelligence_exp: 16 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
}),
|
||||
|
||||
Kidnap: new Crime("Kidnap", CONSTANTS.CrimeKidnap, 120e3, 3.6e6, 5, 6, {
|
||||
Kidnap: new Crime("Kidnap", CrimeType.Kidnap, 120e3, 3.6e6, 5, 6, {
|
||||
strength_exp: 80,
|
||||
defense_exp: 80,
|
||||
dexterity_exp: 80,
|
||||
@ -128,7 +130,7 @@ export const Crimes: IMap<Crime> = {
|
||||
intelligence_exp: 26 * CONSTANTS.IntelligenceCrimeBaseExpGain,
|
||||
}),
|
||||
|
||||
Assassination: new Crime("Assassination", CONSTANTS.CrimeAssassination, 300e3, 12e6, 8, 10, {
|
||||
Assassination: new Crime("Assassination", CrimeType.Assassination, 300e3, 12e6, 8, 10, {
|
||||
strength_exp: 300,
|
||||
defense_exp: 300,
|
||||
dexterity_exp: 300,
|
||||
@ -143,7 +145,7 @@ export const Crimes: IMap<Crime> = {
|
||||
kills: 1,
|
||||
}),
|
||||
|
||||
Heist: new Crime("Heist", CONSTANTS.CrimeHeist, 600e3, 120e6, 18, 15, {
|
||||
Heist: new Crime("Heist", CrimeType.Heist, 600e3, 120e6, 18, 15, {
|
||||
hacking_exp: 450,
|
||||
strength_exp: 450,
|
||||
defense_exp: 450,
|
||||
|
@ -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 ? (
|
||||
<TimerProgress variant="determinate" value={v} color="primary" />
|
||||
<ProgressBar variant="determinate" value={v} color="primary" />
|
||||
) : (
|
||||
<Paper sx={{ p: 1, mb: 1 }}>
|
||||
<TimerProgress variant="determinate" value={v} color="primary" />
|
||||
<ProgressBar variant="determinate" value={v} color="primary" />
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import { Money } from "../../ui/React/Money";
|
||||
import { IRouter } from "../../ui/Router";
|
||||
import { serverMetadata } from "../../Server/data/servers";
|
||||
import { Box } from "@mui/material";
|
||||
import { ClassType } from "../../utils/WorkType";
|
||||
|
||||
type IProps = {
|
||||
loc: Location;
|
||||
@ -33,7 +34,7 @@ export function GymLocation(props: IProps): React.ReactElement {
|
||||
return props.loc.costMult * discount;
|
||||
}
|
||||
|
||||
function train(stat: string): void {
|
||||
function train(stat: ClassType): void {
|
||||
const loc = props.loc;
|
||||
props.p.startClass(calculateCost(), loc.expMult, stat);
|
||||
props.p.startFocusing();
|
||||
@ -41,19 +42,19 @@ export function GymLocation(props: IProps): React.ReactElement {
|
||||
}
|
||||
|
||||
function trainStrength(): void {
|
||||
train(CONSTANTS.ClassGymStrength);
|
||||
train(ClassType.GymStrength);
|
||||
}
|
||||
|
||||
function trainDefense(): void {
|
||||
train(CONSTANTS.ClassGymDefense);
|
||||
train(ClassType.GymDefense);
|
||||
}
|
||||
|
||||
function trainDexterity(): void {
|
||||
train(CONSTANTS.ClassGymDexterity);
|
||||
train(ClassType.GymDexterity);
|
||||
}
|
||||
|
||||
function trainAgility(): void {
|
||||
train(CONSTANTS.ClassGymAgility);
|
||||
train(ClassType.GymAgility);
|
||||
}
|
||||
|
||||
const cost = CONSTANTS.ClassGymBaseCost * calculateCost();
|
||||
|
@ -17,6 +17,8 @@ import { Money } from "../../ui/React/Money";
|
||||
import { use } from "../../ui/Context";
|
||||
import { Box } from "@mui/material";
|
||||
|
||||
import { ClassType } from "../../utils/WorkType";
|
||||
|
||||
type IProps = {
|
||||
loc: Location;
|
||||
};
|
||||
@ -32,7 +34,7 @@ export function UniversityLocation(props: IProps): React.ReactElement {
|
||||
return props.loc.costMult * discount;
|
||||
}
|
||||
|
||||
function take(stat: string): void {
|
||||
function take(stat: ClassType): void {
|
||||
const loc = props.loc;
|
||||
player.startClass(calculateCost(), loc.expMult, stat);
|
||||
player.startFocusing();
|
||||
@ -40,27 +42,27 @@ export function UniversityLocation(props: IProps): React.ReactElement {
|
||||
}
|
||||
|
||||
function study(): void {
|
||||
take(CONSTANTS.ClassStudyComputerScience);
|
||||
take(ClassType.StudyComputerScience);
|
||||
}
|
||||
|
||||
function dataStructures(): void {
|
||||
take(CONSTANTS.ClassDataStructures);
|
||||
take(ClassType.DataStructures);
|
||||
}
|
||||
|
||||
function networks(): void {
|
||||
take(CONSTANTS.ClassNetworks);
|
||||
take(ClassType.Networks);
|
||||
}
|
||||
|
||||
function algorithms(): void {
|
||||
take(CONSTANTS.ClassAlgorithms);
|
||||
take(ClassType.Algorithms);
|
||||
}
|
||||
|
||||
function management(): void {
|
||||
take(CONSTANTS.ClassManagement);
|
||||
take(ClassType.Management);
|
||||
}
|
||||
|
||||
function leadership(): void {
|
||||
take(CONSTANTS.ClassLeadership);
|
||||
take(ClassType.Leadership);
|
||||
}
|
||||
|
||||
const costMult: number = calculateCost();
|
||||
|
@ -49,6 +49,7 @@ import { InternalAPI, NetscriptContext } from "src/Netscript/APIWrapper";
|
||||
import { BlackOperationNames } from "../Bladeburner/data/BlackOperationNames";
|
||||
import { enterBitNode } from "../RedPill";
|
||||
import { FactionNames } from "../Faction/data/FactionNames";
|
||||
import { ClassType, WorkType } from "../utils/WorkType";
|
||||
|
||||
export function NetscriptSingularity(player: IPlayer, workerScript: WorkerScript): InternalAPI<ISingularity> {
|
||||
const getAugmentation = function (_ctx: NetscriptContext, name: string): Augmentation {
|
||||
@ -298,25 +299,25 @@ export function NetscriptSingularity(player: IPlayer, workerScript: WorkerScript
|
||||
return false;
|
||||
}
|
||||
|
||||
let task = "";
|
||||
let task: ClassType;
|
||||
switch (className.toLowerCase()) {
|
||||
case "Study Computer Science".toLowerCase():
|
||||
task = CONSTANTS.ClassStudyComputerScience;
|
||||
task = ClassType.StudyComputerScience;
|
||||
break;
|
||||
case "Data Structures".toLowerCase():
|
||||
task = CONSTANTS.ClassDataStructures;
|
||||
task = ClassType.DataStructures;
|
||||
break;
|
||||
case "Networks".toLowerCase():
|
||||
task = CONSTANTS.ClassNetworks;
|
||||
task = ClassType.Networks;
|
||||
break;
|
||||
case "Algorithms".toLowerCase():
|
||||
task = CONSTANTS.ClassAlgorithms;
|
||||
task = ClassType.Algorithms;
|
||||
break;
|
||||
case "Management".toLowerCase():
|
||||
task = CONSTANTS.ClassManagement;
|
||||
task = ClassType.Management;
|
||||
break;
|
||||
case "Leadership".toLowerCase():
|
||||
task = CONSTANTS.ClassLeadership;
|
||||
task = ClassType.Leadership;
|
||||
break;
|
||||
default:
|
||||
_ctx.log(() => `Invalid class name: ${className}.`);
|
||||
@ -415,19 +416,19 @@ export function NetscriptSingularity(player: IPlayer, workerScript: WorkerScript
|
||||
switch (stat.toLowerCase()) {
|
||||
case "strength".toLowerCase():
|
||||
case "str".toLowerCase():
|
||||
player.startClass(costMult, expMult, CONSTANTS.ClassGymStrength);
|
||||
player.startClass(costMult, expMult, ClassType.GymStrength);
|
||||
break;
|
||||
case "defense".toLowerCase():
|
||||
case "def".toLowerCase():
|
||||
player.startClass(costMult, expMult, CONSTANTS.ClassGymDefense);
|
||||
player.startClass(costMult, expMult, ClassType.GymDefense);
|
||||
break;
|
||||
case "dexterity".toLowerCase():
|
||||
case "dex".toLowerCase():
|
||||
player.startClass(costMult, expMult, CONSTANTS.ClassGymDexterity);
|
||||
player.startClass(costMult, expMult, ClassType.GymDexterity);
|
||||
break;
|
||||
case "agility".toLowerCase():
|
||||
case "agi".toLowerCase():
|
||||
player.startClass(costMult, expMult, CONSTANTS.ClassGymAgility);
|
||||
player.startClass(costMult, expMult, ClassType.GymAgility);
|
||||
break;
|
||||
default:
|
||||
_ctx.log(() => `Invalid stat: ${stat}.`);
|
||||
@ -650,11 +651,11 @@ export function NetscriptSingularity(player: IPlayer, workerScript: WorkerScript
|
||||
}
|
||||
if (
|
||||
!(
|
||||
player.workType == CONSTANTS.WorkTypeFaction ||
|
||||
player.workType == CONSTANTS.WorkTypeCompany ||
|
||||
player.workType == CONSTANTS.WorkTypeCompanyPartTime ||
|
||||
player.workType == CONSTANTS.WorkTypeCreateProgram ||
|
||||
player.workType == CONSTANTS.WorkTypeStudyClass
|
||||
player.workType === WorkType.Faction ||
|
||||
player.workType === WorkType.Company ||
|
||||
player.workType === WorkType.CompanyPartTime ||
|
||||
player.workType === WorkType.CreateProgram ||
|
||||
player.workType === WorkType.StudyClass
|
||||
)
|
||||
) {
|
||||
throw _ctx.helper.makeRuntimeErrorMsg("Cannot change focus for current job");
|
||||
|
@ -30,6 +30,7 @@ import { WorkerScript } from "../Netscript/WorkerScript";
|
||||
import { HacknetServer } from "../Hacknet/HacknetServer";
|
||||
import { ISkillProgress } from "./formulas/skill";
|
||||
import { PlayerAchievement } from "../Achievements/Achievements";
|
||||
import { WorkType, ClassType, CrimeType } from "../utils/WorkType";
|
||||
|
||||
export interface IPlayer {
|
||||
// Class members
|
||||
@ -130,14 +131,14 @@ export interface IPlayer {
|
||||
timeWorkedCreateProgram: number;
|
||||
graftAugmentationName: string;
|
||||
timeWorkedGraftAugmentation: number;
|
||||
crimeType: string;
|
||||
crimeType: CrimeType;
|
||||
committingCrimeThruSingFn: boolean;
|
||||
singFnCrimeWorkerScript: WorkerScript | null;
|
||||
timeNeededToCompleteWork: number;
|
||||
focus: boolean;
|
||||
className: string;
|
||||
className: ClassType;
|
||||
currentWorkFactionName: string;
|
||||
workType: string;
|
||||
workType: WorkType;
|
||||
workCostMult: number;
|
||||
workExpMult: number;
|
||||
currentWorkFactionDescription: string;
|
||||
@ -219,11 +220,11 @@ export interface IPlayer {
|
||||
singularityStopWork(): string;
|
||||
startBladeburner(p: any): void;
|
||||
startFactionWork(faction: Faction): void;
|
||||
startClass(costMult: number, expMult: number, className: string): void;
|
||||
startClass(costMult: number, expMult: number, className: ClassType): void;
|
||||
startCorporation(corpName: string, additionalShares?: number): void;
|
||||
startCrime(
|
||||
router: IRouter,
|
||||
crimeType: string,
|
||||
crimeType: CrimeType,
|
||||
hackExp: number,
|
||||
strExp: number,
|
||||
defExp: number,
|
||||
@ -269,7 +270,7 @@ export interface IPlayer {
|
||||
prestigeSourceFile(): void;
|
||||
calculateSkill(exp: number, mult?: number): number;
|
||||
calculateSkillProgress(exp: number, mult?: number): ISkillProgress;
|
||||
resetWorkStatus(generalType?: string, group?: string, workType?: string): void;
|
||||
resetWorkStatus(generalType?: WorkType, group?: string, workType?: string): void;
|
||||
getWorkHackExpGain(): number;
|
||||
getWorkStrExpGain(): number;
|
||||
getWorkDefExpGain(): number;
|
||||
|
@ -38,6 +38,7 @@ import { PlayerAchievement } from "../../Achievements/Achievements";
|
||||
import { cyrb53 } from "../../utils/StringHelperFunctions";
|
||||
import { getRandomInt } from "../../utils/helpers/getRandomInt";
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { WorkType, ClassType, CrimeType, PlayerFactionWorkType } from "../../utils/WorkType";
|
||||
|
||||
export class PlayerObject implements IPlayer {
|
||||
// Class members
|
||||
@ -135,19 +136,19 @@ export class PlayerObject implements IPlayer {
|
||||
bladeburner_success_chance_mult: number;
|
||||
|
||||
createProgramReqLvl: number;
|
||||
factionWorkType: string;
|
||||
factionWorkType: PlayerFactionWorkType;
|
||||
createProgramName: string;
|
||||
timeWorkedCreateProgram: number;
|
||||
graftAugmentationName: string;
|
||||
timeWorkedGraftAugmentation: number;
|
||||
crimeType: string;
|
||||
crimeType: CrimeType;
|
||||
committingCrimeThruSingFn: boolean;
|
||||
singFnCrimeWorkerScript: WorkerScript | null;
|
||||
timeNeededToCompleteWork: number;
|
||||
focus: boolean;
|
||||
className: string;
|
||||
className: ClassType;
|
||||
currentWorkFactionName: string;
|
||||
workType: string;
|
||||
workType: WorkType;
|
||||
workCostMult: number;
|
||||
workExpMult: number;
|
||||
currentWorkFactionDescription: string;
|
||||
@ -229,11 +230,11 @@ export class PlayerObject implements IPlayer {
|
||||
singularityStopWork: () => string;
|
||||
startBladeburner: (p: any) => void;
|
||||
startFactionWork: (faction: Faction) => void;
|
||||
startClass: (costMult: number, expMult: number, className: string) => void;
|
||||
startClass: (costMult: number, expMult: number, className: ClassType) => void;
|
||||
startCorporation: (corpName: string, additionalShares?: number) => void;
|
||||
startCrime: (
|
||||
router: IRouter,
|
||||
crimeType: string,
|
||||
crimeType: CrimeType,
|
||||
hackExp: number,
|
||||
strExp: number,
|
||||
defExp: number,
|
||||
@ -280,7 +281,7 @@ export class PlayerObject implements IPlayer {
|
||||
prestigeSourceFile: () => void;
|
||||
calculateSkill: (exp: number, mult?: number) => number;
|
||||
calculateSkillProgress: (exp: number, mult?: number) => ISkillProgress;
|
||||
resetWorkStatus: (generalType?: string, group?: string, workType?: string) => void;
|
||||
resetWorkStatus: (generalType?: WorkType, group?: string, workType?: string) => void;
|
||||
getWorkHackExpGain: () => number;
|
||||
getWorkStrExpGain: () => number;
|
||||
getWorkDefExpGain: () => number;
|
||||
@ -398,7 +399,7 @@ export class PlayerObject implements IPlayer {
|
||||
//Flags/variables for working (Company, Faction, Creating Program, Taking Class)
|
||||
this.isWorking = false;
|
||||
this.focus = false;
|
||||
this.workType = "";
|
||||
this.workType = WorkType.None;
|
||||
this.workCostMult = 1;
|
||||
this.workExpMult = 1;
|
||||
|
||||
@ -430,9 +431,9 @@ export class PlayerObject implements IPlayer {
|
||||
this.graftAugmentationName = "";
|
||||
this.timeWorkedGraftAugmentation = 0;
|
||||
|
||||
this.className = "";
|
||||
this.className = ClassType.None;
|
||||
|
||||
this.crimeType = "";
|
||||
this.crimeType = CrimeType.None;
|
||||
|
||||
this.timeWorked = 0; //in m;
|
||||
this.timeWorkedCreateProgram = 0;
|
||||
@ -618,7 +619,7 @@ export class PlayerObject implements IPlayer {
|
||||
this.getUpgradeHomeRamCost = serverMethods.getUpgradeHomeRamCost;
|
||||
this.getUpgradeHomeCoresCost = serverMethods.getUpgradeHomeCoresCost;
|
||||
this.createHacknetServer = serverMethods.createHacknetServer;
|
||||
this.factionWorkType = "";
|
||||
this.factionWorkType = PlayerFactionWorkType.None;
|
||||
this.committingCrimeThruSingFn = false;
|
||||
this.singFnCrimeWorkerScript = null;
|
||||
|
||||
|
@ -66,6 +66,8 @@ import { achievements } from "../../Achievements/Achievements";
|
||||
import { FactionNames } from "../../Faction/data/FactionNames";
|
||||
import { graftingIntBonus } from "../Grafting/GraftingHelpers";
|
||||
|
||||
import { WorkType, PlayerFactionWorkType, ClassType, CrimeType } from "../../utils/WorkType";
|
||||
|
||||
export function init(this: IPlayer): void {
|
||||
/* Initialize Player's home computer */
|
||||
const t_homeComp = safetlyCreateUniqueServer({
|
||||
@ -140,8 +142,8 @@ export function prestigeAugmentation(this: PlayerObject): void {
|
||||
this.currentWorkFactionName = "";
|
||||
this.currentWorkFactionDescription = "";
|
||||
this.createProgramName = "";
|
||||
this.className = "";
|
||||
this.crimeType = "";
|
||||
this.className = ClassType.None;
|
||||
this.crimeType = CrimeType.None;
|
||||
|
||||
this.workHackExpGainRate = 0;
|
||||
this.workStrExpGainRate = 0;
|
||||
@ -500,9 +502,8 @@ export function queryStatFromString(this: IPlayer, str: string): number {
|
||||
}
|
||||
|
||||
/******* Working functions *******/
|
||||
export function resetWorkStatus(this: IPlayer, generalType?: string, group?: string, workType?: string): void {
|
||||
if (this.workType !== CONSTANTS.WorkTypeFaction && generalType === this.workType && group === this.companyName)
|
||||
return;
|
||||
export function resetWorkStatus(this: IPlayer, generalType?: WorkType, group?: string, workType?: string): void {
|
||||
if (this.workType !== WorkType.Faction && generalType === this.workType && group === this.companyName) return;
|
||||
if (generalType === this.workType && group === this.currentWorkFactionName && workType === this.factionWorkType)
|
||||
return;
|
||||
if (this.isWorking) this.singularityStopWork();
|
||||
@ -533,8 +534,8 @@ export function resetWorkStatus(this: IPlayer, generalType?: string, group?: str
|
||||
this.currentWorkFactionDescription = "";
|
||||
this.createProgramName = "";
|
||||
this.graftAugmentationName = "";
|
||||
this.className = "";
|
||||
this.workType = "";
|
||||
this.className = ClassType.None;
|
||||
this.workType = WorkType.None;
|
||||
}
|
||||
|
||||
export function processWorkEarnings(this: IPlayer, numCycles = 1): void {
|
||||
@ -569,10 +570,10 @@ export function processWorkEarnings(this: IPlayer, numCycles = 1): void {
|
||||
|
||||
/* Working for Company */
|
||||
export function startWork(this: IPlayer, companyName: string): void {
|
||||
this.resetWorkStatus(CONSTANTS.WorkTypeCompany, companyName);
|
||||
this.resetWorkStatus(WorkType.Company, companyName);
|
||||
this.isWorking = true;
|
||||
this.companyName = companyName;
|
||||
this.workType = CONSTANTS.WorkTypeCompany;
|
||||
this.workType = WorkType.Company;
|
||||
|
||||
this.workHackExpGainRate = this.getWorkHackExpGain();
|
||||
this.workStrExpGainRate = this.getWorkStrExpGain();
|
||||
@ -589,27 +590,27 @@ export function startWork(this: IPlayer, companyName: string): void {
|
||||
export function process(this: IPlayer, router: IRouter, numCycles = 1): void {
|
||||
// Working
|
||||
if (this.isWorking) {
|
||||
if (this.workType == CONSTANTS.WorkTypeFaction) {
|
||||
if (this.workType === WorkType.Faction) {
|
||||
if (this.workForFaction(numCycles)) {
|
||||
router.toFaction(Factions[this.currentWorkFactionName]);
|
||||
}
|
||||
} else if (this.workType == CONSTANTS.WorkTypeCreateProgram) {
|
||||
} else if (this.workType === WorkType.CreateProgram) {
|
||||
if (this.createProgramWork(numCycles)) {
|
||||
router.toTerminal();
|
||||
}
|
||||
} else if (this.workType == CONSTANTS.WorkTypeStudyClass) {
|
||||
} else if (this.workType === WorkType.StudyClass) {
|
||||
if (this.takeClass(numCycles)) {
|
||||
router.toCity();
|
||||
}
|
||||
} else if (this.workType == CONSTANTS.WorkTypeCrime) {
|
||||
} else if (this.workType === WorkType.Crime) {
|
||||
if (this.commitCrime(numCycles)) {
|
||||
router.toLocation(Locations[LocationName.Slums]);
|
||||
}
|
||||
} else if (this.workType == CONSTANTS.WorkTypeCompanyPartTime) {
|
||||
} else if (this.workType === WorkType.CompanyPartTime) {
|
||||
if (this.workPartTime(numCycles)) {
|
||||
router.toCity();
|
||||
}
|
||||
} else if (this.workType === CONSTANTS.WorkTypeGraftAugmentation) {
|
||||
} else if (this.workType === WorkType.GraftAugmentation) {
|
||||
if (this.graftAugmentationWork(numCycles)) {
|
||||
router.toGrafting();
|
||||
}
|
||||
@ -765,10 +766,10 @@ export function finishWork(this: IPlayer, cancelled: boolean, sing = false): str
|
||||
}
|
||||
|
||||
export function startWorkPartTime(this: IPlayer, companyName: string): void {
|
||||
this.resetWorkStatus(CONSTANTS.WorkTypeCompanyPartTime, companyName);
|
||||
this.resetWorkStatus(WorkType.CompanyPartTime, companyName);
|
||||
this.isWorking = true;
|
||||
this.companyName = companyName;
|
||||
this.workType = CONSTANTS.WorkTypeCompanyPartTime;
|
||||
this.workType = WorkType.CompanyPartTime;
|
||||
|
||||
this.workHackExpGainRate = this.getWorkHackExpGain();
|
||||
this.workStrExpGainRate = this.getWorkStrExpGain();
|
||||
@ -881,26 +882,26 @@ export function startFactionWork(this: IPlayer, faction: Faction): void {
|
||||
this.workRepGainRate *= BitNodeMultipliers.FactionWorkRepGain;
|
||||
|
||||
this.isWorking = true;
|
||||
this.workType = CONSTANTS.WorkTypeFaction;
|
||||
this.workType = WorkType.Faction;
|
||||
this.currentWorkFactionName = faction.name;
|
||||
|
||||
this.timeNeededToCompleteWork = CONSTANTS.MillisecondsPer20Hours;
|
||||
}
|
||||
|
||||
export function startFactionHackWork(this: IPlayer, faction: Faction): void {
|
||||
this.resetWorkStatus(CONSTANTS.WorkTypeFaction, faction.name, CONSTANTS.FactionWorkHacking);
|
||||
this.resetWorkStatus(WorkType.Faction, faction.name, PlayerFactionWorkType.Hacking);
|
||||
|
||||
this.workHackExpGainRate = 0.15 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.workRepGainRate = getHackingWorkRepGain(this, faction);
|
||||
|
||||
this.factionWorkType = CONSTANTS.FactionWorkHacking;
|
||||
this.factionWorkType = PlayerFactionWorkType.Hacking;
|
||||
this.currentWorkFactionDescription = "carrying out hacking contracts";
|
||||
|
||||
this.startFactionWork(faction);
|
||||
}
|
||||
|
||||
export function startFactionFieldWork(this: IPlayer, faction: Faction): void {
|
||||
this.resetWorkStatus(CONSTANTS.WorkTypeFaction, faction.name, CONSTANTS.FactionWorkField);
|
||||
this.resetWorkStatus(WorkType.Faction, faction.name, PlayerFactionWorkType.Field);
|
||||
|
||||
this.workHackExpGainRate = 0.1 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.workStrExpGainRate = 0.1 * this.strength_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
@ -910,14 +911,14 @@ export function startFactionFieldWork(this: IPlayer, faction: Faction): void {
|
||||
this.workChaExpGainRate = 0.1 * this.charisma_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.workRepGainRate = getFactionFieldWorkRepGain(this, faction);
|
||||
|
||||
this.factionWorkType = CONSTANTS.FactionWorkField;
|
||||
this.factionWorkType = PlayerFactionWorkType.Field;
|
||||
this.currentWorkFactionDescription = "carrying out field missions";
|
||||
|
||||
this.startFactionWork(faction);
|
||||
}
|
||||
|
||||
export function startFactionSecurityWork(this: IPlayer, faction: Faction): void {
|
||||
this.resetWorkStatus(CONSTANTS.WorkTypeFaction, faction.name, CONSTANTS.FactionWorkSecurity);
|
||||
this.resetWorkStatus(WorkType.Faction, faction.name, PlayerFactionWorkType.Security);
|
||||
|
||||
this.workHackExpGainRate = 0.05 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.workStrExpGainRate = 0.15 * this.strength_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
@ -927,7 +928,7 @@ export function startFactionSecurityWork(this: IPlayer, faction: Faction): void
|
||||
this.workChaExpGainRate = 0.0 * this.charisma_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
|
||||
this.workRepGainRate = getFactionSecurityWorkRepGain(this, faction);
|
||||
|
||||
this.factionWorkType = CONSTANTS.FactionWorkSecurity;
|
||||
this.factionWorkType = PlayerFactionWorkType.Security;
|
||||
this.currentWorkFactionDescription = "performing security detail";
|
||||
|
||||
this.startFactionWork(faction);
|
||||
@ -942,13 +943,13 @@ export function workForFaction(this: IPlayer, numCycles: number): boolean {
|
||||
|
||||
//Constantly update the rep gain rate
|
||||
switch (this.factionWorkType) {
|
||||
case CONSTANTS.FactionWorkHacking:
|
||||
case PlayerFactionWorkType.Hacking:
|
||||
this.workRepGainRate = getHackingWorkRepGain(this, faction);
|
||||
break;
|
||||
case CONSTANTS.FactionWorkField:
|
||||
case PlayerFactionWorkType.Field:
|
||||
this.workRepGainRate = getFactionFieldWorkRepGain(this, faction);
|
||||
break;
|
||||
case CONSTANTS.FactionWorkSecurity:
|
||||
case PlayerFactionWorkType.Security:
|
||||
this.workRepGainRate = getFactionSecurityWorkRepGain(this, faction);
|
||||
break;
|
||||
default:
|
||||
@ -1261,7 +1262,7 @@ export function getWorkRepGain(this: IPlayer): number {
|
||||
export function startCreateProgramWork(this: IPlayer, programName: string, time: number, reqLevel: number): void {
|
||||
this.resetWorkStatus();
|
||||
this.isWorking = true;
|
||||
this.workType = CONSTANTS.WorkTypeCreateProgram;
|
||||
this.workType = WorkType.CreateProgram;
|
||||
|
||||
//Time needed to complete work affected by hacking skill (linearly based on
|
||||
//ratio of (your skill - required level) to MAX skill)
|
||||
@ -1338,7 +1339,7 @@ export function finishCreateProgramWork(this: IPlayer, cancelled: boolean): stri
|
||||
export function startGraftAugmentationWork(this: IPlayer, augmentationName: string, time: number): void {
|
||||
this.resetWorkStatus();
|
||||
this.isWorking = true;
|
||||
this.workType = CONSTANTS.WorkTypeGraftAugmentation;
|
||||
this.workType = WorkType.GraftAugmentation;
|
||||
|
||||
this.timeNeededToCompleteWork = time;
|
||||
this.graftAugmentationName = augmentationName;
|
||||
@ -1392,10 +1393,10 @@ export function finishGraftAugmentationWork(this: IPlayer, cancelled: boolean, s
|
||||
}
|
||||
|
||||
/* Studying/Taking Classes */
|
||||
export function startClass(this: IPlayer, costMult: number, expMult: number, className: string): void {
|
||||
export function startClass(this: IPlayer, costMult: number, expMult: number, className: ClassType): void {
|
||||
this.resetWorkStatus();
|
||||
this.isWorking = true;
|
||||
this.workType = CONSTANTS.WorkTypeStudyClass;
|
||||
this.workType = WorkType.StudyClass;
|
||||
this.workCostMult = costMult;
|
||||
this.workExpMult = expMult;
|
||||
this.className = className;
|
||||
@ -1487,7 +1488,7 @@ export function finishClass(this: IPlayer, sing = false): string {
|
||||
export function startCrime(
|
||||
this: IPlayer,
|
||||
router: IRouter,
|
||||
crimeType: string,
|
||||
crimeType: CrimeType,
|
||||
hackExp: number,
|
||||
strExp: number,
|
||||
defExp: number,
|
||||
@ -1503,7 +1504,7 @@ export function startCrime(
|
||||
this.resetWorkStatus();
|
||||
this.isWorking = true;
|
||||
this.focus = true;
|
||||
this.workType = CONSTANTS.WorkTypeCrime;
|
||||
this.workType = WorkType.Crime;
|
||||
|
||||
if (workerscript !== null) {
|
||||
this.committingCrimeThruSingFn = true;
|
||||
@ -1668,7 +1669,7 @@ export function finishCrime(this: IPlayer, cancelled: boolean): string {
|
||||
this.committingCrimeThruSingFn = false;
|
||||
this.singFnCrimeWorkerScript = null;
|
||||
this.isWorking = false;
|
||||
this.crimeType = "";
|
||||
this.crimeType = CrimeType.None;
|
||||
this.resetWorkStatus();
|
||||
return "";
|
||||
}
|
||||
@ -1681,25 +1682,25 @@ export function singularityStopWork(this: IPlayer): string {
|
||||
}
|
||||
let res = ""; //Earnings text for work
|
||||
switch (this.workType) {
|
||||
case CONSTANTS.WorkTypeStudyClass:
|
||||
case WorkType.StudyClass:
|
||||
res = this.finishClass(true);
|
||||
break;
|
||||
case CONSTANTS.WorkTypeCompany:
|
||||
case WorkType.Company:
|
||||
res = this.finishWork(true, true);
|
||||
break;
|
||||
case CONSTANTS.WorkTypeCompanyPartTime:
|
||||
case WorkType.CompanyPartTime:
|
||||
res = this.finishWorkPartTime(true);
|
||||
break;
|
||||
case CONSTANTS.WorkTypeFaction:
|
||||
case WorkType.Faction:
|
||||
res = this.finishFactionWork(true, true);
|
||||
break;
|
||||
case CONSTANTS.WorkTypeCreateProgram:
|
||||
case WorkType.CreateProgram:
|
||||
res = this.finishCreateProgramWork(true);
|
||||
break;
|
||||
case CONSTANTS.WorkTypeCrime:
|
||||
case WorkType.Crime:
|
||||
res = this.finishCrime(true);
|
||||
break;
|
||||
case CONSTANTS.WorkTypeGraftAugmentation:
|
||||
case WorkType.GraftAugmentation:
|
||||
res = this.finishGraftAugmentationWork(true, true);
|
||||
break;
|
||||
default:
|
||||
@ -1793,7 +1794,7 @@ export function applyForJob(this: IPlayer, entryPosType: CompanyPosition, sing =
|
||||
}
|
||||
|
||||
this.jobs[company.name] = pos.name;
|
||||
if (!this.isWorking || !this.workType.includes("Working for Company")) this.companyName = company.name;
|
||||
if (!this.isWorking || this.workType !== WorkType.Company) this.companyName = company.name;
|
||||
|
||||
if (!sing) {
|
||||
dialogBoxCreate("Congratulations! You were offered a new job at " + company.name + " as a " + pos.name + "!");
|
||||
@ -1842,7 +1843,7 @@ export function getNextCompanyPosition(
|
||||
}
|
||||
|
||||
export function quitJob(this: IPlayer, company: string, _sing = false): void {
|
||||
if (this.isWorking == true && this.workType.includes("Working for Company") && this.companyName == company) {
|
||||
if (this.isWorking == true && this.workType !== WorkType.Company && this.companyName == company) {
|
||||
this.finishWork(true);
|
||||
}
|
||||
delete this.jobs[company];
|
||||
|
@ -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,10 +127,9 @@ export function SleeveElem(props: IProps): React.ReactElement {
|
||||
}
|
||||
|
||||
return (
|
||||
<Box component={Paper} sx={{ width: "auto" }}>
|
||||
<Box sx={{ m: 1 }}>
|
||||
<Box display="grid" sx={{ gridTemplateColumns: "1fr 1fr", width: "100%", gap: 1 }}>
|
||||
<Box>
|
||||
<>
|
||||
<Paper sx={{ p: 1, display: "grid", gridTemplateColumns: "1fr 1fr", width: "auto", gap: 1 }}>
|
||||
<span>
|
||||
<StatsElement sleeve={props.sleeve} />
|
||||
<Box display="grid" sx={{ gridTemplateColumns: "1fr 1fr", width: "100%" }}>
|
||||
<Button onClick={() => setStatsOpen(true)}>More Stats</Button>
|
||||
@ -151,9 +146,7 @@ export function SleeveElem(props: IProps): React.ReactElement {
|
||||
</span>
|
||||
</Tooltip>
|
||||
<Tooltip
|
||||
title={
|
||||
props.sleeve.shock < 100 ? <Typography>Unlocked when sleeve has fully recovered</Typography> : ""
|
||||
}
|
||||
title={props.sleeve.shock < 100 ? <Typography>Unlocked when sleeve has fully recovered</Typography> : ""}
|
||||
>
|
||||
<span>
|
||||
<Button
|
||||
@ -166,24 +159,25 @@ export function SleeveElem(props: IProps): React.ReactElement {
|
||||
</span>
|
||||
</Tooltip>
|
||||
</Box>
|
||||
</Box>
|
||||
<Box>
|
||||
</span>
|
||||
<span>
|
||||
<EarningsElement sleeve={props.sleeve} />
|
||||
<Box>
|
||||
<TaskSelector player={player} sleeve={props.sleeve} setABC={setABC} />
|
||||
<Button onClick={setTask} sx={{ width: "100%" }}>
|
||||
Set Task
|
||||
</Button>
|
||||
<Typography>{desc}</Typography>
|
||||
<Typography>
|
||||
{props.sleeve.currentTask === SleeveTaskType.Crime &&
|
||||
createProgressBarText({
|
||||
progress: props.sleeve.currentTaskTime / props.sleeve.currentTaskMaxTime,
|
||||
totalTicks: 25,
|
||||
})}
|
||||
{props.sleeve.currentTask === SleeveTaskType.Crime && (
|
||||
<ProgressBar
|
||||
variant="determinate"
|
||||
value={(props.sleeve.currentTaskTime / props.sleeve.currentTaskMaxTime) * 100}
|
||||
color="primary"
|
||||
/>
|
||||
)}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</span>
|
||||
</Paper>
|
||||
<MoreStatsModal open={statsOpen} onClose={() => setStatsOpen(false)} sleeve={props.sleeve} />
|
||||
<MoreEarningsModal open={earningsOpen} onClose={() => setEarningsOpen(false)} sleeve={props.sleeve} />
|
||||
<TravelModal
|
||||
@ -197,8 +191,6 @@ export function SleeveElem(props: IProps): React.ReactElement {
|
||||
onClose={() => setAugmentationsOpen(false)}
|
||||
sleeve={props.sleeve}
|
||||
/>
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||
import { IPlayer } from "../IPlayer";
|
||||
import { ClassType } from "../../utils/WorkType";
|
||||
|
||||
export interface WorkEarnings {
|
||||
workMoneyLossRate: number;
|
||||
@ -25,43 +26,43 @@ export function calculateClassEarnings(player: IPlayer): WorkEarnings {
|
||||
chaExp = 0;
|
||||
const hashManager = player.hashManager;
|
||||
switch (player.className) {
|
||||
case CONSTANTS.ClassStudyComputerScience:
|
||||
case ClassType.StudyComputerScience:
|
||||
hackExp =
|
||||
((CONSTANTS.ClassStudyComputerScienceBaseExp * player.workExpMult) / gameCPS) * hashManager.getStudyMult();
|
||||
break;
|
||||
case CONSTANTS.ClassDataStructures:
|
||||
case ClassType.DataStructures:
|
||||
cost = (CONSTANTS.ClassDataStructuresBaseCost * player.workCostMult) / gameCPS;
|
||||
hackExp = ((CONSTANTS.ClassDataStructuresBaseExp * player.workExpMult) / gameCPS) * hashManager.getStudyMult();
|
||||
break;
|
||||
case CONSTANTS.ClassNetworks:
|
||||
case ClassType.Networks:
|
||||
cost = (CONSTANTS.ClassNetworksBaseCost * player.workCostMult) / gameCPS;
|
||||
hackExp = ((CONSTANTS.ClassNetworksBaseExp * player.workExpMult) / gameCPS) * hashManager.getStudyMult();
|
||||
break;
|
||||
case CONSTANTS.ClassAlgorithms:
|
||||
case ClassType.Algorithms:
|
||||
cost = (CONSTANTS.ClassAlgorithmsBaseCost * player.workCostMult) / gameCPS;
|
||||
hackExp = ((CONSTANTS.ClassAlgorithmsBaseExp * player.workExpMult) / gameCPS) * hashManager.getStudyMult();
|
||||
break;
|
||||
case CONSTANTS.ClassManagement:
|
||||
case ClassType.Management:
|
||||
cost = (CONSTANTS.ClassManagementBaseCost * player.workCostMult) / gameCPS;
|
||||
chaExp = ((CONSTANTS.ClassManagementBaseExp * player.workExpMult) / gameCPS) * hashManager.getStudyMult();
|
||||
break;
|
||||
case CONSTANTS.ClassLeadership:
|
||||
case ClassType.Leadership:
|
||||
cost = (CONSTANTS.ClassLeadershipBaseCost * player.workCostMult) / gameCPS;
|
||||
chaExp = ((CONSTANTS.ClassLeadershipBaseExp * player.workExpMult) / gameCPS) * hashManager.getStudyMult();
|
||||
break;
|
||||
case CONSTANTS.ClassGymStrength:
|
||||
case ClassType.GymStrength:
|
||||
cost = (CONSTANTS.ClassGymBaseCost * player.workCostMult) / gameCPS;
|
||||
strExp = (player.workExpMult / gameCPS) * hashManager.getTrainingMult();
|
||||
break;
|
||||
case CONSTANTS.ClassGymDefense:
|
||||
case ClassType.GymDefense:
|
||||
cost = (CONSTANTS.ClassGymBaseCost * player.workCostMult) / gameCPS;
|
||||
defExp = (player.workExpMult / gameCPS) * hashManager.getTrainingMult();
|
||||
break;
|
||||
case CONSTANTS.ClassGymDexterity:
|
||||
case ClassType.GymDexterity:
|
||||
cost = (CONSTANTS.ClassGymBaseCost * player.workCostMult) / gameCPS;
|
||||
dexExp = (player.workExpMult / gameCPS) * hashManager.getTrainingMult();
|
||||
break;
|
||||
case CONSTANTS.ClassGymAgility:
|
||||
case ClassType.GymAgility:
|
||||
cost = (CONSTANTS.ClassGymBaseCost * player.workCostMult) / gameCPS;
|
||||
agiExp = (player.workExpMult / gameCPS) * hashManager.getTrainingMult();
|
||||
break;
|
||||
|
@ -50,6 +50,8 @@ import { setupUncaughtPromiseHandler } from "./UncaughtPromiseHandler";
|
||||
import { Button, Typography } from "@mui/material";
|
||||
import { SnackbarEvents, ToastVariant } from "./ui/React/Snackbar";
|
||||
|
||||
import { WorkType } from "./utils/WorkType";
|
||||
|
||||
const Engine: {
|
||||
_lastUpdate: number;
|
||||
updateGame: (numCycles?: number) => void;
|
||||
@ -292,19 +294,26 @@ const Engine: {
|
||||
loadAllRunningScripts(Player); // This also takes care of offline production for those scripts
|
||||
if (Player.isWorking) {
|
||||
Player.focus = true;
|
||||
if (Player.workType == CONSTANTS.WorkTypeFaction) {
|
||||
switch (Player.workType) {
|
||||
case WorkType.Faction:
|
||||
Player.workForFaction(numCyclesOffline);
|
||||
} else if (Player.workType == CONSTANTS.WorkTypeCreateProgram) {
|
||||
break;
|
||||
case WorkType.CreateProgram:
|
||||
Player.createProgramWork(numCyclesOffline);
|
||||
} else if (Player.workType == CONSTANTS.WorkTypeStudyClass) {
|
||||
break;
|
||||
case WorkType.StudyClass:
|
||||
Player.takeClass(numCyclesOffline);
|
||||
} else if (Player.workType == CONSTANTS.WorkTypeCrime) {
|
||||
break;
|
||||
case WorkType.Crime:
|
||||
Player.commitCrime(numCyclesOffline);
|
||||
} else if (Player.workType == CONSTANTS.WorkTypeCompanyPartTime) {
|
||||
break;
|
||||
case WorkType.CompanyPartTime:
|
||||
Player.workPartTime(numCyclesOffline);
|
||||
} else if (Player.workType === CONSTANTS.WorkTypeGraftAugmentation) {
|
||||
break;
|
||||
case WorkType.GraftAugmentation:
|
||||
Player.graftAugmentationWork(numCyclesOffline);
|
||||
} else {
|
||||
break;
|
||||
default:
|
||||
Player.work(numCyclesOffline);
|
||||
}
|
||||
} else {
|
||||
|
@ -25,7 +25,8 @@ import { StatsProgressOverviewCell } from "./StatsProgressBar";
|
||||
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||
|
||||
import { Box, Tooltip } from "@mui/material";
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
|
||||
import { WorkType } from "../../utils/WorkType";
|
||||
|
||||
interface IProps {
|
||||
save: () => void;
|
||||
@ -144,8 +145,8 @@ function Work(): React.ReactElement {
|
||||
let header = <></>;
|
||||
let innerText = <></>;
|
||||
switch (player.workType) {
|
||||
case CONSTANTS.WorkTypeCompanyPartTime:
|
||||
case CONSTANTS.WorkTypeCompany:
|
||||
case WorkType.CompanyPartTime:
|
||||
case WorkType.Company:
|
||||
details = (
|
||||
<>
|
||||
{player.jobs[player.companyName]} at <strong>{player.companyName}</strong>
|
||||
@ -162,7 +163,7 @@ function Work(): React.ReactElement {
|
||||
</>
|
||||
);
|
||||
break;
|
||||
case CONSTANTS.WorkTypeFaction:
|
||||
case WorkType.Faction:
|
||||
details = (
|
||||
<>
|
||||
{player.factionWorkType} for <strong>{player.currentWorkFactionName}</strong>
|
||||
@ -179,12 +180,12 @@ function Work(): React.ReactElement {
|
||||
</>
|
||||
);
|
||||
break;
|
||||
case CONSTANTS.WorkTypeStudyClass:
|
||||
case WorkType.StudyClass:
|
||||
details = <>{player.workType}</>;
|
||||
header = <>You are {player.className}</>;
|
||||
innerText = <>{convertTimeMsToTimeElapsedString(player.timeWorked)}</>;
|
||||
break;
|
||||
case CONSTANTS.WorkTypeCreateProgram:
|
||||
case WorkType.CreateProgram:
|
||||
details = <>Coding {player.createProgramName}</>;
|
||||
header = <>Creating a program</>;
|
||||
innerText = (
|
||||
@ -194,7 +195,7 @@ function Work(): React.ReactElement {
|
||||
</>
|
||||
);
|
||||
break;
|
||||
case CONSTANTS.WorkTypeGraftAugmentation:
|
||||
case WorkType.GraftAugmentation:
|
||||
details = <>Grafting {player.graftAugmentationName}</>;
|
||||
header = <>Grafting an Augmentation</>;
|
||||
innerText = (
|
||||
|
13
src/ui/React/Progress.tsx
Normal file
13
src/ui/React/Progress.tsx
Normal file
@ -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);
|
@ -16,13 +16,14 @@ 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) {
|
||||
if (data.content !== undefined) {
|
||||
content = data.content;
|
||||
} else if (data.level !== undefined && data.exp !== undefined) {
|
||||
@ -30,6 +31,7 @@ export const StatsRow = ({ name, color, classes = useStyles(), children, data }:
|
||||
} else if (data.level !== undefined && data.exp === undefined) {
|
||||
content = `${formatNumber(data.level, 0)}`;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<TableRow>
|
||||
|
@ -1,26 +1,47 @@
|
||||
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";
|
||||
import { WorkType, ClassType } from "../utils/WorkType";
|
||||
|
||||
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,18 +56,103 @@ export function WorkInProgressRoot(): React.ReactElement {
|
||||
const player = use.Player();
|
||||
const router = use.Router();
|
||||
|
||||
if (player.workType == CONSTANTS.WorkTypeFaction) {
|
||||
const expGains = [
|
||||
player.workHackExpGained > 0 ? (
|
||||
<StatsRow
|
||||
name="Hacking Exp"
|
||||
color={Settings.theme.hack}
|
||||
data={{
|
||||
content: `${numeralWrapper.formatExp(player.workHackExpGained)} (${numeralWrapper.formatExp(
|
||||
player.workHackExpGainRate * CYCLES_PER_SEC,
|
||||
)} / sec)`,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
),
|
||||
player.workStrExpGained > 0 ? (
|
||||
<StatsRow
|
||||
name="Strength Exp"
|
||||
color={Settings.theme.combat}
|
||||
data={{
|
||||
content: `${numeralWrapper.formatExp(player.workStrExpGained)} (${numeralWrapper.formatExp(
|
||||
player.workStrExpGainRate * CYCLES_PER_SEC,
|
||||
)} / sec)`,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
),
|
||||
player.workDefExpGained > 0 ? (
|
||||
<StatsRow
|
||||
name="Defense Exp"
|
||||
color={Settings.theme.combat}
|
||||
data={{
|
||||
content: `${numeralWrapper.formatExp(player.workDefExpGained)} (${numeralWrapper.formatExp(
|
||||
player.workDefExpGainRate * CYCLES_PER_SEC,
|
||||
)} / sec)`,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
),
|
||||
player.workDexExpGained > 0 ? (
|
||||
<StatsRow
|
||||
name="Dexterity Exp"
|
||||
color={Settings.theme.combat}
|
||||
data={{
|
||||
content: `${numeralWrapper.formatExp(player.workDexExpGained)} (${numeralWrapper.formatExp(
|
||||
player.workDexExpGainRate * CYCLES_PER_SEC,
|
||||
)} / sec)`,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
),
|
||||
player.workAgiExpGained > 0 ? (
|
||||
<StatsRow
|
||||
name="Agility Exp"
|
||||
color={Settings.theme.combat}
|
||||
data={{
|
||||
content: `${numeralWrapper.formatExp(player.workAgiExpGained)} (${numeralWrapper.formatExp(
|
||||
player.workAgiExpGainRate * CYCLES_PER_SEC,
|
||||
)} / sec)`,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
),
|
||||
player.workChaExpGained > 0 ? (
|
||||
<StatsRow
|
||||
name="Charisma Exp"
|
||||
color={Settings.theme.cha}
|
||||
data={{
|
||||
content: `${numeralWrapper.formatExp(player.workChaExpGained)} (${numeralWrapper.formatExp(
|
||||
player.workChaExpGainRate * CYCLES_PER_SEC,
|
||||
)} / sec)`,
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
),
|
||||
];
|
||||
|
||||
let workInfo: IWorkInfo | null;
|
||||
|
||||
switch (player.workType) {
|
||||
case WorkType.Faction: {
|
||||
const faction = Factions[player.currentWorkFactionName];
|
||||
if (!faction) {
|
||||
return (
|
||||
<>
|
||||
<Typography variant="h4" color="primary">
|
||||
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
|
||||
</Typography>
|
||||
<Button onClick={() => router.toFactions()}>Back to Factions</Button>
|
||||
</>
|
||||
);
|
||||
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 {
|
||||
@ -57,81 +163,54 @@ export function WorkInProgressRoot(): React.ReactElement {
|
||||
router.toFaction(faction);
|
||||
player.stopFocusing();
|
||||
}
|
||||
return (
|
||||
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
|
||||
<Grid item>
|
||||
|
||||
workInfo = {
|
||||
buttons: {
|
||||
cancel: cancel,
|
||||
unfocus: unfocus,
|
||||
},
|
||||
title: (
|
||||
<>
|
||||
You are currently {player.currentWorkFactionDescription} for your faction <b>{faction.name}</b>
|
||||
</>
|
||||
),
|
||||
|
||||
description: (
|
||||
<>
|
||||
Current Faction Reputation: <Reputation reputation={faction.playerReputation} />
|
||||
</>
|
||||
),
|
||||
gains: [
|
||||
player.workMoneyGained > 0 ? (
|
||||
<StatsRow name="Money" color={Settings.theme.money}>
|
||||
<Typography>
|
||||
You are currently {player.currentWorkFactionDescription} for your faction {faction.name}
|
||||
<br />
|
||||
(Current Faction Reputation: <Reputation reputation={faction.playerReputation} />
|
||||
). <br />
|
||||
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 />
|
||||
<Reputation reputation={player.workRepGained} /> (
|
||||
<ReputationRate reputation={player.workRepGainRate * CYCLES_PER_SEC} />) reputation for this faction <br />
|
||||
<br />
|
||||
{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 />
|
||||
</>
|
||||
)}
|
||||
<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.
|
||||
<Money money={player.workMoneyGained} /> (
|
||||
<MoneyRate money={player.workMoneyGainRate * CYCLES_PER_SEC} />)
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Button sx={{ mx: 2 }} onClick={cancel}>
|
||||
Stop Faction Work
|
||||
</Button>
|
||||
<Button onClick={unfocus}>Do something else simultaneously</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
</StatsRow>
|
||||
) : (
|
||||
<></>
|
||||
),
|
||||
<StatsRow name="Faction Reputation" color={Settings.theme.rep}>
|
||||
<Typography>
|
||||
<Reputation reputation={player.workRepGained} /> (
|
||||
<ReputationRate reputation={player.workRepGainRate * CYCLES_PER_SEC} />)
|
||||
</Typography>
|
||||
</StatsRow>,
|
||||
...expGains,
|
||||
],
|
||||
progress: {
|
||||
elapsed: player.timeWorked,
|
||||
},
|
||||
|
||||
stopText: "Stop Faction work",
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case WorkType.StudyClass: {
|
||||
const className = player.className;
|
||||
if (player.className !== "") {
|
||||
function cancel(): void {
|
||||
player.finishClass(true);
|
||||
router.toCity();
|
||||
@ -144,89 +223,59 @@ export function WorkInProgressRoot(): React.ReactElement {
|
||||
|
||||
let stopText = "";
|
||||
if (
|
||||
className == CONSTANTS.ClassGymStrength ||
|
||||
className == CONSTANTS.ClassGymDefense ||
|
||||
className == CONSTANTS.ClassGymDexterity ||
|
||||
className == CONSTANTS.ClassGymAgility
|
||||
className === ClassType.GymStrength ||
|
||||
className === ClassType.GymDefense ||
|
||||
className === ClassType.GymDexterity ||
|
||||
className === ClassType.GymAgility
|
||||
) {
|
||||
stopText = "Stop training at gym";
|
||||
} else {
|
||||
stopText = "Stop taking course";
|
||||
}
|
||||
|
||||
return (
|
||||
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
|
||||
<Grid item>
|
||||
workInfo = {
|
||||
buttons: {
|
||||
cancel: cancel,
|
||||
unfocus: unfocus,
|
||||
},
|
||||
title: (
|
||||
<>
|
||||
You are currently <b>{className}</b>
|
||||
</>
|
||||
),
|
||||
|
||||
gains: [
|
||||
<StatsRow name="Total Cost" color={Settings.theme.money}>
|
||||
<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 />
|
||||
{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 />
|
||||
</>
|
||||
)}
|
||||
You may cancel at any time
|
||||
<Money money={-player.workMoneyGained} /> (<MoneyRate money={player.workMoneyLossRate * CYCLES_PER_SEC} />
|
||||
)
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Button sx={{ mx: 2 }} onClick={cancel}>
|
||||
{stopText}
|
||||
</Button>
|
||||
<Button onClick={unfocus}>Do something else simultaneously</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
</StatsRow>,
|
||||
...expGains,
|
||||
],
|
||||
progress: {
|
||||
elapsed: player.timeWorked,
|
||||
},
|
||||
|
||||
stopText: stopText,
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (player.workType == CONSTANTS.WorkTypeCompany) {
|
||||
case WorkType.Company: {
|
||||
const comp = Companies[player.companyName];
|
||||
if (comp == null || !(comp instanceof Company)) {
|
||||
return (
|
||||
<>
|
||||
<Typography variant="h4" color="primary">
|
||||
You cannot work for {player.companyName || "(Company not found)"} at this time, please try again if you
|
||||
think this should have worked
|
||||
</Typography>
|
||||
<Button onClick={() => router.toTerminal()}>Back to Terminal</Button>
|
||||
</>
|
||||
);
|
||||
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;
|
||||
@ -245,84 +294,51 @@ export function WorkInProgressRoot(): React.ReactElement {
|
||||
const penalty = player.cancelationPenalty();
|
||||
|
||||
const penaltyString = penalty === 0.5 ? "half" : "three-quarters";
|
||||
return (
|
||||
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
|
||||
<Grid item>
|
||||
|
||||
workInfo = {
|
||||
buttons: {
|
||||
cancel: cancel,
|
||||
unfocus: unfocus,
|
||||
},
|
||||
title: (
|
||||
<>
|
||||
You are currently working as a <b>{position}</b> at <b>{player.companyName}</b>
|
||||
</>
|
||||
),
|
||||
|
||||
description: (
|
||||
<>
|
||||
Current Company Reputation: <Reputation reputation={companyRep} />
|
||||
</>
|
||||
),
|
||||
gains: [
|
||||
<StatsRow name="Money" color={Settings.theme.money}>
|
||||
<Typography>
|
||||
You are currently working as a {position} at {player.companyName} (Current Company Reputation:{" "}
|
||||
<Reputation reputation={companyRep} />)<br />
|
||||
<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 />
|
||||
<Reputation reputation={player.workRepGained} /> (
|
||||
<ReputationRate reputation={player.workRepGainRate * CYCLES_PER_SEC} />) reputation for this company <br />
|
||||
<br />
|
||||
{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 />
|
||||
</>
|
||||
)}
|
||||
<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.
|
||||
<Money money={player.workMoneyGained} /> (<MoneyRate money={player.workMoneyGainRate * CYCLES_PER_SEC} />)
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Button sx={{ mx: 2 }} onClick={cancel}>
|
||||
Stop Working
|
||||
</Button>
|
||||
<Button onClick={unfocus}>Do something else simultaneously</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
</StatsRow>,
|
||||
<StatsRow name="Company Reputation" color={Settings.theme.rep}>
|
||||
<Typography>
|
||||
<Reputation reputation={player.workRepGained} /> (
|
||||
<ReputationRate reputation={player.workRepGainRate * CYCLES_PER_SEC} />)
|
||||
</Typography>
|
||||
</StatsRow>,
|
||||
...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;
|
||||
}
|
||||
|
||||
if (player.workType == CONSTANTS.WorkTypeCompanyPartTime) {
|
||||
case WorkType.CompanyPartTime: {
|
||||
function cancel(): void {
|
||||
player.finishWorkPartTime(true);
|
||||
router.toJob();
|
||||
@ -339,126 +355,74 @@ export function WorkInProgressRoot(): React.ReactElement {
|
||||
companyRep = comp.playerReputation;
|
||||
|
||||
const position = player.jobs[player.companyName];
|
||||
return (
|
||||
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
|
||||
<Grid item>
|
||||
|
||||
workInfo = {
|
||||
buttons: {
|
||||
cancel: cancel,
|
||||
unfocus: unfocus,
|
||||
},
|
||||
title: (
|
||||
<>
|
||||
You are currently working as a <b>{position}</b> at <b>{player.companyName}</b>
|
||||
</>
|
||||
),
|
||||
|
||||
description: (
|
||||
<>
|
||||
Current Company Reputation: <Reputation reputation={companyRep} />
|
||||
</>
|
||||
),
|
||||
gains: [
|
||||
<StatsRow name="Money" color={Settings.theme.money}>
|
||||
<Typography>
|
||||
<Money money={player.workMoneyGained} /> (<MoneyRate money={player.workMoneyGainRate * CYCLES_PER_SEC} />)
|
||||
</Typography>
|
||||
</StatsRow>,
|
||||
<StatsRow name="Company Reputation" color={Settings.theme.rep}>
|
||||
<Typography>
|
||||
You are currently working as a {position} at {player.companyName} (Current Company Reputation:{" "}
|
||||
<Reputation reputation={companyRep} />)<br />
|
||||
<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 />
|
||||
<Reputation reputation={player.workRepGained} /> (
|
||||
<ReputationRate reputation={player.workRepGainRate * CYCLES_PER_SEC} />
|
||||
) reputation for this company <br />
|
||||
<br />
|
||||
{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 />
|
||||
</>
|
||||
)}
|
||||
<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.
|
||||
<ReputationRate reputation={player.workRepGainRate * CYCLES_PER_SEC} />)
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Button sx={{ mx: 2 }} onClick={cancel}>
|
||||
Stop Working
|
||||
</Button>
|
||||
<Button onClick={unfocus}>Do something else simultaneously</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
</StatsRow>,
|
||||
...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;
|
||||
}
|
||||
|
||||
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 });
|
||||
case WorkType.Crime: {
|
||||
const completion = Math.round((player.timeWorked / player.timeNeededToCompleteWork) * 100);
|
||||
|
||||
return (
|
||||
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
|
||||
<Grid item>
|
||||
<Typography>
|
||||
<Typography>You are attempting to {player.crimeType}.</Typography>
|
||||
<br />
|
||||
|
||||
<Typography>
|
||||
Time remaining: {convertTimeMsToTimeElapsedString(player.timeNeededToCompleteWork - player.timeWorked)}
|
||||
</Typography>
|
||||
|
||||
<br />
|
||||
<pre>{progressBar}</pre>
|
||||
</Typography>
|
||||
</Grid>
|
||||
<Grid item>
|
||||
<Button
|
||||
onClick={() => {
|
||||
workInfo = {
|
||||
buttons: {
|
||||
cancel: () => {
|
||||
router.toLocation(Locations[LocationName.Slums]);
|
||||
player.finishCrime(true);
|
||||
}}
|
||||
>
|
||||
Cancel crime
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
},
|
||||
},
|
||||
title: `You are attempting to ${player.crimeType}`,
|
||||
|
||||
progress: {
|
||||
remaining: player.timeNeededToCompleteWork - player.timeWorked,
|
||||
percentage: completion,
|
||||
},
|
||||
|
||||
stopText: "Cancel crime",
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (player.createProgramName !== "") {
|
||||
case WorkType.CreateProgram: {
|
||||
function cancel(): void {
|
||||
player.finishCreateProgramWork(true);
|
||||
router.toTerminal();
|
||||
@ -467,31 +431,33 @@ export function WorkInProgressRoot(): React.ReactElement {
|
||||
router.toTerminal();
|
||||
player.stopFocusing();
|
||||
}
|
||||
return (
|
||||
<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>
|
||||
<Button sx={{ mx: 2 }} onClick={cancel}>
|
||||
Cancel work on creating program
|
||||
</Button>
|
||||
<Button onClick={unfocus}>Do something else simultaneously</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
|
||||
const completion = (player.timeWorkedCreateProgram / player.timeNeededToCompleteWork) * 100;
|
||||
|
||||
workInfo = {
|
||||
buttons: {
|
||||
cancel: cancel,
|
||||
unfocus: unfocus,
|
||||
},
|
||||
title: (
|
||||
<>
|
||||
You are currently working on coding <b>{player.createProgramName}</b>
|
||||
</>
|
||||
),
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (player.graftAugmentationName !== "") {
|
||||
case WorkType.GraftAugmentation: {
|
||||
function cancel(): void {
|
||||
player.finishGraftAugmentationWork(true);
|
||||
router.toTerminal();
|
||||
@ -500,34 +466,111 @@ export function WorkInProgressRoot(): React.ReactElement {
|
||||
router.toTerminal();
|
||||
player.stopFocusing();
|
||||
}
|
||||
return (
|
||||
<Grid container direction="column" justifyContent="center" alignItems="center" style={{ minHeight: "100vh" }}>
|
||||
<Grid item>
|
||||
<Typography>
|
||||
You are currently working on grafting {player.graftAugmentationName}.
|
||||
<br />
|
||||
<br />
|
||||
You have been working for {convertTimeMsToTimeElapsedString(player.timeWorked)}
|
||||
<br />
|
||||
<br />
|
||||
The augmentation is{" "}
|
||||
{((player.timeWorkedGraftAugmentation / player.timeNeededToCompleteWork) * 100).toFixed(2)}% done being
|
||||
crafted.
|
||||
<br />
|
||||
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 grafting Augmentation
|
||||
</Button>
|
||||
<Button onClick={unfocus}>Do something else simultaneously</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
|
||||
const completion = (player.timeWorkedGraftAugmentation / player.timeNeededToCompleteWork) * 100;
|
||||
|
||||
workInfo = {
|
||||
buttons: {
|
||||
cancel: cancel,
|
||||
unfocus: unfocus,
|
||||
},
|
||||
title: (
|
||||
<>
|
||||
You are currently working on grafting <b>{player.graftAugmentationName}</b>
|
||||
</>
|
||||
),
|
||||
|
||||
progress: {
|
||||
elapsed: player.timeWorked,
|
||||
percentage: completion,
|
||||
},
|
||||
|
||||
stopText: "Stop grafting",
|
||||
stopTooltip: (
|
||||
<>
|
||||
If you cancel, your work will <b>not</b> be saved, and the money you spent will <b>not</b> be returned
|
||||
</>
|
||||
),
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (!player.workType) router.toTerminal();
|
||||
default:
|
||||
router.toTerminal();
|
||||
workInfo = null;
|
||||
}
|
||||
|
||||
if (workInfo === null) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
const tooltipInfo =
|
||||
typeof workInfo?.stopTooltip === "string" ? (
|
||||
<Typography>{workInfo.stopTooltip}</Typography>
|
||||
) : (
|
||||
workInfo.stopTooltip || <></>
|
||||
);
|
||||
|
||||
return (
|
||||
<Container
|
||||
maxWidth="md"
|
||||
sx={{ display: "flex", flexDirection: "column", justifyContent: "center", height: "calc(100vh - 16px)" }}
|
||||
>
|
||||
<Paper sx={{ p: 1, mb: 1 }}>
|
||||
<Typography variant="h6">{workInfo.title}</Typography>
|
||||
<Typography>{workInfo.description}</Typography>
|
||||
{workInfo.gains && (
|
||||
<Table sx={{ mt: 1 }}>
|
||||
<TableBody>
|
||||
{workInfo.gains.map((row) => (
|
||||
<React.Fragment key={uniqueId()}>{row}</React.Fragment>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
)}
|
||||
</Paper>
|
||||
<Paper sx={{ mb: 1, p: 1 }}>
|
||||
{workInfo.progress !== undefined && (
|
||||
<Box sx={{ mb: 1 }}>
|
||||
<Box
|
||||
display="grid"
|
||||
sx={{
|
||||
gridTemplateColumns: `repeat(${Object.keys(workInfo.progress).length}, 1fr)`,
|
||||
width: "100%",
|
||||
justifyItems: "center",
|
||||
textAlign: "center",
|
||||
}}
|
||||
>
|
||||
{workInfo.progress.elapsed !== undefined && (
|
||||
<Typography>{convertTimeMsToTimeElapsedString(workInfo.progress.elapsed)} elapsed</Typography>
|
||||
)}
|
||||
{workInfo.progress.remaining !== undefined && (
|
||||
<Typography>{convertTimeMsToTimeElapsedString(workInfo.progress.remaining)} remaining</Typography>
|
||||
)}
|
||||
{workInfo.progress.percentage !== undefined && (
|
||||
<Typography>{workInfo.progress.percentage.toFixed(2)}% done</Typography>
|
||||
)}
|
||||
</Box>
|
||||
{workInfo.progress.percentage !== undefined && (
|
||||
<ProgressBar variant="determinate" value={workInfo.progress.percentage} color="primary" />
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<Box display="grid" sx={{ gridTemplateColumns: `repeat(${Object.keys(workInfo.buttons).length}, 1fr)` }}>
|
||||
{workInfo.stopTooltip ? (
|
||||
<Tooltip title={tooltipInfo}>
|
||||
<Button onClick={workInfo.buttons.cancel}>{workInfo.stopText}</Button>
|
||||
</Tooltip>
|
||||
) : (
|
||||
<Button onClick={workInfo.buttons.cancel}>{workInfo.stopText}</Button>
|
||||
)}
|
||||
{workInfo.buttons.unfocus && (
|
||||
<Button onClick={workInfo.buttons.unfocus}>Do something else simultaneously</Button>
|
||||
)}
|
||||
</Box>
|
||||
</Paper>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
49
src/utils/WorkType.ts
Normal file
49
src/utils/WorkType.ts
Normal file
@ -0,0 +1,49 @@
|
||||
export enum WorkType {
|
||||
None = "",
|
||||
Company = "Working for Company",
|
||||
CompanyPartTime = "Working for Company part-time",
|
||||
Faction = "Working for Faction",
|
||||
CreateProgram = "Working on Create a Program",
|
||||
StudyClass = "Studying or Taking a class at university",
|
||||
Crime = "Committing a crime",
|
||||
GraftAugmentation = "Grafting an Augmentation",
|
||||
}
|
||||
|
||||
export enum PlayerFactionWorkType {
|
||||
None = "",
|
||||
Hacking = "Faction Hacking Work",
|
||||
Field = "Faction Field Work",
|
||||
Security = "Faction Security Work",
|
||||
}
|
||||
|
||||
export enum ClassType {
|
||||
None = "",
|
||||
StudyComputerScience = "studying Computer Science",
|
||||
DataStructures = "taking a Data Structures course",
|
||||
Networks = "taking a Networks course",
|
||||
Algorithms = "taking an Algorithms course",
|
||||
|
||||
Management = "taking a Management course",
|
||||
Leadership = "taking a Leadership course",
|
||||
|
||||
GymStrength = "training your strength at a gym",
|
||||
GymDefense = "training your defense at a gym",
|
||||
GymDexterity = "training your dexterity at a gym",
|
||||
GymAgility = "training your agility at a gym",
|
||||
}
|
||||
|
||||
export enum CrimeType {
|
||||
None = "",
|
||||
Shoplift = "shoplift",
|
||||
RobStore = "rob a store",
|
||||
Mug = "mug someone",
|
||||
Larceny = "commit larceny",
|
||||
Drugs = "deal drugs",
|
||||
BondForgery = "forge corporate bonds",
|
||||
TraffickArms = "traffick illegal arms",
|
||||
Homicide = "commit homicide",
|
||||
GrandTheftAuto = "commit grand theft auto",
|
||||
Kidnap = "kidnap someone for ransom",
|
||||
Assassination = "assassinate a high-profile target",
|
||||
Heist = "pull off the ultimate heist",
|
||||
}
|
Loading…
Reference in New Issue
Block a user