From 5fc54809de3d4f1563428be0d3c50e756df68a27 Mon Sep 17 00:00:00 2001 From: Lee Stutzman Date: Fri, 3 Apr 2026 03:06:44 +0100 Subject: [PATCH] BUGFIX: Fix skillMaxUpgradeCount returning 1 at extreme skill levels (#2611) --- src/Bladeburner/Skill.ts | 3 +++ test/jest/Bladeburner/Skill.test.ts | 36 +++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 test/jest/Bladeburner/Skill.test.ts diff --git a/src/Bladeburner/Skill.ts b/src/Bladeburner/Skill.ts index 3e6ed1e0a..70e704267 100644 --- a/src/Bladeburner/Skill.ts +++ b/src/Bladeburner/Skill.ts @@ -81,6 +81,9 @@ export class Skill { } calculateMaxUpgradeCount(currentLevel: number, cost: PositiveNumber): number { + // At extreme levels, floating-point precision loss makes currentLevel + 1 === currentLevel, + // causing calculateCost to return 0. No upgrade is possible in this case. + if (this.calculateCost(currentLevel, 1 as PositiveInteger) <= 0) return 0; /** * Define: * - x = count diff --git a/test/jest/Bladeburner/Skill.test.ts b/test/jest/Bladeburner/Skill.test.ts new file mode 100644 index 000000000..84b5a97eb --- /dev/null +++ b/test/jest/Bladeburner/Skill.test.ts @@ -0,0 +1,36 @@ +import { BladeburnerMultName, BladeburnerSkillName } from "@enums"; +import { Skill } from "../../../src/Bladeburner/Skill"; +import { PositiveNumber } from "../../../src/types"; + +const hyperdrive = new Skill({ + name: BladeburnerSkillName.Hyperdrive, + desc: "test", + baseCost: 1, + costInc: 2.5, + mults: { [BladeburnerMultName.ExpGain]: 10 }, +}); + +describe("Bladeburner Skill", () => { + describe("calculateMaxUpgradeCount", () => { + it("should return 0 when currentLevel is too high for floating-point precision", () => { + // At level 1e50, adding 1 is below float64 precision: 1e50 + 1 === 1e50 + // So calculateCost returns 0 for any count, and no upgrade is possible + const result = hyperdrive.calculateMaxUpgradeCount(1e50, 1 as PositiveNumber); + expect(result).toBe(0); + }); + + it("should return correct count at normal levels", () => { + // At level 0 with cost 1, baseCost 1, costInc 2.5: + // cost of 1 level = round(1 * 1 * (1 + 2.5 * (0 + 0/2))) = round(1) = 1 + const result = hyperdrive.calculateMaxUpgradeCount(0, 1 as PositiveNumber); + expect(result).toBe(1); + }); + + it("should return 0 when cost is less than the price of one level", () => { + // At level 10: cost of 1 level = round(1 * 1 * (1 + 2.5 * 10)) = 26 + const costOfOne = hyperdrive.calculateCost(10); + const result = hyperdrive.calculateMaxUpgradeCount(10, (costOfOne - 1) as PositiveNumber); + expect(result).toBe(0); + }); + }); +});