Proof-of-concept, handling purchases of 1e150 lvls at once

Threw something together with a formula that should, for large
purchases, be roughly the same cost as normal. The formula change
may cause noticeable deviation from expected costs for low numbers
of upgrades, though, so I plan to fix that by having high
quantities handled differently than low ones if necessary.
This commit is contained in:
Undeemiss 2022-05-28 20:37:33 -05:00
parent 709fc3ab63
commit 908d5e9570
4 changed files with 278 additions and 274 deletions

@ -236,13 +236,13 @@ export class Bladeburner implements IBladeburner {
}
}
upgradeSkill(skill: Skill): void {
upgradeSkill(skill: Skill, count = 1): void {
// This does NOT handle deduction of skill points
const skillName = skill.name;
if (this.skills[skillName]) {
++this.skills[skillName];
this.skills[skillName] += count;
} else {
this.skills[skillName] = 1;
this.skills[skillName] = count;
}
if (isNaN(this.skills[skillName]) || this.skills[skillName] < 0) {
throw new Error("Level of Skill " + skillName + " is invalid: " + this.skills[skillName]);
@ -1577,8 +1577,7 @@ export class Bladeburner implements IBladeburner {
this.stamina = Math.min(this.maxStamina, this.stamina + staminaGain);
if (this.logging.general) {
this.log(
`${person.whoAmI()}: Rested in Hyperbolic Regeneration Chamber. Restored ${
BladeburnerConstants.HrcHpGain
`${person.whoAmI()}: Rested in Hyperbolic Regeneration Chamber. Restored ${BladeburnerConstants.HrcHpGain
} HP and gained ${numeralWrapper.formatStamina(staminaGain)} stamina`,
);
}
@ -2290,7 +2289,7 @@ export class Bladeburner implements IBladeburner {
}
}
upgradeSkillNetscriptFn(skillName: string, workerScript: WorkerScript): boolean {
upgradeSkillNetscriptFn(skillName: string, count: number, workerScript: WorkerScript): boolean {
const errorLogText = `Invalid skill: '${skillName}'`;
if (!Skills.hasOwnProperty(skillName)) {
workerScript.log("bladeburner.upgradeSkill", () => errorLogText);
@ -2302,10 +2301,10 @@ export class Bladeburner implements IBladeburner {
if (this.skills[skillName] && !isNaN(this.skills[skillName])) {
currentLevel = this.skills[skillName];
}
const cost = skill.calculateCost(currentLevel);
const cost = skill.calculateCost(currentLevel, count);
if (skill.maxLvl && currentLevel >= skill.maxLvl) {
workerScript.log("bladeburner.upgradeSkill", () => `Skill '${skillName}' is already maxed.`);
if (skill.maxLvl && currentLevel + count > skill.maxLvl) {
workerScript.log("bladeburner.upgradeSkill", () => `Skill '${skillName}' cannot be upgraded ${count} time(s).`);
return false;
}
@ -2313,13 +2312,13 @@ export class Bladeburner implements IBladeburner {
workerScript.log(
"bladeburner.upgradeSkill",
() =>
`You do not have enough skill points to upgrade ${skillName} (You have ${this.skillPoints}, you need ${cost})`,
`You do not have enough skill points to upgrade ${skillName} ${count} time(s). (You have ${this.skillPoints}, you need ${cost})`,
);
return false;
}
this.skillPoints -= cost;
this.upgradeSkill(skill);
this.upgradeSkill(skill, count);
workerScript.log("bladeburner.upgradeSkill", () => `'${skillName}' upgraded to level ${this.skills[skillName]}`);
return true;
}

@ -77,7 +77,7 @@ export interface IBladeburner {
getActionCountRemainingNetscriptFn(type: string, name: string, workerScript: WorkerScript): number;
getSkillLevelNetscriptFn(skillName: string, workerScript: WorkerScript): number;
getSkillUpgradeCostNetscriptFn(skillName: string, workerScript: WorkerScript): number;
upgradeSkillNetscriptFn(skillName: string, workerScript: WorkerScript): boolean;
upgradeSkillNetscriptFn(skillName: string, count: number, workerScript: WorkerScript): boolean;
getTeamSizeNetscriptFn(type: string, name: string, workerScript: WorkerScript): number;
setTeamSizeNetscriptFn(type: string, name: string, size: number, workerScript: WorkerScript): number;
joinBladeburnerFactionNetscriptFn(workerScript: WorkerScript): boolean;

@ -133,8 +133,13 @@ export class Skill {
}
}
calculateCost(currentLevel: number): number {
return Math.floor((this.baseCost + currentLevel * this.costInc) * BitNodeMultipliers.BladeburnerSkillCost);
calculateCost(currentLevel: number, count = 1): number {
//unFloored is roughly equivalent to
//(this.baseCost + currentLevel * this.costInc) * BitNodeMultipliers.BladeburnerSkillCost
//being repeated for increasing currentLevel
const preMult = (count + 1) * (2 * this.baseCost + this.costInc * (2 * currentLevel + count)) / 2;
const unFloored = (preMult * BitNodeMultipliers.BladeburnerSkillCost) - count / 2;
return Math.floor(unFloored);
}
getMultiplier(name: string): number {

@ -298,12 +298,12 @@ export function NetscriptBladeburner(player: IPlayer, workerScript: WorkerScript
const bladeburner = player.bladeburner;
if (bladeburner === null) throw new Error("Should not be called without Bladeburner");
try {
for(let i=0; i<count; i++){
if(!bladeburner.upgradeSkillNetscriptFn(skillName, workerScript)){
return i;
}
}
if(bladeburner.upgradeSkillNetscriptFn(skillName, count, workerScript)){
return count;
}
else{
return 0;
}
} catch (e: any) {
throw ctx.makeRuntimeErrorMsg(e);
}