bitburner-src/src/Work/CrimeWork.ts

155 lines
4.6 KiB
TypeScript
Raw Normal View History

import { Reviver, Generic_toJSON, Generic_fromJSON, IReviverValue } from "../utils/JSONReviver";
2022-07-07 08:00:23 +02:00
import { Crime } from "../Crime/Crime";
import { CONSTANTS } from "../Constants";
import { determineCrimeSuccess } from "../Crime/CrimeHelpers";
import { Crimes } from "../Crime/Crimes";
2022-09-06 15:07:12 +02:00
import { Player } from "../Player";
2022-07-07 08:00:23 +02:00
import { dialogBoxCreate } from "../ui/React/DialogBox";
import { CrimeType } from "../utils/WorkType";
import { Work, WorkType } from "./Work";
2022-08-23 22:38:30 +02:00
import { scaleWorkStats, WorkStats } from "./WorkStats";
import { calculateCrimeWorkStats } from "./formulas/Crime";
2022-07-07 08:00:23 +02:00
2022-07-26 21:30:12 +02:00
enum newCrimeType {
SHOPLIFT = "SHOPLIFT",
ROBSTORE = "ROBSTORE",
MUG = "MUG",
LARCENY = "LARCENY",
DRUGS = "DRUGS",
BONDFORGERY = "BONDFORGERY",
TRAFFICKARMS = "TRAFFICKARMS",
HOMICIDE = "HOMICIDE",
GRANDTHEFTAUTO = "GRANDTHEFTAUTO",
KIDNAP = "KIDNAP",
ASSASSINATION = "ASSASSINATION",
HEIST = "HEIST",
}
const convertCrimeType = (crimeType: CrimeType): newCrimeType => {
switch (crimeType) {
2022-07-28 08:46:34 +02:00
case CrimeType.SHOPLIFT:
2022-07-26 21:30:12 +02:00
return newCrimeType.SHOPLIFT;
2022-07-28 08:46:34 +02:00
case CrimeType.ROB_STORE:
2022-07-26 21:30:12 +02:00
return newCrimeType.ROBSTORE;
2022-07-28 08:46:34 +02:00
case CrimeType.MUG:
2022-07-26 21:30:12 +02:00
return newCrimeType.MUG;
2022-07-28 08:46:34 +02:00
case CrimeType.LARCENY:
2022-07-26 21:30:12 +02:00
return newCrimeType.LARCENY;
2022-07-28 08:46:34 +02:00
case CrimeType.DRUGS:
2022-07-26 21:30:12 +02:00
return newCrimeType.DRUGS;
2022-07-28 08:46:34 +02:00
case CrimeType.BOND_FORGERY:
2022-07-26 21:30:12 +02:00
return newCrimeType.BONDFORGERY;
2022-07-28 08:46:34 +02:00
case CrimeType.TRAFFIC_ARMS:
2022-07-26 21:30:12 +02:00
return newCrimeType.TRAFFICKARMS;
2022-07-28 08:46:34 +02:00
case CrimeType.HOMICIDE:
2022-07-26 21:30:12 +02:00
return newCrimeType.HOMICIDE;
2022-07-28 08:46:34 +02:00
case CrimeType.GRAND_THEFT_AUTO:
2022-07-26 21:30:12 +02:00
return newCrimeType.GRANDTHEFTAUTO;
2022-07-28 08:46:34 +02:00
case CrimeType.KIDNAP:
2022-07-26 21:30:12 +02:00
return newCrimeType.KIDNAP;
2022-07-28 08:46:34 +02:00
case CrimeType.ASSASSINATION:
2022-07-26 21:30:12 +02:00
return newCrimeType.ASSASSINATION;
2022-07-28 08:46:34 +02:00
case CrimeType.HEIST:
2022-07-26 21:30:12 +02:00
return newCrimeType.HEIST;
}
return newCrimeType.SHOPLIFT;
};
2022-07-07 08:00:23 +02:00
interface CrimeWorkParams {
crimeType: CrimeType;
singularity: boolean;
}
export const isCrimeWork = (w: Work | null): w is CrimeWork => w !== null && w.type === WorkType.CRIME;
2022-07-07 08:00:23 +02:00
export class CrimeWork extends Work {
crimeType: CrimeType;
2022-07-14 23:43:08 +02:00
unitCompleted: number;
2022-07-07 08:00:23 +02:00
constructor(params?: CrimeWorkParams) {
super(WorkType.CRIME, params?.singularity ?? true);
2022-07-28 08:46:34 +02:00
this.crimeType = params?.crimeType ?? CrimeType.SHOPLIFT;
2022-07-14 23:43:08 +02:00
this.unitCompleted = 0;
2022-07-07 08:00:23 +02:00
}
getCrime(): Crime {
const crime = Object.values(Crimes).find((c) => c.type === this.crimeType);
if (!crime) throw new Error("CrimeWork object constructed with invalid crime type");
return crime;
}
2022-09-06 15:07:12 +02:00
process(cycles = 1): boolean {
2022-07-07 08:00:23 +02:00
this.cyclesWorked += cycles;
const time = Object.values(Crimes).find((c) => c.type === this.crimeType)?.time ?? 0;
2022-07-14 23:43:08 +02:00
this.unitCompleted += CONSTANTS._idleSpeed * cycles;
2022-07-21 20:36:29 +02:00
while (this.unitCompleted >= time) {
2022-09-06 15:07:12 +02:00
this.commit();
2022-07-14 23:43:08 +02:00
this.unitCompleted -= time;
}
return false;
2022-07-07 08:00:23 +02:00
}
2022-07-26 14:08:51 +02:00
earnings(): WorkStats {
return calculateCrimeWorkStats(this.getCrime());
2022-07-26 14:08:51 +02:00
}
2022-09-06 15:07:12 +02:00
commit(): void {
2022-07-26 14:08:51 +02:00
const crime = this.getCrime();
2022-07-07 08:00:23 +02:00
if (crime == null) {
dialogBoxCreate(
`ERR: Unrecognized crime type (${this.crimeType}). This is probably a bug please contact the developer`,
);
return;
}
2022-09-06 15:07:12 +02:00
const focusPenalty = Player.focusPenalty();
2022-07-07 08:00:23 +02:00
// exp times 2 because were trying to maintain the same numbers as before the conversion
// Technically the definition of Crimes should have the success numbers and failure should divide by 4
2022-07-28 17:37:28 +02:00
let gains = scaleWorkStats(this.earnings(), focusPenalty, false);
2022-07-07 08:00:23 +02:00
let karma = crime.karma;
2022-09-06 15:07:12 +02:00
const success = determineCrimeSuccess(crime.type);
2022-07-07 08:00:23 +02:00
if (success) {
2022-09-06 15:07:12 +02:00
Player.gainMoney(gains.money, "crime");
Player.numPeopleKilled += crime.kills;
Player.gainIntelligenceExp(gains.intExp);
2022-07-07 08:00:23 +02:00
} else {
2022-07-26 14:08:51 +02:00
gains = scaleWorkStats(gains, 0.25);
2022-07-07 08:00:23 +02:00
karma /= 4;
}
2022-09-06 15:07:12 +02:00
Player.gainHackingExp(gains.hackExp);
Player.gainStrengthExp(gains.strExp);
Player.gainDefenseExp(gains.defExp);
Player.gainDexterityExp(gains.dexExp);
Player.gainAgilityExp(gains.agiExp);
Player.gainCharismaExp(gains.chaExp);
Player.karma -= karma * focusPenalty;
2022-07-14 23:43:08 +02:00
}
2022-07-07 08:00:23 +02:00
2022-07-26 21:30:12 +02:00
finish(): void {
/** nothing to do */
}
APICopy(): Record<string, unknown> {
return {
type: this.type,
cyclesWorked: this.cyclesWorked,
crimeType: convertCrimeType(this.crimeType),
};
2022-07-07 08:00:23 +02:00
}
/**
* Serialize the current object to a JSON save state.
*/
toJSON(): IReviverValue {
2022-07-07 08:00:23 +02:00
return Generic_toJSON("CrimeWork", this);
}
/**
* Initiatizes a CrimeWork object from a JSON save state.
*/
static fromJSON(value: IReviverValue): CrimeWork {
2022-07-07 08:00:23 +02:00
return Generic_fromJSON(CrimeWork, value.data);
}
}
Reviver.constructors.CrimeWork = CrimeWork;