2022-07-12 07:54:19 +02:00
|
|
|
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";
|
|
|
|
import { IPlayer } from "../PersonObjects/IPlayer";
|
|
|
|
import { dialogBoxCreate } from "../ui/React/DialogBox";
|
2022-07-07 23:28:23 +02:00
|
|
|
import { CrimeType } from "../utils/WorkType";
|
|
|
|
import { Work, WorkType } from "./Work";
|
2022-07-26 14:08:51 +02:00
|
|
|
import { newWorkStats, scaleWorkStats, WorkStats } from "./WorkStats";
|
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;
|
|
|
|
}
|
|
|
|
|
2022-07-07 23:28:23 +02:00
|
|
|
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) {
|
2022-07-12 07:54:19 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
process(player: IPlayer, cycles = 1): boolean {
|
|
|
|
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-07-14 23:43:08 +02:00
|
|
|
this.commit(player);
|
|
|
|
this.unitCompleted -= time;
|
|
|
|
}
|
|
|
|
return false;
|
2022-07-07 08:00:23 +02:00
|
|
|
}
|
|
|
|
|
2022-07-26 14:08:51 +02:00
|
|
|
earnings(): WorkStats {
|
|
|
|
const crime = this.getCrime();
|
|
|
|
return newWorkStats({
|
|
|
|
money: crime.money,
|
|
|
|
hackExp: crime.hacking_exp * 2,
|
|
|
|
strExp: crime.strength_exp * 2,
|
|
|
|
defExp: crime.defense_exp * 2,
|
|
|
|
dexExp: crime.dexterity_exp * 2,
|
|
|
|
agiExp: crime.agility_exp * 2,
|
|
|
|
chaExp: crime.charisma_exp * 2,
|
|
|
|
intExp: crime.intelligence_exp * 2,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2022-07-14 23:43:08 +02:00
|
|
|
commit(player: IPlayer): 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-07-14 23:43:08 +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-26 14:08:51 +02:00
|
|
|
let gains = scaleWorkStats(this.earnings(), focusPenalty);
|
2022-07-07 08:00:23 +02:00
|
|
|
let karma = crime.karma;
|
|
|
|
const success = determineCrimeSuccess(player, crime.type);
|
|
|
|
if (success) {
|
2022-07-26 21:30:12 +02:00
|
|
|
player.gainMoney(gains.money * player.mults.crime_money, "crime");
|
2022-07-07 08:00:23 +02:00
|
|
|
player.numPeopleKilled += crime.kills;
|
2022-07-26 14:08:51 +02:00
|
|
|
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-07-26 14:08:51 +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);
|
2022-07-14 23:43:08 +02:00
|
|
|
player.karma -= karma * focusPenalty;
|
|
|
|
}
|
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.
|
|
|
|
*/
|
2022-07-12 07:54:19 +02:00
|
|
|
toJSON(): IReviverValue {
|
2022-07-07 08:00:23 +02:00
|
|
|
return Generic_toJSON("CrimeWork", this);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initiatizes a CrimeWork object from a JSON save state.
|
|
|
|
*/
|
2022-07-12 07:54:19 +02:00
|
|
|
static fromJSON(value: IReviverValue): CrimeWork {
|
2022-07-07 08:00:23 +02:00
|
|
|
return Generic_fromJSON(CrimeWork, value.data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Reviver.constructors.CrimeWork = CrimeWork;
|