diff --git a/doc/source/changelog.rst b/doc/source/changelog.rst index 8af5fdca7..7ac997654 100644 --- a/doc/source/changelog.rst +++ b/doc/source/changelog.rst @@ -26,7 +26,7 @@ v2.0.0 - 2022-07-19 Work rework * Company faction require 400k rep to join (from 200k) * Backdooring company server reduces faction requirement to 300k. * All work generally no longer keep track of cumulative gains like exp and reputation since it's applied instantly. -* getPlayer returns way less fields but does return the new 'currentWork' field. + * getPlayer returns way less fields but does return the new 'currentWork' field, some fields are moved around. API breaks diff --git a/doc/source/v2.0.0_migration.rst b/doc/source/v2.0.0_migration.rst index 252a83ede..e8bba2d80 100644 --- a/doc/source/v2.0.0_migration.rst +++ b/doc/source/v2.0.0_migration.rst @@ -60,7 +60,16 @@ getPlayer Take a look at the new singularity.getCurrentWork function. All fields ending in _mult have been moved to the 'mults' struct. - For example: getPlayer().hacking_skill_mult is now getPlayer().mults.hacking_skill + For example: getPlayer().hacking_skill_mult => getPlayer().mults.hacking_skill + + skills have been moved to the skills struct + For example: getPlayer().hacking => getPlayer().skills.hacking + + exp have been moved to the exp struct + For example: getPlayer().hacking_exp => getPlayer().exp.hacking + + hp have been moved to the hp struct + For example: getPlayer().max_hp => getPlayer().hp.max or hp.current workForCompany -------------- diff --git a/src/Achievements/Achievements.ts b/src/Achievements/Achievements.ts index c3a52c426..2ee85897d 100644 --- a/src/Achievements/Achievements.ts +++ b/src/Achievements/Achievements.ts @@ -254,13 +254,16 @@ export const achievements: IMap = { HACKING_100000: { ...achievementData["HACKING_100000"], Icon: "hack100000", - Condition: () => Player.hacking >= 100000, + Condition: () => Player.skills.hacking >= 100000, }, COMBAT_3000: { ...achievementData["COMBAT_3000"], Icon: "combat3000", Condition: () => - Player.strength >= 3000 && Player.defense >= 3000 && Player.dexterity >= 3000 && Player.agility >= 3000, + Player.skills.strength >= 3000 && + Player.skills.defense >= 3000 && + Player.skills.dexterity >= 3000 && + Player.skills.agility >= 3000, }, NEUROFLUX_255: { ...achievementData["NEUROFLUX_255"], @@ -477,7 +480,7 @@ export const achievements: IMap = { ...achievementData["INTELLIGENCE_255"], Icon: "INT255", Visible: () => hasAccessToSF(Player, 5), - Condition: () => Player.intelligence >= 255, + Condition: () => Player.skills.intelligence >= 255, }, BLADEBURNER_DIVISION: { ...achievementData["BLADEBURNER_DIVISION"], @@ -644,12 +647,12 @@ export const achievements: IMap = { !Player.sleeves.some( (s) => s.augmentations.length > 0 || - s.hacking_exp > 0 || - s.strength_exp > 0 || - s.defense_exp > 0 || - s.agility_exp > 0 || - s.dexterity_exp > 0 || - s.charisma_exp > 0, + s.exp.hacking > 0 || + s.exp.strength > 0 || + s.exp.defense > 0 || + s.exp.agility > 0 || + s.exp.dexterity > 0 || + s.exp.charisma > 0, ), }, CHALLENGE_BN12: { diff --git a/src/Bladeburner/Action.tsx b/src/Bladeburner/Action.tsx index 21ca7b494..90a735046 100644 --- a/src/Bladeburner/Action.tsx +++ b/src/Bladeburner/Action.tsx @@ -167,8 +167,8 @@ export class Action implements IAction { let baseTime = difficulty / BladeburnerConstants.DifficultyToTimeFactor; const skillFac = inst.skillMultipliers.actionTime; // Always < 1 - const effAgility = person.agility * inst.skillMultipliers.effAgi; - const effDexterity = person.dexterity * inst.skillMultipliers.effDex; + const effAgility = person.skills.agility * inst.skillMultipliers.effAgi; + const effDexterity = person.skills.dexterity * inst.skillMultipliers.effDex; const statFac = 0.5 * (Math.pow(effAgility, BladeburnerConstants.EffAgiExponentialFactor) + diff --git a/src/Bladeburner/Bladeburner.tsx b/src/Bladeburner/Bladeburner.tsx index 830549a20..73b6c21b1 100644 --- a/src/Bladeburner/Bladeburner.tsx +++ b/src/Bladeburner/Bladeburner.tsx @@ -1027,16 +1027,17 @@ export class Bladeburner implements IBladeburner { const CharismaLinearFactor = 1e3; const CharismaExponentialFactor = 0.045; - const charismaEff = Math.pow(person.charisma, CharismaExponentialFactor) + person.charisma / CharismaLinearFactor; + const charismaEff = + Math.pow(person.skills.charisma, CharismaExponentialFactor) + person.skills.charisma / CharismaLinearFactor; return (100 - charismaEff) / 100; } getRecruitmentSuccessChance(person: IPerson): number { - return Math.pow(person.charisma, 0.45) / (this.teamSize - this.sleeveSize + 1); + return Math.pow(person.skills.charisma, 0.45) / (this.teamSize - this.sleeveSize + 1); } getRecruitmentTime(person: IPerson): number { - const effCharisma = person.charisma * this.skillMultipliers.effCha; + const effCharisma = person.skills.charisma * this.skillMultipliers.effCha; const charismaFactor = Math.pow(effCharisma, 0.81) + effCharisma / 90; return Math.max(10, Math.round(BladeburnerConstants.BaseRecruitmentTimeNeeded - charismaFactor)); } @@ -1126,7 +1127,7 @@ export class Bladeburner implements IBladeburner { const sup = player.sleeves.filter((x) => x.bbAction == "Support main sleeve"); for (let i = 0; i > this.teamSize - this.sleeveSize; i--) { const r = Math.floor(Math.random() * sup.length); - sup[r].takeDamage(sup[r].max_hp); + sup[r].takeDamage(sup[r].hp.max); sup.splice(r, 1); } this.teamSize += this.sleeveSize; @@ -1440,7 +1441,7 @@ export class Bladeburner implements IBladeburner { const sup = player.sleeves.filter((x) => x.bbAction == "Support main sleeve"); for (let i = 0; i > this.teamSize - this.sleeveSize; i--) { const r = Math.floor(Math.random() * sup.length); - sup[r].takeDamage(sup[r].max_hp); + sup[r].takeDamage(sup[r].hp.max); sup.splice(r, 1); } this.teamSize += this.sleeveSize; @@ -1489,9 +1490,9 @@ export class Bladeburner implements IBladeburner { case ActionTypes["Field Analysis"]: { // Does not use stamina. Effectiveness depends on hacking, int, and cha let eff = - 0.04 * Math.pow(person.hacking, 0.3) + - 0.04 * Math.pow(person.intelligence, 0.9) + - 0.02 * Math.pow(person.charisma, 0.3); + 0.04 * Math.pow(person.skills.hacking, 0.3) + + 0.04 * Math.pow(person.skills.intelligence, 0.9) + + 0.02 * Math.pow(person.skills.charisma, 0.3); eff *= person.mults.bladeburner_analysis; if (isNaN(eff) || eff < 0) { throw new Error("Field Analysis Effectiveness calculated to be NaN or negative"); @@ -1680,14 +1681,14 @@ export class Bladeburner implements IBladeburner { } calculateStaminaGainPerSecond(player: IPlayer): number { - const effAgility = player.agility * this.skillMultipliers.effAgi; + const effAgility = player.skills.agility * this.skillMultipliers.effAgi; const maxStaminaBonus = this.maxStamina / BladeburnerConstants.MaxStaminaToGainFactor; const gain = (BladeburnerConstants.StaminaGainPerSecond + maxStaminaBonus) * Math.pow(effAgility, 0.17); return gain * (this.skillMultipliers.stamina * player.mults.bladeburner_stamina_gain); } calculateMaxStamina(player: IPlayer): void { - const effAgility = player.agility * this.skillMultipliers.effAgi; + const effAgility = player.skills.agility * this.skillMultipliers.effAgi; const maxStamina = (Math.pow(effAgility, 0.8) + this.staminaBonus) * this.skillMultipliers.stamina * diff --git a/src/Constants.ts b/src/Constants.ts index 0a7bdb0fd..912bd830e 100644 --- a/src/Constants.ts +++ b/src/Constants.ts @@ -89,7 +89,7 @@ export const CONSTANTS: { LatestUpdate: string; } = { VersionString: "2.0.0", - VersionNumber: 21, + VersionNumber: 22, // Speed (in ms) at which the main loop is updated _idleSpeed: 200, @@ -255,7 +255,7 @@ v2.0.0 - 2022-07-19 Work rework * Company faction require 400k rep to join (from 200k) * Backdooring company server reduces faction requirement to 300k. * All work generally no longer keep track of cumulative gains like exp and reputation since it's applied instantly. - * getPlayer returns way less fields but does return the new 'currentWork' field. + * getPlayer returns way less fields but does return the new 'currentWork' field, some fields are moved around. API breaks diff --git a/src/Crime/Crime.ts b/src/Crime/Crime.ts index 65587b0c2..e68096504 100644 --- a/src/Crime/Crime.ts +++ b/src/Crime/Crime.ts @@ -112,13 +112,13 @@ export class Crime { successRate(p: IPerson): number { let chance: number = - this.hacking_success_weight * p.hacking + - this.strength_success_weight * p.strength + - this.defense_success_weight * p.defense + - this.dexterity_success_weight * p.dexterity + - this.agility_success_weight * p.agility + - this.charisma_success_weight * p.charisma + - CONSTANTS.IntelligenceCrimeWeight * p.intelligence; + this.hacking_success_weight * p.skills.hacking + + this.strength_success_weight * p.skills.strength + + this.defense_success_weight * p.skills.defense + + this.dexterity_success_weight * p.skills.dexterity + + this.agility_success_weight * p.skills.agility + + this.charisma_success_weight * p.skills.charisma + + CONSTANTS.IntelligenceCrimeWeight * p.skills.intelligence; chance /= CONSTANTS.MaxSkillLevel; chance /= this.difficulty; chance *= p.mults.crime_success; diff --git a/src/DevMenu/ui/Stats.tsx b/src/DevMenu/ui/Stats.tsx index ae2034d96..a664214cf 100644 --- a/src/DevMenu/ui/Stats.tsx +++ b/src/DevMenu/ui/Stats.tsx @@ -78,13 +78,13 @@ export function Stats(props: IProps): React.ReactElement { } function resetAllExp(): void { - props.player.hacking_exp = 0; - props.player.strength_exp = 0; - props.player.defense_exp = 0; - props.player.dexterity_exp = 0; - props.player.agility_exp = 0; - props.player.charisma_exp = 0; - props.player.intelligence_exp = 0; + props.player.exp.hacking = 0; + props.player.exp.strength = 0; + props.player.exp.defense = 0; + props.player.exp.dexterity = 0; + props.player.exp.agility = 0; + props.player.exp.charisma = 0; + props.player.exp.intelligence = 0; props.player.updateSkillLevels(); } @@ -92,25 +92,25 @@ export function Stats(props: IProps): React.ReactElement { return function () { switch (stat) { case "hacking": - props.player.hacking_exp = 0; + props.player.exp.hacking = 0; break; case "strength": - props.player.strength_exp = 0; + props.player.exp.strength = 0; break; case "defense": - props.player.defense_exp = 0; + props.player.exp.defense = 0; break; case "dexterity": - props.player.dexterity_exp = 0; + props.player.exp.dexterity = 0; break; case "agility": - props.player.agility_exp = 0; + props.player.exp.agility = 0; break; case "charisma": - props.player.charisma_exp = 0; + props.player.exp.charisma = 0; break; case "intelligence": - props.player.intelligence_exp = 0; + props.player.exp.intelligence = 0; break; } props.player.updateSkillLevels(); @@ -124,15 +124,15 @@ export function Stats(props: IProps): React.ReactElement { } function enableIntelligence(): void { - if (props.player.intelligence === 0) { - props.player.intelligence = 1; + if (props.player.skills.intelligence === 0) { + props.player.skills.intelligence = 1; props.player.updateSkillLevels(); } } function disableIntelligence(): void { - props.player.intelligence_exp = 0; - props.player.intelligence = 0; + props.player.exp.intelligence = 0; + props.player.skills.intelligence = 0; props.player.updateSkillLevels(); } diff --git a/src/Hacking.ts b/src/Hacking.ts index 640b45e94..ebaa2b5a0 100644 --- a/src/Hacking.ts +++ b/src/Hacking.ts @@ -9,10 +9,13 @@ import { Server } from "./Server/Server"; export function calculateHackingChance(server: Server, player: IPlayer): number { const hackFactor = 1.75; const difficultyMult = (100 - server.hackDifficulty) / 100; - const skillMult = hackFactor * player.hacking; + const skillMult = hackFactor * player.skills.hacking; const skillChance = (skillMult - server.requiredHackingSkill) / skillMult; const chance = - skillChance * difficultyMult * player.mults.hacking_chance * calculateIntelligenceBonus(player.intelligence, 1); + skillChance * + difficultyMult * + player.mults.hacking_chance * + calculateIntelligenceBonus(player.skills.intelligence, 1); if (chance > 1) { return 1; } @@ -48,7 +51,7 @@ export function calculatePercentMoneyHacked(server: Server, player: IPlayer): nu const balanceFactor = 240; const difficultyMult = (100 - server.hackDifficulty) / 100; - const skillMult = (player.hacking - (server.requiredHackingSkill - 1)) / player.hacking; + const skillMult = (player.skills.hacking - (server.requiredHackingSkill - 1)) / player.skills.hacking; const percentMoneyHacked = (difficultyMult * skillMult * player.mults.hacking_money * BitNodeMultipliers.ScriptHackMoney) / balanceFactor; if (percentMoneyHacked < 0) { @@ -72,12 +75,12 @@ export function calculateHackingTime(server: Server, player: IPlayer): number { const diffFactor = 2.5; let skillFactor = diffFactor * difficultyMult + baseDiff; // tslint:disable-next-line - skillFactor /= player.hacking + baseSkill; + skillFactor /= player.skills.hacking + baseSkill; const hackTimeMultiplier = 5; const hackingTime = (hackTimeMultiplier * skillFactor) / - (player.mults.hacking_speed * calculateIntelligenceBonus(player.intelligence, 1)); + (player.mults.hacking_speed * calculateIntelligenceBonus(player.skills.intelligence, 1)); return hackingTime; } diff --git a/src/Hacking/netscriptCanHack.ts b/src/Hacking/netscriptCanHack.ts index ec47aaed9..885fccdad 100644 --- a/src/Hacking/netscriptCanHack.ts +++ b/src/Hacking/netscriptCanHack.ts @@ -36,7 +36,7 @@ export function netscriptCanHack(server: Server, p: IPlayer): IReturnStatus { } const s = server; - if (s.requiredHackingSkill > p.hacking) { + if (s.requiredHackingSkill > p.skills.hacking) { return { res: false, msg: `Cannot hack ${server.hostname} server because your hacking skill is not high enough`, diff --git a/src/Hospital/Hospital.ts b/src/Hospital/Hospital.ts index c392df19c..abfbc65e3 100644 --- a/src/Hospital/Hospital.ts +++ b/src/Hospital/Hospital.ts @@ -6,13 +6,13 @@ export function getHospitalizationCost(p: IPlayer): number { return 0; } - return Math.min(p.money * 0.1, (p.max_hp - p.hp) * CONSTANTS.HospitalCostPerHp); + return Math.min(p.money * 0.1, (p.hp.max - p.hp.current) * CONSTANTS.HospitalCostPerHp); } export function calculateHospitalizationCost(p: IPlayer, damage: number): number { - const oldhp = p.hp; - p.hp -= damage; + const oldhp = p.hp.current; + p.hp.current -= damage; const cost = getHospitalizationCost(p); - p.hp = oldhp; + p.hp.current = oldhp; return cost; } diff --git a/src/Infiltration/formulas/game.ts b/src/Infiltration/formulas/game.ts index f6f052c6f..e6ab67a54 100644 --- a/src/Infiltration/formulas/game.ts +++ b/src/Infiltration/formulas/game.ts @@ -2,14 +2,19 @@ import { IPlayer } from "../../PersonObjects/IPlayer"; import { calculateSkill } from "../../PersonObjects/formulas/skill"; function calculateRawDiff(player: IPlayer, stats: number, startingDifficulty: number): number { - const difficulty = startingDifficulty - Math.pow(stats, 0.9) / 250 - player.intelligence / 1600; + const difficulty = startingDifficulty - Math.pow(stats, 0.9) / 250 - player.skills.intelligence / 1600; if (difficulty < 0) return 0; if (difficulty > 3) return 3; return difficulty; } export function calculateDifficulty(player: IPlayer, startingSecurityLevel: number): number { - const totalStats = player.strength + player.defense + player.dexterity + player.agility + player.charisma; + const totalStats = + player.skills.strength + + player.skills.defense + + player.skills.dexterity + + player.skills.agility + + player.skills.charisma; return calculateRawDiff(player, totalStats, startingSecurityLevel); } diff --git a/src/Infiltration/ui/Game.tsx b/src/Infiltration/ui/Game.tsx index 52c972add..c0ebef6f8 100644 --- a/src/Infiltration/ui/Game.tsx +++ b/src/Infiltration/ui/Game.tsx @@ -91,7 +91,7 @@ export function Game(props: IProps): React.ReactElement { // Kill the player immediately if they use automation, so // it's clear they're not meant to const damage = options?.automated - ? player.hp + ? player.hp.current : props.StartingDifficulty * 3 * (player.hasAugmentation(AugmentationNames.WKSharmonizer, true) ? 0.5 : 1); if (player.takeDamage(damage)) { router.toCity(); diff --git a/src/Locations/ui/HospitalLocation.tsx b/src/Locations/ui/HospitalLocation.tsx index 2be5ae449..bdc002a93 100644 --- a/src/Locations/ui/HospitalLocation.tsx +++ b/src/Locations/ui/HospitalLocation.tsx @@ -34,7 +34,7 @@ export class HospitalLocation extends React.Component { this.getHealed = this.getHealed.bind(this); this.state = { - currHp: this.props.p.hp, + currHp: this.props.p.hp.current, }; } @@ -47,20 +47,20 @@ export class HospitalLocation extends React.Component { return; } - if (this.props.p.hp < 0) { - this.props.p.hp = 0; + if (this.props.p.hp.current < 0) { + this.props.p.hp.current = 0; } - if (this.props.p.hp >= this.props.p.max_hp) { + if (this.props.p.hp.current >= this.props.p.hp.max) { return; } const cost = this.getCost(); this.props.p.loseMoney(cost, "hospitalization"); - this.props.p.hp = this.props.p.max_hp; + this.props.p.hp.current = this.props.p.hp.max; // This just forces a re-render to update the cost this.setState({ - currHp: this.props.p.hp, + currHp: this.props.p.hp.current, }); dialogBoxCreate( diff --git a/src/Locations/ui/SpecialLocation.tsx b/src/Locations/ui/SpecialLocation.tsx index 0aedb1cee..ecf83e494 100644 --- a/src/Locations/ui/SpecialLocation.tsx +++ b/src/Locations/ui/SpecialLocation.tsx @@ -54,7 +54,12 @@ export function SpecialLocation(props: IProps): React.ReactElement { if (p.inBladeburner()) { // Enter Bladeburner division router.toBladeburner(); - } else if (p.strength >= 100 && p.defense >= 100 && p.dexterity >= 100 && p.agility >= 100) { + } else if ( + p.skills.strength >= 100 && + p.skills.defense >= 100 && + p.skills.dexterity >= 100 && + p.skills.agility >= 100 + ) { // Apply for Bladeburner division p.startBladeburner(); dialogBoxCreate("You have been accepted into the Bladeburner division!"); @@ -96,14 +101,14 @@ export function SpecialLocation(props: IProps): React.ReactElement { N00dles(); // This is the true power of the noodles. if (player.sourceFiles.length > 0) player.giveExploit(Exploit.N00dles); if (player.sourceFileLvl(5) > 0 || player.bitNodeN === 5) { - player.intelligence_exp *= 1.0000000000000002; + player.exp.intelligence *= 1.0000000000000002; } - player.hacking_exp *= 1.0000000000000002; - player.strength_exp *= 1.0000000000000002; - player.defense_exp *= 1.0000000000000002; - player.agility_exp *= 1.0000000000000002; - player.dexterity_exp *= 1.0000000000000002; - player.charisma_exp *= 1.0000000000000002; + player.exp.hacking *= 1.0000000000000002; + player.exp.strength *= 1.0000000000000002; + player.exp.defense *= 1.0000000000000002; + player.exp.agility *= 1.0000000000000002; + player.exp.dexterity *= 1.0000000000000002; + player.exp.charisma *= 1.0000000000000002; for (const node of player.hacknetNodes) { if (node instanceof HacknetNode) { player.gainMoney(node.moneyGainRatePerSecond * 0.001, "other"); diff --git a/src/Message/MessageHelpers.ts b/src/Message/MessageHelpers.ts index cf36f15ad..82d0d6353 100644 --- a/src/Message/MessageHelpers.ts +++ b/src/Message/MessageHelpers.ts @@ -76,33 +76,33 @@ function checkForMessagesToSend(): void { throw new Error("The world daemon is not a server???? Please un-break reality"); } //If the daemon can be hacked, send the player icarus.msg - if (Player.hacking >= worldDaemon.requiredHackingSkill) { + if (Player.skills.hacking >= worldDaemon.requiredHackingSkill) { sendMessage(redpill, Player.sourceFiles.length === 0); } //If the daemon cannot be hacked, send the player truthgazer.msg a single time. else if (!recvd(truthGazer)) { sendMessage(truthGazer); } - } else if (!recvd(jumper0) && Player.hacking >= 25) { + } else if (!recvd(jumper0) && Player.skills.hacking >= 25) { sendMessage(jumper0); const flightName = Programs.Flight.name; const homeComp = Player.getHomeComputer(); if (!homeComp.programs.includes(flightName)) { homeComp.programs.push(flightName); } - } else if (!recvd(jumper1) && Player.hacking >= 40) { + } else if (!recvd(jumper1) && Player.skills.hacking >= 40) { sendMessage(jumper1); - } else if (!recvd(cybersecTest) && Player.hacking >= 50) { + } else if (!recvd(cybersecTest) && Player.skills.hacking >= 50) { sendMessage(cybersecTest); - } else if (!recvd(jumper2) && Player.hacking >= 175) { + } else if (!recvd(jumper2) && Player.skills.hacking >= 175) { sendMessage(jumper2); - } else if (!recvd(nitesecTest) && Player.hacking >= 200) { + } else if (!recvd(nitesecTest) && Player.skills.hacking >= 200) { sendMessage(nitesecTest); - } else if (!recvd(jumper3) && Player.hacking >= 350) { + } else if (!recvd(jumper3) && Player.skills.hacking >= 350) { sendMessage(jumper3); - } else if (!recvd(jumper4) && Player.hacking >= 490) { + } else if (!recvd(jumper4) && Player.skills.hacking >= 490) { sendMessage(jumper4); - } else if (!recvd(bitrunnersTest) && Player.hacking >= 500) { + } else if (!recvd(bitrunnersTest) && Player.skills.hacking >= 500) { sendMessage(bitrunnersTest); } } diff --git a/src/NetscriptFunctions.ts b/src/NetscriptFunctions.ts index 71b9ddeeb..e5825101c 100644 --- a/src/NetscriptFunctions.ts +++ b/src/NetscriptFunctions.ts @@ -941,7 +941,9 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { }, share: (ctx: NetscriptContext) => async (): Promise => { ctx.log(() => "Sharing this computer."); - const end = StartSharing(workerScript.scriptRef.threads * calculateIntelligenceBonus(Player.intelligence, 2)); + const end = StartSharing( + workerScript.scriptRef.threads * calculateIntelligenceBonus(Player.skills.intelligence, 2), + ); return netscriptDelay(10000, workerScript).finally(function () { ctx.log(() => "Finished sharing this computer."); end(); @@ -1614,8 +1616,8 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { }, getHackingLevel: (ctx: NetscriptContext) => (): number => { Player.updateSkillLevels(); - ctx.log(() => `returned ${Player.hacking}`); - return Player.hacking; + ctx.log(() => `returned ${Player.skills.hacking}`); + return Player.skills.hacking; }, getHackingMultipliers: () => (): HackingMultipliers => { return { @@ -2434,21 +2436,9 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { }, getPlayer: () => (): INetscriptPlayer => { const data = { - hacking: Player.hacking, hp: Player.hp, - max_hp: Player.max_hp, - strength: Player.strength, - defense: Player.defense, - dexterity: Player.dexterity, - agility: Player.agility, - charisma: Player.charisma, - intelligence: Player.intelligence, - hacking_exp: Player.hacking_exp, - strength_exp: Player.strength_exp, - defense_exp: Player.defense_exp, - dexterity_exp: Player.dexterity_exp, - agility_exp: Player.agility_exp, - charisma_exp: Player.charisma_exp, + skills: Player.skills, + exp: Player.exp, hacking_chance_mult: Player.mults.hacking_chance, mults: JSON.parse(JSON.stringify(Player.mults)), numPeopleKilled: Player.numPeopleKilled, @@ -2469,7 +2459,6 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS { inBladeburner: Player.inBladeburner(), hasCorporation: Player.hasCorporation(), entropy: Player.entropy, - currentWork: Player.currentWork, }; Object.assign(data.jobs, Player.jobs); return data; diff --git a/src/NetscriptFunctions/Bladeburner.ts b/src/NetscriptFunctions/Bladeburner.ts index b126d9938..d0ddc1677 100644 --- a/src/NetscriptFunctions/Bladeburner.ts +++ b/src/NetscriptFunctions/Bladeburner.ts @@ -403,10 +403,10 @@ export function NetscriptBladeburner(player: IPlayer, workerScript: WorkerScript if (player.bladeburner instanceof Bladeburner) { return true; // Already member } else if ( - player.strength >= 100 && - player.defense >= 100 && - player.dexterity >= 100 && - player.agility >= 100 + player.skills.strength >= 100 && + player.skills.defense >= 100 && + player.skills.dexterity >= 100 && + player.skills.agility >= 100 ) { player.bladeburner = new Bladeburner(player); ctx.log(() => "You have been accepted into the Bladeburner division"); diff --git a/src/NetscriptFunctions/Singularity.ts b/src/NetscriptFunctions/Singularity.ts index 1b14a7046..ff6402bae 100644 --- a/src/NetscriptFunctions/Singularity.ts +++ b/src/NetscriptFunctions/Singularity.ts @@ -1257,7 +1257,7 @@ export function NetscriptSingularity(player: IPlayer, workerScript: WorkerScript const wd = GetServer(SpecialServers.WorldDaemon); if (!(wd instanceof Server)) throw new Error("WorldDaemon was not a normal server. This is a bug contact dev."); - if (player.hacking < wd.requiredHackingSkill) return false; + if (player.skills.hacking < wd.requiredHackingSkill) return false; if (!wd.hasAdminRights) return false; return true; }; diff --git a/src/NetscriptFunctions/Sleeve.ts b/src/NetscriptFunctions/Sleeve.ts index f13ba2e74..bb8109f67 100644 --- a/src/NetscriptFunctions/Sleeve.ts +++ b/src/NetscriptFunctions/Sleeve.ts @@ -40,12 +40,12 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI { shock: 100 - sl.shock, sync: sl.sync, memory: sl.memory, - hacking: sl.hacking, - strength: sl.strength, - defense: sl.defense, - dexterity: sl.dexterity, - agility: sl.agility, - charisma: sl.charisma, + hacking: sl.skills.hacking, + strength: sl.skills.strength, + defense: sl.skills.defense, + dexterity: sl.skills.dexterity, + agility: sl.skills.agility, + charisma: sl.skills.charisma, }; }; @@ -206,10 +206,10 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI { return { tor: false, city: sl.city, - hp: sl.hp, + hp: sl.hp.current, jobs: Object.keys(player.jobs), // technically sleeves have the same jobs as the player. jobTitle: Object.values(player.jobs), - maxHp: sl.max_hp, + maxHp: sl.hp.max, mult: { agility: sl.mults.agility, diff --git a/src/PersonObjects/HP.ts b/src/PersonObjects/HP.ts new file mode 100644 index 000000000..35b263fbf --- /dev/null +++ b/src/PersonObjects/HP.ts @@ -0,0 +1,4 @@ +export interface HP { + current: number; + max: number; +} diff --git a/src/PersonObjects/IPerson.ts b/src/PersonObjects/IPerson.ts index 6d4d48d6f..f1611d483 100644 --- a/src/PersonObjects/IPerson.ts +++ b/src/PersonObjects/IPerson.ts @@ -2,29 +2,15 @@ // a Sleeve. Used for functions that need to take in both. import { IPlayerOwnedAugmentation } from "../Augmentation/PlayerOwnedAugmentation"; +import { HP } from "./HP"; import { ITaskTracker } from "./ITaskTracker"; import { Multipliers } from "./Multipliers"; +import { Skills } from "./Skills"; export interface IPerson { - // Stats - hacking: number; - strength: number; - defense: number; - dexterity: number; - agility: number; - charisma: number; - intelligence: number; - hp: number; - max_hp: number; - - // Experience - hacking_exp: number; - strength_exp: number; - defense_exp: number; - dexterity_exp: number; - agility_exp: number; - charisma_exp: number; - intelligence_exp: number; + hp: HP; + skills: Skills; + exp: Skills; mults: Multipliers; diff --git a/src/PersonObjects/IPlayer.ts b/src/PersonObjects/IPlayer.ts index 815cf54f4..4070fd0e1 100644 --- a/src/PersonObjects/IPlayer.ts +++ b/src/PersonObjects/IPlayer.ts @@ -31,6 +31,8 @@ import { PlayerAchievement } from "../Achievements/Achievements"; import { IPerson } from "./IPerson"; import { Work } from "../Work/Work"; import { Multipliers } from "./Multipliers"; +import { Skills } from "./Skills"; +import { HP } from "./HP"; export interface IPlayer extends IPerson { bitNodeN: number; @@ -47,12 +49,10 @@ export interface IPlayer extends IPerson { hashManager: HashManager; hasTixApiAccess: boolean; hasWseAccount: boolean; - hp: number; jobs: IMap; karma: number; numPeopleKilled: number; location: LocationName; - max_hp: number; readonly money: number; moneySourceA: MoneySourceTracker; moneySourceB: MoneySourceTracker; @@ -70,23 +70,9 @@ export interface IPlayer extends IPerson { lastUpdate: number; totalPlaytime: number; - // Stats - hacking: number; - strength: number; - defense: number; - dexterity: number; - agility: number; - charisma: number; - intelligence: number; - - // Experience - hacking_exp: number; - strength_exp: number; - defense_exp: number; - dexterity_exp: number; - agility_exp: number; - charisma_exp: number; - intelligence_exp: number; + hp: HP; + skills: Skills; + exp: Skills; mults: Multipliers; diff --git a/src/PersonObjects/Person.ts b/src/PersonObjects/Person.ts index 47a15f26d..974c47065 100644 --- a/src/PersonObjects/Person.ts +++ b/src/PersonObjects/Person.ts @@ -8,32 +8,30 @@ import { calculateSkill } from "./formulas/skill"; import { calculateIntelligenceBonus } from "./formulas/intelligence"; import { IPerson } from "./IPerson"; import { defaultMultipliers, mergeMultipliers } from "./Multipliers"; +import { Skills } from "./Skills"; +import { HP } from "./HP"; // Base class representing a person-like object export abstract class Person implements IPerson { - /** - * Stats - */ - hacking = 1; - strength = 1; - defense = 1; - dexterity = 1; - agility = 1; - charisma = 1; - intelligence = 0; - hp = 10; - max_hp = 10; - - /** - * Experience - */ - hacking_exp = 0; - strength_exp = 0; - defense_exp = 0; - dexterity_exp = 0; - agility_exp = 0; - charisma_exp = 0; - intelligence_exp = 0; + hp: HP = { current: 10, max: 10 }; + skills: Skills = { + hacking: 1, + strength: 1, + defense: 1, + dexterity: 1, + agility: 1, + charisma: 1, + intelligence: 1, + }; + exp: Skills = { + hacking: 0, + strength: 0, + defense: 0, + dexterity: 0, + agility: 0, + charisma: 0, + intelligence: 0, + }; mults = defaultMultipliers(); @@ -81,12 +79,12 @@ export abstract class Person implements IPerson { getFactionFieldWorkRepGain(): number { const t = (0.9 * - (this.hacking / CONSTANTS.MaxSkillLevel + - this.strength / CONSTANTS.MaxSkillLevel + - this.defense / CONSTANTS.MaxSkillLevel + - this.dexterity / CONSTANTS.MaxSkillLevel + - this.agility / CONSTANTS.MaxSkillLevel + - this.charisma / CONSTANTS.MaxSkillLevel)) / + (this.skills.hacking / CONSTANTS.MaxSkillLevel + + this.skills.strength / CONSTANTS.MaxSkillLevel + + this.skills.defense / CONSTANTS.MaxSkillLevel + + this.skills.dexterity / CONSTANTS.MaxSkillLevel + + this.skills.agility / CONSTANTS.MaxSkillLevel + + this.skills.charisma / CONSTANTS.MaxSkillLevel)) / 5.5; return t * this.mults.faction_rep; } @@ -96,7 +94,7 @@ export abstract class Person implements IPerson { * when doing Hacking Work for a faction */ getFactionHackingWorkRepGain(): number { - return (this.hacking / CONSTANTS.MaxSkillLevel) * this.mults.faction_rep; + return (this.skills.hacking / CONSTANTS.MaxSkillLevel) * this.mults.faction_rep; } /** @@ -106,11 +104,11 @@ export abstract class Person implements IPerson { getFactionSecurityWorkRepGain(): number { const t = (0.9 * - (this.hacking / CONSTANTS.MaxSkillLevel + - this.strength / CONSTANTS.MaxSkillLevel + - this.defense / CONSTANTS.MaxSkillLevel + - this.dexterity / CONSTANTS.MaxSkillLevel + - this.agility / CONSTANTS.MaxSkillLevel)) / + (this.skills.hacking / CONSTANTS.MaxSkillLevel + + this.skills.strength / CONSTANTS.MaxSkillLevel + + this.skills.defense / CONSTANTS.MaxSkillLevel + + this.skills.dexterity / CONSTANTS.MaxSkillLevel + + this.skills.agility / CONSTANTS.MaxSkillLevel)) / 4.5; return t * this.mults.faction_rep; } @@ -126,44 +124,44 @@ export abstract class Person implements IPerson { * Update all stat levels */ updateStatLevels(): void { - this.hacking = Math.max( + this.skills.hacking = Math.max( 1, - Math.floor(this.calculateStat(this.hacking_exp, this.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier)), + Math.floor(this.calculateStat(this.exp.hacking, this.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier)), ); - this.strength = Math.max( + this.skills.strength = Math.max( 1, Math.floor( - this.calculateStat(this.strength_exp, this.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier), + this.calculateStat(this.exp.strength, this.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier), ), ); - this.defense = Math.max( + this.skills.defense = Math.max( 1, - Math.floor(this.calculateStat(this.defense_exp, this.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier)), + Math.floor(this.calculateStat(this.exp.defense, this.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier)), ); - this.dexterity = Math.max( + this.skills.dexterity = Math.max( 1, Math.floor( - this.calculateStat(this.dexterity_exp, this.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier), + this.calculateStat(this.exp.dexterity, this.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier), ), ); - this.agility = Math.max( + this.skills.agility = Math.max( 1, - Math.floor(this.calculateStat(this.agility_exp, this.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier)), + Math.floor(this.calculateStat(this.exp.agility, this.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier)), ); - this.charisma = Math.max( + this.skills.charisma = Math.max( 1, Math.floor( - this.calculateStat(this.charisma_exp, this.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier), + this.calculateStat(this.exp.charisma, this.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier), ), ); - const ratio: number = this.hp / this.max_hp; - this.max_hp = Math.floor(10 + this.defense / 10); - this.hp = Math.round(this.max_hp * ratio); + const ratio: number = this.hp.current / this.hp.max; + this.hp.max = Math.floor(10 + this.skills.defense / 10); + this.hp.current = Math.round(this.hp.max * ratio); } getIntelligenceBonus(weight: number): number { - return calculateIntelligenceBonus(this.intelligence, weight); + return calculateIntelligenceBonus(this.skills.intelligence, weight); } abstract takeDamage(amt: number): boolean; diff --git a/src/PersonObjects/Player/PlayerObject.ts b/src/PersonObjects/Player/PlayerObject.ts index 3c32ccf75..fb7d34585 100644 --- a/src/PersonObjects/Player/PlayerObject.ts +++ b/src/PersonObjects/Player/PlayerObject.ts @@ -40,6 +40,8 @@ import { ITaskTracker } from "../ITaskTracker"; import { CONSTANTS } from "../../Constants"; import { Work } from "src/Work/Work"; import { defaultMultipliers, Multipliers } from "../Multipliers"; +import { HP } from "../HP"; +import { Skills } from "../Skills"; export class PlayerObject implements IPlayer { // Class members @@ -58,13 +60,11 @@ export class PlayerObject implements IPlayer { hashManager: HashManager; hasTixApiAccess: boolean; hasWseAccount: boolean; - hp: number; jobs: IMap; init: () => void; karma: number; numPeopleKilled: number; location: LocationName; - max_hp: number; money: number; moneySourceA: MoneySourceTracker; moneySourceB: MoneySourceTracker; @@ -84,23 +84,9 @@ export class PlayerObject implements IPlayer { lastSave: number; totalPlaytime: number; - // Stats - hacking: number; - strength: number; - defense: number; - dexterity: number; - agility: number; - charisma: number; - intelligence: number; - - // Experience - hacking_exp: number; - strength_exp: number; - defense_exp: number; - dexterity_exp: number; - agility_exp: number; - charisma_exp: number; - intelligence_exp: number; + hp: HP; + skills: Skills; + exp: Skills; mults: Multipliers; @@ -197,31 +183,25 @@ export class PlayerObject implements IPlayer { focusPenalty: () => number; constructor() { - //Skills and stats - this.hacking = 1; - - //Combat stats - this.hp = 10; - this.max_hp = 10; - this.strength = 1; - this.defense = 1; - this.dexterity = 1; - this.agility = 1; - - //Labor stats - this.charisma = 1; - - //Special stats - this.intelligence = 0; - - //Experience and multipliers - this.hacking_exp = 0; - this.strength_exp = 0; - this.defense_exp = 0; - this.dexterity_exp = 0; - this.agility_exp = 0; - this.charisma_exp = 0; - this.intelligence_exp = 0; + this.hp = { current: 10, max: 10 }; + this.skills = { + hacking: 1, + strength: 1, + defense: 1, + dexterity: 1, + agility: 1, + charisma: 1, + intelligence: 1, + }; + this.exp = { + hacking: 0, + strength: 0, + defense: 0, + dexterity: 0, + agility: 0, + charisma: 0, + intelligence: 0, + }; this.mults = defaultMultipliers(); diff --git a/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts b/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts index c43351a1f..1af8e7398 100644 --- a/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts +++ b/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts @@ -78,21 +78,21 @@ export function prestigeAugmentation(this: PlayerObject): void { this.numPeopleKilled = 0; //Reset stats - this.hacking = 1; + this.skills.hacking = 1; - this.strength = 1; - this.defense = 1; - this.dexterity = 1; - this.agility = 1; + this.skills.strength = 1; + this.skills.defense = 1; + this.skills.dexterity = 1; + this.skills.agility = 1; - this.charisma = 1; + this.skills.charisma = 1; - this.hacking_exp = 0; - this.strength_exp = 0; - this.defense_exp = 0; - this.dexterity_exp = 0; - this.agility_exp = 0; - this.charisma_exp = 0; + this.exp.hacking = 0; + this.exp.strength = 0; + this.exp.defense = 0; + this.exp.dexterity = 0; + this.exp.agility = 0; + this.exp.charisma = 0; this.money = 1000 + CONSTANTS.Donations; @@ -136,7 +136,7 @@ export function prestigeAugmentation(this: PlayerObject): void { // Reapply augs, re-calculate skills and reset HP this.reapplyAllAugmentations(true); - this.hp = this.max_hp; + this.hp.current = this.hp.max; this.finishWork(true); } @@ -197,46 +197,46 @@ export function calculateSkillProgress(this: IPlayer, exp: number, mult = 1): IS } export function updateSkillLevels(this: IPlayer): void { - this.hacking = Math.max( + this.skills.hacking = Math.max( 1, - Math.floor(this.calculateSkill(this.hacking_exp, this.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier)), + Math.floor(this.calculateSkill(this.exp.hacking, this.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier)), ); - this.strength = Math.max( + this.skills.strength = Math.max( 1, Math.floor( - this.calculateSkill(this.strength_exp, this.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier), + this.calculateSkill(this.exp.strength, this.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier), ), ); - this.defense = Math.max( + this.skills.defense = Math.max( 1, - Math.floor(this.calculateSkill(this.defense_exp, this.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier)), + Math.floor(this.calculateSkill(this.exp.defense, this.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier)), ); - this.dexterity = Math.max( + this.skills.dexterity = Math.max( 1, Math.floor( - this.calculateSkill(this.dexterity_exp, this.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier), + this.calculateSkill(this.exp.dexterity, this.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier), ), ); - this.agility = Math.max( + this.skills.agility = Math.max( 1, - Math.floor(this.calculateSkill(this.agility_exp, this.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier)), + Math.floor(this.calculateSkill(this.exp.agility, this.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier)), ); - this.charisma = Math.max( + this.skills.charisma = Math.max( 1, Math.floor( - this.calculateSkill(this.charisma_exp, this.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier), + this.calculateSkill(this.exp.charisma, this.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier), ), ); - if (this.intelligence > 0) { - this.intelligence = Math.floor(this.calculateSkill(this.intelligence_exp)); + if (this.skills.intelligence > 0) { + this.skills.intelligence = Math.floor(this.calculateSkill(this.exp.intelligence)); } else { - this.intelligence = 0; + this.skills.intelligence = 0; } - const ratio = this.hp / this.max_hp; - this.max_hp = Math.floor(10 + this.defense / 10); - this.hp = Math.round(this.max_hp * ratio); + const ratio = this.hp.current / this.hp.max; + this.hp.max = Math.floor(10 + this.skills.defense / 10); + this.hp.current = Math.round(this.hp.max * ratio); } export function resetMultipliers(this: IPlayer): void { @@ -311,12 +311,15 @@ export function gainHackingExp(this: IPerson, exp: number): void { console.error("ERR: NaN passed into Player.gainHackingExp()"); return; } - this.hacking_exp += exp; - if (this.hacking_exp < 0) { - this.hacking_exp = 0; + this.exp.hacking += exp; + if (this.exp.hacking < 0) { + this.exp.hacking = 0; } - this.hacking = calculateSkillF(this.hacking_exp, this.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier); + this.skills.hacking = calculateSkillF( + this.exp.hacking, + this.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier, + ); } export function gainStrengthExp(this: IPerson, exp: number): void { @@ -324,12 +327,15 @@ export function gainStrengthExp(this: IPerson, exp: number): void { console.error("ERR: NaN passed into Player.gainStrengthExp()"); return; } - this.strength_exp += exp; - if (this.strength_exp < 0) { - this.strength_exp = 0; + this.exp.strength += exp; + if (this.exp.strength < 0) { + this.exp.strength = 0; } - this.strength = calculateSkillF(this.strength_exp, this.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier); + this.skills.strength = calculateSkillF( + this.exp.strength, + this.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier, + ); } export function gainDefenseExp(this: IPerson, exp: number): void { @@ -337,15 +343,18 @@ export function gainDefenseExp(this: IPerson, exp: number): void { console.error("ERR: NaN passed into player.gainDefenseExp()"); return; } - this.defense_exp += exp; - if (this.defense_exp < 0) { - this.defense_exp = 0; + this.exp.defense += exp; + if (this.exp.defense < 0) { + this.exp.defense = 0; } - this.defense = calculateSkillF(this.defense_exp, this.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier); - const ratio = this.hp / this.max_hp; - this.max_hp = Math.floor(10 + this.defense / 10); - this.hp = Math.round(this.max_hp * ratio); + this.skills.defense = calculateSkillF( + this.exp.defense, + this.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier, + ); + const ratio = this.hp.current / this.hp.max; + this.hp.max = Math.floor(10 + this.skills.defense / 10); + this.hp.current = Math.round(this.hp.max * ratio); } export function gainDexterityExp(this: IPerson, exp: number): void { @@ -353,13 +362,13 @@ export function gainDexterityExp(this: IPerson, exp: number): void { console.error("ERR: NaN passed into Player.gainDexterityExp()"); return; } - this.dexterity_exp += exp; - if (this.dexterity_exp < 0) { - this.dexterity_exp = 0; + this.exp.dexterity += exp; + if (this.exp.dexterity < 0) { + this.exp.dexterity = 0; } - this.dexterity = calculateSkillF( - this.dexterity_exp, + this.skills.dexterity = calculateSkillF( + this.exp.dexterity, this.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier, ); } @@ -369,12 +378,15 @@ export function gainAgilityExp(this: IPerson, exp: number): void { console.error("ERR: NaN passed into Player.gainAgilityExp()"); return; } - this.agility_exp += exp; - if (this.agility_exp < 0) { - this.agility_exp = 0; + this.exp.agility += exp; + if (this.exp.agility < 0) { + this.exp.agility = 0; } - this.agility = calculateSkillF(this.agility_exp, this.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier); + this.skills.agility = calculateSkillF( + this.exp.agility, + this.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier, + ); } export function gainCharismaExp(this: IPerson, exp: number): void { @@ -382,12 +394,15 @@ export function gainCharismaExp(this: IPerson, exp: number): void { console.error("ERR: NaN passed into Player.gainCharismaExp()"); return; } - this.charisma_exp += exp; - if (this.charisma_exp < 0) { - this.charisma_exp = 0; + this.exp.charisma += exp; + if (this.exp.charisma < 0) { + this.exp.charisma = 0; } - this.charisma = calculateSkillF(this.charisma_exp, this.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier); + this.skills.charisma = calculateSkillF( + this.exp.charisma, + this.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier, + ); } export function gainIntelligenceExp(this: IPerson, exp: number): void { @@ -395,9 +410,9 @@ export function gainIntelligenceExp(this: IPerson, exp: number): void { console.error("ERROR: NaN passed into Player.gainIntelligenceExp()"); return; } - if (Player.sourceFileLvl(5) > 0 || this.intelligence > 0) { - this.intelligence_exp += exp; - this.intelligence = Math.floor(this.calculateSkill(this.intelligence_exp, 1)); + if (Player.sourceFileLvl(5) > 0 || this.skills.intelligence > 0) { + this.exp.intelligence += exp; + this.skills.intelligence = Math.floor(this.calculateSkill(this.exp.intelligence, 1)); } } @@ -415,25 +430,25 @@ export function gainStats(this: IPerson, retValue: ITaskTracker): void { export function queryStatFromString(this: IPlayer, str: string): number { const tempStr = str.toLowerCase(); if (tempStr.includes("hack")) { - return this.hacking; + return this.skills.hacking; } if (tempStr.includes("str")) { - return this.strength; + return this.skills.strength; } if (tempStr.includes("def")) { - return this.defense; + return this.skills.defense; } if (tempStr.includes("dex")) { - return this.dexterity; + return this.skills.dexterity; } if (tempStr.includes("agi")) { - return this.agility; + return this.skills.agility; } if (tempStr.includes("cha")) { - return this.charisma; + return this.skills.charisma; } if (tempStr.includes("int")) { - return this.intelligence; + return this.skills.intelligence; } return 0; } @@ -453,8 +468,8 @@ export function takeDamage(this: IPlayer, amt: number): boolean { return false; } - this.hp -= amt; - if (this.hp <= 0) { + this.hp.current -= amt; + if (this.hp.current <= 0) { this.hospitalize(); return true; } else { @@ -467,9 +482,9 @@ export function regenerateHp(this: IPerson, amt: number): void { console.warn(`Player.regenerateHp() called without a numeric argument: ${amt}`); return; } - this.hp += amt; - if (this.hp > this.max_hp) { - this.hp = this.max_hp; + this.hp.current += amt; + if (this.hp.current > this.hp.max) { + this.hp.current = this.hp.max; } } @@ -478,7 +493,7 @@ export function hospitalize(this: IPlayer): number { SnackbarEvents.emit(`You've been Hospitalized for ${numeralWrapper.formatMoney(cost)}`, ToastVariant.WARNING, 2000); this.loseMoney(cost, "hospitalization"); - this.hp = this.max_hp; + this.hp.current = this.hp.max; return cost; } @@ -754,12 +769,12 @@ export function isQualified(this: IPlayer, company: Company, position: CompanyPo const reqCharisma = position.requiredCharisma > 0 ? position.requiredCharisma + offset : 0; return ( - this.hacking >= reqHacking && - this.strength >= reqStrength && - this.defense >= reqDefense && - this.dexterity >= reqDexterity && - this.agility >= reqAgility && - this.charisma >= reqCharisma && + this.skills.hacking >= reqHacking && + this.skills.strength >= reqStrength && + this.skills.defense >= reqDefense && + this.skills.dexterity >= reqDexterity && + this.skills.agility >= reqAgility && + this.skills.charisma >= reqCharisma && company.playerReputation >= position.requiredReputation ); } @@ -851,11 +866,11 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] { !illuminatiFac.alreadyInvited && numAugmentations >= 30 && this.money >= 150000000000 && - this.hacking >= 1500 && - this.strength >= 1200 && - this.defense >= 1200 && - this.dexterity >= 1200 && - this.agility >= 1200 + this.skills.hacking >= 1500 && + this.skills.strength >= 1200 && + this.skills.defense >= 1200 && + this.skills.dexterity >= 1200 && + this.skills.agility >= 1200 ) { invitedFactions.push(illuminatiFac); } @@ -868,8 +883,11 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] { !daedalusFac.alreadyInvited && numAugmentations >= BitNodeMultipliers.DaedalusAugsRequirement && this.money >= 100000000000 && - (this.hacking >= 2500 || - (this.strength >= 1500 && this.defense >= 1500 && this.dexterity >= 1500 && this.agility >= 1500)) + (this.skills.hacking >= 2500 || + (this.skills.strength >= 1500 && + this.skills.defense >= 1500 && + this.skills.dexterity >= 1500 && + this.skills.agility >= 1500)) ) { invitedFactions.push(daedalusFac); } @@ -882,11 +900,11 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] { !covenantFac.alreadyInvited && numAugmentations >= 20 && this.money >= 75000000000 && - this.hacking >= 850 && - this.strength >= 850 && - this.defense >= 850 && - this.dexterity >= 850 && - this.agility >= 850 + this.skills.hacking >= 850 && + this.skills.strength >= 850 && + this.skills.defense >= 850 && + this.skills.dexterity >= 850 && + this.skills.agility >= 850 ) { invitedFactions.push(covenantFac); } @@ -1131,11 +1149,11 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] { !speakersforthedeadFac.isBanned && !speakersforthedeadFac.isMember && !speakersforthedeadFac.alreadyInvited && - this.hacking >= 100 && - this.strength >= 300 && - this.defense >= 300 && - this.dexterity >= 300 && - this.agility >= 300 && + this.skills.hacking >= 100 && + this.skills.strength >= 300 && + this.skills.defense >= 300 && + this.skills.dexterity >= 300 && + this.skills.agility >= 300 && this.numPeopleKilled >= 30 && this.karma <= -45 && !allCompanies.includes(LocationName.Sector12CIA) && @@ -1150,11 +1168,11 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] { !thedarkarmyFac.isBanned && !thedarkarmyFac.isMember && !thedarkarmyFac.alreadyInvited && - this.hacking >= 300 && - this.strength >= 300 && - this.defense >= 300 && - this.dexterity >= 300 && - this.agility >= 300 && + this.skills.hacking >= 300 && + this.skills.strength >= 300 && + this.skills.defense >= 300 && + this.skills.dexterity >= 300 && + this.skills.agility >= 300 && this.city == CityName.Chongqing && this.numPeopleKilled >= 5 && this.karma <= -45 && @@ -1170,11 +1188,11 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] { !thesyndicateFac.isBanned && !thesyndicateFac.isMember && !thesyndicateFac.alreadyInvited && - this.hacking >= 200 && - this.strength >= 200 && - this.defense >= 200 && - this.dexterity >= 200 && - this.agility >= 200 && + this.skills.hacking >= 200 && + this.skills.strength >= 200 && + this.skills.defense >= 200 && + this.skills.dexterity >= 200 && + this.skills.agility >= 200 && (this.city == CityName.Aevum || this.city == CityName.Sector12) && this.money >= 10000000 && this.karma <= -90 && @@ -1206,10 +1224,10 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] { !tetradsFac.isMember && !tetradsFac.alreadyInvited && (this.city == CityName.Chongqing || this.city == CityName.NewTokyo || this.city == CityName.Ishima) && - this.strength >= 75 && - this.defense >= 75 && - this.dexterity >= 75 && - this.agility >= 75 && + this.skills.strength >= 75 && + this.skills.defense >= 75 && + this.skills.dexterity >= 75 && + this.skills.agility >= 75 && this.karma <= -18 ) { invitedFactions.push(tetradsFac); @@ -1221,10 +1239,10 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] { !slumsnakesFac.isBanned && !slumsnakesFac.isMember && !slumsnakesFac.alreadyInvited && - this.strength >= 30 && - this.defense >= 30 && - this.dexterity >= 30 && - this.agility >= 30 && + this.skills.strength >= 30 && + this.skills.defense >= 30 && + this.skills.dexterity >= 30 && + this.skills.agility >= 30 && this.karma <= -9 && this.money >= 1000000 ) { @@ -1255,7 +1273,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] { !netburnersFac.isBanned && !netburnersFac.isMember && !netburnersFac.alreadyInvited && - this.hacking >= 80 && + this.skills.hacking >= 80 && totalHacknetRam >= 8 && totalHacknetCores >= 4 && totalHacknetLevels >= 100 @@ -1270,7 +1288,7 @@ export function checkForFactionInvitations(this: IPlayer): Faction[] { !tiandihuiFac.isMember && !tiandihuiFac.alreadyInvited && this.money >= 1000000 && - this.hacking >= 50 && + this.skills.hacking >= 50 && (this.city == CityName.Chongqing || this.city == CityName.NewTokyo || this.city == CityName.Ishima) ) { invitedFactions.push(tiandihuiFac); @@ -1418,7 +1436,7 @@ export function giveAchievement(this: IPlayer, achievementId: string): void { } export function getIntelligenceBonus(this: IPlayer, weight: number): number { - return calculateIntelligenceBonus(this.intelligence, weight); + return calculateIntelligenceBonus(this.skills.intelligence, weight); } export function getCasinoWinnings(this: IPlayer): number { diff --git a/src/PersonObjects/Skills.ts b/src/PersonObjects/Skills.ts new file mode 100644 index 000000000..48bf1232c --- /dev/null +++ b/src/PersonObjects/Skills.ts @@ -0,0 +1,9 @@ +export interface Skills { + hacking: number; + strength: number; + defense: number; + dexterity: number; + agility: number; + charisma: number; + intelligence: number; +} diff --git a/src/PersonObjects/Sleeve/Sleeve.ts b/src/PersonObjects/Sleeve/Sleeve.ts index 06bdefc9e..97a6c9d1d 100644 --- a/src/PersonObjects/Sleeve/Sleeve.ts +++ b/src/PersonObjects/Sleeve/Sleeve.ts @@ -289,27 +289,27 @@ export class Sleeve extends Person { // Also the player does not earn anything if (fromOtherSleeve) { if (exp.hack > 0) { - this.hacking_exp += exp.hack; + this.exp.hacking += exp.hack; } if (exp.str > 0) { - this.strength_exp += exp.str; + this.exp.strength += exp.str; } if (exp.def > 0) { - this.defense_exp += exp.def; + this.exp.defense += exp.def; } if (exp.dex > 0) { - this.dexterity_exp += exp.dex; + this.exp.dexterity += exp.dex; } if (exp.agi > 0) { - this.agility_exp += exp.agi; + this.exp.agility += exp.agi; } if (exp.cha > 0) { - this.charisma_exp += exp.cha; + this.exp.charisma += exp.cha; } return createTaskTracker(); @@ -469,12 +469,12 @@ export class Sleeve extends Person { } const jobPerformance: number = companyPosition.calculateJobPerformance( - this.hacking, - this.strength, - this.defense, - this.dexterity, - this.agility, - this.charisma, + this.skills.hacking, + this.skills.strength, + this.skills.defense, + this.skills.dexterity, + this.skills.agility, + this.skills.charisma, ); const favorMult = 1 + company.favor / 100; @@ -485,12 +485,12 @@ export class Sleeve extends Person { } installAugmentation(aug: Augmentation): void { - this.hacking_exp = 0; - this.strength_exp = 0; - this.defense_exp = 0; - this.dexterity_exp = 0; - this.agility_exp = 0; - this.charisma_exp = 0; + this.exp.hacking = 0; + this.exp.strength = 0; + this.exp.defense = 0; + this.exp.dexterity = 0; + this.exp.agility = 0; + this.exp.charisma = 0; this.applyAugmentation(aug); this.augmentations.push({ name: aug.name, level: 1 }); this.updateStatLevels(); @@ -509,12 +509,12 @@ export class Sleeve extends Person { */ prestige(p: IPlayer): void { // Reset exp - this.hacking_exp = 0; - this.strength_exp = 0; - this.defense_exp = 0; - this.dexterity_exp = 0; - this.agility_exp = 0; - this.charisma_exp = 0; + this.exp.hacking = 0; + this.exp.strength = 0; + this.exp.defense = 0; + this.exp.dexterity = 0; + this.exp.agility = 0; + this.exp.charisma = 0; // Reset task-related stuff this.resetTaskStatus(p); @@ -1232,10 +1232,10 @@ export class Sleeve extends Person { return false; } - this.hp -= amt; - if (this.hp <= 0) { + this.hp.current -= amt; + if (this.hp.current <= 0) { this.shock = Math.min(1, this.shock - 0.5); - this.hp = this.max_hp; + this.hp.current = this.hp.max; return true; } else { return false; diff --git a/src/PersonObjects/Sleeve/ui/MoreStatsModal.tsx b/src/PersonObjects/Sleeve/ui/MoreStatsModal.tsx index 8e82a4618..23a0c7ef0 100644 --- a/src/PersonObjects/Sleeve/ui/MoreStatsModal.tsx +++ b/src/PersonObjects/Sleeve/ui/MoreStatsModal.tsx @@ -20,33 +20,33 @@ export function MoreStatsModal(props: IProps): React.ReactElement { rows={[ [ <>Hacking: , - props.sleeve.hacking, - <> ({numeralWrapper.formatExp(props.sleeve.hacking_exp)} exp), + props.sleeve.skills.hacking, + <> ({numeralWrapper.formatExp(props.sleeve.exp.hacking)} exp), ], [ <>Strength: , - props.sleeve.strength, - <> ({numeralWrapper.formatExp(props.sleeve.strength_exp)} exp), + props.sleeve.skills.strength, + <> ({numeralWrapper.formatExp(props.sleeve.exp.strength)} exp), ], [ <>Defense: , - props.sleeve.defense, - <> ({numeralWrapper.formatExp(props.sleeve.defense_exp)} exp), + props.sleeve.skills.defense, + <> ({numeralWrapper.formatExp(props.sleeve.exp.defense)} exp), ], [ <>Dexterity: , - props.sleeve.dexterity, - <> ({numeralWrapper.formatExp(props.sleeve.dexterity_exp)} exp), + props.sleeve.skills.dexterity, + <> ({numeralWrapper.formatExp(props.sleeve.exp.dexterity)} exp), ], [ <>Agility: , - props.sleeve.agility, - <> ({numeralWrapper.formatExp(props.sleeve.agility_exp)} exp), + props.sleeve.skills.agility, + <> ({numeralWrapper.formatExp(props.sleeve.exp.agility)} exp), ], [ <>Charisma: , - props.sleeve.charisma, - <> ({numeralWrapper.formatExp(props.sleeve.charisma_exp)} exp), + props.sleeve.skills.charisma, + <> ({numeralWrapper.formatExp(props.sleeve.exp.charisma)} exp), ], ]} title="Stats:" diff --git a/src/PersonObjects/Sleeve/ui/StatsElement.tsx b/src/PersonObjects/Sleeve/ui/StatsElement.tsx index c79585f1f..5851319b0 100644 --- a/src/PersonObjects/Sleeve/ui/StatsElement.tsx +++ b/src/PersonObjects/Sleeve/ui/StatsElement.tsx @@ -29,38 +29,40 @@ export function StatsElement(props: IProps): React.ReactElement { name="HP" color={Settings.theme.hp} data={{ - content: `${numeralWrapper.formatHp(props.sleeve.hp)} / ${numeralWrapper.formatHp(props.sleeve.max_hp)}`, + content: `${numeralWrapper.formatHp(props.sleeve.hp.current)} / ${numeralWrapper.formatHp( + props.sleeve.hp.max, + )}`, }} /> diff --git a/src/PersonObjects/formulas/reputation.ts b/src/PersonObjects/formulas/reputation.ts index e94f3e6f3..d9a500c70 100644 --- a/src/PersonObjects/formulas/reputation.ts +++ b/src/PersonObjects/formulas/reputation.ts @@ -14,7 +14,7 @@ function mult(f: Faction): number { export function getHackingWorkRepGain(p: IPlayer, f: Faction): number { return ( - ((p.hacking + p.intelligence / 3) / CONSTANTS.MaxSkillLevel) * + ((p.skills.hacking + p.skills.intelligence / 3) / CONSTANTS.MaxSkillLevel) * p.mults.faction_rep * p.getIntelligenceBonus(1) * mult(f) * @@ -24,7 +24,12 @@ export function getHackingWorkRepGain(p: IPlayer, f: Faction): number { export function getFactionSecurityWorkRepGain(p: IPlayer, f: Faction): number { const t = - (0.9 * (p.strength + p.defense + p.dexterity + p.agility + (p.hacking + p.intelligence) * CalculateShareMult())) / + (0.9 * + (p.skills.strength + + p.skills.defense + + p.skills.dexterity + + p.skills.agility + + (p.skills.hacking + p.skills.intelligence) * CalculateShareMult())) / CONSTANTS.MaxSkillLevel / 4.5; return t * p.mults.faction_rep * mult(f) * p.getIntelligenceBonus(1); @@ -33,12 +38,12 @@ export function getFactionSecurityWorkRepGain(p: IPlayer, f: Faction): number { export function getFactionFieldWorkRepGain(p: IPlayer, f: Faction): number { const t = (0.9 * - (p.strength + - p.defense + - p.dexterity + - p.agility + - p.charisma + - (p.hacking + p.intelligence) * CalculateShareMult())) / + (p.skills.strength + + p.skills.defense + + p.skills.dexterity + + p.skills.agility + + p.skills.charisma + + (p.skills.hacking + p.skills.intelligence) * CalculateShareMult())) / CONSTANTS.MaxSkillLevel / 5.5; return t * p.mults.faction_rep * mult(f) * p.getIntelligenceBonus(1); diff --git a/src/Programs/data/ProgramsMetadata.ts b/src/Programs/data/ProgramsMetadata.ts index 18846acd7..28c700c5f 100644 --- a/src/Programs/data/ProgramsMetadata.ts +++ b/src/Programs/data/ProgramsMetadata.ts @@ -15,13 +15,13 @@ import { FactionNames } from "../../Faction/data/FactionNames"; function requireHackingLevel(lvl: number) { return function (p: IPlayer) { - return p.hacking + p.intelligence / 2 >= lvl; + return p.skills.hacking + p.skills.intelligence / 2 >= lvl; }; } function bitFlumeRequirements() { return function (p: IPlayer) { - return p.sourceFiles.length > 0 && p.hacking >= 1; + return p.sourceFiles.length > 0 && p.skills.hacking >= 1; }; } @@ -308,11 +308,12 @@ export const programsMetadata: IProgramCreationParams[] = [ create: null, run: (router: IRouter, terminal: ITerminal, player: IPlayer): void => { const numAugReq = BitNodeMultipliers.DaedalusAugsRequirement; - const fulfilled = player.augmentations.length >= numAugReq && player.money > 1e11 && player.hacking >= 2500; + const fulfilled = + player.augmentations.length >= numAugReq && player.money > 1e11 && player.skills.hacking >= 2500; if (!fulfilled) { terminal.print(`Augmentations: ${player.augmentations.length} / ${numAugReq}`); terminal.print(`Money: ${numeralWrapper.formatMoney(player.money)} / $100b`); - terminal.print(`Hacking skill: ${player.hacking} / 2500`); + terminal.print(`Hacking skill: ${player.skills.hacking} / 2500`); return; } diff --git a/src/Programs/ui/ProgramsRoot.tsx b/src/Programs/ui/ProgramsRoot.tsx index b5838c8d1..a8638ab4a 100644 --- a/src/Programs/ui/ProgramsRoot.tsx +++ b/src/Programs/ui/ProgramsRoot.tsx @@ -48,7 +48,7 @@ export function ProgramsRoot(): React.ReactElement { }, []); const getHackingLevelRemaining = (lvl: number): number => { - return Math.ceil(Math.max(lvl - (player.hacking + player.intelligence / 2), 0)); + return Math.ceil(Math.max(lvl - (player.skills.hacking + player.skills.intelligence / 2), 0)); }; const getProgCompletion = (name: string): number => { diff --git a/src/RedPill.tsx b/src/RedPill.tsx index 2c49116bf..693982d87 100644 --- a/src/RedPill.tsx +++ b/src/RedPill.tsx @@ -47,9 +47,9 @@ function giveSourceFile(bitNodeNumber: number): void { } else { const playerSrcFile = new PlayerOwnedSourceFile(bitNodeNumber, 1); Player.sourceFiles.push(playerSrcFile); - if (bitNodeNumber === 5 && Player.intelligence === 0) { + if (bitNodeNumber === 5 && Player.skills.intelligence === 0) { // Artificial Intelligence - Player.intelligence = 1; + Player.skills.intelligence = 1; } dialogBoxCreate( <> @@ -69,11 +69,11 @@ export function enterBitNode(router: IRouter, flume: boolean, destroyedBitNode: if (!flume) { giveSourceFile(destroyedBitNode); } else if (Player.sourceFileLvl(5) === 0 && newBitNode !== 5) { - Player.intelligence = 0; - Player.intelligence_exp = 0; + Player.skills.intelligence = 0; + Player.exp.intelligence = 0; } - if (newBitNode === 5 && Player.intelligence === 0) { - Player.intelligence = 1; + if (newBitNode === 5 && Player.skills.intelligence === 0) { + Player.skills.intelligence = 1; } // Set new Bit Node Player.bitNodeN = newBitNode; diff --git a/src/SaveObject.tsx b/src/SaveObject.tsx index 765b5ba55..0e3a12ae6 100755 --- a/src/SaveObject.tsx +++ b/src/SaveObject.tsx @@ -218,7 +218,7 @@ class BitburnerSaveObject { totalPlaytime: importedPlayer.totalPlaytime, money: importedPlayer.money, - hacking: importedPlayer.hacking, + hacking: importedPlayer.skills.hacking, augmentations: importedPlayer.augmentations?.reduce((total, current) => (total += current.level), 0) ?? 0, factions: importedPlayer.factions?.length ?? 0, @@ -462,6 +462,22 @@ function evaluateVersionCompatibility(ver: string | number): void { if (create) Player.getHomeComputer().pushProgram(create); const graft = anyPlayer["graftAugmentationName"]; if (graft) Player.augmentations.push({ name: graft, level: 1 }); + } + if (ver < 22) { + // reset HP correctly to avoid crash + anyPlayer.hp = { current: 1, max: 1 }; + for (const sleeve of anyPlayer.sleeves) { + sleeve.hp = { current: 1, max: 1 }; + } + + // transfer over old exp to new struct + anyPlayer.exp.hacking = anyPlayer.hacking_exp; + anyPlayer.exp.strength = anyPlayer.strength_exp; + anyPlayer.exp.defense = anyPlayer.defense_exp; + anyPlayer.exp.dexterity = anyPlayer.dexterity_exp; + anyPlayer.exp.agility = anyPlayer.agility_exp; + anyPlayer.exp.charisma = anyPlayer.charisma_exp; + anyPlayer.exp.intelligence = anyPlayer.intelligence_exp; v2APIBreak(); } } diff --git a/src/ScriptEditor/NetscriptDefinitions.d.ts b/src/ScriptEditor/NetscriptDefinitions.d.ts index db73db978..04e0b3b5f 100644 --- a/src/ScriptEditor/NetscriptDefinitions.d.ts +++ b/src/ScriptEditor/NetscriptDefinitions.d.ts @@ -1,3 +1,24 @@ +/** + * @public + */ +export interface HP { + current: number; + max: number; +} + +/** + * @public + */ +export interface Skills { + hacking: number; + strength: number; + defense: number; + dexterity: number; + agility: number; + charisma: number; + intelligence: number; +} + /** * @public */ @@ -31,21 +52,9 @@ type FilenameOrPID = number | string; * @public */ interface Player { - hacking: number; - hp: number; - max_hp: number; - strength: number; - defense: number; - dexterity: number; - agility: number; - charisma: number; - intelligence: number; - hacking_exp: number; - strength_exp: number; - defense_exp: number; - dexterity_exp: number; - agility_exp: number; - charisma_exp: number; + hp: HP; + skills: Skills; + exp: Skills; mults: Multipliers; numPeopleKilled: number; money: number; diff --git a/src/Terminal/commands/backdoor.ts b/src/Terminal/commands/backdoor.ts index 8f9e84a91..2f49745e9 100644 --- a/src/Terminal/commands/backdoor.ts +++ b/src/Terminal/commands/backdoor.ts @@ -29,7 +29,7 @@ export function backdoor( ); } else if (!normalServer.hasAdminRights) { terminal.error("You do not have admin rights for this machine! Cannot backdoor"); - } else if (normalServer.requiredHackingSkill > player.hacking) { + } else if (normalServer.requiredHackingSkill > player.skills.hacking) { terminal.error( "Your hacking skill is not high enough to use backdoor on this machine. Try analyzing the machine to determine the required hacking skill", ); diff --git a/src/Terminal/commands/grow.ts b/src/Terminal/commands/grow.ts index 87e6b9f83..6169a3a99 100644 --- a/src/Terminal/commands/grow.ts +++ b/src/Terminal/commands/grow.ts @@ -34,7 +34,7 @@ export function grow( terminal.error("You do not have admin rights for this machine! Cannot grow"); return; } - if (normalServer.requiredHackingSkill > player.hacking) { + if (normalServer.requiredHackingSkill > player.skills.hacking) { terminal.error( "Your hacking skill is not high enough to attempt hacking this machine. Try analyzing the machine to determine the required hacking skill", ); diff --git a/src/Terminal/commands/hack.ts b/src/Terminal/commands/hack.ts index 7b6030d26..cc66bd26a 100644 --- a/src/Terminal/commands/hack.ts +++ b/src/Terminal/commands/hack.ts @@ -34,7 +34,7 @@ export function hack( terminal.error("You do not have admin rights for this machine! Cannot hack"); return; } - if (normalServer.requiredHackingSkill > player.hacking) { + if (normalServer.requiredHackingSkill > player.skills.hacking) { terminal.error( "Your hacking skill is not high enough to attempt hacking this machine. Try analyzing the machine to determine the required hacking skill", ); diff --git a/src/Terminal/commands/weaken.ts b/src/Terminal/commands/weaken.ts index f060174d9..9586db7c0 100644 --- a/src/Terminal/commands/weaken.ts +++ b/src/Terminal/commands/weaken.ts @@ -34,7 +34,7 @@ export function weaken( terminal.error("You do not have admin rights for this machine! Cannot weaken"); return; } - if (normalServer.requiredHackingSkill > player.hacking) { + if (normalServer.requiredHackingSkill > player.skills.hacking) { terminal.error( "Your hacking skill is not high enough to attempt hacking this machine. Try analyzing the machine to determine the required hacking skill", ); diff --git a/src/Work/CreateProgramWork.ts b/src/Work/CreateProgramWork.ts index 77b89b783..da463a752 100644 --- a/src/Work/CreateProgramWork.ts +++ b/src/Work/CreateProgramWork.ts @@ -63,7 +63,7 @@ export class CreateProgramWork extends Work { } //Higher hacking skill will allow you to create programs faster const reqLvl = this.getProgram().create?.level ?? 0; - let skillMult = (player.hacking / reqLvl) * player.getIntelligenceBonus(3); //This should always be greater than 1; + let skillMult = (player.skills.hacking / reqLvl) * player.getIntelligenceBonus(3); //This should always be greater than 1; skillMult = 1 + (skillMult - 1) / 5; //The divider constant can be adjusted as necessary skillMult *= focusBonus; //Skill multiplier directly applied to "time worked" diff --git a/src/Work/formulas/Company.ts b/src/Work/formulas/Company.ts index 8db541b3f..489121290 100644 --- a/src/Work/formulas/Company.ts +++ b/src/Work/formulas/Company.ts @@ -27,15 +27,15 @@ export const calculateCompanyWorkStats = (player: IPlayer, company: Company): Wo } let jobPerformance = companyPosition.calculateJobPerformance( - player.hacking, - player.strength, - player.defense, - player.dexterity, - player.agility, - player.charisma, + player.skills.hacking, + player.skills.strength, + player.skills.defense, + player.skills.dexterity, + player.skills.agility, + player.skills.charisma, ); - jobPerformance += player.intelligence / CONSTANTS.MaxSkillLevel; + jobPerformance += player.skills.intelligence / CONSTANTS.MaxSkillLevel; return { money: diff --git a/src/ui/CharacterStats.tsx b/src/ui/CharacterStats.tsx index 01c45c54c..f0034fbd6 100644 --- a/src/ui/CharacterStats.tsx +++ b/src/ui/CharacterStats.tsx @@ -293,38 +293,38 @@ export function CharacterStats(): React.ReactElement { - {player.intelligence > 0 && (player.bitNodeN === 5 || player.sourceFileLvl(5) > 0) && ( + {player.skills.intelligence > 0 && (player.bitNodeN === 5 || player.sourceFileLvl(5) > 0) && ( )} diff --git a/src/ui/React/CharacterOverview.tsx b/src/ui/React/CharacterOverview.tsx index fef65d104..adbcdc2f5 100644 --- a/src/ui/React/CharacterOverview.tsx +++ b/src/ui/React/CharacterOverview.tsx @@ -44,8 +44,8 @@ function Intelligence(): React.ReactElement { const theme = useTheme(); const player = use.Player(); const classes = useStyles(); - if (player.intelligence === 0) return <>; - const progress = player.calculateSkillProgress(player.intelligence_exp); + if (player.skills.intelligence === 0) return <>; + const progress = player.calculateSkillProgress(player.exp.intelligence); return ( <> @@ -54,7 +54,9 @@ function Intelligence(): React.ReactElement { Int  - {numeralWrapper.formatSkill(player.intelligence)} + + {numeralWrapper.formatSkill(player.skills.intelligence)} + @@ -292,27 +294,27 @@ export function CharacterOverview({ save, killScripts }: IProps): React.ReactEle const theme = useTheme(); const hackingProgress = player.calculateSkillProgress( - player.hacking_exp, + player.exp.hacking, player.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier, ); const strengthProgress = player.calculateSkillProgress( - player.strength_exp, + player.exp.strength, player.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier, ); const defenseProgress = player.calculateSkillProgress( - player.defense_exp, + player.exp.defense, player.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier, ); const dexterityProgress = player.calculateSkillProgress( - player.dexterity_exp, + player.exp.dexterity, player.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier, ); const agilityProgress = player.calculateSkillProgress( - player.agility_exp, + player.exp.agility, player.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier, ); const charismaProgress = player.calculateSkillProgress( - player.charisma_exp, + player.exp.charisma, player.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier, ); @@ -326,7 +328,7 @@ export function CharacterOverview({ save, killScripts }: IProps): React.ReactEle - {numeralWrapper.formatHp(player.hp)} / {numeralWrapper.formatHp(player.max_hp)} + {numeralWrapper.formatHp(player.hp.current)} / {numeralWrapper.formatHp(player.hp.max)} @@ -355,7 +357,9 @@ export function CharacterOverview({ save, killScripts }: IProps): React.ReactEle Hack  - {numeralWrapper.formatSkill(player.hacking)} + + {numeralWrapper.formatSkill(player.skills.hacking)} + @@ -379,7 +383,9 @@ export function CharacterOverview({ save, killScripts }: IProps): React.ReactEle Str  - {numeralWrapper.formatSkill(player.strength)} + + {numeralWrapper.formatSkill(player.skills.strength)} + @@ -398,7 +404,9 @@ export function CharacterOverview({ save, killScripts }: IProps): React.ReactEle Def  - {numeralWrapper.formatSkill(player.defense)} + + {numeralWrapper.formatSkill(player.skills.defense)} + @@ -417,7 +425,9 @@ export function CharacterOverview({ save, killScripts }: IProps): React.ReactEle Dex  - {numeralWrapper.formatSkill(player.dexterity)} + + {numeralWrapper.formatSkill(player.skills.dexterity)} + @@ -436,7 +446,9 @@ export function CharacterOverview({ save, killScripts }: IProps): React.ReactEle Agi  - {numeralWrapper.formatSkill(player.agility)} + + {numeralWrapper.formatSkill(player.skills.agility)} + @@ -455,7 +467,9 @@ export function CharacterOverview({ save, killScripts }: IProps): React.ReactEle Cha  - {numeralWrapper.formatSkill(player.charisma)} + + {numeralWrapper.formatSkill(player.skills.charisma)} + diff --git a/src/utils/v2APIBreak.ts b/src/utils/v2APIBreak.ts index 19f36714e..c9636e819 100644 --- a/src/utils/v2APIBreak.ts +++ b/src/utils/v2APIBreak.ts @@ -86,6 +86,22 @@ const getPlayerFields = [ "workDefExpGainRate", "workAgiExpGained", "className", + "hacking", + "strength", + "defense", + "dexterity", + "agility", + "charisma", + "intelligence", + "hacking_exp", + "strength_exp", + "defense_exp", + "dexterity_exp", + "agility_exp", + "charisma_exp", + "intelligence_exp", + "hp", + "max_hp", ]; const mults = [ @@ -188,7 +204,7 @@ export const v2APIBreak = () => { for (const f of getPlayerFields) { rules.push({ match: new RegExp(f, "g"), - reason: `The work system is completely reworked and ns.getPlayer().${f} no longer exists. This data is likely available inside ns.getPlayer().currentWork`, + reason: `The work system is completely reworked and ns.getPlayer().${f} no longer exists. This data is likely available inside ns.getPlayer().currentWork, skills, exp, or hp`, offenders: [], }); }