bitburner-src/src/Work/CrimeWork.ts

107 lines
3.4 KiB
TypeScript
Raw Normal View History

import { Player } from "@player";
import { CrimeType } from "@enums";
import { constructorsForReviver, Generic_toJSON, Generic_fromJSON, IReviverValue } from "../utils/JSONReviver";
2022-07-07 02:00:23 -04:00
import { Crime } from "../Crime/Crime";
import { CONSTANTS } from "../Constants";
import { determineCrimeSuccess } from "../Crime/CrimeHelpers";
2022-07-07 02:00:23 -04:00
import { Crimes } from "../Crime/Crimes";
import { dialogBoxCreate } from "../ui/React/DialogBox";
import { Work, WorkType } from "./Work";
2022-08-23 16:38:30 -04:00
import { scaleWorkStats, WorkStats } from "./WorkStats";
import { calculateCrimeWorkStats } from "./Formulas";
import { getEnumHelper } from "../utils/EnumHelper";
2022-07-26 15:30:12 -04:00
2022-07-07 02:00:23 -04: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 02:00:23 -04:00
export class CrimeWork extends Work {
crimeType: CrimeType;
2022-07-14 17:43:08 -04:00
unitCompleted: number;
2022-07-07 02:00:23 -04:00
constructor(params?: CrimeWorkParams) {
super(WorkType.CRIME, params?.singularity ?? true);
this.crimeType = params?.crimeType ?? CrimeType.shoplift;
2022-07-14 17:43:08 -04:00
this.unitCompleted = 0;
2022-07-07 02:00:23 -04:00
}
getCrime(): Crime {
WIP: Crimes streamlining. (#138) * streamline crimes * Crimes object is now indexed by CrimeType enum instead of an entirely new set of keys that aren't used for anything else. This eliminated a lot of instances of iterating to find the right crime for a given CrimeType. * Removed unused `None` CrimeType which allowed typing Crimes as a Record<CrimeType, Crime>. * Added slums tooltip text as a crime property, to allow streamlining slums. * Refactor slums location - removed repetitive code, rerenders 1/sec to update chances * Fix bugged descriptive text when sleeve is committing a crime (was "is attempting to DRUGS", now uses correct text e.g. "to deal drugs"). * Remove unused and now unneeded NewCrimeType enum. Values were identical to existing CrimeType values after removing unused None. * Add CrimeType enum in NetscriptDefinition.d.ts * Also update broken ToastVariant type. Better support for enums in player scripts. * Still todo is modifying some NS functions to expect CrimeType as input (rough crime names will continue to work to avoid breaking scripts) * Expect enum use for crime functions Affected functions: * ns.singularity.commitCrime * ns.singularity.getCrimeChance * ns.singularity.getCrimeStats * ns.sleeve.setToCommitCrime * formulas.work.crimeGains (param type only) - Affected functions still will fall back to rough names, except formulas.work.crimeGains which already only accepted the enum members. - Some documentation changes: * examples updated to use uppercase expected form. * Note on sleeve.setToCommitCrime that it only accepts exact matches removed. It already, and still does, accept any rough crime name (but the enum is expected input). * note about needing to use isBusy to schedule crimes remove - crimes autoloop now. * Since expected string inputs are documented directly on the type, removed list of crimes from sleeve.setToCommitCrimes
2022-10-21 11:57:37 -04:00
return Crimes[this.crimeType];
2022-07-07 02:00:23 -04:00
}
2022-09-06 09:07:12 -04:00
process(cycles = 1): boolean {
2022-07-07 02:00:23 -04:00
this.cyclesWorked += cycles;
const time = Object.values(Crimes).find((c) => c.type === this.crimeType)?.time ?? 0;
2023-02-21 09:44:18 -05:00
this.unitCompleted += CONSTANTS.MilliPerCycle * cycles;
2022-07-21 14:36:29 -04:00
while (this.unitCompleted >= time) {
2022-09-06 09:07:12 -04:00
this.commit();
2022-07-14 17:43:08 -04:00
this.unitCompleted -= time;
}
return false;
2022-07-07 02:00:23 -04:00
}
2022-07-26 08:08:51 -04:00
earnings(): WorkStats {
return calculateCrimeWorkStats(Player, this.getCrime());
2022-07-26 08:08:51 -04:00
}
2022-09-06 09:07:12 -04:00
commit(): void {
2022-07-26 08:08:51 -04:00
const crime = this.getCrime();
2022-07-07 02:00:23 -04:00
if (crime == null) {
dialogBoxCreate(
`ERR: Unrecognized crime type (${this.crimeType}). This is probably a bug please contact the developer`,
);
return;
}
const focusBonus = Player.focusPenalty();
2022-07-07 02:00:23 -04: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
let gains = scaleWorkStats(this.earnings(), focusBonus, false);
2022-07-07 02:00:23 -04:00
let karma = crime.karma;
2022-09-06 09:07:12 -04:00
const success = determineCrimeSuccess(crime.type);
2022-07-07 02:00:23 -04:00
if (success) {
2022-09-06 09:07:12 -04:00
Player.gainMoney(gains.money, "crime");
Player.numPeopleKilled += crime.kills;
Player.gainIntelligenceExp(gains.intExp);
2022-07-07 02:00:23 -04:00
} else {
2022-07-26 08:08:51 -04:00
gains = scaleWorkStats(gains, 0.25);
2022-07-07 02:00:23 -04:00
karma /= 4;
}
2022-09-06 09:07:12 -04: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 * focusBonus;
2022-07-14 17:43:08 -04:00
}
2022-07-07 02:00:23 -04:00
2022-07-26 15:30:12 -04:00
finish(): void {
/** nothing to do */
}
APICopy() {
2022-07-26 15:30:12 -04:00
return {
type: WorkType.CRIME as const,
2022-07-26 15:30:12 -04:00
cyclesWorked: this.cyclesWorked,
crimeType: this.crimeType,
2022-07-26 15:30:12 -04:00
};
2022-07-07 02:00:23 -04:00
}
/** Serialize the current object to a JSON save state. */
toJSON(): IReviverValue {
2022-07-07 02:00:23 -04:00
return Generic_toJSON("CrimeWork", this);
}
2022-10-09 01:25:31 -04:00
/** Initializes a CrimeWork object from a JSON save state. */
static fromJSON(value: IReviverValue): CrimeWork {
const crimeWork = Generic_fromJSON(CrimeWork, value.data);
2023-10-17 07:19:32 -04:00
crimeWork.crimeType = getEnumHelper("CrimeType").getMember(crimeWork.crimeType, { alwaysMatch: true });
return crimeWork;
2022-07-07 02:00:23 -04:00
}
}
constructorsForReviver.CrimeWork = CrimeWork;