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
literal 0
HcmV?d00001
diff --git a/test/jest/Migration/save-files/v2.8.1_500int_override_100int.gz b/test/jest/Migration/save-files/v2.8.1_500int_override_100int.gz
new file mode 100644
index 0000000000000000000000000000000000000000..98f3162c09bda7a69831ca8561b63f1484a0c1a6
GIT binary patch
literal 8773
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 {
initGameEnvironment();
});
+function testIntelligenceOverride(
+ ns: NSFull,
+ prestigeAPI: "b1tflum3" | "destroyW0r1dD43m0n",
+ expectSuccessPrestige: () => void,
+ setUpBeforePrestige = () => {},
+): void {
+ Player.sourceFiles.set(5, 1);
+ // Start without exp.
+ expect(Player.exp.intelligence).toStrictEqual(0);
+ expect(Player.skills.intelligence).toStrictEqual(1);
+ expect(Player.persistentIntelligenceData.exp).toStrictEqual(0);
+ // Gain 1e6 exp (skill = 242).
+ Player.gainIntelligenceExp(1e6);
+ expect(Player.exp.intelligence).toStrictEqual(1e6);
+ expect(Player.skills.intelligence).toStrictEqual(242);
+ expect(Player.persistentIntelligenceData.exp).toStrictEqual(1e6);
+
+ // Prestige and check if intelligenceOverride works (exp is set to 11255, skill = 100, and
+ // persistentIntelligenceData.exp is still 1e6).
+ const intelligenceExpGainOnPrestige = prestigeAPI === "destroyW0r1dD43m0n" ? 300 : 0;
+ setUpBeforePrestige();
+ ns.singularity[prestigeAPI](nextBN, undefined, {
+ ...ns.getResetInfo().bitNodeOptions,
+ intelligenceOverride: 100,
+ });
+ expectSuccessPrestige();
+ expect(Player.bitNodeOptions.intelligenceOverride).toStrictEqual(100);
+ expect(Player.exp.intelligence).toStrictEqual(11255.317546552918 + intelligenceExpGainOnPrestige);
+ expect(Player.skills.intelligence).toStrictEqual(100);
+ expect(Player.persistentIntelligenceData.exp).toStrictEqual(1e6 + intelligenceExpGainOnPrestige);
+
+ // Gain 500e3 exp.
+ const intExpGain = 500e3;
+ Player.gainIntelligenceExp(intExpGain);
+ // Check if int gain is accumulated correctly in both Player.exp.intelligence and
+ // Player.persistentIntelligenceData.exp.
+ expect(Player.exp.intelligence).toStrictEqual(11255.317546552918 + intelligenceExpGainOnPrestige + intExpGain);
+ expect(Player.skills.intelligence).toStrictEqual(220);
+ expect(Player.persistentIntelligenceData.exp).toStrictEqual(1e6 + intelligenceExpGainOnPrestige + intExpGain);
+
+ // Prestige and check if int gain is still retained correctly.
+ setUpBeforePrestige();
+ ns.singularity[prestigeAPI](nextBN, undefined, {
+ ...ns.getResetInfo().bitNodeOptions,
+ intelligenceOverride: undefined,
+ });
+ expectSuccessPrestige();
+ expect(Player.bitNodeOptions.intelligenceOverride).toStrictEqual(undefined);
+ expect(Player.exp.intelligence).toStrictEqual(1e6 + intelligenceExpGainOnPrestige * 2 + intExpGain);
+ expect(Player.skills.intelligence).toStrictEqual(255);
+ expect(Player.persistentIntelligenceData.exp).toStrictEqual(1e6 + intelligenceExpGainOnPrestige * 2 + intExpGain);
+
+ // Prestige with intelligenceOverride set higher than the persistent int skill and check if the int skill is
+ // incorrectly set to that value.
+ setUpBeforePrestige();
+ ns.singularity[prestigeAPI](nextBN, undefined, {
+ ...ns.getResetInfo().bitNodeOptions,
+ intelligenceOverride: 1000,
+ });
+ expectSuccessPrestige();
+ expect(Player.bitNodeOptions.intelligenceOverride).toStrictEqual(1000);
+ expect(Player.exp.intelligence).toStrictEqual(1e6 + intelligenceExpGainOnPrestige * 3 + intExpGain);
+ expect(Player.skills.intelligence).toStrictEqual(255);
+ expect(Player.persistentIntelligenceData.exp).toStrictEqual(1e6 + intelligenceExpGainOnPrestige * 3 + intExpGain);
+
+ // Start testing another scenario.
+ // Set the initial state (int exp = 1e6, skill = 242) and bitflume.
+ Player.exp.intelligence = 1e6;
+ Player.skills.intelligence = 242;
+ Player.persistentIntelligenceData.exp = 1e6;
+ ns.singularity.b1tflum3(nextBN, undefined, {
+ ...ns.getResetInfo().bitNodeOptions,
+ intelligenceOverride: undefined,
+ });
+
+ // Double-check the initial state.
+ expect(Player.exp.intelligence).toStrictEqual(1e6);
+ expect(Player.skills.intelligence).toStrictEqual(242);
+ expect(Player.persistentIntelligenceData.exp).toStrictEqual(1e6);
+ expect(Player.bitNodeOptions.intelligenceOverride).toStrictEqual(undefined);
+
+ // Limit int skill to 100.
+ setUpBeforePrestige();
+ ns.singularity[prestigeAPI](nextBN, undefined, {
+ ...ns.getResetInfo().bitNodeOptions,
+ intelligenceOverride: 100,
+ });
+ expectSuccessPrestige();
+
+ // Check if int is overridden correctly.
+ expect(Player.bitNodeOptions.intelligenceOverride).toStrictEqual(100);
+ expect(Player.exp.intelligence).toStrictEqual(11255.317546552918 + intelligenceExpGainOnPrestige);
+ expect(Player.skills.intelligence).toStrictEqual(100);
+ expect(Player.persistentIntelligenceData.exp).toStrictEqual(1e6 + intelligenceExpGainOnPrestige);
+
+ // Limit int skill to 1000.
+ setUpBeforePrestige();
+ ns.singularity[prestigeAPI](nextBN, undefined, {
+ ...ns.getResetInfo().bitNodeOptions,
+ intelligenceOverride: 1000,
+ });
+ expectSuccessPrestige();
+
+ // The limit is higher than the persistent int skill, so it's not applied. Exp and skill are reset back to the initial
+ // state, plus the int exp gained from prestige.
+ expect(Player.bitNodeOptions.intelligenceOverride).toStrictEqual(1000);
+ expect(Player.exp.intelligence).toStrictEqual(1e6 + intelligenceExpGainOnPrestige * 2);
+ expect(Player.skills.intelligence).toStrictEqual(242);
+ expect(Player.persistentIntelligenceData.exp).toStrictEqual(1e6 + intelligenceExpGainOnPrestige * 2);
+}
+
+function setUpBeforeDestroyingWD(): void {
+ Player.queueAugmentation(AugmentationName.TheRedPill);
+ installAugmentations();
+ Player.gainHackingExp(1e100);
+ const wdServer = GetServerOrThrow(SpecialServers.WorldDaemon);
+ wdServer.hasAdminRights = true;
+ Player.startBladeburner();
+ setNumBlackOpsComplete(blackOpsArray.length);
+}
+
describe("b1tflum3", () => {
beforeEach(() => {
setupBasicTestingEnvironment();
- Player.queueAugmentation(AugmentationName.TheRedPill);
+ Player.queueAugmentation(AugmentationName.Targeting1);
installAugmentations();
Player.gainHackingExp(1e100);
- const wdServer = GetServerOrThrow(SpecialServers.WorldDaemon);
- wdServer.hasAdminRights = true;
});
// Make sure that the player is in the next BN without SF rewards.
const expectSucceedInB1tflum3 = () => {
expect(Player.bitNodeN).toStrictEqual(nextBN);
expect(Player.augmentations.length).toStrictEqual(0);
+ expect(Player.exp.hacking).toStrictEqual(0);
expect(Player.sourceFileLvl(1)).toStrictEqual(0);
};
@@ -79,15 +199,20 @@ describe("b1tflum3", () => {
});
expectSucceedInB1tflum3();
});
+ test("intelligenceOverride", () => {
+ testIntelligenceOverride(getNS(), "b1tflum3", expectSucceedInB1tflum3);
+ });
});
+ // Make sure that the player is still in the same BN without SF rewards.
+ const expectFailToB1tflum3 = () => {
+ expect(Player.bitNodeN).toStrictEqual(1);
+ expect(Player.augmentations.length).toStrictEqual(1);
+ expect(Player.augmentations[0].name).toStrictEqual(AugmentationName.Targeting1);
+ expect(Player.exp.hacking).toStrictEqual(1e100);
+ expect(Player.sourceFileLvl(1)).toStrictEqual(0);
+ };
describe("Failure", () => {
- // Make sure that the player is still in the same BN without SF rewards.
- const expectFailToB1tflum3 = () => {
- expect(Player.bitNodeN).toStrictEqual(1);
- expect(Player.augmentations.length).toStrictEqual(1);
- expect(Player.sourceFileLvl(1)).toStrictEqual(0);
- };
test("Invalid intelligenceOverride", () => {
const ns = getNS();
expect(() => {
@@ -114,13 +239,7 @@ describe("b1tflum3", () => {
describe("destroyW0r1dD43m0n", () => {
beforeEach(() => {
setupBasicTestingEnvironment();
- Player.queueAugmentation(AugmentationName.TheRedPill);
- installAugmentations();
- Player.gainHackingExp(1e100);
- const wdServer = GetServerOrThrow(SpecialServers.WorldDaemon);
- wdServer.hasAdminRights = true;
- Player.startBladeburner();
- setNumBlackOpsComplete(blackOpsArray.length);
+ setUpBeforeDestroyingWD();
});
describe("Success", () => {
@@ -162,6 +281,9 @@ describe("destroyW0r1dD43m0n", () => {
});
expectSucceedInDestroyingWD();
});
+ test("intelligenceOverride", () => {
+ testIntelligenceOverride(getNS(), "destroyW0r1dD43m0n", expectSucceedInDestroyingWD, setUpBeforeDestroyingWD);
+ });
});
describe("Failure", () => {
@@ -488,6 +610,7 @@ describe("purchaseProgram", () => {
const spiedExceptionAlert = jest.spyOn(exceptionAlertModule, "exceptionAlert");
const ns = getNS();
expect(Player.hasProgram(CompletedProgramName.darkscape)).toStrictEqual(false);
+ // @ts-expect-error - Intentionally use lowercase program name
expect(ns.singularity.purchaseProgram(CompletedProgramName.darkscape.toLowerCase())).toStrictEqual(true);
expect(Player.hasProgram(CompletedProgramName.darkscape)).toStrictEqual(true);
expect(spiedExceptionAlert).not.toHaveBeenCalled();
@@ -507,6 +630,7 @@ describe("purchaseProgram", () => {
});
test("Invalid program name", () => {
const ns = getNS();
+ // @ts-expect-error - Intentionally use invalid program name
expect(ns.singularity.purchaseProgram("InvalidProgram.exe")).toStrictEqual(false);
});
test("Not enough money", () => {
diff --git a/test/jest/__snapshots__/FullSave.test.ts.snap b/test/jest/__snapshots__/FullSave.test.ts.snap
index de155d47d..4062c8341 100644
--- a/test/jest/__snapshots__/FullSave.test.ts.snap
+++ b/test/jest/__snapshots__/FullSave.test.ts.snap
@@ -534,6 +534,9 @@ exports[`Check Save File Continuity PlayerSave continuity 1`] = `
"work_money": 1,
},
"numPeopleKilled": 0,
+ "persistentIntelligenceData": {
+ "exp": 0,
+ },
"playtimeSinceLastAug": 0,
"playtimeSinceLastBitnode": 0,
"purchasedServers": [],
@@ -614,6 +617,9 @@ exports[`Check Save File Continuity PlayerSave continuity 1`] = `
"strength_exp": 1,
"work_money": 1,
},
+ "persistentIntelligenceData": {
+ "exp": 0,
+ },
"queuedAugmentations": [],
"shock": 100,
"skills": {
@@ -686,6 +692,9 @@ exports[`Check Save File Continuity PlayerSave continuity 1`] = `
"strength_exp": 1,
"work_money": 1,
},
+ "persistentIntelligenceData": {
+ "exp": 0,
+ },
"queuedAugmentations": [],
"shock": 100,
"skills": {