Merge pull request #3612 from nickofolas/improvement/refactor-work-type

WORK: Refactor work types to use `enum`s instead of constants
This commit is contained in:
hydroflame 2022-05-04 20:20:26 -04:00 committed by GitHub
commit 2db2b78745
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 228 additions and 218 deletions

@ -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,

@ -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,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 = (

@ -19,6 +19,7 @@ import { ProgressBar } from "./React/Progress";
import { Reputation } from "./React/Reputation";
import { ReputationRate } from "./React/ReputationRate";
import { StatsRow } from "./React/StatsRow";
import { WorkType, ClassType } from "../utils/WorkType";
const CYCLES_PER_SEC = 1000 / CONSTANTS.MilliPerCycle;
@ -139,7 +140,7 @@ export function WorkInProgressRoot(): React.ReactElement {
let workInfo: IWorkInfo | null;
switch (player.workType) {
case CONSTANTS.WorkTypeFaction: {
case WorkType.Faction: {
const faction = Factions[player.currentWorkFactionName];
if (!faction) {
workInfo = {
@ -208,7 +209,7 @@ export function WorkInProgressRoot(): React.ReactElement {
break;
}
case CONSTANTS.WorkTypeStudyClass: {
case WorkType.StudyClass: {
const className = player.className;
function cancel(): void {
player.finishClass(true);
@ -222,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 {
@ -262,7 +263,7 @@ export function WorkInProgressRoot(): React.ReactElement {
break;
}
case CONSTANTS.WorkTypeCompany: {
case WorkType.Company: {
const comp = Companies[player.companyName];
if (comp == null || !(comp instanceof Company)) {
workInfo = {
@ -337,7 +338,7 @@ export function WorkInProgressRoot(): React.ReactElement {
break;
}
case CONSTANTS.WorkTypeCompanyPartTime: {
case WorkType.CompanyPartTime: {
function cancel(): void {
player.finishWorkPartTime(true);
router.toJob();
@ -398,7 +399,7 @@ export function WorkInProgressRoot(): React.ReactElement {
break;
}
case CONSTANTS.WorkTypeCrime: {
case WorkType.Crime: {
const completion = Math.round((player.timeWorked / player.timeNeededToCompleteWork) * 100);
workInfo = {
@ -421,7 +422,7 @@ export function WorkInProgressRoot(): React.ReactElement {
break;
}
case CONSTANTS.WorkTypeCreateProgram: {
case WorkType.CreateProgram: {
function cancel(): void {
player.finishCreateProgramWork(true);
router.toTerminal();
@ -456,7 +457,7 @@ export function WorkInProgressRoot(): React.ReactElement {
break;
}
case CONSTANTS.WorkTypeGraftAugmentation: {
case WorkType.GraftAugmentation: {
function cancel(): void {
player.finishGraftAugmentationWork(true);
router.toTerminal();

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",
}