2022-07-07 23:28:23 +02:00
|
|
|
import React from "react";
|
2022-07-12 07:54:19 +02:00
|
|
|
import { Reviver, Generic_toJSON, Generic_fromJSON, IReviverValue } from "../utils/JSONReviver";
|
2022-07-07 23:28:23 +02:00
|
|
|
import { CONSTANTS } from "../Constants";
|
|
|
|
import { LocationName } from "../Locations/data/LocationNames";
|
|
|
|
import { numeralWrapper } from "../ui/numeralFormat";
|
|
|
|
import { dialogBoxCreate } from "../ui/React/DialogBox";
|
|
|
|
import { Money } from "../ui/React/Money";
|
|
|
|
import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions";
|
2022-09-06 15:07:12 +02:00
|
|
|
import { Player } from "../Player";
|
2022-07-07 23:28:23 +02:00
|
|
|
import { calculateClassEarnings as calculateClassEarningsRate } from "./formulas/Class";
|
|
|
|
import { Work, WorkType } from "./Work";
|
|
|
|
import { applyWorkStats, newWorkStats, sumWorkStats, WorkStats } from "./WorkStats";
|
|
|
|
|
|
|
|
export enum ClassType {
|
2022-07-26 21:30:12 +02:00
|
|
|
StudyComputerScience = "STUDYCOMPUTERSCIENCE",
|
|
|
|
DataStructures = "DATASTRUCTURES",
|
|
|
|
Networks = "NETWORKS",
|
|
|
|
Algorithms = "ALGORITHMS",
|
|
|
|
|
|
|
|
Management = "MANAGEMENT",
|
|
|
|
Leadership = "LEADERSHIP",
|
|
|
|
|
|
|
|
GymStrength = "GYMSTRENGTH",
|
|
|
|
GymDefense = "GYMDEFENSE",
|
|
|
|
GymDexterity = "GYMDEXTERITY",
|
|
|
|
GymAgility = "GYMAGILITY",
|
2022-07-07 23:28:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export interface Class {
|
|
|
|
youAreCurrently: string;
|
|
|
|
type: ClassType;
|
|
|
|
earnings: WorkStats;
|
|
|
|
}
|
|
|
|
|
|
|
|
export const Classes: Record<ClassType, Class> = {
|
|
|
|
[ClassType.StudyComputerScience]: {
|
|
|
|
youAreCurrently: "studying Computer Science",
|
|
|
|
type: ClassType.StudyComputerScience,
|
|
|
|
earnings: newWorkStats({ hackExp: 0.5, intExp: 0.01 }),
|
|
|
|
},
|
|
|
|
[ClassType.DataStructures]: {
|
|
|
|
youAreCurrently: "taking a Data Structures course",
|
|
|
|
type: ClassType.DataStructures,
|
|
|
|
earnings: newWorkStats({
|
|
|
|
money: -40,
|
|
|
|
hackExp: 1,
|
|
|
|
intExp: 0.01,
|
|
|
|
}),
|
|
|
|
},
|
|
|
|
[ClassType.Networks]: {
|
|
|
|
youAreCurrently: "taking a Networks course",
|
|
|
|
type: ClassType.Networks,
|
|
|
|
earnings: newWorkStats({
|
|
|
|
money: -80,
|
|
|
|
hackExp: 2,
|
|
|
|
intExp: 0.01,
|
|
|
|
}),
|
|
|
|
},
|
|
|
|
[ClassType.Algorithms]: {
|
|
|
|
youAreCurrently: "taking an Algorithms course",
|
|
|
|
type: ClassType.Algorithms,
|
|
|
|
earnings: newWorkStats({
|
|
|
|
money: -320,
|
|
|
|
hackExp: 4,
|
|
|
|
intExp: 0.01,
|
|
|
|
}),
|
|
|
|
},
|
|
|
|
[ClassType.Management]: {
|
|
|
|
youAreCurrently: "taking a Management course",
|
|
|
|
type: ClassType.Management,
|
|
|
|
earnings: newWorkStats({
|
|
|
|
money: -160,
|
|
|
|
chaExp: 2,
|
|
|
|
intExp: 0.01,
|
|
|
|
}),
|
|
|
|
},
|
|
|
|
[ClassType.Leadership]: {
|
|
|
|
youAreCurrently: "taking a Leadership course",
|
|
|
|
type: ClassType.Leadership,
|
|
|
|
earnings: newWorkStats({
|
|
|
|
money: -320,
|
|
|
|
chaExp: 4,
|
|
|
|
intExp: 0.01,
|
|
|
|
}),
|
|
|
|
},
|
|
|
|
[ClassType.GymStrength]: {
|
|
|
|
youAreCurrently: "training your strength at a gym",
|
|
|
|
type: ClassType.GymStrength,
|
|
|
|
earnings: newWorkStats({
|
|
|
|
money: -120,
|
|
|
|
strExp: 1,
|
|
|
|
}),
|
|
|
|
},
|
|
|
|
[ClassType.GymDefense]: {
|
|
|
|
youAreCurrently: "training your defense at a gym",
|
|
|
|
type: ClassType.GymDefense,
|
|
|
|
earnings: newWorkStats({
|
|
|
|
money: -120,
|
|
|
|
defExp: 1,
|
|
|
|
}),
|
|
|
|
},
|
|
|
|
[ClassType.GymDexterity]: {
|
|
|
|
youAreCurrently: "training your dexterity at a gym",
|
|
|
|
type: ClassType.GymDexterity,
|
|
|
|
earnings: newWorkStats({
|
|
|
|
money: -120,
|
|
|
|
dexExp: 1,
|
|
|
|
}),
|
|
|
|
},
|
|
|
|
[ClassType.GymAgility]: {
|
|
|
|
youAreCurrently: "training your agility at a gym",
|
|
|
|
type: ClassType.GymAgility,
|
|
|
|
earnings: newWorkStats({
|
|
|
|
money: -120,
|
|
|
|
agiExp: 1,
|
|
|
|
}),
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
interface ClassWorkParams {
|
|
|
|
classType: ClassType;
|
|
|
|
location: LocationName;
|
|
|
|
singularity: boolean;
|
|
|
|
}
|
|
|
|
|
|
|
|
export const isClassWork = (w: Work | null): w is ClassWork => w !== null && w.type === WorkType.CLASS;
|
|
|
|
|
|
|
|
export class ClassWork extends Work {
|
|
|
|
classType: ClassType;
|
|
|
|
location: LocationName;
|
|
|
|
earnings = newWorkStats();
|
|
|
|
|
|
|
|
constructor(params?: ClassWorkParams) {
|
2022-07-12 07:54:19 +02:00
|
|
|
super(WorkType.CLASS, params?.singularity ?? true);
|
2022-07-07 23:28:23 +02:00
|
|
|
this.classType = params?.classType ?? ClassType.StudyComputerScience;
|
|
|
|
this.location = params?.location ?? LocationName.Sector12RothmanUniversity;
|
|
|
|
}
|
|
|
|
|
|
|
|
isGym(): boolean {
|
|
|
|
return [ClassType.GymAgility, ClassType.GymDefense, ClassType.GymDexterity, ClassType.GymStrength].includes(
|
|
|
|
this.classType,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
getClass(): Class {
|
|
|
|
return Classes[this.classType];
|
|
|
|
}
|
|
|
|
|
2022-09-06 15:07:12 +02:00
|
|
|
calculateRates(): WorkStats {
|
|
|
|
return calculateClassEarningsRate(Player, this.classType, this.location);
|
2022-07-07 23:28:23 +02:00
|
|
|
}
|
|
|
|
|
2022-09-06 15:07:12 +02:00
|
|
|
process(cycles: number): boolean {
|
2022-07-07 23:28:23 +02:00
|
|
|
this.cyclesWorked += cycles;
|
2022-09-06 15:07:12 +02:00
|
|
|
const rate = this.calculateRates();
|
|
|
|
const earnings = applyWorkStats(Player, rate, cycles, "class");
|
2022-07-07 23:28:23 +02:00
|
|
|
this.earnings = sumWorkStats(this.earnings, earnings);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
finish(): void {
|
|
|
|
if (!this.singularity) {
|
|
|
|
dialogBoxCreate(
|
|
|
|
<>
|
|
|
|
After {this.getClass().youAreCurrently} for{" "}
|
|
|
|
{convertTimeMsToTimeElapsedString(this.cyclesWorked * CONSTANTS._idleSpeed)}, <br />
|
|
|
|
you spent a total of <Money money={-this.earnings.money} />. <br />
|
|
|
|
<br />
|
|
|
|
You earned a total of: <br />
|
|
|
|
{numeralWrapper.formatExp(this.earnings.hackExp)} hacking exp <br />
|
|
|
|
{numeralWrapper.formatExp(this.earnings.strExp)} strength exp <br />
|
|
|
|
{numeralWrapper.formatExp(this.earnings.defExp)} defense exp <br />
|
|
|
|
{numeralWrapper.formatExp(this.earnings.dexExp)} dexterity exp <br />
|
|
|
|
{numeralWrapper.formatExp(this.earnings.agiExp)} agility exp <br />
|
|
|
|
{numeralWrapper.formatExp(this.earnings.chaExp)} charisma exp
|
|
|
|
<br />
|
|
|
|
</>,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-07-26 21:30:12 +02:00
|
|
|
APICopy(): Record<string, unknown> {
|
|
|
|
return {
|
|
|
|
type: this.type,
|
|
|
|
cyclesWorked: this.cyclesWorked,
|
|
|
|
classType: this.classType,
|
|
|
|
location: this.location,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2022-10-04 12:40:10 +02:00
|
|
|
/** Serialize the current object to a JSON save state. */
|
2022-07-12 07:54:19 +02:00
|
|
|
toJSON(): IReviverValue {
|
2022-07-07 23:28:23 +02:00
|
|
|
return Generic_toJSON("ClassWork", this);
|
|
|
|
}
|
|
|
|
|
2022-10-09 07:25:31 +02:00
|
|
|
/** Initializes a ClassWork object from a JSON save state. */
|
2022-07-12 07:54:19 +02:00
|
|
|
static fromJSON(value: IReviverValue): ClassWork {
|
2022-07-07 23:28:23 +02:00
|
|
|
return Generic_fromJSON(ClassWork, value.data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Reviver.constructors.ClassWork = ClassWork;
|