From c510e478855595c0b47d37999ae9b1a68fe408a1 Mon Sep 17 00:00:00 2001 From: Snarling <84951833+Snarling@users.noreply.github.com> Date: Tue, 20 Sep 2022 01:57:46 -0400 Subject: [PATCH] Player is now a Person Use correct class inheritance, use class as type and remove IPlayer --- src/Bladeburner/Action.tsx | 10 +- src/Bladeburner/Bladeburner.tsx | 18 +- src/Bladeburner/IAction.tsx | 10 +- src/Bladeburner/IBladeburner.ts | 18 +- src/CotMG/StaneksGift.ts | 2 +- src/Crime/Crime.ts | 4 +- src/Crime/formulas/crime.ts | 40 ---- src/Faction/formulas/donation.ts | 4 +- src/Hacking.ts | 14 +- src/Netscript/NetscriptHelpers.ts | 6 +- src/PersonObjects/IPerson.ts | 33 --- src/PersonObjects/Person.ts | 134 ++--------- src/PersonObjects/PersonMethods.ts | 199 ++++++++++++++++ src/PersonObjects/Player/PlayerObject.ts | 53 +---- .../Player/PlayerObjectGeneralMethods.ts | 220 ------------------ src/PersonObjects/Sleeve/Sleeve.ts | 5 +- src/PersonObjects/Sleeve/SleeveMethods.ts | 9 +- src/PersonObjects/formulas/reputation.ts | 8 +- src/PersonObjects/formulas/skill.ts | 4 + src/Server/formulas/grow.ts | 4 +- src/Work/WorkStats.ts | 6 +- src/Work/formulas/Class.ts | 4 +- src/Work/formulas/Company.ts | 4 +- src/Work/formulas/Faction.ts | 6 +- 24 files changed, 297 insertions(+), 518 deletions(-) delete mode 100644 src/Crime/formulas/crime.ts delete mode 100644 src/PersonObjects/IPerson.ts create mode 100644 src/PersonObjects/PersonMethods.ts diff --git a/src/Bladeburner/Action.tsx b/src/Bladeburner/Action.tsx index 90a735046..9ec88479a 100644 --- a/src/Bladeburner/Action.tsx +++ b/src/Bladeburner/Action.tsx @@ -5,7 +5,7 @@ import { Generic_fromJSON, Generic_toJSON, IReviverValue, Reviver } from "../uti import { BladeburnerConstants } from "./data/Constants"; import { IBladeburner } from "./IBladeburner"; import { IAction, ISuccessChanceParams } from "./IAction"; -import { IPerson } from "../PersonObjects/IPerson"; +import { Person } from "../PersonObjects/Person"; class StatsMultiplier { [key: string]: number; @@ -153,7 +153,7 @@ export class Action implements IAction { * Tests for success. Should be called when an action has completed * @param inst {Bladeburner} - Bladeburner instance */ - attempt(inst: IBladeburner, person: IPerson): boolean { + attempt(inst: IBladeburner, person: Person): boolean { return Math.random() < this.getSuccessChance(inst, person); } @@ -162,7 +162,7 @@ export class Action implements IAction { return 1; } - getActionTime(inst: IBladeburner, person: IPerson): number { + getActionTime(inst: IBladeburner, person: Person): number { const difficulty = this.getDifficulty(); let baseTime = difficulty / BladeburnerConstants.DifficultyToTimeFactor; const skillFac = inst.skillMultipliers.actionTime; // Always < 1 @@ -212,7 +212,7 @@ export class Action implements IAction { return 1; } - getEstSuccessChance(inst: IBladeburner, person: IPerson): [number, number] { + getEstSuccessChance(inst: IBladeburner, person: Person): [number, number] { function clamp(x: number): number { return Math.max(0, Math.min(x, 1)); } @@ -233,7 +233,7 @@ export class Action implements IAction { * @params - options: * est (bool): Get success chance estimate instead of real success chance */ - getSuccessChance(inst: IBladeburner, person: IPerson, params: ISuccessChanceParams = { est: false }): number { + getSuccessChance(inst: IBladeburner, person: Person, params: ISuccessChanceParams = { est: false }): number { if (inst == null) { throw new Error("Invalid Bladeburner instance passed into Action.getSuccessChance"); } diff --git a/src/Bladeburner/Bladeburner.tsx b/src/Bladeburner/Bladeburner.tsx index 66e4bda0f..c52b72431 100644 --- a/src/Bladeburner/Bladeburner.tsx +++ b/src/Bladeburner/Bladeburner.tsx @@ -16,7 +16,7 @@ import { City } from "./City"; import { IAction } from "./IAction"; import { Player } from "../Player"; import { createTaskTracker, ITaskTracker } from "../PersonObjects/ITaskTracker"; -import { IPerson } from "../PersonObjects/IPerson"; +import { Person } from "../PersonObjects/Person"; import { Router } from "../ui/GameRoot"; import { ConsoleHelpText } from "./data/Help"; import { exceptionAlert } from "../utils/helpers/exceptionAlert"; @@ -995,7 +995,7 @@ export class Bladeburner implements IBladeburner { * @param action(Action obj) - Derived action class * @param success(bool) - Whether action was successful */ - getActionStats(action: IAction, person: IPerson, success: boolean): ITaskTracker { + getActionStats(action: IAction, person: Person, success: boolean): ITaskTracker { const difficulty = action.getDifficulty(); /** @@ -1025,7 +1025,7 @@ export class Bladeburner implements IBladeburner { }; } - getDiplomacyEffectiveness(person: IPerson): number { + getDiplomacyEffectiveness(person: Person): number { // Returns a decimal by which the city's chaos level should be multiplied (e.g. 0.98) const CharismaLinearFactor = 1e3; const CharismaExponentialFactor = 0.045; @@ -1035,11 +1035,11 @@ export class Bladeburner implements IBladeburner { return (100 - charismaEff) / 100; } - getRecruitmentSuccessChance(person: IPerson): number { + getRecruitmentSuccessChance(person: Person): number { return Math.pow(person.skills.charisma, 0.45) / (this.teamSize - this.sleeveSize + 1); } - getRecruitmentTime(person: IPerson): number { + getRecruitmentTime(person: Person): number { 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)); @@ -1257,7 +1257,7 @@ export class Bladeburner implements IBladeburner { } } - completeAction(person: IPerson, actionIdent: IActionIdentifier, isPlayer = true): ITaskTracker { + completeAction(person: Person, actionIdent: IActionIdentifier, isPlayer = true): ITaskTracker { let retValue = createTaskTracker(); switch (actionIdent.type) { case ActionTypes["Contract"]: @@ -1610,7 +1610,7 @@ export class Bladeburner implements IBladeburner { } } - changeRank(person: IPerson, change: number): void { + changeRank(person: Person, change: number): void { if (isNaN(change)) { throw new Error("NaN passed into Bladeburner.changeRank()"); } @@ -2146,7 +2146,7 @@ export class Bladeburner implements IBladeburner { } } - getActionTimeNetscriptFn(person: IPerson, type: string, name: string): number | string { + getActionTimeNetscriptFn(person: Person, type: string, name: string): number | string { const actionId = this.getActionIdFromTypeAndName(type, name); if (actionId == null) { return "bladeburner.getActionTime"; @@ -2177,7 +2177,7 @@ export class Bladeburner implements IBladeburner { } } - getActionEstimatedSuccessChanceNetscriptFn(person: IPerson, type: string, name: string): [number, number] | string { + getActionEstimatedSuccessChanceNetscriptFn(person: Person, type: string, name: string): [number, number] | string { const actionId = this.getActionIdFromTypeAndName(type, name); if (actionId == null) { return "bladeburner.getActionEstimatedSuccessChance"; diff --git a/src/Bladeburner/IAction.tsx b/src/Bladeburner/IAction.tsx index 55202d638..0f396fa32 100644 --- a/src/Bladeburner/IAction.tsx +++ b/src/Bladeburner/IAction.tsx @@ -1,5 +1,5 @@ import { IReviverValue } from "../utils/JSONReviver"; -import { IPerson } from "../PersonObjects/IPerson"; +import { Person } from "../PersonObjects/Person"; import { IBladeburner } from "./IBladeburner"; interface IStatsMultiplier { @@ -57,15 +57,15 @@ export interface IAction { teamCount: number; getDifficulty(): number; - attempt(inst: IBladeburner, person: IPerson): boolean; + attempt(inst: IBladeburner, person: Person): boolean; getActionTimePenalty(): number; - getActionTime(inst: IBladeburner, person: IPerson): number; + getActionTime(inst: IBladeburner, person: Person): number; getTeamSuccessBonus(inst: IBladeburner): number; getActionTypeSkillSuccessBonus(inst: IBladeburner): number; getChaosCompetencePenalty(inst: IBladeburner, params: ISuccessChanceParams): number; getChaosDifficultyBonus(inst: IBladeburner): number; - getEstSuccessChance(inst: IBladeburner, person: IPerson): [number, number]; - getSuccessChance(inst: IBladeburner, person: IPerson, params: ISuccessChanceParams): number; + getEstSuccessChance(inst: IBladeburner, person: Person): [number, number]; + getSuccessChance(inst: IBladeburner, person: Person, params: ISuccessChanceParams): number; getSuccessesNeededForNextLevel(baseSuccessesPerLevel: number): number; setMaxLevel(baseSuccessesPerLevel: number): void; toJSON(): IReviverValue; diff --git a/src/Bladeburner/IBladeburner.ts b/src/Bladeburner/IBladeburner.ts index 80062b3c2..0f3353ba1 100644 --- a/src/Bladeburner/IBladeburner.ts +++ b/src/Bladeburner/IBladeburner.ts @@ -2,7 +2,7 @@ import { IActionIdentifier } from "./IActionIdentifier"; import { City } from "./City"; import { Skill } from "./Skill"; import { IAction } from "./IAction"; -import { IPerson } from "../PersonObjects/IPerson"; +import { Person } from "../PersonObjects/Person"; import { ITaskTracker } from "../PersonObjects/ITaskTracker"; import { WorkerScript } from "../Netscript/WorkerScript"; import { Contract } from "./Contract"; @@ -82,8 +82,8 @@ export interface IBladeburner { getGeneralActionNamesNetscriptFn(): string[]; getSkillNamesNetscriptFn(): string[]; startActionNetscriptFn(type: string, name: string, workerScript: WorkerScript): boolean; - getActionTimeNetscriptFn(person: IPerson, type: string, name: string): number | string; - getActionEstimatedSuccessChanceNetscriptFn(person: IPerson, type: string, name: string): [number, number] | string; + getActionTimeNetscriptFn(person: Person, type: string, name: string): number | string; + getActionEstimatedSuccessChanceNetscriptFn(person: Person, type: string, name: string): [number, number] | string; getActionCountRemainingNetscriptFn(type: string, name: string, workerScript: WorkerScript): number; getSkillLevelNetscriptFn(skillName: string, workerScript: WorkerScript): number; getSkillUpgradeCostNetscriptFn(skillName: string, count: number, workerScript: WorkerScript): number; @@ -102,23 +102,23 @@ export interface IBladeburner { triggerMigration(sourceCityName: string): void; triggerPotentialMigration(sourceCityName: string, chance: number): void; randomEvent(): void; - getDiplomacyEffectiveness(person: IPerson): number; - getRecruitmentSuccessChance(person: IPerson): number; - getRecruitmentTime(person: IPerson): number; + getDiplomacyEffectiveness(person: Person): number; + getRecruitmentSuccessChance(person: Person): number; + getRecruitmentTime(person: Person): number; resetSkillMultipliers(): void; updateSkillMultipliers(): void; completeOperation(success: boolean): void; getActionObject(actionId: IActionIdentifier): IAction | null; completeContract(success: boolean, actionIdent: IActionIdentifier): void; - completeAction(person: IPerson, actionIdent: IActionIdentifier, isPlayer?: boolean): ITaskTracker; + completeAction(person: Person, actionIdent: IActionIdentifier, isPlayer?: boolean): ITaskTracker; infiltrateSynthoidCommunities(): void; - changeRank(person: IPerson, change: number): void; + changeRank(person: Person, change: number): void; processAction(seconds: number): void; calculateStaminaGainPerSecond(): number; calculateMaxStamina(): void; create(): void; process(): void; - getActionStats(action: IAction, person: IPerson, success: boolean): ITaskTracker; + getActionStats(action: IAction, person: Person, success: boolean): ITaskTracker; sleeveSupport(joining: boolean): void; toJSON(): IReviverValue; } diff --git a/src/CotMG/StaneksGift.ts b/src/CotMG/StaneksGift.ts index 2943eee4c..876f9e41d 100644 --- a/src/CotMG/StaneksGift.ts +++ b/src/CotMG/StaneksGift.ts @@ -225,7 +225,7 @@ export class StaneksGift implements IStaneksGift { if (!sleeve.hasAugmentation(AugmentationNames.ZOE)) continue; sleeve.resetMultipliers(); sleeve.mults = mergeMultipliers(sleeve.mults, sleeveMults); - sleeve.updateStatLevels(); + sleeve.updateSkillLevels(); } } diff --git a/src/Crime/Crime.ts b/src/Crime/Crime.ts index 8edf124f8..399518581 100644 --- a/src/Crime/Crime.ts +++ b/src/Crime/Crime.ts @@ -1,6 +1,6 @@ import { CONSTANTS } from "../Constants"; import { Player } from "../Player"; -import { IPerson } from "../PersonObjects/IPerson"; +import { Person } from "../PersonObjects/Person"; import { WorkerScript } from "../Netscript/WorkerScript"; import { CrimeType } from "../utils/WorkType"; import { CrimeWork } from "../Work/CrimeWork"; @@ -115,7 +115,7 @@ export class Crime { return this.time; } - successRate(p: IPerson): number { + successRate(p: Person): number { let chance: number = this.hacking_success_weight * p.skills.hacking + this.strength_success_weight * p.skills.strength + diff --git a/src/Crime/formulas/crime.ts b/src/Crime/formulas/crime.ts deleted file mode 100644 index 0a896028b..000000000 --- a/src/Crime/formulas/crime.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { calculateIntelligenceBonus } from "../../PersonObjects/formulas/intelligence"; -import { CONSTANTS } from "../../Constants"; - -export interface ICrime { - hacking_success_weight: number; - strength_success_weight: number; - defense_success_weight: number; - dexterity_success_weight: number; - agility_success_weight: number; - charisma_success_weight: number; - difficulty: number; -} - -export interface IPerson { - hacking: number; - strength: number; - defense: number; - dexterity: number; - agility: number; - charisma: number; - intelligence: number; - crime_success_mult: number; -} - -export function calculateCrimeSuccessChance(crime: ICrime, person: IPerson): number { - let chance: number = - crime.hacking_success_weight * person.hacking + - crime.strength_success_weight * person.strength + - crime.defense_success_weight * person.defense + - crime.dexterity_success_weight * person.dexterity + - crime.agility_success_weight * person.agility + - crime.charisma_success_weight * person.charisma + - CONSTANTS.IntelligenceCrimeWeight * person.intelligence; - chance /= CONSTANTS.MaxSkillLevel; - chance /= crime.difficulty; - chance *= person.crime_success_mult; - chance *= calculateIntelligenceBonus(person.intelligence); - - return Math.min(chance, 1); -} diff --git a/src/Faction/formulas/donation.ts b/src/Faction/formulas/donation.ts index 0bcd8c645..14d14bfaf 100644 --- a/src/Faction/formulas/donation.ts +++ b/src/Faction/formulas/donation.ts @@ -1,6 +1,6 @@ import { CONSTANTS } from "../../Constants"; -import { IPerson } from "../../PersonObjects/IPerson"; +import { Person } from "../../PersonObjects/Person"; -export function repFromDonation(amt: number, person: IPerson): number { +export function repFromDonation(amt: number, person: Person): number { return (amt / CONSTANTS.DonateMoneyToRepDivisor) * person.mults.faction_rep; } diff --git a/src/Hacking.ts b/src/Hacking.ts index 91feb8883..d0febe357 100644 --- a/src/Hacking.ts +++ b/src/Hacking.ts @@ -1,12 +1,12 @@ import { BitNodeMultipliers } from "./BitNode/BitNodeMultipliers"; -import { IPerson } from "./PersonObjects/IPerson"; +import { Person } from "./PersonObjects/Person"; import { calculateIntelligenceBonus } from "./PersonObjects/formulas/intelligence"; import { Server } from "./Server/Server"; /** * Returns the chance the person has to successfully hack a server */ -export function calculateHackingChance(server: Server, person: IPerson): number { +export function calculateHackingChance(server: Server, person: Person): number { const hackFactor = 1.75; const difficultyMult = (100 - server.hackDifficulty) / 100; const skillMult = hackFactor * person.skills.hacking; @@ -30,7 +30,7 @@ export function calculateHackingChance(server: Server, person: IPerson): number * Returns the amount of hacking experience the person will gain upon * successfully hacking a server */ -export function calculateHackingExpGain(server: Server, person: IPerson): number { +export function calculateHackingExpGain(server: Server, person: Person): number { const baseExpGain = 3; const diffFactor = 0.3; if (server.baseDifficulty == null) { @@ -46,7 +46,7 @@ export function calculateHackingExpGain(server: Server, person: IPerson): number * Returns the percentage of money that will be stolen from a server if * it is successfully hacked (returns the decimal form, not the actual percent value) */ -export function calculatePercentMoneyHacked(server: Server, person: IPerson): number { +export function calculatePercentMoneyHacked(server: Server, person: Person): number { // Adjust if needed for balancing. This is the divisor for the final calculation const balanceFactor = 240; @@ -67,7 +67,7 @@ export function calculatePercentMoneyHacked(server: Server, person: IPerson): nu /** * Returns time it takes to complete a hack on a server, in seconds */ -export function calculateHackingTime(server: Server, person: IPerson): number { +export function calculateHackingTime(server: Server, person: Person): number { const difficultyMult = server.requiredHackingSkill * server.hackDifficulty; const baseDiff = 500; @@ -88,7 +88,7 @@ export function calculateHackingTime(server: Server, person: IPerson): number { /** * Returns time it takes to complete a grow operation on a server, in seconds */ -export function calculateGrowTime(server: Server, person: IPerson): number { +export function calculateGrowTime(server: Server, person: Person): number { const growTimeMultiplier = 3.2; // Relative to hacking time. 16/5 = 3.2 return growTimeMultiplier * calculateHackingTime(server, person); @@ -97,7 +97,7 @@ export function calculateGrowTime(server: Server, person: IPerson): number { /** * Returns time it takes to complete a weaken operation on a server, in seconds */ -export function calculateWeakenTime(server: Server, person: IPerson): number { +export function calculateWeakenTime(server: Server, person: Person): number { const weakenTimeMultiplier = 4; // Relative to hacking time return weakenTimeMultiplier * calculateHackingTime(server, person); diff --git a/src/Netscript/NetscriptHelpers.ts b/src/Netscript/NetscriptHelpers.ts index 79a2dc2bb..be1cae56c 100644 --- a/src/Netscript/NetscriptHelpers.ts +++ b/src/Netscript/NetscriptHelpers.ts @@ -21,7 +21,7 @@ import { CONSTANTS } from "../Constants"; import { influenceStockThroughServerHack } from "../StockMarket/PlayerInfluencing"; import { IPort, NetscriptPort } from "../NetscriptPort"; import { NetscriptPorts } from "../NetscriptWorker"; -import { IPerson } from "../PersonObjects/IPerson"; +import { Person } from "../PersonObjects/Person"; import { FormulaGang } from "../Gang/formulas/formulas"; import { GangMember } from "../Gang/GangMember"; import { GangMemberTask } from "../Gang/GangMemberTask"; @@ -498,7 +498,7 @@ function getValidPort(ctx: NetscriptContext, port: number): IPort { return iport; } -function player(ctx: NetscriptContext, p: unknown): IPerson { +function player(ctx: NetscriptContext, p: unknown): Person { const fakePlayer = { hp: undefined, mults: undefined, @@ -518,7 +518,7 @@ function player(ctx: NetscriptContext, p: unknown): IPerson { entropy: undefined, }; if (!roughlyIs(fakePlayer, p)) throw makeRuntimeErrorMsg(ctx, `player should be a Player.`, "TYPE"); - return p as IPerson; + return p as Person; } function server(ctx: NetscriptContext, s: unknown): Server { diff --git a/src/PersonObjects/IPerson.ts b/src/PersonObjects/IPerson.ts deleted file mode 100644 index f1611d483..000000000 --- a/src/PersonObjects/IPerson.ts +++ /dev/null @@ -1,33 +0,0 @@ -// Interface that represents either the player (PlayerObject) or -// 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 { - hp: HP; - skills: Skills; - exp: Skills; - - mults: Multipliers; - - augmentations: IPlayerOwnedAugmentation[]; - - getIntelligenceBonus(weight: number): number; - gainHackingExp(exp: number): void; - gainStrengthExp(exp: number): void; - gainDefenseExp(exp: number): void; - gainDexterityExp(exp: number): void; - gainAgilityExp(exp: number): void; - gainCharismaExp(exp: number): void; - gainIntelligenceExp(exp: number): void; - gainStats(retValue: ITaskTracker): void; - calculateSkill(exp: number, mult?: number): number; - takeDamage(amt: number): boolean; - regenerateHp: (amt: number) => void; - queryStatFromString: (str: string) => number; - whoAmI: () => string; -} diff --git a/src/PersonObjects/Person.ts b/src/PersonObjects/Person.ts index c08cc38dd..794f2ed62 100644 --- a/src/PersonObjects/Person.ts +++ b/src/PersonObjects/Person.ts @@ -1,18 +1,15 @@ -import * as generalMethods from "./Player/PlayerObjectGeneralMethods"; -import { Augmentation } from "../Augmentation/Augmentation"; +import * as personMethods from "./PersonMethods"; import { IPlayerOwnedAugmentation } from "../Augmentation/PlayerOwnedAugmentation"; -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; import { CityName } from "../Locations/data/CityNames"; -import { CONSTANTS } from "../Constants"; import { calculateSkill } from "./formulas/skill"; import { calculateIntelligenceBonus } from "./formulas/intelligence"; -import { IPerson } from "./IPerson"; -import { defaultMultipliers, mergeAugmentation } from "./Multipliers"; +import { defaultMultipliers } from "./Multipliers"; import { Skills } from "./Skills"; import { HP } from "./HP"; +import { IReviverValue } from "../utils/JSONReviver"; // Base class representing a person-like object -export abstract class Person implements IPerson { +export abstract class Person { hp: HP = { current: 10, max: 10 }; skills: Skills = { hacking: 1, @@ -45,126 +42,31 @@ export abstract class Person implements IPerson { */ city: CityName = CityName.Sector12; - gainHackingExp = generalMethods.gainHackingExp; - gainStrengthExp = generalMethods.gainStrengthExp; - gainDefenseExp = generalMethods.gainDefenseExp; - gainDexterityExp = generalMethods.gainDexterityExp; - gainAgilityExp = generalMethods.gainAgilityExp; - gainCharismaExp = generalMethods.gainCharismaExp; - gainIntelligenceExp = generalMethods.gainIntelligenceExp; - gainStats = generalMethods.gainStats; - calculateSkill = generalMethods.calculateSkill; - regenerateHp = generalMethods.regenerateHp; - queryStatFromString = generalMethods.queryStatFromString; - - /** - * Updates this object's multipliers for the given augmentation - */ - applyAugmentation(aug: Augmentation): void { - this.mults = mergeAugmentation(this.mults, aug.mults); - } - - /** - * Given an experience amount and stat multiplier, calculates the - * stat level. Stat-agnostic (same formula for every stat) - */ - calculateStat(exp: number, mult = 1): number { - return calculateSkill(exp, mult); - } - - /** - * Calculate and return the amount of faction reputation earned per cycle - * when doing Field Work for a faction - */ - getFactionFieldWorkRepGain(): number { - const t = - (0.9 * - (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; - } - - /** - * Calculate and return the amount of faction reputation earned per cycle - * when doing Hacking Work for a faction - */ - getFactionHackingWorkRepGain(): number { - return (this.skills.hacking / CONSTANTS.MaxSkillLevel) * this.mults.faction_rep; - } - - /** - * Calculate and return the amount of faction reputation earned per cycle - * when doing Security Work for a faction - */ - getFactionSecurityWorkRepGain(): number { - const t = - (0.9 * - (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; - } + gainHackingExp = personMethods.gainHackingExp; + gainStrengthExp = personMethods.gainStrengthExp; + gainDefenseExp = personMethods.gainDefenseExp; + gainDexterityExp = personMethods.gainDexterityExp; + gainAgilityExp = personMethods.gainAgilityExp; + gainCharismaExp = personMethods.gainCharismaExp; + gainIntelligenceExp = personMethods.gainIntelligenceExp; + gainStats = personMethods.gainStats; + regenerateHp = personMethods.regenerateHp; + queryStatFromString = personMethods.queryStatFromString; + updateSkillLevels = personMethods.updateSkillLevels; + calculateSkill = calculateSkill; //Class version is equal to imported version /** * Reset all multipliers to 1 */ - resetMultipliers(): void { + resetMultipliers() { this.mults = defaultMultipliers(); } - /** - * Update all stat levels - */ - updateStatLevels(): void { - this.skills.hacking = Math.max( - 1, - Math.floor(this.calculateStat(this.exp.hacking, this.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier)), - ); - this.skills.strength = Math.max( - 1, - Math.floor( - this.calculateStat(this.exp.strength, this.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier), - ), - ); - this.skills.defense = Math.max( - 1, - Math.floor(this.calculateStat(this.exp.defense, this.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier)), - ); - this.skills.dexterity = Math.max( - 1, - Math.floor( - this.calculateStat(this.exp.dexterity, this.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier), - ), - ); - this.skills.agility = Math.max( - 1, - Math.floor(this.calculateStat(this.exp.agility, this.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier)), - ); - this.skills.charisma = Math.max( - 1, - Math.floor( - this.calculateStat(this.exp.charisma, this.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier), - ), - ); - - 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.skills.intelligence, weight); } abstract takeDamage(amt: number): boolean; - abstract whoAmI(): string; + abstract toJSON(): IReviverValue; } diff --git a/src/PersonObjects/PersonMethods.ts b/src/PersonObjects/PersonMethods.ts new file mode 100644 index 000000000..b3657c438 --- /dev/null +++ b/src/PersonObjects/PersonMethods.ts @@ -0,0 +1,199 @@ +import { Person } from "./Person"; +import { calculateSkill } from "./formulas/skill"; +import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { Player } from "../Player"; +import { ITaskTracker } from "./ITaskTracker"; + +export function gainHackingExp(this: Person, exp: number): void { + if (isNaN(exp)) { + console.error("ERR: NaN passed into Player.gainHackingExp()"); + return; + } + this.exp.hacking += exp; + if (this.exp.hacking < 0) { + this.exp.hacking = 0; + } + + this.skills.hacking = calculateSkill( + this.exp.hacking, + this.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier, + ); +} + +export function gainStrengthExp(this: Person, exp: number): void { + if (isNaN(exp)) { + console.error("ERR: NaN passed into Player.gainStrengthExp()"); + return; + } + this.exp.strength += exp; + if (this.exp.strength < 0) { + this.exp.strength = 0; + } + + this.skills.strength = calculateSkill( + this.exp.strength, + this.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier, + ); +} + +export function gainDefenseExp(this: Person, exp: number): void { + if (isNaN(exp)) { + console.error("ERR: NaN passed into player.gainDefenseExp()"); + return; + } + this.exp.defense += exp; + if (this.exp.defense < 0) { + this.exp.defense = 0; + } + + this.skills.defense = calculateSkill( + 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: Person, exp: number): void { + if (isNaN(exp)) { + console.error("ERR: NaN passed into Player.gainDexterityExp()"); + return; + } + this.exp.dexterity += exp; + if (this.exp.dexterity < 0) { + this.exp.dexterity = 0; + } + + this.skills.dexterity = calculateSkill( + this.exp.dexterity, + this.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier, + ); +} + +export function gainAgilityExp(this: Person, exp: number): void { + if (isNaN(exp)) { + console.error("ERR: NaN passed into Player.gainAgilityExp()"); + return; + } + this.exp.agility += exp; + if (this.exp.agility < 0) { + this.exp.agility = 0; + } + + this.skills.agility = calculateSkill( + this.exp.agility, + this.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier, + ); +} + +export function gainCharismaExp(this: Person, exp: number): void { + if (isNaN(exp)) { + console.error("ERR: NaN passed into Player.gainCharismaExp()"); + return; + } + this.exp.charisma += exp; + if (this.exp.charisma < 0) { + this.exp.charisma = 0; + } + + this.skills.charisma = calculateSkill( + this.exp.charisma, + this.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier, + ); +} + +export function gainIntelligenceExp(this: Person, exp: number): void { + if (isNaN(exp)) { + console.error("ERROR: NaN passed into Player.gainIntelligenceExp()"); + return; + } + if (Player.sourceFileLvl(5) > 0 || this.skills.intelligence > 0 || Player.bitNodeN === 5) { + this.exp.intelligence += exp; + this.skills.intelligence = Math.floor(this.calculateSkill(this.exp.intelligence, 1)); + } +} +export function gainStats(this: Person, retValue: ITaskTracker): void { + this.gainHackingExp(retValue.hack * this.mults.hacking_exp); + this.gainStrengthExp(retValue.str * this.mults.strength_exp); + this.gainDefenseExp(retValue.def * this.mults.defense_exp); + this.gainDexterityExp(retValue.dex * this.mults.dexterity_exp); + this.gainAgilityExp(retValue.agi * this.mults.agility_exp); + this.gainCharismaExp(retValue.cha * this.mults.charisma_exp); + this.gainIntelligenceExp(retValue.int); +} + +//Given a string expression like "str" or "strength", returns the given stat +export function queryStatFromString(this: Person, str: string): number { + const tempStr = str.toLowerCase(); + if (tempStr.includes("hack")) { + return this.skills.hacking; + } + if (tempStr.includes("str")) { + return this.skills.strength; + } + if (tempStr.includes("def")) { + return this.skills.defense; + } + if (tempStr.includes("dex")) { + return this.skills.dexterity; + } + if (tempStr.includes("agi")) { + return this.skills.agility; + } + if (tempStr.includes("cha")) { + return this.skills.charisma; + } + if (tempStr.includes("int")) { + return this.skills.intelligence; + } + return 0; +} + +export function regenerateHp(this: Person, amt: number): void { + if (typeof amt !== "number") { + console.warn(`Player.regenerateHp() called without a numeric argument: ${amt}`); + return; + } + this.hp.current += amt; + if (this.hp.current > this.hp.max) { + this.hp.current = this.hp.max; + } +} + +export function updateSkillLevels(this: Person): void { + this.skills.hacking = Math.max( + 1, + Math.floor(this.calculateSkill(this.exp.hacking, this.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier)), + ); + this.skills.strength = Math.max( + 1, + Math.floor( + this.calculateSkill(this.exp.strength, this.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier), + ), + ); + this.skills.defense = Math.max( + 1, + Math.floor(this.calculateSkill(this.exp.defense, this.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier)), + ); + this.skills.dexterity = Math.max( + 1, + Math.floor( + this.calculateSkill(this.exp.dexterity, this.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier), + ), + ); + this.skills.agility = Math.max( + 1, + Math.floor(this.calculateSkill(this.exp.agility, this.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier)), + ); + this.skills.charisma = Math.max( + 1, + Math.floor( + this.calculateSkill(this.exp.charisma, this.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier), + ), + ); + + 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); +} diff --git a/src/PersonObjects/Player/PlayerObject.ts b/src/PersonObjects/Player/PlayerObject.ts index af67f569a..e083fb46a 100644 --- a/src/PersonObjects/Player/PlayerObject.ts +++ b/src/PersonObjects/Player/PlayerObject.ts @@ -11,7 +11,6 @@ import { Sleeve } from "../Sleeve/Sleeve"; import { IPlayerOwnedSourceFile } from "../../SourceFile/PlayerOwnedSourceFile"; import { Exploit } from "../../Exploits/Exploit"; -import { IPerson } from "../IPerson"; import { LocationName } from "../../Locations/data/LocationNames"; import { IPlayerOwnedAugmentation } from "../../Augmentation/PlayerOwnedAugmentation"; import { ICorporation } from "../../Corporation/ICorporation"; @@ -20,7 +19,6 @@ import { IBladeburner } from "../../Bladeburner/IBladeburner"; import { HacknetNode } from "../../Hacknet/HacknetNode"; import { HashManager } from "../../Hacknet/HashManager"; -import { CityName } from "../../Locations/data/CityNames"; import { MoneySourceTracker } from "../../utils/MoneySourceTracker"; import { Reviver, Generic_toJSON, Generic_fromJSON, IReviverValue } from "../../utils/JSONReviver"; @@ -29,15 +27,11 @@ import { cyrb53 } from "../../utils/StringHelperFunctions"; import { getRandomInt } from "../../utils/helpers/getRandomInt"; import { CONSTANTS } from "../../Constants"; import { Work } from "src/Work/Work"; -import { defaultMultipliers } from "../Multipliers"; -import { HP } from "../HP"; -import { Skills } from "../Skills"; +import { Person } from "../Person"; -export class PlayerObject implements IPerson { - // Class members - augmentations: IPlayerOwnedAugmentation[] = []; +export class PlayerObject extends Person { + // Player-specific properties bitNodeN = 1; //current bitnode - city = CityName.Sector12; corporation: ICorporation | null = null; gang: IGang | null = null; bladeburner: IBladeburner | null = null; @@ -73,34 +67,12 @@ export class PlayerObject implements IPerson { lastSave = 0; totalPlaytime = 0; - hp: HP = { current: 10, max: 10 }; - skills: Skills = { - hacking: 1, - strength: 1, - defense: 1, - dexterity: 1, - agility: 1, - charisma: 1, - intelligence: 0, - }; - exp: Skills = { - hacking: 0, - strength: 0, - defense: 0, - dexterity: 0, - agility: 0, - charisma: 0, - intelligence: 0, - }; - - mults = defaultMultipliers(); - currentWork: Work | null = null; focus = false; entropy = 0; - // Methods + // Player-specific methods init = generalMethods.init; startWork = workMethods.startWork; processWork = workMethods.processWork; @@ -124,14 +96,6 @@ export class PlayerObject implements IPerson { canAccessGang = gangMethods.canAccessGang; canAccessGrafting = generalMethods.canAccessGrafting; canAfford = generalMethods.canAfford; - gainHackingExp = generalMethods.gainHackingExp; - gainStrengthExp = generalMethods.gainStrengthExp; - gainDefenseExp = generalMethods.gainDefenseExp; - gainDexterityExp = generalMethods.gainDexterityExp; - gainAgilityExp = generalMethods.gainAgilityExp; - gainCharismaExp = generalMethods.gainCharismaExp; - gainIntelligenceExp = generalMethods.gainIntelligenceExp; - gainStats = generalMethods.gainStats; gainMoney = generalMethods.gainMoney; getCurrentServer = serverMethods.getCurrentServer; getGangFaction = gangMethods.getGangFaction; @@ -153,7 +117,6 @@ export class PlayerObject implements IPerson { loseMoney = generalMethods.loseMoney; reapplyAllAugmentations = generalMethods.reapplyAllAugmentations; reapplyAllSourceFiles = generalMethods.reapplyAllSourceFiles; - regenerateHp = generalMethods.regenerateHp; recordMoneySource = generalMethods.recordMoneySource; setMoney = generalMethods.setMoney; startBladeburner = bladeburnerMethods.startBladeburner; @@ -164,21 +127,16 @@ export class PlayerObject implements IPerson { travel = generalMethods.travel; giveExploit = generalMethods.giveExploit; giveAchievement = generalMethods.giveAchievement; - queryStatFromString = generalMethods.queryStatFromString; - getIntelligenceBonus = generalMethods.getIntelligenceBonus; getCasinoWinnings = generalMethods.getCasinoWinnings; quitJob = generalMethods.quitJob; hasJob = generalMethods.hasJob; createHacknetServer = serverMethods.createHacknetServer; queueAugmentation = generalMethods.queueAugmentation; receiveInvite = generalMethods.receiveInvite; - updateSkillLevels = generalMethods.updateSkillLevels; gainCodingContractReward = generalMethods.gainCodingContractReward; stopFocusing = generalMethods.stopFocusing; - resetMultipliers = generalMethods.resetMultipliers; prestigeAugmentation = generalMethods.prestigeAugmentation; prestigeSourceFile = generalMethods.prestigeSourceFile; - calculateSkill = generalMethods.calculateSkill; calculateSkillProgress = generalMethods.calculateSkillProgress; hospitalize = generalMethods.hospitalize; checkForFactionInvitations = generalMethods.checkForFactionInvitations; @@ -189,6 +147,7 @@ export class PlayerObject implements IPerson { focusPenalty = generalMethods.focusPenalty; constructor() { + super(); // Let's get a hash of some semi-random stuff so we have something unique. this.identifier = cyrb53( "I-" + @@ -219,4 +178,4 @@ export class PlayerObject implements IPerson { } } -Reviver.constructors.PlayerObject = PlayerObject; +Reviver.constructors.PlayerObject = PlayerObject; \ No newline at end of file diff --git a/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts b/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts index e44277f8f..f27c3bd50 100644 --- a/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts +++ b/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts @@ -24,11 +24,9 @@ import { LocationName } from "../../Locations/data/LocationNames"; import { Sleeve } from "../Sleeve/Sleeve"; import { isSleeveCompanyWork } from "../Sleeve/Work/SleeveCompanyWork"; import { - calculateSkill as calculateSkillF, calculateSkillProgress as calculateSkillProgressF, ISkillProgress, } from "../formulas/skill"; -import { calculateIntelligenceBonus } from "../formulas/intelligence"; import { GetServer, AddToAllServers, createUniqueRandomIp } from "../../Server/AllServers"; import { Server } from "../../Server/Server"; import { safetlyCreateUniqueServer } from "../../Server/ServerHelpers"; @@ -47,12 +45,8 @@ import { dialogBoxCreate } from "../../ui/React/DialogBox"; import { SnackbarEvents, ToastVariant } from "../../ui/React/Snackbar"; import { achievements } from "../../Achievements/Achievements"; import { FactionNames } from "../../Faction/data/FactionNames"; -import { ITaskTracker } from "../ITaskTracker"; -import { IPerson } from "../IPerson"; -import { Player } from "../../Player"; import { isCompanyWork } from "../../Work/CompanyWork"; -import { defaultMultipliers } from "../Multipliers"; import { serverMetadata } from "../../Server/data/servers"; export function init(this: PlayerObject): void { @@ -186,63 +180,11 @@ export function receiveInvite(this: PlayerObject, factionName: string): void { this.factionInvitations.push(factionName); } -//Calculates skill level based on experience. The same formula will be used for every skill -export function calculateSkill(this: IPerson, exp: number, mult = 1): number { - return calculateSkillF(exp, mult); -} - //Calculates skill level progress based on experience. The same formula will be used for every skill export function calculateSkillProgress(this: PlayerObject, exp: number, mult = 1): ISkillProgress { return calculateSkillProgressF(exp, mult); } -export function updateSkillLevels(this: PlayerObject): void { - this.skills.hacking = Math.max( - 1, - Math.floor(this.calculateSkill(this.exp.hacking, this.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier)), - ); - this.skills.strength = Math.max( - 1, - Math.floor( - this.calculateSkill(this.exp.strength, this.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier), - ), - ); - this.skills.defense = Math.max( - 1, - Math.floor(this.calculateSkill(this.exp.defense, this.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier)), - ); - this.skills.dexterity = Math.max( - 1, - Math.floor( - this.calculateSkill(this.exp.dexterity, this.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier), - ), - ); - this.skills.agility = Math.max( - 1, - Math.floor(this.calculateSkill(this.exp.agility, this.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier)), - ); - this.skills.charisma = Math.max( - 1, - Math.floor( - this.calculateSkill(this.exp.charisma, this.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier), - ), - ); - - if (this.skills.intelligence > 0) { - this.skills.intelligence = Math.floor(this.calculateSkill(this.exp.intelligence)); - } else { - this.skills.intelligence = 0; - } - - 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: PlayerObject): void { - this.mults = defaultMultipliers(); -} - export function hasProgram(this: PlayerObject, programName: string): boolean { const home = this.getHomeComputer(); if (home == null) { @@ -306,153 +248,6 @@ export function recordMoneySource(this: PlayerObject, amt: number, source: strin this.moneySourceB.record(amt, source); } -export function gainHackingExp(this: IPerson, exp: number): void { - if (isNaN(exp)) { - console.error("ERR: NaN passed into Player.gainHackingExp()"); - return; - } - this.exp.hacking += exp; - if (this.exp.hacking < 0) { - this.exp.hacking = 0; - } - - this.skills.hacking = calculateSkillF( - this.exp.hacking, - this.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier, - ); -} - -export function gainStrengthExp(this: IPerson, exp: number): void { - if (isNaN(exp)) { - console.error("ERR: NaN passed into Player.gainStrengthExp()"); - return; - } - this.exp.strength += exp; - if (this.exp.strength < 0) { - this.exp.strength = 0; - } - - this.skills.strength = calculateSkillF( - this.exp.strength, - this.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier, - ); -} - -export function gainDefenseExp(this: IPerson, exp: number): void { - if (isNaN(exp)) { - console.error("ERR: NaN passed into player.gainDefenseExp()"); - return; - } - this.exp.defense += exp; - if (this.exp.defense < 0) { - this.exp.defense = 0; - } - - 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 { - if (isNaN(exp)) { - console.error("ERR: NaN passed into Player.gainDexterityExp()"); - return; - } - this.exp.dexterity += exp; - if (this.exp.dexterity < 0) { - this.exp.dexterity = 0; - } - - this.skills.dexterity = calculateSkillF( - this.exp.dexterity, - this.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier, - ); -} - -export function gainAgilityExp(this: IPerson, exp: number): void { - if (isNaN(exp)) { - console.error("ERR: NaN passed into Player.gainAgilityExp()"); - return; - } - this.exp.agility += exp; - if (this.exp.agility < 0) { - this.exp.agility = 0; - } - - this.skills.agility = calculateSkillF( - this.exp.agility, - this.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier, - ); -} - -export function gainCharismaExp(this: IPerson, exp: number): void { - if (isNaN(exp)) { - console.error("ERR: NaN passed into Player.gainCharismaExp()"); - return; - } - this.exp.charisma += exp; - if (this.exp.charisma < 0) { - this.exp.charisma = 0; - } - - this.skills.charisma = calculateSkillF( - this.exp.charisma, - this.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier, - ); -} - -export function gainIntelligenceExp(this: IPerson, exp: number): void { - if (isNaN(exp)) { - console.error("ERROR: NaN passed into Player.gainIntelligenceExp()"); - return; - } - if (Player.sourceFileLvl(5) > 0 || this.skills.intelligence > 0 || Player.bitNodeN === 5) { - this.exp.intelligence += exp; - this.skills.intelligence = Math.floor(this.calculateSkill(this.exp.intelligence, 1)); - } -} - -export function gainStats(this: IPerson, retValue: ITaskTracker): void { - this.gainHackingExp(retValue.hack * this.mults.hacking_exp); - this.gainStrengthExp(retValue.str * this.mults.strength_exp); - this.gainDefenseExp(retValue.def * this.mults.defense_exp); - this.gainDexterityExp(retValue.dex * this.mults.dexterity_exp); - this.gainAgilityExp(retValue.agi * this.mults.agility_exp); - this.gainCharismaExp(retValue.cha * this.mults.charisma_exp); - this.gainIntelligenceExp(retValue.int); -} - -//Given a string expression like "str" or "strength", returns the given stat -export function queryStatFromString(this: PlayerObject, str: string): number { - const tempStr = str.toLowerCase(); - if (tempStr.includes("hack")) { - return this.skills.hacking; - } - if (tempStr.includes("str")) { - return this.skills.strength; - } - if (tempStr.includes("def")) { - return this.skills.defense; - } - if (tempStr.includes("dex")) { - return this.skills.dexterity; - } - if (tempStr.includes("agi")) { - return this.skills.agility; - } - if (tempStr.includes("cha")) { - return this.skills.charisma; - } - if (tempStr.includes("int")) { - return this.skills.intelligence; - } - return 0; -} - export function startFocusing(this: PlayerObject): void { this.focus = true; } @@ -477,17 +272,6 @@ export function takeDamage(this: PlayerObject, amt: number): boolean { } } -export function regenerateHp(this: IPerson, amt: number): void { - if (typeof amt !== "number") { - console.warn(`Player.regenerateHp() called without a numeric argument: ${amt}`); - return; - } - this.hp.current += amt; - if (this.hp.current > this.hp.max) { - this.hp.current = this.hp.max; - } -} - export function hospitalize(this: PlayerObject): number { const cost = getHospitalizationCost(); SnackbarEvents.emit(`You've been Hospitalized for ${numeralWrapper.formatMoney(cost)}`, ToastVariant.WARNING, 2000); @@ -1441,10 +1225,6 @@ export function giveAchievement(this: PlayerObject, achievementId: string): void } } -export function getIntelligenceBonus(this: PlayerObject, weight: number): number { - return calculateIntelligenceBonus(this.skills.intelligence, weight); -} - export function getCasinoWinnings(this: PlayerObject): number { return this.moneySourceA.casino; } diff --git a/src/PersonObjects/Sleeve/Sleeve.ts b/src/PersonObjects/Sleeve/Sleeve.ts index ff0f92f40..2b0d5c4a5 100644 --- a/src/PersonObjects/Sleeve/Sleeve.ts +++ b/src/PersonObjects/Sleeve/Sleeve.ts @@ -80,6 +80,7 @@ export class Sleeve extends Person { this.shockRecovery(); } + applyAugmentation = sleeveMethods.applyAugmentation; findPurchasableAugs = sleeveMethods.findPurchasableAugs; shockBonus(): number { @@ -147,7 +148,7 @@ export class Sleeve extends Person { this.exp.charisma = 0; this.applyAugmentation(aug); this.augmentations.push({ name: aug.name, level: 1 }); - this.updateStatLevels(); + this.updateSkillLevels(); } /** @@ -161,7 +162,7 @@ export class Sleeve extends Person { this.exp.dexterity = 0; this.exp.agility = 0; this.exp.charisma = 0; - this.updateStatLevels(); + this.updateSkillLevels(); this.hp.current = this.hp.max; // Reset task-related stuff diff --git a/src/PersonObjects/Sleeve/SleeveMethods.ts b/src/PersonObjects/Sleeve/SleeveMethods.ts index 08d762d29..0607ea85f 100644 --- a/src/PersonObjects/Sleeve/SleeveMethods.ts +++ b/src/PersonObjects/Sleeve/SleeveMethods.ts @@ -6,10 +6,17 @@ import { Player } from "../../Player"; import { Augmentation } from "../../Augmentation/Augmentation"; import { StaticAugmentations } from "../../Augmentation/StaticAugmentations"; import { Factions } from "../../Faction/Factions"; -import { Multipliers } from "../Multipliers"; +import { mergeMultipliers, Multipliers } from "../Multipliers"; import { AugmentationNames } from "../../Augmentation/data/AugmentationNames"; import { getFactionAugmentationsFiltered } from "../../Faction/FactionHelpers"; +/** + * Updates this object's multipliers for the given augmentation + */ +export function applyAugmentation(this: Sleeve, aug: Augmentation): void { + this.mults = mergeMultipliers(this.mults, aug.mults); +} + export function findPurchasableAugs(this: Sleeve): Augmentation[] { // You can only purchase Augmentations that are actually available from // your factions. I.e. you must be in a faction that has the Augmentation diff --git a/src/PersonObjects/formulas/reputation.ts b/src/PersonObjects/formulas/reputation.ts index 149d66733..f549493ff 100644 --- a/src/PersonObjects/formulas/reputation.ts +++ b/src/PersonObjects/formulas/reputation.ts @@ -1,7 +1,7 @@ import { CONSTANTS } from "../../Constants"; import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; import { CalculateShareMult } from "../../NetworkShare/Share"; -import { IPerson } from "../IPerson"; +import { Person } from "../Person"; import { calculateIntelligenceBonus } from "./intelligence"; function mult(favor: number): number { @@ -12,7 +12,7 @@ function mult(favor: number): number { return favorMult * BitNodeMultipliers.FactionWorkRepGain; } -export function getHackingWorkRepGain(p: IPerson, favor: number): number { +export function getHackingWorkRepGain(p: Person, favor: number): number { return ( ((p.skills.hacking + p.skills.intelligence / 3) / CONSTANTS.MaxSkillLevel) * p.mults.faction_rep * @@ -22,7 +22,7 @@ export function getHackingWorkRepGain(p: IPerson, favor: number): number { ); } -export function getFactionSecurityWorkRepGain(p: IPerson, favor: number): number { +export function getFactionSecurityWorkRepGain(p: Person, favor: number): number { const t = (0.9 * (p.skills.strength + @@ -35,7 +35,7 @@ export function getFactionSecurityWorkRepGain(p: IPerson, favor: number): number return t * p.mults.faction_rep * mult(favor) * calculateIntelligenceBonus(p.skills.intelligence, 1); } -export function getFactionFieldWorkRepGain(p: IPerson, favor: number): number { +export function getFactionFieldWorkRepGain(p: Person, favor: number): number { const t = (0.9 * (p.skills.strength + diff --git a/src/PersonObjects/formulas/skill.ts b/src/PersonObjects/formulas/skill.ts index 7f22253ca..e8f0bc479 100644 --- a/src/PersonObjects/formulas/skill.ts +++ b/src/PersonObjects/formulas/skill.ts @@ -1,3 +1,7 @@ +/** + * Given an experience amount and stat multiplier, calculates the + * stat level. Stat-agnostic (same formula for every stat) + */ export function calculateSkill(exp: number, mult = 1): number { return Math.max(Math.floor(mult * (32 * Math.log(exp + 534.5) - 200)), 1); } diff --git a/src/Server/formulas/grow.ts b/src/Server/formulas/grow.ts index 4ab2fa761..a739adf7b 100644 --- a/src/Server/formulas/grow.ts +++ b/src/Server/formulas/grow.ts @@ -1,9 +1,9 @@ import { CONSTANTS } from "../../Constants"; import { Server } from "../Server"; import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; -import { IPerson } from "../../PersonObjects/IPerson"; +import { Person } from "../../PersonObjects/Person"; -export function calculateServerGrowth(server: Server, threads: number, p: IPerson, cores = 1): number { +export function calculateServerGrowth(server: Server, threads: number, p: Person, cores = 1): number { const numServerGrowthCycles = Math.max(Math.floor(threads), 0); //Get adjusted growth rate, which accounts for server security diff --git a/src/Work/WorkStats.ts b/src/Work/WorkStats.ts index 442fbfd1b..fb98b66cb 100644 --- a/src/Work/WorkStats.ts +++ b/src/Work/WorkStats.ts @@ -1,4 +1,4 @@ -import { IPerson } from "src/PersonObjects/IPerson"; +import { Person } from "src/PersonObjects/Person"; import { Player } from "../Player"; export interface WorkStats { @@ -68,7 +68,7 @@ export const scaleWorkStats = (w: WorkStats, n: number, scaleMoney = true): Work }; }; -export const applyWorkStats = (target: IPerson, workStats: WorkStats, cycles: number, source: string): WorkStats => { +export const applyWorkStats = (target: Person, workStats: WorkStats, cycles: number, source: string): WorkStats => { const expStats = applyWorkStatsExp(target, workStats, cycles); const gains = { money: workStats.money * cycles, @@ -86,7 +86,7 @@ export const applyWorkStats = (target: IPerson, workStats: WorkStats, cycles: nu return gains; }; -export const applyWorkStatsExp = (target: IPerson, workStats: WorkStats, cycles: number): WorkStats => { +export const applyWorkStatsExp = (target: Person, workStats: WorkStats, cycles: number): WorkStats => { const gains = { money: 0, reputation: 0, diff --git a/src/Work/formulas/Class.ts b/src/Work/formulas/Class.ts index 54ede73fb..d685e497b 100644 --- a/src/Work/formulas/Class.ts +++ b/src/Work/formulas/Class.ts @@ -8,7 +8,7 @@ import { WorkStats } from "../WorkStats"; import { Server } from "../../Server/Server"; import { GetServer } from "../../Server/AllServers"; import { serverMetadata } from "../../Server/data/servers"; -import { IPerson } from "../../PersonObjects/IPerson"; +import { Person } from "../../PersonObjects/Person"; import { LocationName } from "../../Locations/data/LocationNames"; const gameCPS = 1000 / CONSTANTS._idleSpeed; // 5 cycles per second @@ -20,7 +20,7 @@ export function calculateCost(classs: Class, location: Location): number { return classs.earnings.money * location.costMult * discount; } -export function calculateClassEarnings(person: IPerson, type: ClassType, locationName: LocationName): WorkStats { +export function calculateClassEarnings(person: Person, type: ClassType, locationName: LocationName): WorkStats { //Find cost and exp gain per game cycle const hashManager = Player.hashManager; const classs = Classes[type]; diff --git a/src/Work/formulas/Company.ts b/src/Work/formulas/Company.ts index 801b8813b..710cd89e6 100644 --- a/src/Work/formulas/Company.ts +++ b/src/Work/formulas/Company.ts @@ -4,9 +4,9 @@ import { Player } from "../../Player"; import { WorkStats } from "../WorkStats"; import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; import { CONSTANTS } from "../../Constants"; -import { IPerson } from "src/PersonObjects/IPerson"; +import { Person } from "../../PersonObjects/Person"; -export const calculateCompanyWorkStats = (worker: IPerson, company: Company): WorkStats => { +export const calculateCompanyWorkStats = (worker: Person, company: Company): WorkStats => { const companyPositionName = Player.jobs[company.name]; const companyPosition = CompanyPositions[companyPositionName]; diff --git a/src/Work/formulas/Faction.ts b/src/Work/formulas/Faction.ts index 0a2913f38..1dd704c3a 100644 --- a/src/Work/formulas/Faction.ts +++ b/src/Work/formulas/Faction.ts @@ -1,4 +1,4 @@ -import { IPerson } from "../../PersonObjects/IPerson"; +import { Person } from "../../PersonObjects/Person"; import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; import { CONSTANTS } from "../../Constants"; import { FactionWorkType } from "../data/FactionWorkType"; @@ -30,7 +30,7 @@ export const FactionWorkStats: Record = { }), }; -export const calculateFactionRep = (person: IPerson, tpe: FactionWorkType, favor: number): number => { +export const calculateFactionRep = (person: Person, tpe: FactionWorkType, favor: number): number => { const repFormulas = { [FactionWorkType.HACKING]: getHackingWorkRepGain, [FactionWorkType.FIELD]: getFactionFieldWorkRepGain, @@ -39,7 +39,7 @@ export const calculateFactionRep = (person: IPerson, tpe: FactionWorkType, favor return repFormulas[tpe](person, favor); }; -export function calculateFactionExp(person: IPerson, tpe: FactionWorkType): WorkStats { +export function calculateFactionExp(person: Person, tpe: FactionWorkType): WorkStats { const baseStats = FactionWorkStats[tpe]; return { money: 0,