diff --git a/markdown/bitburner.sleeveinfiltratetask.md b/markdown/bitburner.sleeveinfiltratetask.md index ec850d5a4..7f3d92dc8 100644 --- a/markdown/bitburner.sleeveinfiltratetask.md +++ b/markdown/bitburner.sleeveinfiltratetask.md @@ -8,5 +8,10 @@ **Signature:** ```typescript -type SleeveInfiltrateTask = { type: "INFILTRATE"; cyclesWorked: number; cyclesNeeded: number }; +type SleeveInfiltrateTask = { + type: "INFILTRATE"; + cyclesWorked: number; + cyclesNeeded: number; + nextCompletion: Promise; +}; ``` diff --git a/src/PersonObjects/Sleeve/Work/SleeveBladeburnerWork.ts b/src/PersonObjects/Sleeve/Work/SleeveBladeburnerWork.ts index e7e37aa35..0f56925a2 100644 --- a/src/PersonObjects/Sleeve/Work/SleeveBladeburnerWork.ts +++ b/src/PersonObjects/Sleeve/Work/SleeveBladeburnerWork.ts @@ -1,3 +1,4 @@ +import type { PromisePair } from "../../../Types/Promises"; import { Player } from "@player"; import { Generic_fromJSON, Generic_toJSON, IReviverValue, constructorsForReviver } from "../../../utils/JSONReviver"; import { Sleeve } from "../Sleeve"; @@ -21,14 +22,10 @@ export class SleeveBladeburnerWork extends SleeveWorkClass { cyclesWorked = 0; actionType: "General" | "Contracts"; actionName: string; - signalCompletion = () => { - // Intentionally empty function, this is just an initial value and will never be used. - }; - nextCompletionPromise: Promise | null; + nextCompletionPair: PromisePair = { promise: null, resolve: null }; constructor(params?: SleeveBladeburnerWorkParams) { super(); - this.nextCompletionPromise = null; this.actionType = params?.type ?? "General"; this.actionName = params?.name ?? "Field Analysis"; } @@ -40,7 +37,11 @@ export class SleeveBladeburnerWork extends SleeveWorkClass { } finish() { - if (this.nextCompletionPromise) this.signalCompletion(); + if (this.nextCompletionPair.resolve) { + this.nextCompletionPair.resolve(); + this.nextCompletionPair.resolve = null; + this.nextCompletionPair.promise = null; + } } process(sleeve: Sleeve, cycles: number) { @@ -73,12 +74,13 @@ export class SleeveBladeburnerWork extends SleeveWorkClass { this.tasksCompleted++; this.cyclesWorked -= this.cyclesNeeded(sleeve); // Resolve and reset nextCompletion promise - if (this.nextCompletionPromise) this.signalCompletion(); + this.finish(); } } get nextCompletion(): Promise { - if (!this.nextCompletionPromise) this.nextCompletionPromise = new Promise((r) => (this.signalCompletion = r)); - return this.nextCompletionPromise; + if (!this.nextCompletionPair.promise) + this.nextCompletionPair.promise = new Promise((r) => (this.nextCompletionPair.resolve = r)); + return this.nextCompletionPair.promise; } APICopy(sleeve: Sleeve) { @@ -93,7 +95,7 @@ export class SleeveBladeburnerWork extends SleeveWorkClass { }; } - static savedKeys = getKeyList(SleeveBladeburnerWork, { removedKeys: ["signalCompletion", "nextCompletion"] }); + static savedKeys = getKeyList(SleeveBladeburnerWork, { removedKeys: ["nextCompletionPair"] }); /** Serialize the current object to a JSON save state. */ toJSON(): IReviverValue { diff --git a/src/PersonObjects/Sleeve/Work/SleeveInfiltrateWork.ts b/src/PersonObjects/Sleeve/Work/SleeveInfiltrateWork.ts index dc505dc64..ac02da50a 100644 --- a/src/PersonObjects/Sleeve/Work/SleeveInfiltrateWork.ts +++ b/src/PersonObjects/Sleeve/Work/SleeveInfiltrateWork.ts @@ -1,8 +1,10 @@ +import type { PromisePair } from "../../../Types/Promises"; import { Player } from "@player"; import { Generic_fromJSON, Generic_toJSON, IReviverValue, constructorsForReviver } from "../../../utils/JSONReviver"; import { Sleeve } from "../Sleeve"; import { SleeveWorkClass, SleeveWorkType } from "./Work"; import { CONSTANTS } from "../../../Constants"; +import { getKeyList } from "../../../utils/helpers/getKeyList"; const infiltrateCycles = 60000 / CONSTANTS.MilliPerCycle; @@ -12,6 +14,7 @@ export const isSleeveInfiltrateWork = (w: SleeveWorkClass | null): w is SleeveIn export class SleeveInfiltrateWork extends SleeveWorkClass { type: SleeveWorkType.INFILTRATE = SleeveWorkType.INFILTRATE; cyclesWorked = 0; + nextCompletionPair: PromisePair = { promise: null, resolve: null }; cyclesNeeded(): number { return infiltrateCycles; @@ -23,25 +26,34 @@ export class SleeveInfiltrateWork extends SleeveWorkClass { if (this.cyclesWorked > this.cyclesNeeded()) { this.cyclesWorked -= this.cyclesNeeded(); Player.bladeburner.infiltrateSynthoidCommunities(); + this.finish(); } } + get nextCompletion(): Promise { + if (!this.nextCompletionPair.promise) + this.nextCompletionPair.promise = new Promise((r) => (this.nextCompletionPair.resolve = r)); + return this.nextCompletionPair.promise; + } APICopy() { return { type: SleeveWorkType.INFILTRATE as const, cyclesWorked: this.cyclesWorked, cyclesNeeded: this.cyclesNeeded(), + nextCompletion: this.nextCompletion, }; } + static savedKeys = getKeyList(SleeveInfiltrateWork, { removedKeys: ["nextCompletionPair"] }); + /** Serialize the current object to a JSON save state. */ toJSON(): IReviverValue { - return Generic_toJSON("SleeveInfiltrateWork", this); + return Generic_toJSON("SleeveInfiltrateWork", this, SleeveInfiltrateWork.savedKeys); } /** Initializes a BladeburnerWork object from a JSON save state. */ static fromJSON(value: IReviverValue): SleeveInfiltrateWork { - return Generic_fromJSON(SleeveInfiltrateWork, value.data); + return Generic_fromJSON(SleeveInfiltrateWork, value.data, SleeveInfiltrateWork.savedKeys); } } diff --git a/src/ScriptEditor/NetscriptDefinitions.d.ts b/src/ScriptEditor/NetscriptDefinitions.d.ts index 52de9b436..92feea77b 100644 --- a/src/ScriptEditor/NetscriptDefinitions.d.ts +++ b/src/ScriptEditor/NetscriptDefinitions.d.ts @@ -1034,7 +1034,12 @@ type SleeveFactionTask = { }; /** @public */ -type SleeveInfiltrateTask = { type: "INFILTRATE"; cyclesWorked: number; cyclesNeeded: number }; +type SleeveInfiltrateTask = { + type: "INFILTRATE"; + cyclesWorked: number; + cyclesNeeded: number; + nextCompletion: Promise; +}; /** @public */ type SleeveRecoveryTask = { type: "RECOVERY" };