BLADEBURNER: Allow upgrading skill level over max safe integer (#1509)

This commit is contained in:
catloversg 2024-08-01 02:48:09 +07:00 committed by GitHub
parent 0ceb478e32
commit bcb4a3835b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 31 additions and 10 deletions

@ -143,17 +143,29 @@ export class Bladeburner {
/** Directly sets a skill level, with no validation */ /** Directly sets a skill level, with no validation */
setSkillLevel(skillName: BladeSkillName, value: number) { setSkillLevel(skillName: BladeSkillName, value: number) {
this.skills[skillName] = clampInteger(value, 0); this.skills[skillName] = clampInteger(value, 0, Number.MAX_VALUE);
this.updateSkillMultipliers(); this.updateSkillMultipliers();
} }
/** Attempts to perform a skill upgrade, gives a message on both success and failure */ /** Attempts to perform a skill upgrade, gives a message on both success and failure */
upgradeSkill(skillName: BladeSkillName, count = 1): Attempt<{ message: string }> { upgradeSkill(skillName: BladeSkillName, count = 1): Attempt<{ message: string }> {
const availability = Skills[skillName].canUpgrade(this, count); const currentSkillLevel = this.skills[skillName] ?? 0;
if (!availability.available) return { message: `Cannot upgrade ${skillName}: ${availability.error}` }; const actualCount = currentSkillLevel + count - currentSkillLevel;
if (actualCount === 0) {
return {
message: `Cannot upgrade ${skillName}: Due to floating-point inaccuracy and the small value of specified "count", your skill cannot be upgraded.`,
};
}
const availability = Skills[skillName].canUpgrade(this, actualCount);
if (!availability.available) {
return { message: `Cannot upgrade ${skillName}: ${availability.error}` };
}
this.skillPoints -= availability.cost; this.skillPoints -= availability.cost;
this.setSkillLevel(skillName, (this.skills[skillName] ?? 0) + count); this.setSkillLevel(skillName, currentSkillLevel + actualCount);
return { success: true, message: `Upgraded skill ${skillName} by ${count} level${count > 1 ? "s" : ""}` }; return {
success: true,
message: `Upgraded skill ${skillName} by ${actualCount} level${actualCount > 1 ? "s" : ""}`,
};
} }
executeConsoleCommands(commands: string): void { executeConsoleCommands(commands: string): void {

@ -30,11 +30,12 @@ export class Skill {
this.desc = params.desc; this.desc = params.desc;
this.baseCost = params.baseCost ?? 1; this.baseCost = params.baseCost ?? 1;
this.costInc = params.costInc ?? 1; this.costInc = params.costInc ?? 1;
this.maxLvl = params.maxLvl ?? Number.MAX_SAFE_INTEGER; this.maxLvl = params.maxLvl ?? Number.MAX_VALUE;
for (const [multName, mult] of getRecordEntries(params.mults)) this.mults[multName] = mult; for (const [multName, mult] of getRecordEntries(params.mults)) this.mults[multName] = mult;
} }
calculateCost(currentLevel: number, count = 1 as PositiveInteger): number { calculateCost(currentLevel: number, count = 1 as PositiveInteger): number {
const actualCount = currentLevel + count - currentLevel;
/** /**
* The cost of the next level: (baseCost + currentLevel * costInc) * mult. The cost needs to be an integer, so we * The cost of the next level: (baseCost + currentLevel * costInc) * mult. The cost needs to be an integer, so we
* need to use Math.floor or Math.round. * need to use Math.floor or Math.round.
@ -76,16 +77,24 @@ export class Skill {
* *
*/ */
return Math.round( return Math.round(
count * currentNodeMults.BladeburnerSkillCost * (this.baseCost + this.costInc * (currentLevel + (count - 1) / 2)), actualCount *
currentNodeMults.BladeburnerSkillCost *
(this.baseCost + this.costInc * (currentLevel + (actualCount - 1) / 2)),
); );
} }
canUpgrade(bladeburner: Bladeburner, count = 1): Availability<{ cost: number }> { canUpgrade(bladeburner: Bladeburner, count = 1): Availability<{ cost: number }> {
const currentLevel = bladeburner.skills[this.name] ?? 0; const currentLevel = bladeburner.skills[this.name] ?? 0;
if (!isPositiveInteger(count)) return { error: `Invalid upgrade count ${count}` }; if (!isPositiveInteger(count)) {
if (currentLevel + count > this.maxLvl) return { error: `Upgraded level ${currentLevel + count} exceeds max` }; return { error: `Invalid upgrade count ${count}` };
}
if (currentLevel + count > this.maxLvl) {
return { error: `Upgraded level ${currentLevel + count} exceeds max` };
}
const cost = this.calculateCost(currentLevel, count); const cost = this.calculateCost(currentLevel, count);
if (cost > bladeburner.skillPoints) return { error: `Insufficient skill points for upgrade` }; if (cost > bladeburner.skillPoints) {
return { error: `Insufficient skill points for upgrade` };
}
return { available: true, cost }; return { available: true, cost };
} }