diff --git a/src/Achievements/Achievements.ts b/src/Achievements/Achievements.ts index 69cf75266..a1758310f 100644 --- a/src/Achievements/Achievements.ts +++ b/src/Achievements/Achievements.ts @@ -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 = ((data)).achievements; @@ -390,13 +391,12 @@ export const achievements: IMap = { WORKOUT: { ...achievementData["WORKOUT"], Icon: "WORKOUT", - Condition: () => - [ - CONSTANTS.ClassGymStrength, - CONSTANTS.ClassGymDefense, - CONSTANTS.ClassGymDexterity, - CONSTANTS.ClassGymAgility, - ].includes(Player.className), + Condition: () => { + if (Player.className === null) return false; + return [ClassType.GymStrength, ClassType.GymDefense, ClassType.GymDexterity, ClassType.GymAgility].includes( + Player.className, + ); + }, }, TOR: { ...achievementData["TOR"], diff --git a/src/Constants.ts b/src/Constants.ts index 0abc7eff4..78e2094f4 100644 --- a/src/Constants.ts +++ b/src/Constants.ts @@ -63,20 +63,7 @@ export const CONSTANTS: { GameCyclesPerQuarterHour: number; MillisecondsPerFiveMinutes: number; GameCyclesPerFiveMinutes: number; - FactionWorkHacking: string; - FactionWorkField: string; - FactionWorkSecurity: string; - ClassStudyComputerScience: string; - ClassDataStructures: string; - ClassNetworks: string; - ClassAlgorithms: string; - ClassManagement: string; - ClassLeadership: string; - ClassGymStrength: string; - ClassGymDefense: string; - ClassGymDexterity: string; - ClassGymAgility: string; - ClassDataStructuresBaseCost: number; + ClassDataStructuresBaseCost: number; ClassNetworksBaseCost: number; ClassAlgorithmsBaseCost: number; ClassManagementBaseCost: number; @@ -216,20 +203,6 @@ export const CONSTANTS: { // Player Work & Action BaseFocusBonus: 0.8, - FactionWorkHacking: "Faction Hacking Work", - FactionWorkField: "Faction Field Work", - FactionWorkSecurity: "Faction Security Work", - - 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, diff --git a/src/Locations/ui/GymLocation.tsx b/src/Locations/ui/GymLocation.tsx index 72bb2dd2b..c7eb516f5 100644 --- a/src/Locations/ui/GymLocation.tsx +++ b/src/Locations/ui/GymLocation.tsx @@ -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(); diff --git a/src/Locations/ui/UniversityLocation.tsx b/src/Locations/ui/UniversityLocation.tsx index dc696b950..029293c50 100644 --- a/src/Locations/ui/UniversityLocation.tsx +++ b/src/Locations/ui/UniversityLocation.tsx @@ -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(); diff --git a/src/NetscriptFunctions.ts b/src/NetscriptFunctions.ts index 412cb903b..c14694837 100644 --- a/src/NetscriptFunctions.ts +++ b/src/NetscriptFunctions.ts @@ -2482,7 +2482,7 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { workMoneyGained: Player.workMoneyGained, createProgramName: Player.createProgramName, createProgramReqLvl: Player.createProgramReqLvl, - className: Player.className, + className: Player.className ?? "", // Avoids breaking scripts that for some reason rely on this crimeType: Player.crimeType, work_money_mult: Player.work_money_mult, hacknet_node_money_mult: Player.hacknet_node_money_mult, diff --git a/src/NetscriptFunctions/Singularity.ts b/src/NetscriptFunctions/Singularity.ts index 38a8c4056..1f7bf1c86 100644 --- a/src/NetscriptFunctions/Singularity.ts +++ b/src/NetscriptFunctions/Singularity.ts @@ -49,7 +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 { WorkType } from "../utils/WorkType"; +import { ClassType, WorkType } from "../utils/WorkType"; export function NetscriptSingularity(player: IPlayer, workerScript: WorkerScript): InternalAPI { const getAugmentation = function (_ctx: NetscriptContext, name: string): Augmentation { @@ -299,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}.`); @@ -416,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}.`); diff --git a/src/PersonObjects/IPlayer.ts b/src/PersonObjects/IPlayer.ts index cd47150ba..e973ff967 100644 --- a/src/PersonObjects/IPlayer.ts +++ b/src/PersonObjects/IPlayer.ts @@ -30,7 +30,7 @@ import { WorkerScript } from "../Netscript/WorkerScript"; import { HacknetServer } from "../Hacknet/HacknetServer"; import { ISkillProgress } from "./formulas/skill"; import { PlayerAchievement } from "../Achievements/Achievements"; -import { WorkType } from "../utils/WorkType"; +import { WorkType, ClassType } from "../utils/WorkType"; export interface IPlayer { // Class members @@ -136,7 +136,7 @@ export interface IPlayer { singFnCrimeWorkerScript: WorkerScript | null; timeNeededToCompleteWork: number; focus: boolean; - className: string; + className: ClassType | null; currentWorkFactionName: string; workType: WorkType | null; workCostMult: number; @@ -220,7 +220,7 @@ 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, diff --git a/src/PersonObjects/Player/PlayerObject.ts b/src/PersonObjects/Player/PlayerObject.ts index 7ce304b45..fefbdfca4 100644 --- a/src/PersonObjects/Player/PlayerObject.ts +++ b/src/PersonObjects/Player/PlayerObject.ts @@ -38,7 +38,7 @@ import { PlayerAchievement } from "../../Achievements/Achievements"; import { cyrb53 } from "../../utils/StringHelperFunctions"; import { getRandomInt } from "../../utils/helpers/getRandomInt"; import { CONSTANTS } from "../../Constants"; -import { WorkType } from "../../utils/WorkType"; +import { WorkType, ClassType } from "../../utils/WorkType"; export class PlayerObject implements IPlayer { // Class members @@ -146,7 +146,7 @@ export class PlayerObject implements IPlayer { singFnCrimeWorkerScript: WorkerScript | null; timeNeededToCompleteWork: number; focus: boolean; - className: string; + className: ClassType | null; currentWorkFactionName: string; workType: WorkType | null; workCostMult: number; @@ -230,7 +230,7 @@ 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, @@ -431,7 +431,7 @@ export class PlayerObject implements IPlayer { this.graftAugmentationName = ""; this.timeWorkedGraftAugmentation = 0; - this.className = ""; + this.className = null; this.crimeType = ""; diff --git a/src/PersonObjects/Player/PlayerObjectGeneralMethods.tsx b/src/PersonObjects/Player/PlayerObjectGeneralMethods.tsx index 1198bdc5f..8286af6de 100644 --- a/src/PersonObjects/Player/PlayerObjectGeneralMethods.tsx +++ b/src/PersonObjects/Player/PlayerObjectGeneralMethods.tsx @@ -66,7 +66,7 @@ import { achievements } from "../../Achievements/Achievements"; import { FactionNames } from "../../Faction/data/FactionNames"; import { graftingIntBonus } from "../Grafting/GraftingHelpers"; -import { WorkType } from "../../utils/WorkType"; +import { WorkType, FactionWorkType, ClassType } from "../../utils/WorkType"; export function init(this: IPlayer): void { /* Initialize Player's home computer */ @@ -142,7 +142,7 @@ export function prestigeAugmentation(this: PlayerObject): void { this.currentWorkFactionName = ""; this.currentWorkFactionDescription = ""; this.createProgramName = ""; - this.className = ""; + this.className = null; this.crimeType = ""; this.workHackExpGainRate = 0; @@ -503,8 +503,7 @@ export function queryStatFromString(this: IPlayer, str: string): number { /******* Working functions *******/ 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 (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(); @@ -535,7 +534,7 @@ export function resetWorkStatus(this: IPlayer, generalType?: WorkType, group?: s this.currentWorkFactionDescription = ""; this.createProgramName = ""; this.graftAugmentationName = ""; - this.className = ""; + this.className = null; this.workType = null; } @@ -890,19 +889,19 @@ export function startFactionWork(this: IPlayer, faction: Faction): void { } export function startFactionHackWork(this: IPlayer, faction: Faction): void { - this.resetWorkStatus(WorkType.Faction, faction.name, CONSTANTS.FactionWorkHacking); + this.resetWorkStatus(WorkType.Faction, faction.name, FactionWorkType.Hacking); this.workHackExpGainRate = 0.15 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain; this.workRepGainRate = getHackingWorkRepGain(this, faction); - this.factionWorkType = CONSTANTS.FactionWorkHacking; + this.factionWorkType = FactionWorkType.Hacking; this.currentWorkFactionDescription = "carrying out hacking contracts"; this.startFactionWork(faction); } export function startFactionFieldWork(this: IPlayer, faction: Faction): void { - this.resetWorkStatus(WorkType.Faction, faction.name, CONSTANTS.FactionWorkField); + this.resetWorkStatus(WorkType.Faction, faction.name, FactionWorkType.Field); this.workHackExpGainRate = 0.1 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain; this.workStrExpGainRate = 0.1 * this.strength_exp_mult * BitNodeMultipliers.FactionWorkExpGain; @@ -912,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 = FactionWorkType.Field; this.currentWorkFactionDescription = "carrying out field missions"; this.startFactionWork(faction); } export function startFactionSecurityWork(this: IPlayer, faction: Faction): void { - this.resetWorkStatus(WorkType.Faction, faction.name, CONSTANTS.FactionWorkSecurity); + this.resetWorkStatus(WorkType.Faction, faction.name, FactionWorkType.Security); this.workHackExpGainRate = 0.05 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain; this.workStrExpGainRate = 0.15 * this.strength_exp_mult * BitNodeMultipliers.FactionWorkExpGain; @@ -929,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 = FactionWorkType.Security; this.currentWorkFactionDescription = "performing security detail"; this.startFactionWork(faction); @@ -944,13 +943,13 @@ export function workForFaction(this: IPlayer, numCycles: number): boolean { //Constantly update the rep gain rate switch (this.factionWorkType) { - case CONSTANTS.FactionWorkHacking: + case FactionWorkType.Hacking: this.workRepGainRate = getHackingWorkRepGain(this, faction); break; - case CONSTANTS.FactionWorkField: + case FactionWorkType.Field: this.workRepGainRate = getFactionFieldWorkRepGain(this, faction); break; - case CONSTANTS.FactionWorkSecurity: + case FactionWorkType.Security: this.workRepGainRate = getFactionSecurityWorkRepGain(this, faction); break; default: @@ -1394,7 +1393,7 @@ 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 = WorkType.StudyClass; diff --git a/src/PersonObjects/formulas/work.ts b/src/PersonObjects/formulas/work.ts index 50ca8e743..6a8e90933 100644 --- a/src/PersonObjects/formulas/work.ts +++ b/src/PersonObjects/formulas/work.ts @@ -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; diff --git a/src/ui/WorkInProgressRoot.tsx b/src/ui/WorkInProgressRoot.tsx index 345d39724..a94d6776a 100644 --- a/src/ui/WorkInProgressRoot.tsx +++ b/src/ui/WorkInProgressRoot.tsx @@ -19,7 +19,7 @@ import { ProgressBar } from "./React/Progress"; import { Reputation } from "./React/Reputation"; import { ReputationRate } from "./React/ReputationRate"; import { StatsRow } from "./React/StatsRow"; -import { WorkType } from "../utils/WorkType"; +import { WorkType, ClassType } from "../utils/WorkType"; const CYCLES_PER_SEC = 1000 / CONSTANTS.MilliPerCycle; @@ -223,10 +223,10 @@ 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 { diff --git a/src/utils/WorkType.ts b/src/utils/WorkType.ts index 22c91d44c..67a77f31c 100644 --- a/src/utils/WorkType.ts +++ b/src/utils/WorkType.ts @@ -7,3 +7,39 @@ export enum WorkType { Crime = "Committing a crime", GraftAugmentation = "Grafting an Augmentation", } + +export enum FactionWorkType { + Hacking = "Faction Hacking Work", + Field = "Faction Field Work", + Security = "Faction Security Work", +} + +export enum ClassType { + 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 { + 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", +}