mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2026-04-22 17:23:00 +02:00
Convert crime to new work model
This commit is contained in:
@@ -4,6 +4,7 @@ import * as corporationMethods from "./PlayerObjectCorporationMethods";
|
||||
import * as gangMethods from "./PlayerObjectGangMethods";
|
||||
import * as generalMethods from "./PlayerObjectGeneralMethods";
|
||||
import * as serverMethods from "./PlayerObjectServerMethods";
|
||||
import * as workMethods from "./PlayerObjectWorkMethods";
|
||||
|
||||
import { IMap } from "../../types";
|
||||
import { Sleeve } from "../Sleeve/Sleeve";
|
||||
@@ -40,6 +41,7 @@ import { getRandomInt } from "../../utils/helpers/getRandomInt";
|
||||
import { ITaskTracker } from "../ITaskTracker";
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { WorkType, ClassType, CrimeType, PlayerFactionWorkType } from "../../utils/WorkType";
|
||||
import { Work } from "src/Work/Work";
|
||||
|
||||
export class PlayerObject implements IPlayer {
|
||||
// Class members
|
||||
@@ -136,15 +138,13 @@ export class PlayerObject implements IPlayer {
|
||||
bladeburner_analysis_mult: number;
|
||||
bladeburner_success_chance_mult: number;
|
||||
|
||||
currentWork: Work | null;
|
||||
createProgramReqLvl: number;
|
||||
factionWorkType: PlayerFactionWorkType;
|
||||
createProgramName: string;
|
||||
timeWorkedCreateProgram: number;
|
||||
graftAugmentationName: string;
|
||||
timeWorkedGraftAugmentation: number;
|
||||
crimeType: CrimeType;
|
||||
committingCrimeThruSingFn: boolean;
|
||||
singFnCrimeWorkerScript: WorkerScript | null;
|
||||
timeNeededToCompleteWork: number;
|
||||
focus: boolean;
|
||||
className: ClassType;
|
||||
@@ -175,6 +175,9 @@ export class PlayerObject implements IPlayer {
|
||||
entropy: number;
|
||||
|
||||
// Methods
|
||||
startNEWWork: (w: Work) => void;
|
||||
processNEWWork: (cycles: number) => void;
|
||||
finishNEWWork: (cancelled: boolean) => void;
|
||||
work: (numCycles: number) => boolean;
|
||||
workPartTime: (numCycles: number) => boolean;
|
||||
workForFaction: (numCycles: number) => boolean;
|
||||
@@ -234,19 +237,6 @@ export class PlayerObject implements IPlayer {
|
||||
startFactionWork: (faction: Faction) => void;
|
||||
startClass: (costMult: number, expMult: number, className: ClassType) => void;
|
||||
startCorporation: (corpName: string, additionalShares?: number) => void;
|
||||
startCrime: (
|
||||
router: IRouter,
|
||||
crimeType: CrimeType,
|
||||
hackExp: number,
|
||||
strExp: number,
|
||||
defExp: number,
|
||||
dexExp: number,
|
||||
agiExp: number,
|
||||
chaExp: number,
|
||||
money: number,
|
||||
time: number,
|
||||
singParams: any,
|
||||
) => void;
|
||||
startFactionFieldWork: (faction: Faction) => void;
|
||||
startFactionHackWork: (faction: Faction) => void;
|
||||
startFactionSecurityWork: (faction: Faction) => void;
|
||||
@@ -276,7 +266,6 @@ export class PlayerObject implements IPlayer {
|
||||
finishWork: (cancelled: boolean, sing?: boolean) => string;
|
||||
cancelationPenalty: () => number;
|
||||
finishWorkPartTime: (sing?: boolean) => string;
|
||||
finishCrime: (cancelled: boolean) => string;
|
||||
finishCreateProgramWork: (cancelled: boolean) => string;
|
||||
resetMultipliers: () => void;
|
||||
prestigeAugmentation: () => void;
|
||||
@@ -296,7 +285,6 @@ export class PlayerObject implements IPlayer {
|
||||
hospitalize: () => void;
|
||||
createProgramWork: (numCycles: number) => boolean;
|
||||
takeClass: (numCycles: number) => boolean;
|
||||
commitCrime: (numCycles: number) => boolean;
|
||||
checkForFactionInvitations: () => Faction[];
|
||||
setBitNodeNumber: (n: number) => void;
|
||||
getMult: (name: string) => number;
|
||||
@@ -435,8 +423,6 @@ export class PlayerObject implements IPlayer {
|
||||
|
||||
this.className = ClassType.None;
|
||||
|
||||
this.crimeType = CrimeType.None;
|
||||
|
||||
this.timeWorked = 0; //in m;
|
||||
this.timeWorkedCreateProgram = 0;
|
||||
this.timeNeededToCompleteWork = 0;
|
||||
@@ -495,6 +481,8 @@ export class PlayerObject implements IPlayer {
|
||||
this.achievements = [];
|
||||
this.terminalCommandHistory = [];
|
||||
|
||||
this.currentWork = null;
|
||||
|
||||
// Let's get a hash of some semi-random stuff so we have something unique.
|
||||
this.identifier = cyrb53(
|
||||
"I-" +
|
||||
@@ -532,6 +520,9 @@ export class PlayerObject implements IPlayer {
|
||||
this.processWorkEarnings = generalMethods.processWorkEarnings;
|
||||
this.startWork = generalMethods.startWork;
|
||||
this.cancelationPenalty = generalMethods.cancelationPenalty;
|
||||
this.startNEWWork = workMethods.start;
|
||||
this.processNEWWork = workMethods.process;
|
||||
this.finishNEWWork = workMethods.finish;
|
||||
this.work = generalMethods.work;
|
||||
this.finishWork = generalMethods.finishWork;
|
||||
this.startWorkPartTime = generalMethods.startWorkPartTime;
|
||||
@@ -563,9 +554,6 @@ export class PlayerObject implements IPlayer {
|
||||
this.startClass = generalMethods.startClass;
|
||||
this.takeClass = generalMethods.takeClass;
|
||||
this.finishClass = generalMethods.finishClass;
|
||||
this.startCrime = generalMethods.startCrime;
|
||||
this.commitCrime = generalMethods.commitCrime;
|
||||
this.finishCrime = generalMethods.finishCrime;
|
||||
this.singularityStopWork = generalMethods.singularityStopWork;
|
||||
this.takeDamage = generalMethods.takeDamage;
|
||||
this.regenerateHp = generalMethods.regenerateHp;
|
||||
@@ -623,8 +611,6 @@ export class PlayerObject implements IPlayer {
|
||||
this.getUpgradeHomeCoresCost = serverMethods.getUpgradeHomeCoresCost;
|
||||
this.createHacknetServer = serverMethods.createHacknetServer;
|
||||
this.factionWorkType = PlayerFactionWorkType.None;
|
||||
this.committingCrimeThruSingFn = false;
|
||||
this.singFnCrimeWorkerScript = null;
|
||||
|
||||
this.getMult = generalMethods.getMult;
|
||||
this.setMult = generalMethods.setMult;
|
||||
|
||||
@@ -146,7 +146,6 @@ export function prestigeAugmentation(this: PlayerObject): void {
|
||||
this.currentWorkFactionDescription = "";
|
||||
this.createProgramName = "";
|
||||
this.className = ClassType.None;
|
||||
this.crimeType = CrimeType.None;
|
||||
|
||||
this.workHackExpGainRate = 0;
|
||||
this.workStrExpGainRate = 0;
|
||||
@@ -615,10 +614,6 @@ export function process(this: IPlayer, router: IRouter, numCycles = 1): void {
|
||||
if (this.takeClass(numCycles)) {
|
||||
router.toCity();
|
||||
}
|
||||
} else if (this.workType === WorkType.Crime) {
|
||||
if (this.commitCrime(numCycles)) {
|
||||
router.toLocation(Locations[LocationName.Slums]);
|
||||
}
|
||||
} else if (this.workType === WorkType.CompanyPartTime) {
|
||||
if (this.workPartTime(numCycles)) {
|
||||
router.toCity();
|
||||
@@ -1330,10 +1325,7 @@ export function finishCreateProgramWork(this: IPlayer, cancelled: boolean): stri
|
||||
if (!cancelled) {
|
||||
//Complete case
|
||||
this.gainIntelligenceExp((CONSTANTS.IntelligenceProgramBaseExpGain * this.timeWorked) / 1000);
|
||||
const lines = [
|
||||
`You've finished creating ${programName}!`,
|
||||
"The new program can be found on your home computer.",
|
||||
];
|
||||
const lines = [`You've finished creating ${programName}!`, "The new program can be found on your home computer."];
|
||||
dialogBoxCreate(lines.join("<br>"));
|
||||
message = lines.join(" ");
|
||||
|
||||
@@ -1501,196 +1493,6 @@ export function finishClass(this: IPlayer, sing = false): string {
|
||||
return "";
|
||||
}
|
||||
|
||||
//The EXP and $ gains are hardcoded. Time is in ms
|
||||
export function startCrime(
|
||||
this: IPlayer,
|
||||
router: IRouter,
|
||||
crimeType: CrimeType,
|
||||
hackExp: number,
|
||||
strExp: number,
|
||||
defExp: number,
|
||||
dexExp: number,
|
||||
agiExp: number,
|
||||
chaExp: number,
|
||||
money: number,
|
||||
time: number,
|
||||
workerscript: WorkerScript | null = null,
|
||||
): void {
|
||||
this.crimeType = crimeType;
|
||||
|
||||
this.resetWorkStatus();
|
||||
this.isWorking = true;
|
||||
this.focus = true;
|
||||
this.workType = WorkType.Crime;
|
||||
|
||||
if (workerscript !== null) {
|
||||
this.committingCrimeThruSingFn = true;
|
||||
this.singFnCrimeWorkerScript = workerscript;
|
||||
}
|
||||
|
||||
this.workHackExpGained = hackExp * this.hacking_exp_mult * BitNodeMultipliers.CrimeExpGain;
|
||||
this.workStrExpGained = strExp * this.strength_exp_mult * BitNodeMultipliers.CrimeExpGain;
|
||||
this.workDefExpGained = defExp * this.defense_exp_mult * BitNodeMultipliers.CrimeExpGain;
|
||||
this.workDexExpGained = dexExp * this.dexterity_exp_mult * BitNodeMultipliers.CrimeExpGain;
|
||||
this.workAgiExpGained = agiExp * this.agility_exp_mult * BitNodeMultipliers.CrimeExpGain;
|
||||
this.workChaExpGained = chaExp * this.charisma_exp_mult * BitNodeMultipliers.CrimeExpGain;
|
||||
this.workMoneyGained = money * this.crime_money_mult * BitNodeMultipliers.CrimeMoney;
|
||||
|
||||
this.timeNeededToCompleteWork = time;
|
||||
router.toWork();
|
||||
}
|
||||
|
||||
export function commitCrime(this: IPlayer, numCycles: number): boolean {
|
||||
this.timeWorked += CONSTANTS._idleSpeed * numCycles;
|
||||
|
||||
if (this.timeWorked >= this.timeNeededToCompleteWork) {
|
||||
this.finishCrime(false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function finishCrime(this: IPlayer, cancelled: boolean): string {
|
||||
//Determine crime success/failure
|
||||
if (!cancelled) {
|
||||
if (determineCrimeSuccess(this, this.crimeType)) {
|
||||
//Handle Karma and crime statistics
|
||||
let crime = null;
|
||||
for (const i of Object.keys(Crimes)) {
|
||||
if (Crimes[i].type == this.crimeType) {
|
||||
crime = Crimes[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (crime == null) {
|
||||
dialogBoxCreate(
|
||||
`ERR: Unrecognized crime type (${this.crimeType}). This is probably a bug please contact the developer`,
|
||||
);
|
||||
return "";
|
||||
}
|
||||
this.gainMoney(this.workMoneyGained, "crime");
|
||||
this.karma -= crime.karma;
|
||||
this.numPeopleKilled += crime.kills;
|
||||
if (crime.intelligence_exp > 0) {
|
||||
this.gainIntelligenceExp(crime.intelligence_exp);
|
||||
}
|
||||
|
||||
//On a crime success, gain 2x exp
|
||||
this.workHackExpGained *= 2;
|
||||
this.workStrExpGained *= 2;
|
||||
this.workDefExpGained *= 2;
|
||||
this.workDexExpGained *= 2;
|
||||
this.workAgiExpGained *= 2;
|
||||
this.workChaExpGained *= 2;
|
||||
const ws = this.singFnCrimeWorkerScript;
|
||||
if (this.committingCrimeThruSingFn && ws !== null) {
|
||||
if (ws.disableLogs.ALL == null && ws.disableLogs.commitCrime == null) {
|
||||
ws.scriptRef.log(
|
||||
"SUCCESS: Crime successful! Gained " +
|
||||
numeralWrapper.formatMoney(this.workMoneyGained) +
|
||||
", " +
|
||||
numeralWrapper.formatExp(this.workHackExpGained) +
|
||||
" hack exp, " +
|
||||
numeralWrapper.formatExp(this.workStrExpGained) +
|
||||
" str exp, " +
|
||||
numeralWrapper.formatExp(this.workDefExpGained) +
|
||||
" def exp, " +
|
||||
numeralWrapper.formatExp(this.workDexExpGained) +
|
||||
" dex exp, " +
|
||||
numeralWrapper.formatExp(this.workAgiExpGained) +
|
||||
" agi exp, " +
|
||||
numeralWrapper.formatExp(this.workChaExpGained) +
|
||||
" cha exp.",
|
||||
);
|
||||
}
|
||||
} else {
|
||||
dialogBoxCreate(
|
||||
<>
|
||||
Crime successful!
|
||||
<br />
|
||||
<br />
|
||||
You gained:
|
||||
<br />
|
||||
<Money money={this.workMoneyGained} />
|
||||
<br />
|
||||
{numeralWrapper.formatExp(this.workHackExpGained)} hacking experience <br />
|
||||
{numeralWrapper.formatExp(this.workStrExpGained)} strength experience
|
||||
<br />
|
||||
{numeralWrapper.formatExp(this.workDefExpGained)} defense experience
|
||||
<br />
|
||||
{numeralWrapper.formatExp(this.workDexExpGained)} dexterity experience
|
||||
<br />
|
||||
{numeralWrapper.formatExp(this.workAgiExpGained)} agility experience
|
||||
<br />
|
||||
{numeralWrapper.formatExp(this.workChaExpGained)} charisma experience
|
||||
</>,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
//Exp halved on failure
|
||||
this.workHackExpGained /= 2;
|
||||
this.workStrExpGained /= 2;
|
||||
this.workDefExpGained /= 2;
|
||||
this.workDexExpGained /= 2;
|
||||
this.workAgiExpGained /= 2;
|
||||
this.workChaExpGained /= 2;
|
||||
const ws = this.singFnCrimeWorkerScript;
|
||||
if (this.committingCrimeThruSingFn && ws !== null) {
|
||||
if (ws.disableLogs.ALL == null && ws.disableLogs.commitCrime == null) {
|
||||
ws.scriptRef.log(
|
||||
"FAIL: Crime failed! Gained " +
|
||||
numeralWrapper.formatExp(this.workHackExpGained) +
|
||||
" hack exp, " +
|
||||
numeralWrapper.formatExp(this.workStrExpGained) +
|
||||
" str exp, " +
|
||||
numeralWrapper.formatExp(this.workDefExpGained) +
|
||||
" def exp, " +
|
||||
numeralWrapper.formatExp(this.workDexExpGained) +
|
||||
" dex exp, " +
|
||||
numeralWrapper.formatExp(this.workAgiExpGained) +
|
||||
" agi exp, " +
|
||||
numeralWrapper.formatExp(this.workChaExpGained) +
|
||||
" cha exp.",
|
||||
);
|
||||
}
|
||||
} else {
|
||||
dialogBoxCreate(
|
||||
<>
|
||||
Crime failed!
|
||||
<br />
|
||||
<br />
|
||||
You gained:
|
||||
<br />
|
||||
{numeralWrapper.formatExp(this.workHackExpGained)} hacking experience <br />
|
||||
{numeralWrapper.formatExp(this.workStrExpGained)} strength experience
|
||||
<br />
|
||||
{numeralWrapper.formatExp(this.workDefExpGained)} defense experience
|
||||
<br />
|
||||
{numeralWrapper.formatExp(this.workDexExpGained)} dexterity experience
|
||||
<br />
|
||||
{numeralWrapper.formatExp(this.workAgiExpGained)} agility experience
|
||||
<br />
|
||||
{numeralWrapper.formatExp(this.workChaExpGained)} charisma experience
|
||||
</>,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this.gainHackingExp(this.workHackExpGained);
|
||||
this.gainStrengthExp(this.workStrExpGained);
|
||||
this.gainDefenseExp(this.workDefExpGained);
|
||||
this.gainDexterityExp(this.workDexExpGained);
|
||||
this.gainAgilityExp(this.workAgiExpGained);
|
||||
this.gainCharismaExp(this.workChaExpGained);
|
||||
}
|
||||
this.committingCrimeThruSingFn = false;
|
||||
this.singFnCrimeWorkerScript = null;
|
||||
this.isWorking = false;
|
||||
this.crimeType = CrimeType.None;
|
||||
this.resetWorkStatus();
|
||||
return "";
|
||||
}
|
||||
|
||||
//Cancels the player's current "work" assignment and gives the proper rewards
|
||||
//Used only for Singularity functions, so no popups are created
|
||||
export function singularityStopWork(this: IPlayer): string {
|
||||
@@ -1714,9 +1516,6 @@ export function singularityStopWork(this: IPlayer): string {
|
||||
case WorkType.CreateProgram:
|
||||
res = this.finishCreateProgramWork(true);
|
||||
break;
|
||||
case WorkType.Crime:
|
||||
res = this.finishCrime(true);
|
||||
break;
|
||||
case WorkType.GraftAugmentation:
|
||||
res = this.finishGraftAugmentationWork(true, true);
|
||||
break;
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { Work } from "../../Work/Work";
|
||||
import { IPlayer } from "../IPlayer";
|
||||
|
||||
export function start(this: IPlayer, w: Work): void {
|
||||
if (this.currentWork !== null) {
|
||||
this.currentWork.finish(this, true);
|
||||
}
|
||||
this.currentWork = w;
|
||||
}
|
||||
export function process(this: IPlayer, cycles = 1): void {
|
||||
if (this.currentWork === null) return;
|
||||
const finished = this.currentWork.process(this, cycles);
|
||||
if (finished) {
|
||||
this.finishNEWWork(false);
|
||||
}
|
||||
}
|
||||
export function finish(this: IPlayer, cancelled: boolean): void {
|
||||
if (this.currentWork === null) return;
|
||||
this.currentWork.finish(this, cancelled);
|
||||
this.currentWork = null;
|
||||
}
|
||||
Reference in New Issue
Block a user