extract multipliers in its own type

This commit is contained in:
Olivier Gagnon 2022-07-14 18:43:33 -04:00
parent 0550bc188c
commit 5629c16def
44 changed files with 1250 additions and 1505 deletions

@ -16,6 +16,7 @@ import { StaticAugmentations } from "./StaticAugmentations";
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
import { getBaseAugmentationPriceMultiplier, getGenericAugmentationPriceMultiplier } from "./AugmentationHelpers"; import { getBaseAugmentationPriceMultiplier, getGenericAugmentationPriceMultiplier } from "./AugmentationHelpers";
import { initSoAAugmentations } from "./data/AugmentationCreator"; import { initSoAAugmentations } from "./data/AugmentationCreator";
import { Multipliers, defaultMultipliers } from "../PersonObjects/Multipliers";
export interface AugmentationCosts { export interface AugmentationCosts {
moneyCost: number; moneyCost: number;
@ -32,48 +33,48 @@ export interface IConstructorParams {
repCost: number; repCost: number;
factions: string[]; factions: string[];
hacking_mult?: number; hacking?: number;
strength_mult?: number; strength?: number;
defense_mult?: number; defense?: number;
dexterity_mult?: number; dexterity?: number;
agility_mult?: number; agility?: number;
charisma_mult?: number; charisma?: number;
hacking_exp_mult?: number; hacking_exp?: number;
strength_exp_mult?: number; strength_exp?: number;
defense_exp_mult?: number; defense_exp?: number;
dexterity_exp_mult?: number; dexterity_exp?: number;
agility_exp_mult?: number; agility_exp?: number;
charisma_exp_mult?: number; charisma_exp?: number;
hacking_chance_mult?: number; hacking_chance?: number;
hacking_speed_mult?: number; hacking_speed?: number;
hacking_money_mult?: number; hacking_money?: number;
hacking_grow_mult?: number; hacking_grow?: number;
company_rep_mult?: number; company_rep?: number;
faction_rep_mult?: number; faction_rep?: number;
crime_money_mult?: number; crime_money?: number;
crime_success_mult?: number; crime_success?: number;
work_money_mult?: number; work_money?: number;
hacknet_node_money_mult?: number; hacknet_node_money?: number;
hacknet_node_purchase_cost_mult?: number; hacknet_node_purchase_cost?: number;
hacknet_node_ram_cost_mult?: number; hacknet_node_ram_cost?: number;
hacknet_node_core_cost_mult?: number; hacknet_node_core_cost?: number;
hacknet_node_level_cost_mult?: number; hacknet_node_level_cost?: number;
bladeburner_max_stamina_mult?: number; bladeburner_max_stamina?: number;
bladeburner_stamina_gain_mult?: number; bladeburner_stamina_gain?: number;
bladeburner_analysis_mult?: number; bladeburner_analysis?: number;
bladeburner_success_chance_mult?: number; bladeburner_success_chance?: number;
infiltration_base_rep_increase?: number; infiltration_base_rep_increase?: number;
infiltration_rep_mult?: number; infiltration_rep?: number;
infiltration_trade_mult?: number; infiltration_trade?: number;
infiltration_sell_mult?: number; infiltration_sell?: number;
infiltration_timer_mult?: number; infiltration_timer?: number;
infiltration_damage_reduction_mult?: number; infiltration_damage_reduction?: number;
startingMoney?: number; startingMoney?: number;
programs?: string[]; programs?: string[];
} }
function generateStatsDescription(mults: IMap<number>, programs?: string[], startingMoney?: number): JSX.Element { function generateStatsDescription(mults: Multipliers, programs?: string[], startingMoney?: number): JSX.Element {
const f = (x: number, decimals = 0): string => { const f = (x: number, decimals = 0): string => {
// look, I don't know how to make a "smart decimals" // look, I don't know how to make a "smart decimals"
// todo, make it smarter // todo, make it smarter
@ -84,323 +85,278 @@ function generateStatsDescription(mults: IMap<number>, programs?: string[], star
let desc = <>Effects:</>; let desc = <>Effects:</>;
if ( if (
mults.hacking_mult && mults.hacking !== 1 &&
mults.hacking_mult == mults.strength_mult && mults.hacking == mults.strength &&
mults.hacking_mult == mults.defense_mult && mults.hacking == mults.defense &&
mults.hacking_mult == mults.dexterity_mult && mults.hacking == mults.dexterity &&
mults.hacking_mult == mults.agility_mult && mults.hacking == mults.agility &&
mults.hacking_mult == mults.charisma_mult mults.hacking == mults.charisma
) { ) {
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.hacking_mult - 1)} all skills <br />+{f(mults.hacking - 1)} all skills
</> </>
); );
} else { } else {
if (mults.hacking_mult) if (mults.hacking !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.hacking_mult - 1)} hacking skill <br />+{f(mults.hacking - 1)} hacking skill
</> </>
); );
if ( if (
mults.strength_mult && mults.strength !== 1 &&
mults.strength_mult == mults.defense_mult && mults.strength == mults.defense &&
mults.strength_mult == mults.dexterity_mult && mults.strength == mults.dexterity &&
mults.strength_mult == mults.agility_mult mults.strength == mults.agility
) { ) {
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.strength_mult - 1)} combat skills <br />+{f(mults.strength - 1)} combat skills
</> </>
); );
} else { } else {
if (mults.strength_mult) if (mults.strength !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.strength_mult - 1)} strength skill <br />+{f(mults.strength - 1)} strength skill
</> </>
); );
if (mults.defense_mult) if (mults.defense !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.defense_mult - 1)} defense skill <br />+{f(mults.defense - 1)} defense skill
</> </>
); );
if (mults.dexterity_mult) if (mults.dexterity !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.dexterity_mult - 1)} dexterity skill <br />+{f(mults.dexterity - 1)} dexterity skill
</> </>
); );
if (mults.agility_mult) if (mults.agility !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.agility_mult - 1)} agility skill <br />+{f(mults.agility - 1)} agility skill
</> </>
); );
} }
if (mults.charisma_mult) if (mults.charisma !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.charisma_mult - 1)} charisma skill <br />+{f(mults.charisma - 1)} charisma skill
</> </>
); );
} }
if ( if (
mults.hacking_exp_mult && mults.hacking_exp !== 1 &&
mults.hacking_exp_mult === mults.strength_exp_mult && mults.hacking_exp === mults.strength_exp &&
mults.hacking_exp_mult === mults.defense_exp_mult && mults.hacking_exp === mults.defense_exp &&
mults.hacking_exp_mult === mults.dexterity_exp_mult && mults.hacking_exp === mults.dexterity_exp &&
mults.hacking_exp_mult === mults.agility_exp_mult && mults.hacking_exp === mults.agility_exp &&
mults.hacking_exp_mult === mults.charisma_exp_mult mults.hacking_exp === mults.charisma_exp
) { ) {
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.hacking_exp_mult - 1)} exp for all skills <br />+{f(mults.hacking_exp - 1)} exp for all skills
</> </>
); );
} else { } else {
if (mults.hacking_exp_mult) if (mults.hacking_exp !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.hacking_exp_mult - 1)} hacking exp <br />+{f(mults.hacking_exp - 1)} hacking exp
</> </>
); );
if ( if (
mults.strength_exp_mult && mults.strength_exp !== 1 &&
mults.strength_exp_mult === mults.defense_exp_mult && mults.strength_exp === mults.defense_exp &&
mults.strength_exp_mult === mults.dexterity_exp_mult && mults.strength_exp === mults.dexterity_exp &&
mults.strength_exp_mult === mults.agility_exp_mult mults.strength_exp === mults.agility_exp
) { ) {
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.strength_exp_mult - 1)} combat exp <br />+{f(mults.strength_exp - 1)} combat exp
</> </>
); );
} else { } else {
if (mults.strength_exp_mult) if (mults.strength_exp !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.strength_exp_mult - 1)} strength exp <br />+{f(mults.strength_exp - 1)} strength exp
</> </>
); );
if (mults.defense_exp_mult) if (mults.defense_exp !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.defense_exp_mult - 1)} defense exp <br />+{f(mults.defense_exp - 1)} defense exp
</> </>
); );
if (mults.dexterity_exp_mult) if (mults.dexterity_exp !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.dexterity_exp_mult - 1)} dexterity exp <br />+{f(mults.dexterity_exp - 1)} dexterity exp
</> </>
); );
if (mults.agility_exp_mult) if (mults.agility_exp !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.agility_exp_mult - 1)} agility exp <br />+{f(mults.agility_exp - 1)} agility exp
</> </>
); );
} }
if (mults.charisma_exp_mult) if (mults.charisma_exp !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.charisma_exp_mult - 1)} charisma exp <br />+{f(mults.charisma_exp - 1)} charisma exp
</> </>
); );
} }
if (mults.hacking_speed_mult) if (mults.hacking_speed !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.hacking_speed_mult - 1)} faster hack(), grow(), and weaken() <br />+{f(mults.hacking_speed - 1)} faster hack(), grow(), and weaken()
</> </>
); );
if (mults.hacking_chance_mult) if (mults.hacking_chance !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.hacking_chance_mult - 1)} hack() success chance <br />+{f(mults.hacking_chance - 1)} hack() success chance
</> </>
); );
if (mults.hacking_money_mult) if (mults.hacking_money !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.hacking_money_mult - 1)} hack() power <br />+{f(mults.hacking_money - 1)} hack() power
</> </>
); );
if (mults.hacking_grow_mult) if (mults.hacking_grow !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.hacking_grow_mult - 1)} grow() power <br />+{f(mults.hacking_grow - 1)} grow() power
</> </>
); );
if (mults.faction_rep_mult && mults.faction_rep_mult === mults.company_rep_mult) { if (mults.faction_rep !== 1 && mults.faction_rep === mults.company_rep) {
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.faction_rep_mult - 1)} reputation from factions and companies <br />+{f(mults.faction_rep - 1)} reputation from factions and companies
</> </>
); );
} else { } else {
if (mults.faction_rep_mult) if (mults.faction_rep !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.faction_rep_mult - 1)} reputation from factions <br />+{f(mults.faction_rep - 1)} reputation from factions
</> </>
); );
if (mults.company_rep_mult) if (mults.company_rep !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.company_rep_mult - 1)} reputation from companies <br />+{f(mults.company_rep - 1)} reputation from companies
</> </>
); );
} }
if (mults.crime_money_mult) if (mults.crime_money !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.crime_money_mult - 1)} crime money <br />+{f(mults.crime_money - 1)} crime money
</> </>
); );
if (mults.crime_success_mult) if (mults.crime_success !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.crime_success_mult - 1)} crime success rate <br />+{f(mults.crime_success - 1)} crime success rate
</> </>
); );
if (mults.work_money_mult) if (mults.work_money !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.work_money_mult - 1)} work money <br />+{f(mults.work_money - 1)} work money
</> </>
); );
if (mults.hacknet_node_money_mult) if (mults.hacknet_node_money !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.hacknet_node_money_mult - 1)} hacknet production <br />+{f(mults.hacknet_node_money - 1)} hacknet production
</> </>
); );
if (mults.hacknet_node_purchase_cost_mult) if (mults.hacknet_node_purchase_cost !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />-{f(-(mults.hacknet_node_purchase_cost_mult - 1))} hacknet nodes cost <br />-{f(-(mults.hacknet_node_purchase_cost - 1))} hacknet nodes cost
</> </>
); );
if (mults.hacknet_node_level_cost_mult) if (mults.hacknet_node_level_cost !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />-{f(-(mults.hacknet_node_level_cost_mult - 1))} hacknet nodes upgrade cost <br />-{f(-(mults.hacknet_node_level_cost - 1))} hacknet nodes upgrade cost
</> </>
); );
if (mults.bladeburner_max_stamina_mult) if (mults.bladeburner_max_stamina !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.bladeburner_max_stamina_mult - 1)} Bladeburner Max Stamina <br />+{f(mults.bladeburner_max_stamina - 1)} Bladeburner Max Stamina
</> </>
); );
if (mults.bladeburner_stamina_gain_mult) if (mults.bladeburner_stamina_gain !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.bladeburner_stamina_gain_mult - 1)} Bladeburner Stamina gain <br />+{f(mults.bladeburner_stamina_gain - 1)} Bladeburner Stamina gain
</> </>
); );
if (mults.bladeburner_analysis_mult) if (mults.bladeburner_analysis !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.bladeburner_analysis_mult - 1)} Bladeburner Field Analysis effectiveness <br />+{f(mults.bladeburner_analysis - 1)} Bladeburner Field Analysis effectiveness
</> </>
); );
if (mults.bladeburner_success_chance_mult) if (mults.bladeburner_success_chance !== 1)
desc = ( desc = (
<> <>
{desc} {desc}
<br />+{f(mults.bladeburner_success_chance_mult - 1)} Bladeburner Contracts and Operations success chance <br />+{f(mults.bladeburner_success_chance - 1)} Bladeburner Contracts and Operations success chance
</> </>
); );
if (mults.infiltration_base_rep_increase)
desc = (
<>
{desc}
<br />+{f(mults.infiltration_base_rep_increase - 1)} Infiltration {FactionNames.ShadowsOfAnarchy} Reputation
base reward
</>
);
if (mults.infiltration_rep_mult)
desc = (
<>
{desc}
<br />+{f(mults.infiltration_rep_mult - 1)} Infiltration {FactionNames.ShadowsOfAnarchy} Reputation reward
</>
);
if (mults.infiltration_trade_mult)
desc = (
<>
{desc}
<br />+{f(mults.infiltration_trade_mult - 1)} Infiltration Reputation for trading information
</>
);
if (mults.infiltration_sell_mult)
desc = (
<>
{desc}
<br />+{f(mults.infiltration_sell_mult - 1)} Infiltration cash reward for selling information
</>
);
if (mults.infiltration_timer_mult)
desc = (
<>
{desc}
<br />+{f(mults.infiltration_timer_mult - 1)} Infiltration time per minigame
</>
);
if (mults.infiltration_damage_reduction_mult)
desc = (
<>
{desc}
<br />
{f(mults.infiltration_damage_reduction_mult - 1)} Infiltration health lost per failed minigame
</>
);
if (startingMoney) if (startingMoney)
desc = ( desc = (
<> <>
@ -445,7 +401,7 @@ export class Augmentation {
// Multipliers given by this Augmentation. Must match the property name in // Multipliers given by this Augmentation. Must match the property name in
// The Player/Person classes // The Player/Person classes
mults: IMap<number> = {}; mults: Multipliers = defaultMultipliers();
// Factions that offer this aug. // Factions that offer this aug.
factions: string[] = []; factions: string[] = [];
@ -474,114 +430,95 @@ export class Augmentation {
} }
// Set multipliers // Set multipliers
if (params.hacking_mult) { if (params.hacking) {
this.mults.hacking_mult = params.hacking_mult; this.mults.hacking = params.hacking;
} }
if (params.strength_mult) { if (params.strength) {
this.mults.strength_mult = params.strength_mult; this.mults.strength = params.strength;
} }
if (params.defense_mult) { if (params.defense) {
this.mults.defense_mult = params.defense_mult; this.mults.defense = params.defense;
} }
if (params.dexterity_mult) { if (params.dexterity) {
this.mults.dexterity_mult = params.dexterity_mult; this.mults.dexterity = params.dexterity;
} }
if (params.agility_mult) { if (params.agility) {
this.mults.agility_mult = params.agility_mult; this.mults.agility = params.agility;
} }
if (params.charisma_mult) { if (params.charisma) {
this.mults.charisma_mult = params.charisma_mult; this.mults.charisma = params.charisma;
} }
if (params.hacking_exp_mult) { if (params.hacking_exp) {
this.mults.hacking_exp_mult = params.hacking_exp_mult; this.mults.hacking_exp = params.hacking_exp;
} }
if (params.strength_exp_mult) { if (params.strength_exp) {
this.mults.strength_exp_mult = params.strength_exp_mult; this.mults.strength_exp = params.strength_exp;
} }
if (params.defense_exp_mult) { if (params.defense_exp) {
this.mults.defense_exp_mult = params.defense_exp_mult; this.mults.defense_exp = params.defense_exp;
} }
if (params.dexterity_exp_mult) { if (params.dexterity_exp) {
this.mults.dexterity_exp_mult = params.dexterity_exp_mult; this.mults.dexterity_exp = params.dexterity_exp;
} }
if (params.agility_exp_mult) { if (params.agility_exp) {
this.mults.agility_exp_mult = params.agility_exp_mult; this.mults.agility_exp = params.agility_exp;
} }
if (params.charisma_exp_mult) { if (params.charisma_exp) {
this.mults.charisma_exp_mult = params.charisma_exp_mult; this.mults.charisma_exp = params.charisma_exp;
} }
if (params.hacking_chance_mult) { if (params.hacking_chance) {
this.mults.hacking_chance_mult = params.hacking_chance_mult; this.mults.hacking_chance = params.hacking_chance;
} }
if (params.hacking_speed_mult) { if (params.hacking_speed) {
this.mults.hacking_speed_mult = params.hacking_speed_mult; this.mults.hacking_speed = params.hacking_speed;
} }
if (params.hacking_money_mult) { if (params.hacking_money) {
this.mults.hacking_money_mult = params.hacking_money_mult; this.mults.hacking_money = params.hacking_money;
} }
if (params.hacking_grow_mult) { if (params.hacking_grow) {
this.mults.hacking_grow_mult = params.hacking_grow_mult; this.mults.hacking_grow = params.hacking_grow;
} }
if (params.company_rep_mult) { if (params.company_rep) {
this.mults.company_rep_mult = params.company_rep_mult; this.mults.company_rep = params.company_rep;
} }
if (params.faction_rep_mult) { if (params.faction_rep) {
this.mults.faction_rep_mult = params.faction_rep_mult; this.mults.faction_rep = params.faction_rep;
} }
if (params.crime_money_mult) { if (params.crime_money) {
this.mults.crime_money_mult = params.crime_money_mult; this.mults.crime_money = params.crime_money;
} }
if (params.crime_success_mult) { if (params.crime_success) {
this.mults.crime_success_mult = params.crime_success_mult; this.mults.crime_success = params.crime_success;
} }
if (params.work_money_mult) { if (params.work_money) {
this.mults.work_money_mult = params.work_money_mult; this.mults.work_money = params.work_money;
} }
if (params.hacknet_node_money_mult) { if (params.hacknet_node_money) {
this.mults.hacknet_node_money_mult = params.hacknet_node_money_mult; this.mults.hacknet_node_money = params.hacknet_node_money;
} }
if (params.hacknet_node_purchase_cost_mult) { if (params.hacknet_node_purchase_cost) {
this.mults.hacknet_node_purchase_cost_mult = params.hacknet_node_purchase_cost_mult; this.mults.hacknet_node_purchase_cost = params.hacknet_node_purchase_cost;
} }
if (params.hacknet_node_ram_cost_mult) { if (params.hacknet_node_ram_cost) {
this.mults.hacknet_node_ram_cost_mult = params.hacknet_node_ram_cost_mult; this.mults.hacknet_node_ram_cost = params.hacknet_node_ram_cost;
} }
if (params.hacknet_node_core_cost_mult) { if (params.hacknet_node_core_cost) {
this.mults.hacknet_node_core_cost_mult = params.hacknet_node_core_cost_mult; this.mults.hacknet_node_core_cost = params.hacknet_node_core_cost;
} }
if (params.hacknet_node_level_cost_mult) { if (params.hacknet_node_level_cost) {
this.mults.hacknet_node_level_cost_mult = params.hacknet_node_level_cost_mult; this.mults.hacknet_node_level_cost = params.hacknet_node_level_cost;
} }
if (params.bladeburner_max_stamina_mult) { if (params.bladeburner_max_stamina) {
this.mults.bladeburner_max_stamina_mult = params.bladeburner_max_stamina_mult; this.mults.bladeburner_max_stamina = params.bladeburner_max_stamina;
} }
if (params.bladeburner_stamina_gain_mult) { if (params.bladeburner_stamina_gain) {
this.mults.bladeburner_stamina_gain_mult = params.bladeburner_stamina_gain_mult; this.mults.bladeburner_stamina_gain = params.bladeburner_stamina_gain;
} }
if (params.bladeburner_analysis_mult) { if (params.bladeburner_analysis) {
this.mults.bladeburner_analysis_mult = params.bladeburner_analysis_mult; this.mults.bladeburner_analysis = params.bladeburner_analysis;
} }
if (params.bladeburner_success_chance_mult) { if (params.bladeburner_success_chance) {
this.mults.bladeburner_success_chance_mult = params.bladeburner_success_chance_mult; this.mults.bladeburner_success_chance = params.bladeburner_success_chance;
}
if (params.infiltration_base_rep_increase) {
this.mults.infiltration_base_rep_increase = params.infiltration_base_rep_increase;
}
if (params.infiltration_rep_mult) {
this.mults.infiltration_rep_mult = params.infiltration_rep_mult;
}
if (params.infiltration_trade_mult) {
this.mults.infiltration_trade_mult = params.infiltration_trade_mult;
}
if (params.infiltration_sell_mult) {
this.mults.infiltration_sell_mult = params.infiltration_sell_mult;
}
if (params.infiltration_timer_mult) {
this.mults.infiltration_timer_mult = params.infiltration_timer_mult;
}
if (params.infiltration_damage_reduction_mult) {
this.mults.infiltration_damage_reduction_mult = params.infiltration_damage_reduction_mult;
} }
if (params.stats === undefined) if (params.stats === undefined)

@ -21,6 +21,7 @@ import {
initUnstableCircadianModulator, initUnstableCircadianModulator,
} from "./data/AugmentationCreator"; } from "./data/AugmentationCreator";
import { Router } from "../ui/GameRoot"; import { Router } from "../ui/GameRoot";
import { mergeMultipliers } from "../PersonObjects/Multipliers";
export function AddToStaticAugmentations(aug: Augmentation): void { export function AddToStaticAugmentations(aug: Augmentation): void {
const name = aug.name; const name = aug.name;
@ -74,10 +75,7 @@ function applyAugmentation(aug: IPlayerOwnedAugmentation, reapply = false): void
const staticAugmentation = StaticAugmentations[aug.name]; const staticAugmentation = StaticAugmentations[aug.name];
// Apply multipliers // Apply multipliers
for (const mult of Object.keys(staticAugmentation.mults)) { Player.mults = mergeMultipliers(Player.mults, staticAugmentation.mults);
const v = Player.getMult(mult) * staticAugmentation.mults[mult];
Player.setMult(mult, v);
}
// Special logic for Congruity Implant // Special logic for Congruity Implant
if (aug.name === AugmentationNames.CongruityImplant && !reapply) { if (aug.name === AugmentationNames.CongruityImplant && !reapply) {

File diff suppressed because it is too large Load Diff

@ -4,6 +4,7 @@
import { DoubleArrow } from "@mui/icons-material"; import { DoubleArrow } from "@mui/icons-material";
import { List, ListItem, ListItemText, Paper, Typography } from "@mui/material"; import { List, ListItem, ListItemText, Paper, Typography } from "@mui/material";
import * as React from "react"; import * as React from "react";
import { Multipliers, defaultMultipliers, mergeMultipliers } from "../../PersonObjects/Multipliers";
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
import { Player } from "../../Player"; import { Player } from "../../Player";
import { Settings } from "../../Settings/Settings"; import { Settings } from "../../Settings/Settings";
@ -14,14 +15,11 @@ interface IAugmentedStats {
[index: string]: number; [index: string]: number;
} }
function calculateAugmentedStats(): IAugmentedStats { function calculateAugmentedStats(): Multipliers {
const augP: IAugmentedStats = {}; let augP: Multipliers = defaultMultipliers();
for (const aug of Player.queuedAugmentations) { for (const aug of Player.queuedAugmentations) {
const augObj = StaticAugmentations[aug.name]; const augObj = StaticAugmentations[aug.name];
for (const mult of Object.keys(augObj.mults)) { augP = mergeMultipliers(augP, augObj.mults);
const v = augP[mult] ? augP[mult] : 1;
augP[mult] = v * augObj.mults[mult];
}
} }
return augP; return augP;
} }
@ -98,35 +96,35 @@ export function PlayerMultipliers(): React.ReactElement {
...[ ...[
{ {
mult: "Hacking Chance", mult: "Hacking Chance",
current: Player.hacking_chance_mult, current: Player.mults.hacking_chance,
augmented: Player.hacking_chance_mult * mults.hacking_chance_mult, augmented: Player.mults.hacking_chance * mults.hacking_chance,
}, },
{ {
mult: "Hacking Speed", mult: "Hacking Speed",
current: Player.hacking_speed_mult, current: Player.mults.hacking_speed,
augmented: Player.hacking_speed_mult * mults.hacking_speed_mult, augmented: Player.mults.hacking_speed * mults.hacking_speed,
}, },
{ {
mult: "Hacking Money", mult: "Hacking Money",
current: Player.hacking_money_mult, current: Player.mults.hacking_money,
augmented: Player.hacking_money_mult * mults.hacking_money_mult, augmented: Player.mults.hacking_money * mults.hacking_money,
bnMult: BitNodeMultipliers.ScriptHackMoney, bnMult: BitNodeMultipliers.ScriptHackMoney,
}, },
{ {
mult: "Hacking Growth", mult: "Hacking Growth",
current: Player.hacking_grow_mult, current: Player.mults.hacking_grow,
augmented: Player.hacking_grow_mult * mults.hacking_grow_mult, augmented: Player.mults.hacking_grow * mults.hacking_grow,
}, },
{ {
mult: "Hacking Level", mult: "Hacking Level",
current: Player.hacking_mult, current: Player.mults.hacking,
augmented: Player.hacking_mult * mults.hacking_mult, augmented: Player.mults.hacking * mults.hacking,
bnMult: BitNodeMultipliers.HackingLevelMultiplier, bnMult: BitNodeMultipliers.HackingLevelMultiplier,
}, },
{ {
mult: "Hacking Experience", mult: "Hacking Experience",
current: Player.hacking_exp_mult, current: Player.mults.hacking_exp,
augmented: Player.hacking_exp_mult * mults.hacking_exp_mult, augmented: Player.mults.hacking_exp * mults.hacking_exp,
bnMult: BitNodeMultipliers.HackExpGain, bnMult: BitNodeMultipliers.HackExpGain,
}, },
].map((data: MultiplierListItemData) => ].map((data: MultiplierListItemData) =>
@ -137,47 +135,47 @@ export function PlayerMultipliers(): React.ReactElement {
...[ ...[
{ {
mult: "Strength Level", mult: "Strength Level",
current: Player.strength_mult, current: Player.mults.strength,
augmented: Player.strength_mult * mults.strength_mult, augmented: Player.mults.strength * mults.strength,
bnMult: BitNodeMultipliers.StrengthLevelMultiplier, bnMult: BitNodeMultipliers.StrengthLevelMultiplier,
}, },
{ {
mult: "Strength Experience", mult: "Strength Experience",
current: Player.strength_exp_mult, current: Player.mults.strength_exp,
augmented: Player.strength_exp_mult * mults.strength_exp_mult, augmented: Player.mults.strength_exp * mults.strength_exp,
}, },
{ {
mult: "Defense Level", mult: "Defense Level",
current: Player.defense_mult, current: Player.mults.defense,
augmented: Player.defense_mult * mults.defense_mult, augmented: Player.mults.defense * mults.defense,
bnMult: BitNodeMultipliers.DefenseLevelMultiplier, bnMult: BitNodeMultipliers.DefenseLevelMultiplier,
}, },
{ {
mult: "Defense Experience", mult: "Defense Experience",
current: Player.defense_exp_mult, current: Player.mults.defense_exp,
augmented: Player.defense_exp_mult * mults.defense_exp_mult, augmented: Player.mults.defense_exp * mults.defense_exp,
}, },
{ {
mult: "Dexterity Level", mult: "Dexterity Level",
current: Player.dexterity_mult, current: Player.mults.dexterity,
augmented: Player.dexterity_mult * mults.dexterity_mult, augmented: Player.mults.dexterity * mults.dexterity,
bnMult: BitNodeMultipliers.DexterityLevelMultiplier, bnMult: BitNodeMultipliers.DexterityLevelMultiplier,
}, },
{ {
mult: "Dexterity Experience", mult: "Dexterity Experience",
current: Player.dexterity_exp_mult, current: Player.mults.dexterity_exp,
augmented: Player.dexterity_exp_mult * mults.dexterity_exp_mult, augmented: Player.mults.dexterity_exp * mults.dexterity_exp,
}, },
{ {
mult: "Agility Level", mult: "Agility Level",
current: Player.agility_mult, current: Player.mults.agility,
augmented: Player.agility_mult * mults.agility_mult, augmented: Player.mults.agility * mults.agility,
bnMult: BitNodeMultipliers.AgilityLevelMultiplier, bnMult: BitNodeMultipliers.AgilityLevelMultiplier,
}, },
{ {
mult: "Agility Experience", mult: "Agility Experience",
current: Player.agility_exp_mult, current: Player.mults.agility_exp,
augmented: Player.agility_exp_mult * mults.agility_exp_mult, augmented: Player.mults.agility_exp * mults.agility_exp,
}, },
].map((data: MultiplierListItemData) => ].map((data: MultiplierListItemData) =>
Object.defineProperty(data, "color", { Object.defineProperty(data, "color", {
@ -186,73 +184,73 @@ export function PlayerMultipliers(): React.ReactElement {
), ),
{ {
mult: "Charisma Level", mult: "Charisma Level",
current: Player.charisma_mult, current: Player.mults.charisma,
augmented: Player.charisma_mult * mults.charisma_mult, augmented: Player.mults.charisma * mults.charisma,
bnMult: BitNodeMultipliers.CharismaLevelMultiplier, bnMult: BitNodeMultipliers.CharismaLevelMultiplier,
color: Settings.theme.cha, color: Settings.theme.cha,
}, },
{ {
mult: "Charisma Experience", mult: "Charisma Experience",
current: Player.charisma_exp_mult, current: Player.mults.charisma_exp,
augmented: Player.charisma_exp_mult * mults.charisma_exp_mult, augmented: Player.mults.charisma_exp * mults.charisma_exp,
color: Settings.theme.cha, color: Settings.theme.cha,
}, },
]; ];
const rightColData: MultiplierListItemData[] = [ const rightColData: MultiplierListItemData[] = [
{ {
mult: "Hacknet Node Production", mult: "Hacknet Node Production",
current: Player.hacknet_node_money_mult, current: Player.mults.hacknet_node_money,
augmented: Player.hacknet_node_money_mult * mults.hacknet_node_money_mult, augmented: Player.mults.hacknet_node_money * mults.hacknet_node_money,
bnMult: BitNodeMultipliers.HacknetNodeMoney, bnMult: BitNodeMultipliers.HacknetNodeMoney,
}, },
{ {
mult: "Hacknet Node Purchase Cost", mult: "Hacknet Node Purchase Cost",
current: Player.hacknet_node_purchase_cost_mult, current: Player.mults.hacknet_node_purchase_cost,
augmented: Player.hacknet_node_purchase_cost_mult * mults.hacknet_node_purchase_cost_mult, augmented: Player.mults.hacknet_node_purchase_cost * mults.hacknet_node_purchase_cost,
}, },
{ {
mult: "Hacknet Node RAM Upgrade Cost", mult: "Hacknet Node RAM Upgrade Cost",
current: Player.hacknet_node_ram_cost_mult, current: Player.mults.hacknet_node_ram_cost,
augmented: Player.hacknet_node_ram_cost_mult * mults.hacknet_node_ram_cost_mult, augmented: Player.mults.hacknet_node_ram_cost * mults.hacknet_node_ram_cost,
}, },
{ {
mult: "Hacknet Node Core Purchase Cost", mult: "Hacknet Node Core Purchase Cost",
current: Player.hacknet_node_core_cost_mult, current: Player.mults.hacknet_node_core_cost,
augmented: Player.hacknet_node_core_cost_mult * mults.hacknet_node_core_cost_mult, augmented: Player.mults.hacknet_node_core_cost * mults.hacknet_node_core_cost,
}, },
{ {
mult: "Hacknet Node Level Upgrade Cost", mult: "Hacknet Node Level Upgrade Cost",
current: Player.hacknet_node_level_cost_mult, current: Player.mults.hacknet_node_level_cost,
augmented: Player.hacknet_node_level_cost_mult * mults.hacknet_node_level_cost_mult, augmented: Player.mults.hacknet_node_level_cost * mults.hacknet_node_level_cost,
}, },
{ {
mult: "Company Reputation Gain", mult: "Company Reputation Gain",
current: Player.company_rep_mult, current: Player.mults.company_rep,
augmented: Player.company_rep_mult * mults.company_rep_mult, augmented: Player.mults.company_rep * mults.company_rep,
}, },
{ {
mult: "Faction Reputation Gain", mult: "Faction Reputation Gain",
current: Player.faction_rep_mult, current: Player.mults.faction_rep,
augmented: Player.faction_rep_mult * mults.faction_rep_mult, augmented: Player.mults.faction_rep * mults.faction_rep,
bnMult: BitNodeMultipliers.FactionWorkRepGain, bnMult: BitNodeMultipliers.FactionWorkRepGain,
}, },
{ {
mult: "Salary", mult: "Salary",
current: Player.work_money_mult, current: Player.mults.work_money,
augmented: Player.work_money_mult * mults.work_money_mult, augmented: Player.mults.work_money * mults.work_money,
bnMult: BitNodeMultipliers.CompanyWorkMoney, bnMult: BitNodeMultipliers.CompanyWorkMoney,
color: Settings.theme.money, color: Settings.theme.money,
}, },
{ {
mult: "Crime Success Chance", mult: "Crime Success Chance",
current: Player.crime_success_mult, current: Player.mults.crime_success,
augmented: Player.crime_success_mult * mults.crime_success_mult, augmented: Player.mults.crime_success * mults.crime_success,
color: Settings.theme.combat, color: Settings.theme.combat,
}, },
{ {
mult: "Crime Money", mult: "Crime Money",
current: Player.crime_money_mult, current: Player.mults.crime_money,
augmented: Player.crime_money_mult * mults.crime_money_mult, augmented: Player.mults.crime_money * mults.crime_money,
bnMult: BitNodeMultipliers.CrimeMoney, bnMult: BitNodeMultipliers.CrimeMoney,
color: Settings.theme.money, color: Settings.theme.money,
}, },
@ -262,23 +260,23 @@ export function PlayerMultipliers(): React.ReactElement {
rightColData.push( rightColData.push(
{ {
mult: "Bladeburner Success Chance", mult: "Bladeburner Success Chance",
current: Player.bladeburner_success_chance_mult, current: Player.mults.bladeburner_success_chance,
augmented: Player.bladeburner_success_chance_mult * mults.bladeburner_success_chance_mult, augmented: Player.mults.bladeburner_success_chance * mults.bladeburner_success_chance,
}, },
{ {
mult: "Bladeburner Max Stamina", mult: "Bladeburner Max Stamina",
current: Player.bladeburner_max_stamina_mult, current: Player.mults.bladeburner_max_stamina,
augmented: Player.bladeburner_max_stamina_mult * mults.bladeburner_max_stamina_mult, augmented: Player.mults.bladeburner_max_stamina * mults.bladeburner_max_stamina,
}, },
{ {
mult: "Bladeburner Stamina Gain", mult: "Bladeburner Stamina Gain",
current: Player.bladeburner_stamina_gain_mult, current: Player.mults.bladeburner_stamina_gain,
augmented: Player.bladeburner_stamina_gain_mult * mults.bladeburner_stamina_gain_mult, augmented: Player.mults.bladeburner_stamina_gain * mults.bladeburner_stamina_gain,
}, },
{ {
mult: "Bladeburner Field Analysis", mult: "Bladeburner Field Analysis",
current: Player.bladeburner_analysis_mult, current: Player.mults.bladeburner_analysis,
augmented: Player.bladeburner_analysis_mult * mults.bladeburner_analysis_mult, augmented: Player.mults.bladeburner_analysis * mults.bladeburner_analysis,
}, },
); );
} }

@ -274,7 +274,7 @@ export class Action implements IAction {
} }
// Augmentation multiplier // Augmentation multiplier
competence *= Player.bladeburner_success_chance_mult; competence *= Player.mults.bladeburner_success_chance;
if (isNaN(competence)) { if (isNaN(competence)) {
throw new Error("Competence calculated as NaN in Action.getSuccessChance()"); throw new Error("Competence calculated as NaN in Action.getSuccessChance()");

@ -1469,10 +1469,10 @@ export class Bladeburner implements IBladeburner {
} }
case ActionTypes["Training"]: { case ActionTypes["Training"]: {
this.stamina -= 0.5 * BladeburnerConstants.BaseStaminaLoss; this.stamina -= 0.5 * BladeburnerConstants.BaseStaminaLoss;
const strExpGain = 30 * person.strength_exp_mult, const strExpGain = 30 * person.mults.strength_exp,
defExpGain = 30 * person.defense_exp_mult, defExpGain = 30 * person.mults.defense_exp,
dexExpGain = 30 * person.dexterity_exp_mult, dexExpGain = 30 * person.mults.dexterity_exp,
agiExpGain = 30 * person.agility_exp_mult, agiExpGain = 30 * person.mults.agility_exp,
staminaGain = 0.04 * this.skillMultipliers.stamina; staminaGain = 0.04 * this.skillMultipliers.stamina;
retValue.str = strExpGain; retValue.str = strExpGain;
retValue.def = defExpGain; retValue.def = defExpGain;
@ -1504,12 +1504,12 @@ export class Bladeburner implements IBladeburner {
0.04 * Math.pow(person.hacking, 0.3) + 0.04 * Math.pow(person.hacking, 0.3) +
0.04 * Math.pow(person.intelligence, 0.9) + 0.04 * Math.pow(person.intelligence, 0.9) +
0.02 * Math.pow(person.charisma, 0.3); 0.02 * Math.pow(person.charisma, 0.3);
eff *= person.bladeburner_analysis_mult; eff *= person.mults.bladeburner_analysis;
if (isNaN(eff) || eff < 0) { if (isNaN(eff) || eff < 0) {
throw new Error("Field Analysis Effectiveness calculated to be NaN or negative"); throw new Error("Field Analysis Effectiveness calculated to be NaN or negative");
} }
const hackingExpGain = 20 * person.hacking_exp_mult; const hackingExpGain = 20 * person.mults.hacking_exp;
const charismaExpGain = 20 * person.charisma_exp_mult; const charismaExpGain = 20 * person.mults.charisma_exp;
const rankGain = 0.1 * BitNodeMultipliers.BladeburnerRank; const rankGain = 0.1 * BitNodeMultipliers.BladeburnerRank;
retValue.hack = hackingExpGain; retValue.hack = hackingExpGain;
retValue.cha = charismaExpGain; retValue.cha = charismaExpGain;
@ -1647,7 +1647,7 @@ export class Bladeburner implements IBladeburner {
if (bladeburnerFac.isMember) { if (bladeburnerFac.isMember) {
const favorBonus = 1 + bladeburnerFac.favor / 100; const favorBonus = 1 + bladeburnerFac.favor / 100;
bladeburnerFac.playerReputation += bladeburnerFac.playerReputation +=
BladeburnerConstants.RankToFactionRepFactor * change * person.faction_rep_mult * favorBonus; BladeburnerConstants.RankToFactionRepFactor * change * person.mults.faction_rep * favorBonus;
} }
} }
@ -1695,7 +1695,7 @@ export class Bladeburner implements IBladeburner {
const effAgility = player.agility * this.skillMultipliers.effAgi; const effAgility = player.agility * this.skillMultipliers.effAgi;
const maxStaminaBonus = this.maxStamina / BladeburnerConstants.MaxStaminaToGainFactor; const maxStaminaBonus = this.maxStamina / BladeburnerConstants.MaxStaminaToGainFactor;
const gain = (BladeburnerConstants.StaminaGainPerSecond + maxStaminaBonus) * Math.pow(effAgility, 0.17); const gain = (BladeburnerConstants.StaminaGainPerSecond + maxStaminaBonus) * Math.pow(effAgility, 0.17);
return gain * (this.skillMultipliers.stamina * player.bladeburner_stamina_gain_mult); return gain * (this.skillMultipliers.stamina * player.mults.bladeburner_stamina_gain);
} }
calculateMaxStamina(player: IPlayer): void { calculateMaxStamina(player: IPlayer): void {
@ -1703,7 +1703,7 @@ export class Bladeburner implements IBladeburner {
const maxStamina = const maxStamina =
(Math.pow(effAgility, 0.8) + this.staminaBonus) * (Math.pow(effAgility, 0.8) + this.staminaBonus) *
this.skillMultipliers.stamina * this.skillMultipliers.stamina *
player.bladeburner_max_stamina_mult; player.mults.bladeburner_max_stamina;
if (this.maxStamina !== maxStamina) { if (this.maxStamina !== maxStamina) {
const oldMax = this.maxStamina; const oldMax = this.maxStamina;
this.maxStamina = maxStamina; this.maxStamina = maxStamina;

@ -173,13 +173,13 @@ export function Stats(props: IProps): React.ReactElement {
<Typography>Skill Points: {formatNumber(props.bladeburner.skillPoints, 0)}</Typography> <Typography>Skill Points: {formatNumber(props.bladeburner.skillPoints, 0)}</Typography>
<br /> <br />
<Typography> <Typography>
Aug. Success Chance mult: {formatNumber(props.player.bladeburner_success_chance_mult * 100, 1)}% Aug. Success Chance mult: {formatNumber(props.player.mults.bladeburner_success_chance * 100, 1)}%
<br /> <br />
Aug. Max Stamina mult: {formatNumber(props.player.bladeburner_max_stamina_mult * 100, 1)}% Aug. Max Stamina mult: {formatNumber(props.player.mults.bladeburner_max_stamina * 100, 1)}%
<br /> <br />
Aug. Stamina Gain mult: {formatNumber(props.player.bladeburner_stamina_gain_mult * 100, 1)}% Aug. Stamina Gain mult: {formatNumber(props.player.mults.bladeburner_stamina_gain * 100, 1)}%
<br /> <br />
Aug. Field Analysis mult: {formatNumber(props.player.bladeburner_analysis_mult * 100, 1)}% Aug. Field Analysis mult: {formatNumber(props.player.mults.bladeburner_analysis * 100, 1)}%
</Typography> </Typography>
</Box> </Box>
</Paper> </Paper>

@ -38,7 +38,7 @@ export class StaneksGift implements IStaneksGift {
} }
const cotmg = Factions[FactionNames.ChurchOfTheMachineGod]; const cotmg = Factions[FactionNames.ChurchOfTheMachineGod];
cotmg.playerReputation += (player.faction_rep_mult * (Math.pow(threads, 0.95) * (cotmg.favor + 100))) / 1000; cotmg.playerReputation += (player.mults.faction_rep * (Math.pow(threads, 0.95) * (cotmg.favor + 100))) / 1000;
} }
inBonus(): boolean { inBonus(): boolean {
@ -146,66 +146,66 @@ export class StaneksGift implements IStaneksGift {
const power = this.effect(aFrag); const power = this.effect(aFrag);
switch (fragment.type) { switch (fragment.type) {
case FragmentType.HackingChance: case FragmentType.HackingChance:
p.hacking_chance_mult *= power; p.mults.hacking_chance *= power;
break; break;
case FragmentType.HackingSpeed: case FragmentType.HackingSpeed:
p.hacking_speed_mult *= power; p.mults.hacking_speed *= power;
break; break;
case FragmentType.HackingMoney: case FragmentType.HackingMoney:
p.hacking_money_mult *= power; p.mults.hacking_money *= power;
break; break;
case FragmentType.HackingGrow: case FragmentType.HackingGrow:
p.hacking_grow_mult *= power; p.mults.hacking_grow *= power;
break; break;
case FragmentType.Hacking: case FragmentType.Hacking:
p.hacking_mult *= power; p.mults.hacking *= power;
p.hacking_exp_mult *= power; p.mults.hacking_exp *= power;
break; break;
case FragmentType.Strength: case FragmentType.Strength:
p.strength_mult *= power; p.mults.strength *= power;
p.strength_exp_mult *= power; p.mults.strength_exp *= power;
break; break;
case FragmentType.Defense: case FragmentType.Defense:
p.defense_mult *= power; p.mults.defense *= power;
p.defense_exp_mult *= power; p.mults.defense_exp *= power;
break; break;
case FragmentType.Dexterity: case FragmentType.Dexterity:
p.dexterity_mult *= power; p.mults.dexterity *= power;
p.dexterity_exp_mult *= power; p.mults.dexterity_exp *= power;
break; break;
case FragmentType.Agility: case FragmentType.Agility:
p.agility_mult *= power; p.mults.agility *= power;
p.agility_exp_mult *= power; p.mults.agility_exp *= power;
break; break;
case FragmentType.Charisma: case FragmentType.Charisma:
p.charisma_mult *= power; p.mults.charisma *= power;
p.charisma_exp_mult *= power; p.mults.charisma_exp *= power;
break; break;
case FragmentType.HacknetMoney: case FragmentType.HacknetMoney:
p.hacknet_node_money_mult *= power; p.mults.hacknet_node_money *= power;
break; break;
case FragmentType.HacknetCost: case FragmentType.HacknetCost:
p.hacknet_node_purchase_cost_mult /= power; p.mults.hacknet_node_purchase_cost /= power;
p.hacknet_node_ram_cost_mult /= power; p.mults.hacknet_node_ram_cost /= power;
p.hacknet_node_core_cost_mult /= power; p.mults.hacknet_node_core_cost /= power;
p.hacknet_node_level_cost_mult /= power; p.mults.hacknet_node_level_cost /= power;
break; break;
case FragmentType.Rep: case FragmentType.Rep:
p.company_rep_mult *= power; p.mults.company_rep *= power;
p.faction_rep_mult *= power; p.mults.faction_rep *= power;
break; break;
case FragmentType.WorkMoney: case FragmentType.WorkMoney:
p.work_money_mult *= power; p.mults.work_money *= power;
break; break;
case FragmentType.Crime: case FragmentType.Crime:
p.crime_success_mult *= power; p.mults.crime_success *= power;
p.crime_money_mult *= power; p.mults.crime_money *= power;
break; break;
case FragmentType.Bladeburner: case FragmentType.Bladeburner:
p.bladeburner_max_stamina_mult *= power; p.mults.bladeburner_max_stamina *= power;
p.bladeburner_stamina_gain_mult *= power; p.mults.bladeburner_stamina_gain *= power;
p.bladeburner_analysis_mult *= power; p.mults.bladeburner_analysis *= power;
p.bladeburner_success_chance_mult *= power; p.mults.bladeburner_success_chance *= power;
break; break;
} }
} }

@ -124,7 +124,7 @@ export class Crime {
CONSTANTS.IntelligenceCrimeWeight * p.intelligence; CONSTANTS.IntelligenceCrimeWeight * p.intelligence;
chance /= CONSTANTS.MaxSkillLevel; chance /= CONSTANTS.MaxSkillLevel;
chance /= this.difficulty; chance /= this.difficulty;
chance *= p.crime_success_mult; chance *= p.mults.crime_success;
chance *= p.getIntelligenceBonus(1); chance *= p.getIntelligenceBonus(1);
return Math.min(chance, 1); return Math.min(chance, 1);

@ -9,36 +9,36 @@ export function applyExploit(): void {
const inc = Math.pow(1.001, Player.exploits.length); const inc = Math.pow(1.001, Player.exploits.length);
const dec = Math.pow(0.999, Player.exploits.length); const dec = Math.pow(0.999, Player.exploits.length);
Player.hacking_chance_mult *= inc; Player.mults.hacking_chance *= inc;
Player.hacking_speed_mult *= inc; Player.mults.hacking_speed *= inc;
Player.hacking_money_mult *= inc; Player.mults.hacking_money *= inc;
Player.hacking_grow_mult *= inc; Player.mults.hacking_grow *= inc;
Player.hacking_mult *= inc; Player.mults.hacking *= inc;
Player.strength_mult *= inc; Player.mults.strength *= inc;
Player.defense_mult *= inc; Player.mults.defense *= inc;
Player.dexterity_mult *= inc; Player.mults.dexterity *= inc;
Player.agility_mult *= inc; Player.mults.agility *= inc;
Player.charisma_mult *= inc; Player.mults.charisma *= inc;
Player.hacking_exp_mult *= inc; Player.mults.hacking_exp *= inc;
Player.strength_exp_mult *= inc; Player.mults.strength_exp *= inc;
Player.defense_exp_mult *= inc; Player.mults.defense_exp *= inc;
Player.dexterity_exp_mult *= inc; Player.mults.dexterity_exp *= inc;
Player.agility_exp_mult *= inc; Player.mults.agility_exp *= inc;
Player.charisma_exp_mult *= inc; Player.mults.charisma_exp *= inc;
Player.company_rep_mult *= inc; Player.mults.company_rep *= inc;
Player.faction_rep_mult *= inc; Player.mults.faction_rep *= inc;
Player.crime_money_mult *= inc; Player.mults.crime_money *= inc;
Player.crime_success_mult *= inc; Player.mults.crime_success *= inc;
Player.hacknet_node_money_mult *= inc; Player.mults.hacknet_node_money *= inc;
Player.hacknet_node_purchase_cost_mult *= dec; Player.mults.hacknet_node_purchase_cost *= dec;
Player.hacknet_node_ram_cost_mult *= dec; Player.mults.hacknet_node_ram_cost *= dec;
Player.hacknet_node_core_cost_mult *= dec; Player.mults.hacknet_node_core_cost *= dec;
Player.hacknet_node_level_cost_mult *= dec; Player.mults.hacknet_node_level_cost *= dec;
Player.work_money_mult *= inc; Player.mults.work_money *= inc;
} }

@ -133,7 +133,7 @@ export function processPassiveFactionRepGain(numCycles: number): void {
const fRep = getFactionFieldWorkRepGain(Player, faction); const fRep = getFactionFieldWorkRepGain(Player, faction);
const rate = Math.max(hRep * favorMult, sRep * favorMult, fRep * favorMult, 1 / 120); const rate = Math.max(hRep * favorMult, sRep * favorMult, fRep * favorMult, 1 / 120);
faction.playerReputation += rate * numCycles * Player.faction_rep_mult * BitNodeMultipliers.FactionPassiveRepGain; faction.playerReputation += rate * numCycles * Player.mults.faction_rep * BitNodeMultipliers.FactionPassiveRepGain;
} }
} }

@ -2,5 +2,5 @@ import { CONSTANTS } from "../../Constants";
import { IPlayer } from "../../PersonObjects/IPlayer"; import { IPlayer } from "../../PersonObjects/IPlayer";
export function repFromDonation(amt: number, player: IPlayer): number { export function repFromDonation(amt: number, player: IPlayer): number {
return (amt / CONSTANTS.DonateMoneyToRepDivisor) * player.faction_rep_mult; return (amt / CONSTANTS.DonateMoneyToRepDivisor) * player.mults.faction_rep;
} }

@ -132,7 +132,7 @@ export class Gang implements IGang {
} }
const favorMult = 1 + fac.favor / 100; const favorMult = 1 + fac.favor / 100;
fac.playerReputation += (player.faction_rep_mult * gain * favorMult) / GangConstants.GangRespectToReputationRatio; fac.playerReputation += (player.mults.faction_rep * gain * favorMult) / GangConstants.GangRespectToReputationRatio;
// Keep track of respect gained per member // Keep track of respect gained per member
for (let i = 0; i < this.members.length; ++i) { for (let i = 0; i < this.members.length; ++i) {

@ -12,7 +12,7 @@ export function calculateHackingChance(server: Server, player: IPlayer): number
const skillMult = hackFactor * player.hacking; const skillMult = hackFactor * player.hacking;
const skillChance = (skillMult - server.requiredHackingSkill) / skillMult; const skillChance = (skillMult - server.requiredHackingSkill) / skillMult;
const chance = const chance =
skillChance * difficultyMult * player.hacking_chance_mult * calculateIntelligenceBonus(player.intelligence, 1); skillChance * difficultyMult * player.mults.hacking_chance * calculateIntelligenceBonus(player.intelligence, 1);
if (chance > 1) { if (chance > 1) {
return 1; return 1;
} }
@ -36,7 +36,7 @@ export function calculateHackingExpGain(server: Server, player: IPlayer): number
let expGain = baseExpGain; let expGain = baseExpGain;
expGain += server.baseDifficulty * diffFactor; expGain += server.baseDifficulty * diffFactor;
return expGain * player.hacking_exp_mult * BitNodeMultipliers.HackExpGain; return expGain * player.mults.hacking_exp * BitNodeMultipliers.HackExpGain;
} }
/** /**
@ -50,7 +50,7 @@ export function calculatePercentMoneyHacked(server: Server, player: IPlayer): nu
const difficultyMult = (100 - server.hackDifficulty) / 100; const difficultyMult = (100 - server.hackDifficulty) / 100;
const skillMult = (player.hacking - (server.requiredHackingSkill - 1)) / player.hacking; const skillMult = (player.hacking - (server.requiredHackingSkill - 1)) / player.hacking;
const percentMoneyHacked = const percentMoneyHacked =
(difficultyMult * skillMult * player.hacking_money_mult * BitNodeMultipliers.ScriptHackMoney) / balanceFactor; (difficultyMult * skillMult * player.mults.hacking_money * BitNodeMultipliers.ScriptHackMoney) / balanceFactor;
if (percentMoneyHacked < 0) { if (percentMoneyHacked < 0) {
return 0; return 0;
} }
@ -77,7 +77,7 @@ export function calculateHackingTime(server: Server, player: IPlayer): number {
const hackTimeMultiplier = 5; const hackTimeMultiplier = 5;
const hackingTime = const hackingTime =
(hackTimeMultiplier * skillFactor) / (hackTimeMultiplier * skillFactor) /
(player.hacking_speed_mult * calculateIntelligenceBonus(player.intelligence, 1)); (player.mults.hacking_speed * calculateIntelligenceBonus(player.intelligence, 1));
return hackingTime; return hackingTime;
} }

@ -66,7 +66,7 @@ export function purchaseHacknet(player: IPlayer): number {
// Auto generate a name for the Node // Auto generate a name for the Node
const name = "hacknet-node-" + numOwned; const name = "hacknet-node-" + numOwned;
const node = new HacknetNode(name, player.hacknet_node_money_mult); const node = new HacknetNode(name, player.mults.hacknet_node_money);
player.loseMoney(cost, "hacknet_expenses"); player.loseMoney(cost, "hacknet_expenses");
player.hacknetNodes.push(node); player.hacknetNodes.push(node);
@ -80,11 +80,11 @@ export function hasMaxNumberHacknetServers(player: IPlayer): boolean {
} }
export function getCostOfNextHacknetNode(player: IPlayer): number { export function getCostOfNextHacknetNode(player: IPlayer): number {
return calculateNodeCost(player.hacknetNodes.length + 1, player.hacknet_node_purchase_cost_mult); return calculateNodeCost(player.hacknetNodes.length + 1, player.mults.hacknet_node_purchase_cost);
} }
export function getCostOfNextHacknetServer(player: IPlayer): number { export function getCostOfNextHacknetServer(player: IPlayer): number {
return calculateServerCost(player.hacknetNodes.length + 1, player.hacknet_node_purchase_cost_mult); return calculateServerCost(player.hacknetNodes.length + 1, player.mults.hacknet_node_purchase_cost);
} }
// Calculate the maximum number of times the Player can afford to upgrade a Hacknet Node's level // Calculate the maximum number of times the Player can afford to upgrade a Hacknet Node's level
@ -97,14 +97,14 @@ export function getMaxNumberLevelUpgrades(
throw new Error(`getMaxNumberLevelUpgrades() called without maxLevel arg`); throw new Error(`getMaxNumberLevelUpgrades() called without maxLevel arg`);
} }
if (player.money < nodeObj.calculateLevelUpgradeCost(1, player.hacknet_node_level_cost_mult)) { if (player.money < nodeObj.calculateLevelUpgradeCost(1, player.mults.hacknet_node_level_cost)) {
return 0; return 0;
} }
let min = 1; let min = 1;
let max = maxLevel - 1; let max = maxLevel - 1;
const levelsToMax = maxLevel - nodeObj.level; const levelsToMax = maxLevel - nodeObj.level;
if (player.money > nodeObj.calculateLevelUpgradeCost(levelsToMax, player.hacknet_node_level_cost_mult)) { if (player.money > nodeObj.calculateLevelUpgradeCost(levelsToMax, player.mults.hacknet_node_level_cost)) {
return levelsToMax; return levelsToMax;
} }
@ -112,13 +112,13 @@ export function getMaxNumberLevelUpgrades(
const curr = ((min + max) / 2) | 0; const curr = ((min + max) / 2) | 0;
if ( if (
curr !== maxLevel && curr !== maxLevel &&
player.money > nodeObj.calculateLevelUpgradeCost(curr, player.hacknet_node_level_cost_mult) && player.money > nodeObj.calculateLevelUpgradeCost(curr, player.mults.hacknet_node_level_cost) &&
player.money < nodeObj.calculateLevelUpgradeCost(curr + 1, player.hacknet_node_level_cost_mult) player.money < nodeObj.calculateLevelUpgradeCost(curr + 1, player.mults.hacknet_node_level_cost)
) { ) {
return Math.min(levelsToMax, curr); return Math.min(levelsToMax, curr);
} else if (player.money < nodeObj.calculateLevelUpgradeCost(curr, player.hacknet_node_level_cost_mult)) { } else if (player.money < nodeObj.calculateLevelUpgradeCost(curr, player.mults.hacknet_node_level_cost)) {
max = curr - 1; max = curr - 1;
} else if (player.money > nodeObj.calculateLevelUpgradeCost(curr, player.hacknet_node_level_cost_mult)) { } else if (player.money > nodeObj.calculateLevelUpgradeCost(curr, player.mults.hacknet_node_level_cost)) {
min = curr + 1; min = curr + 1;
} else { } else {
return Math.min(levelsToMax, curr); return Math.min(levelsToMax, curr);
@ -137,7 +137,7 @@ export function getMaxNumberRamUpgrades(
throw new Error(`getMaxNumberRamUpgrades() called without maxLevel arg`); throw new Error(`getMaxNumberRamUpgrades() called without maxLevel arg`);
} }
if (player.money < nodeObj.calculateRamUpgradeCost(1, player.hacknet_node_ram_cost_mult)) { if (player.money < nodeObj.calculateRamUpgradeCost(1, player.mults.hacknet_node_ram_cost)) {
return 0; return 0;
} }
@ -147,13 +147,13 @@ export function getMaxNumberRamUpgrades(
} else { } else {
levelsToMax = Math.round(Math.log2(maxLevel / nodeObj.ram)); levelsToMax = Math.round(Math.log2(maxLevel / nodeObj.ram));
} }
if (player.money > nodeObj.calculateRamUpgradeCost(levelsToMax, player.hacknet_node_ram_cost_mult)) { if (player.money > nodeObj.calculateRamUpgradeCost(levelsToMax, player.mults.hacknet_node_ram_cost)) {
return levelsToMax; return levelsToMax;
} }
//We'll just loop until we find the max //We'll just loop until we find the max
for (let i = levelsToMax - 1; i >= 0; --i) { for (let i = levelsToMax - 1; i >= 0; --i) {
if (player.money > nodeObj.calculateRamUpgradeCost(i, player.hacknet_node_ram_cost_mult)) { if (player.money > nodeObj.calculateRamUpgradeCost(i, player.mults.hacknet_node_ram_cost)) {
return i; return i;
} }
} }
@ -170,14 +170,14 @@ export function getMaxNumberCoreUpgrades(
throw new Error(`getMaxNumberCoreUpgrades() called without maxLevel arg`); throw new Error(`getMaxNumberCoreUpgrades() called without maxLevel arg`);
} }
if (player.money < nodeObj.calculateCoreUpgradeCost(1, player.hacknet_node_core_cost_mult)) { if (player.money < nodeObj.calculateCoreUpgradeCost(1, player.mults.hacknet_node_core_cost)) {
return 0; return 0;
} }
let min = 1; let min = 1;
let max = maxLevel - 1; let max = maxLevel - 1;
const levelsToMax = maxLevel - nodeObj.cores; const levelsToMax = maxLevel - nodeObj.cores;
if (player.money > nodeObj.calculateCoreUpgradeCost(levelsToMax, player.hacknet_node_core_cost_mult)) { if (player.money > nodeObj.calculateCoreUpgradeCost(levelsToMax, player.mults.hacknet_node_core_cost)) {
return levelsToMax; return levelsToMax;
} }
@ -186,13 +186,13 @@ export function getMaxNumberCoreUpgrades(
const curr = ((min + max) / 2) | 0; const curr = ((min + max) / 2) | 0;
if ( if (
curr != maxLevel && curr != maxLevel &&
player.money > nodeObj.calculateCoreUpgradeCost(curr, player.hacknet_node_core_cost_mult) && player.money > nodeObj.calculateCoreUpgradeCost(curr, player.mults.hacknet_node_core_cost) &&
player.money < nodeObj.calculateCoreUpgradeCost(curr + 1, player.hacknet_node_core_cost_mult) player.money < nodeObj.calculateCoreUpgradeCost(curr + 1, player.mults.hacknet_node_core_cost)
) { ) {
return Math.min(levelsToMax, curr); return Math.min(levelsToMax, curr);
} else if (player.money < nodeObj.calculateCoreUpgradeCost(curr, player.hacknet_node_core_cost_mult)) { } else if (player.money < nodeObj.calculateCoreUpgradeCost(curr, player.mults.hacknet_node_core_cost)) {
max = curr - 1; max = curr - 1;
} else if (player.money > nodeObj.calculateCoreUpgradeCost(curr, player.hacknet_node_core_cost_mult)) { } else if (player.money > nodeObj.calculateCoreUpgradeCost(curr, player.mults.hacknet_node_core_cost)) {
min = curr + 1; min = curr + 1;
} else { } else {
return Math.min(levelsToMax, curr); return Math.min(levelsToMax, curr);
@ -242,7 +242,7 @@ export function getMaxNumberCacheUpgrades(player: IPlayer, nodeObj: HacknetServe
export function purchaseLevelUpgrade(player: IPlayer, node: HacknetNode | HacknetServer, levels = 1): boolean { export function purchaseLevelUpgrade(player: IPlayer, node: HacknetNode | HacknetServer, levels = 1): boolean {
const sanitizedLevels = Math.round(levels); const sanitizedLevels = Math.round(levels);
const cost = node.calculateLevelUpgradeCost(sanitizedLevels, player.hacknet_node_level_cost_mult); const cost = node.calculateLevelUpgradeCost(sanitizedLevels, player.mults.hacknet_node_level_cost);
if (isNaN(cost) || cost <= 0 || sanitizedLevels < 0) { if (isNaN(cost) || cost <= 0 || sanitizedLevels < 0) {
return false; return false;
} }
@ -266,14 +266,14 @@ export function purchaseLevelUpgrade(player: IPlayer, node: HacknetNode | Hackne
} }
player.loseMoney(cost, "hacknet_expenses"); player.loseMoney(cost, "hacknet_expenses");
node.upgradeLevel(sanitizedLevels, player.hacknet_node_money_mult); node.upgradeLevel(sanitizedLevels, player.mults.hacknet_node_money);
return true; return true;
} }
export function purchaseRamUpgrade(player: IPlayer, node: HacknetNode | HacknetServer, levels = 1): boolean { export function purchaseRamUpgrade(player: IPlayer, node: HacknetNode | HacknetServer, levels = 1): boolean {
const sanitizedLevels = Math.round(levels); const sanitizedLevels = Math.round(levels);
const cost = node.calculateRamUpgradeCost(sanitizedLevels, player.hacknet_node_ram_cost_mult); const cost = node.calculateRamUpgradeCost(sanitizedLevels, player.mults.hacknet_node_ram_cost);
if (isNaN(cost) || cost <= 0 || sanitizedLevels < 0) { if (isNaN(cost) || cost <= 0 || sanitizedLevels < 0) {
return false; return false;
} }
@ -305,14 +305,14 @@ export function purchaseRamUpgrade(player: IPlayer, node: HacknetNode | HacknetS
} }
player.loseMoney(cost, "hacknet_expenses"); player.loseMoney(cost, "hacknet_expenses");
node.upgradeRam(sanitizedLevels, player.hacknet_node_money_mult); node.upgradeRam(sanitizedLevels, player.mults.hacknet_node_money);
return true; return true;
} }
export function purchaseCoreUpgrade(player: IPlayer, node: HacknetNode | HacknetServer, levels = 1): boolean { export function purchaseCoreUpgrade(player: IPlayer, node: HacknetNode | HacknetServer, levels = 1): boolean {
const sanitizedLevels = Math.round(levels); const sanitizedLevels = Math.round(levels);
const cost = node.calculateCoreUpgradeCost(sanitizedLevels, player.hacknet_node_core_cost_mult); const cost = node.calculateCoreUpgradeCost(sanitizedLevels, player.mults.hacknet_node_core_cost);
if (isNaN(cost) || cost <= 0 || sanitizedLevels < 0) { if (isNaN(cost) || cost <= 0 || sanitizedLevels < 0) {
return false; return false;
} }
@ -336,7 +336,7 @@ export function purchaseCoreUpgrade(player: IPlayer, node: HacknetNode | Hacknet
} }
player.loseMoney(cost, "hacknet_expenses"); player.loseMoney(cost, "hacknet_expenses");
node.upgradeCore(sanitizedLevels, player.hacknet_node_money_mult); node.upgradeCore(sanitizedLevels, player.mults.hacknet_node_money);
return true; return true;
} }
@ -415,7 +415,7 @@ function processAllHacknetServerEarnings(player: IPlayer, numCycles: number): nu
if (ip instanceof HacknetNode) throw new Error(`player nodes should not be HacketNode`); if (ip instanceof HacknetNode) throw new Error(`player nodes should not be HacketNode`);
const hserver = GetServer(ip); const hserver = GetServer(ip);
if (!(hserver instanceof HacknetServer)) throw new Error(`player nodes shoud not be Server`); if (!(hserver instanceof HacknetServer)) throw new Error(`player nodes shoud not be Server`);
hserver.updateHashRate(player.hacknet_node_money_mult); hserver.updateHashRate(player.mults.hacknet_node_money);
const h = hserver.process(numCycles); const h = hserver.process(numCycles);
hashes += h; hashes += h;
} }

@ -125,7 +125,7 @@ export class HacknetServer extends BaseServer implements IHacknetNode {
updateRamUsed(ram: number, player: IPlayer): void { updateRamUsed(ram: number, player: IPlayer): void {
super.updateRamUsed(ram, player); super.updateRamUsed(ram, player);
this.updateHashRate(player.hacknet_node_money_mult); this.updateHashRate(player.mults.hacknet_node_money);
} }
updateHashCapacity(): void { updateHashCapacity(): void {

@ -54,13 +54,13 @@ export function HacknetNodeElem(props: IProps): React.ReactElement {
multiplier = getMaxNumberLevelUpgrades(props.player, node, HacknetNodeConstants.MaxLevel); multiplier = getMaxNumberLevelUpgrades(props.player, node, HacknetNodeConstants.MaxLevel);
} else { } else {
const levelsToMax = HacknetNodeConstants.MaxLevel - node.level; const levelsToMax = HacknetNodeConstants.MaxLevel - node.level;
multiplier = Math.min(levelsToMax, purchaseMult ); multiplier = Math.min(levelsToMax, purchaseMult);
} }
const increase = const increase =
calculateMoneyGainRate(node.level + multiplier, node.ram, node.cores, props.player.hacknet_node_money_mult) - calculateMoneyGainRate(node.level + multiplier, node.ram, node.cores, props.player.mults.hacknet_node_money) -
node.moneyGainRatePerSecond; node.moneyGainRatePerSecond;
const upgradeLevelCost = node.calculateLevelUpgradeCost(multiplier, props.player.hacknet_node_level_cost_mult); const upgradeLevelCost = node.calculateLevelUpgradeCost(multiplier, props.player.mults.hacknet_node_level_cost);
upgradeLevelButton = ( upgradeLevelButton = (
<Tooltip <Tooltip
title={ title={
@ -94,7 +94,7 @@ export function HacknetNodeElem(props: IProps): React.ReactElement {
multiplier = getMaxNumberRamUpgrades(props.player, node, HacknetNodeConstants.MaxRam); multiplier = getMaxNumberRamUpgrades(props.player, node, HacknetNodeConstants.MaxRam);
} else { } else {
const levelsToMax = Math.round(Math.log2(HacknetNodeConstants.MaxRam / node.ram)); const levelsToMax = Math.round(Math.log2(HacknetNodeConstants.MaxRam / node.ram));
multiplier = Math.min(levelsToMax, purchaseMult ); multiplier = Math.min(levelsToMax, purchaseMult);
} }
const increase = const increase =
@ -102,9 +102,9 @@ export function HacknetNodeElem(props: IProps): React.ReactElement {
node.level, node.level,
node.ram * Math.pow(2, multiplier), node.ram * Math.pow(2, multiplier),
node.cores, node.cores,
props.player.hacknet_node_money_mult, props.player.mults.hacknet_node_money,
) - node.moneyGainRatePerSecond; ) - node.moneyGainRatePerSecond;
const upgradeRamCost = node.calculateRamUpgradeCost(multiplier, props.player.hacknet_node_ram_cost_mult); const upgradeRamCost = node.calculateRamUpgradeCost(multiplier, props.player.mults.hacknet_node_ram_cost);
upgradeRAMButton = ( upgradeRAMButton = (
<Tooltip <Tooltip
title={ title={
@ -144,13 +144,13 @@ export function HacknetNodeElem(props: IProps): React.ReactElement {
multiplier = getMaxNumberCoreUpgrades(props.player, node, HacknetNodeConstants.MaxCores); multiplier = getMaxNumberCoreUpgrades(props.player, node, HacknetNodeConstants.MaxCores);
} else { } else {
const levelsToMax = HacknetNodeConstants.MaxCores - node.cores; const levelsToMax = HacknetNodeConstants.MaxCores - node.cores;
multiplier = Math.min(levelsToMax, purchaseMult ); multiplier = Math.min(levelsToMax, purchaseMult);
} }
const increase = const increase =
calculateMoneyGainRate(node.level, node.ram, node.cores + multiplier, props.player.hacknet_node_money_mult) - calculateMoneyGainRate(node.level, node.ram, node.cores + multiplier, props.player.mults.hacknet_node_money) -
node.moneyGainRatePerSecond; node.moneyGainRatePerSecond;
const upgradeCoreCost = node.calculateCoreUpgradeCost(multiplier, props.player.hacknet_node_core_cost_mult); const upgradeCoreCost = node.calculateCoreUpgradeCost(multiplier, props.player.mults.hacknet_node_core_cost);
upgradeCoresButton = ( upgradeCoresButton = (
<Tooltip <Tooltip
title={ title={

@ -61,11 +61,16 @@ export function HacknetServerElem(props: IProps): React.ReactElement {
} }
const base_increase = const base_increase =
calculateHashGainRate(node.level + multiplier, 0, node.maxRam, node.cores, props.player.hacknet_node_money_mult) - calculateHashGainRate(
calculateHashGainRate(node.level, 0, node.maxRam, node.cores, props.player.hacknet_node_money_mult); node.level + multiplier,
0,
node.maxRam,
node.cores,
props.player.mults.hacknet_node_money,
) - calculateHashGainRate(node.level, 0, node.maxRam, node.cores, props.player.mults.hacknet_node_money);
const modded_increase = (base_increase * (node.maxRam - node.ramUsed)) / node.maxRam; const modded_increase = (base_increase * (node.maxRam - node.ramUsed)) / node.maxRam;
const upgradeLevelCost = node.calculateLevelUpgradeCost(multiplier, props.player.hacknet_node_level_cost_mult); const upgradeLevelCost = node.calculateLevelUpgradeCost(multiplier, props.player.mults.hacknet_node_level_cost);
upgradeLevelButton = ( upgradeLevelButton = (
<Tooltip <Tooltip
title={ title={
@ -122,8 +127,8 @@ export function HacknetServerElem(props: IProps): React.ReactElement {
0, 0,
node.maxRam * Math.pow(2, multiplier), node.maxRam * Math.pow(2, multiplier),
node.cores, node.cores,
props.player.hacknet_node_money_mult, props.player.mults.hacknet_node_money,
) - calculateHashGainRate(node.level, 0, node.maxRam, node.cores, props.player.hacknet_node_money_mult); ) - calculateHashGainRate(node.level, 0, node.maxRam, node.cores, props.player.mults.hacknet_node_money);
const modded_increase = const modded_increase =
calculateHashGainRate( calculateHashGainRate(
@ -131,11 +136,11 @@ export function HacknetServerElem(props: IProps): React.ReactElement {
node.ramUsed, node.ramUsed,
node.maxRam * Math.pow(2, multiplier), node.maxRam * Math.pow(2, multiplier),
node.cores, node.cores,
props.player.hacknet_node_money_mult, props.player.mults.hacknet_node_money,
) - ) -
calculateHashGainRate(node.level, node.ramUsed, node.maxRam, node.cores, props.player.hacknet_node_money_mult); calculateHashGainRate(node.level, node.ramUsed, node.maxRam, node.cores, props.player.mults.hacknet_node_money);
const upgradeRamCost = node.calculateRamUpgradeCost(multiplier, props.player.hacknet_node_ram_cost_mult); const upgradeRamCost = node.calculateRamUpgradeCost(multiplier, props.player.mults.hacknet_node_ram_cost);
upgradeRamButton = ( upgradeRamButton = (
<Tooltip <Tooltip
title={ title={
@ -179,11 +184,16 @@ export function HacknetServerElem(props: IProps): React.ReactElement {
} }
const base_increase = const base_increase =
calculateHashGainRate(node.level, 0, node.maxRam, node.cores + multiplier, props.player.hacknet_node_money_mult) - calculateHashGainRate(
calculateHashGainRate(node.level, 0, node.maxRam, node.cores, props.player.hacknet_node_money_mult); node.level,
0,
node.maxRam,
node.cores + multiplier,
props.player.mults.hacknet_node_money,
) - calculateHashGainRate(node.level, 0, node.maxRam, node.cores, props.player.mults.hacknet_node_money);
const modded_increase = (base_increase * (node.maxRam - node.ramUsed)) / node.maxRam; const modded_increase = (base_increase * (node.maxRam - node.ramUsed)) / node.maxRam;
const upgradeCoreCost = node.calculateCoreUpgradeCost(multiplier, props.player.hacknet_node_core_cost_mult); const upgradeCoreCost = node.calculateCoreUpgradeCost(multiplier, props.player.mults.hacknet_node_core_cost);
upgradeCoresButton = ( upgradeCoresButton = (
<Tooltip <Tooltip
title={ title={

@ -16,10 +16,10 @@ export function calculateDifficulty(player: IPlayer, startingSecurityLevel: numb
export function calculateReward(player: IPlayer, startingSecurityLevel: number): number { export function calculateReward(player: IPlayer, startingSecurityLevel: number): number {
const xpMult = 10 * 60 * 15; const xpMult = 10 * 60 * 15;
const total = const total =
calculateSkill(player.strength_exp_mult * xpMult, player.strength_mult) + calculateSkill(player.mults.strength_exp * xpMult, player.mults.strength) +
calculateSkill(player.defense_exp_mult * xpMult, player.defense_mult) + calculateSkill(player.mults.defense_exp * xpMult, player.mults.defense) +
calculateSkill(player.agility_exp_mult * xpMult, player.agility_mult) + calculateSkill(player.mults.agility_exp * xpMult, player.mults.agility) +
calculateSkill(player.dexterity_exp_mult * xpMult, player.dexterity_mult) + calculateSkill(player.mults.dexterity_exp * xpMult, player.mults.dexterity) +
calculateSkill(player.charisma_exp_mult * xpMult, player.charisma_mult); calculateSkill(player.mults.charisma_exp * xpMult, player.mults.charisma);
return calculateRawDiff(player, total, startingSecurityLevel); return calculateRawDiff(player, total, startingSecurityLevel);
} }

@ -1511,19 +1511,19 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
}, },
getHackingMultipliers: () => (): HackingMultipliers => { getHackingMultipliers: () => (): HackingMultipliers => {
return { return {
chance: Player.hacking_chance_mult, chance: Player.mults.hacking_chance,
speed: Player.hacking_speed_mult, speed: Player.mults.hacking_speed,
money: Player.hacking_money_mult, money: Player.mults.hacking_money,
growth: Player.hacking_grow_mult, growth: Player.mults.hacking_grow,
}; };
}, },
getHacknetMultipliers: () => (): HacknetMultipliers => { getHacknetMultipliers: () => (): HacknetMultipliers => {
return { return {
production: Player.hacknet_node_money_mult, production: Player.mults.hacknet_node_money,
purchaseCost: Player.hacknet_node_purchase_cost_mult, purchaseCost: Player.mults.hacknet_node_purchase_cost,
ramCost: Player.hacknet_node_ram_cost_mult, ramCost: Player.mults.hacknet_node_ram_cost,
coreCost: Player.hacknet_node_core_cost_mult, coreCost: Player.mults.hacknet_node_core_cost,
levelCost: Player.hacknet_node_level_cost_mult, levelCost: Player.mults.hacknet_node_level_cost,
}; };
}, },
getBitNodeMultipliers: (ctx: NetscriptContext) => (): IBNMults => { getBitNodeMultipliers: (ctx: NetscriptContext) => (): IBNMults => {
@ -2366,51 +2366,23 @@ export function NetscriptFunctions(workerScript: WorkerScript): NS {
agility: Player.agility, agility: Player.agility,
charisma: Player.charisma, charisma: Player.charisma,
intelligence: Player.intelligence, intelligence: Player.intelligence,
hacking_chance_mult: Player.hacking_chance_mult,
hacking_speed_mult: Player.hacking_speed_mult,
hacking_money_mult: Player.hacking_money_mult,
hacking_grow_mult: Player.hacking_grow_mult,
hacking_exp: Player.hacking_exp, hacking_exp: Player.hacking_exp,
strength_exp: Player.strength_exp, strength_exp: Player.strength_exp,
defense_exp: Player.defense_exp, defense_exp: Player.defense_exp,
dexterity_exp: Player.dexterity_exp, dexterity_exp: Player.dexterity_exp,
agility_exp: Player.agility_exp, agility_exp: Player.agility_exp,
charisma_exp: Player.charisma_exp, charisma_exp: Player.charisma_exp,
hacking_mult: Player.hacking_mult, hacking_chance_mult: Player.mults.hacking_chance,
strength_mult: Player.strength_mult, mults: JSON.parse(JSON.stringify(Player.mults)),
defense_mult: Player.defense_mult,
dexterity_mult: Player.dexterity_mult,
agility_mult: Player.agility_mult,
charisma_mult: Player.charisma_mult,
hacking_exp_mult: Player.hacking_exp_mult,
strength_exp_mult: Player.strength_exp_mult,
defense_exp_mult: Player.defense_exp_mult,
dexterity_exp_mult: Player.dexterity_exp_mult,
agility_exp_mult: Player.agility_exp_mult,
charisma_exp_mult: Player.charisma_exp_mult,
company_rep_mult: Player.company_rep_mult,
faction_rep_mult: Player.faction_rep_mult,
numPeopleKilled: Player.numPeopleKilled, numPeopleKilled: Player.numPeopleKilled,
money: Player.money, money: Player.money,
city: Player.city, city: Player.city,
location: Player.location, location: Player.location,
companyName: Player.companyName, companyName: Player.companyName,
crime_money_mult: Player.crime_money_mult,
crime_success_mult: Player.crime_success_mult,
work_money_mult: Player.work_money_mult,
hacknet_node_money_mult: Player.hacknet_node_money_mult,
hacknet_node_purchase_cost_mult: Player.hacknet_node_purchase_cost_mult,
hacknet_node_ram_cost_mult: Player.hacknet_node_ram_cost_mult,
hacknet_node_core_cost_mult: Player.hacknet_node_core_cost_mult,
hacknet_node_level_cost_mult: Player.hacknet_node_level_cost_mult,
hasWseAccount: Player.hasWseAccount, hasWseAccount: Player.hasWseAccount,
hasTixApiAccess: Player.hasTixApiAccess, hasTixApiAccess: Player.hasTixApiAccess,
has4SData: Player.has4SData, has4SData: Player.has4SData,
has4SDataTixApi: Player.has4SDataTixApi, has4SDataTixApi: Player.has4SDataTixApi,
bladeburner_max_stamina_mult: Player.bladeburner_max_stamina_mult,
bladeburner_stamina_gain_mult: Player.bladeburner_stamina_gain_mult,
bladeburner_analysis_mult: Player.bladeburner_analysis_mult,
bladeburner_success_chance_mult: Player.bladeburner_success_chance_mult,
bitNodeN: Player.bitNodeN, bitNodeN: Player.bitNodeN,
totalPlaytime: Player.totalPlaytime, totalPlaytime: Player.totalPlaytime,
playtimeSinceLastAug: Player.playtimeSinceLastAug, playtimeSinceLastAug: Player.playtimeSinceLastAug,

@ -257,7 +257,7 @@ export function NetscriptCorporation(player: IPlayer, workerScript: WorkerScript
function getMaterial(divisionName: string, cityName: string, materialName: string): Material { function getMaterial(divisionName: string, cityName: string, materialName: string): Material {
const warehouse = getWarehouse(divisionName, cityName); const warehouse = getWarehouse(divisionName, cityName);
const matName = (materialName ).replace(/ /g, ""); const matName = materialName.replace(/ /g, "");
const material = warehouse.materials[matName]; const material = warehouse.materials[matName];
if (material === undefined) throw new Error(`Invalid material name: '${materialName}'`); if (material === undefined) throw new Error(`Invalid material name: '${materialName}'`);
return material; return material;
@ -725,9 +725,11 @@ export function NetscriptCorporation(player: IPlayer, workerScript: WorkerScript
const employeeName = ctx.helper.string("employeeName", _employeeName); const employeeName = ctx.helper.string("employeeName", _employeeName);
const job = ctx.helper.string("job", _job); const job = ctx.helper.string("job", _job);
const employee = getEmployee(divisionName, cityName, employeeName); const employee = getEmployee(divisionName, cityName, employeeName);
return netscriptDelay(["Training", "Unassigned"].includes(employee.pos) ? 0 : 1000, workerScript).then(function () { return netscriptDelay(["Training", "Unassigned"].includes(employee.pos) ? 0 : 1000, workerScript).then(
return Promise.resolve(AssignJob(employee, job)); function () {
}); return Promise.resolve(AssignJob(employee, job));
},
);
}, },
hireEmployee: hireEmployee:
(ctx: NetscriptContext) => (ctx: NetscriptContext) =>
@ -777,7 +779,7 @@ export function NetscriptCorporation(player: IPlayer, workerScript: WorkerScript
const office = getOffice(divisionName, cityName); const office = getOffice(divisionName, cityName);
const corporation = getCorporation(); const corporation = getCorporation();
return netscriptDelay( return netscriptDelay(
(60 * 1000) / (player.hacking_speed_mult * calculateIntelligenceBonus(player.intelligence, 1)), (60 * 1000) / (player.mults.hacking_speed * calculateIntelligenceBonus(player.intelligence, 1)),
workerScript, workerScript,
).then(function () { ).then(function () {
return Promise.resolve(ThrowParty(corporation, office, costPerEmployee)); return Promise.resolve(ThrowParty(corporation, office, costPerEmployee));
@ -791,7 +793,7 @@ export function NetscriptCorporation(player: IPlayer, workerScript: WorkerScript
const cityName = ctx.helper.city("cityName", _cityName); const cityName = ctx.helper.city("cityName", _cityName);
const corporation = getCorporation(); const corporation = getCorporation();
return netscriptDelay( return netscriptDelay(
(60 * 1000) / (player.hacking_speed_mult * calculateIntelligenceBonus(player.intelligence, 1)), (60 * 1000) / (player.mults.hacking_speed * calculateIntelligenceBonus(player.intelligence, 1)),
workerScript, workerScript,
).then(function () { ).then(function () {
return Promise.resolve(BuyCoffee(corporation, getDivision(divisionName), getOffice(divisionName, cityName))); return Promise.resolve(BuyCoffee(corporation, getDivision(divisionName), getOffice(divisionName, cityName)));

@ -141,7 +141,7 @@ export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript): I
const i = ctx.helper.number("i", _i); const i = ctx.helper.number("i", _i);
const n = ctx.helper.number("n", _n); const n = ctx.helper.number("n", _n);
const node = getHacknetNode(ctx, i); const node = getHacknetNode(ctx, i);
return node.calculateLevelUpgradeCost(n, player.hacknet_node_level_cost_mult); return node.calculateLevelUpgradeCost(n, player.mults.hacknet_node_level_cost);
}, },
getRamUpgradeCost: getRamUpgradeCost:
(ctx: NetscriptContext) => (ctx: NetscriptContext) =>
@ -149,7 +149,7 @@ export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript): I
const i = ctx.helper.number("i", _i); const i = ctx.helper.number("i", _i);
const n = ctx.helper.number("n", _n); const n = ctx.helper.number("n", _n);
const node = getHacknetNode(ctx, i); const node = getHacknetNode(ctx, i);
return node.calculateRamUpgradeCost(n, player.hacknet_node_ram_cost_mult); return node.calculateRamUpgradeCost(n, player.mults.hacknet_node_ram_cost);
}, },
getCoreUpgradeCost: getCoreUpgradeCost:
(ctx: NetscriptContext) => (ctx: NetscriptContext) =>
@ -157,7 +157,7 @@ export function NetscriptHacknet(player: IPlayer, workerScript: WorkerScript): I
const i = ctx.helper.number("i", _i); const i = ctx.helper.number("i", _i);
const n = ctx.helper.number("n", _n); const n = ctx.helper.number("n", _n);
const node = getHacknetNode(ctx, i); const node = getHacknetNode(ctx, i);
return node.calculateCoreUpgradeCost(n, player.hacknet_node_core_cost_mult); return node.calculateCoreUpgradeCost(n, player.mults.hacknet_node_core_cost);
}, },
getCacheUpgradeCost: getCacheUpgradeCost:
(ctx: NetscriptContext) => (ctx: NetscriptContext) =>

@ -679,23 +679,23 @@ export function NetscriptSingularity(player: IPlayer, workerScript: WorkerScript
jobTitles: Object.values(player.jobs), jobTitles: Object.values(player.jobs),
maxHp: player.max_hp, maxHp: player.max_hp,
mult: { mult: {
agility: player.agility_mult, agility: player.mults.agility,
agilityExp: player.agility_exp_mult, agilityExp: player.mults.agility_exp,
charisma: player.charisma, charisma: player.charisma,
charismaExp: player.charisma_exp, charismaExp: player.charisma_exp,
companyRep: player.company_rep_mult, companyRep: player.mults.company_rep,
crimeMoney: player.crime_money_mult, crimeMoney: player.mults.crime_money,
crimeSuccess: player.crime_success_mult, crimeSuccess: player.mults.crime_success,
defense: player.defense_mult, defense: player.mults.defense,
defenseExp: player.defense_exp_mult, defenseExp: player.mults.defense_exp,
dexterity: player.dexterity_mult, dexterity: player.mults.dexterity,
dexterityExp: player.dexterity_exp_mult, dexterityExp: player.mults.dexterity_exp,
factionRep: player.faction_rep_mult, factionRep: player.mults.faction_rep,
hacking: player.hacking_mult, hacking: player.mults.hacking,
hackingExp: player.hacking_exp_mult, hackingExp: player.mults.hacking_exp,
strength: player.strength_mult, strength: player.mults.strength,
strengthExp: player.strength_exp_mult, strengthExp: player.mults.strength_exp,
workMoney: player.work_money_mult, workMoney: player.mults.work_money,
}, },
tor: player.hasTorRouter(), tor: player.hasTorRouter(),
hackingExp: player.hacking_exp, hackingExp: player.hacking_exp,
@ -1115,7 +1115,7 @@ export function NetscriptSingularity(player: IPlayer, workerScript: WorkerScript
); );
return false; return false;
} }
const repGain = (amt / CONSTANTS.DonateMoneyToRepDivisor) * player.faction_rep_mult; const repGain = (amt / CONSTANTS.DonateMoneyToRepDivisor) * player.mults.faction_rep;
faction.playerReputation += repGain; faction.playerReputation += repGain;
player.loseMoney(amt, "other"); player.loseMoney(amt, "other");
_ctx.log( _ctx.log(

@ -210,23 +210,23 @@ export function NetscriptSleeve(player: IPlayer): InternalAPI<ISleeve> {
maxHp: sl.max_hp, maxHp: sl.max_hp,
mult: { mult: {
agility: sl.agility_mult, agility: sl.mults.agility,
agilityExp: sl.agility_exp_mult, agilityExp: sl.mults.agility_exp,
charisma: sl.charisma_mult, charisma: sl.mults.charisma,
charismaExp: sl.charisma_exp_mult, charismaExp: sl.mults.charisma_exp,
companyRep: sl.company_rep_mult, companyRep: sl.mults.company_rep,
crimeMoney: sl.crime_money_mult, crimeMoney: sl.mults.crime_money,
crimeSuccess: sl.crime_success_mult, crimeSuccess: sl.mults.crime_success,
defense: sl.defense_mult, defense: sl.mults.defense,
defenseExp: sl.defense_exp_mult, defenseExp: sl.mults.defense_exp,
dexterity: sl.dexterity_mult, dexterity: sl.mults.dexterity,
dexterityExp: sl.dexterity_exp_mult, dexterityExp: sl.mults.dexterity_exp,
factionRep: sl.faction_rep_mult, factionRep: sl.mults.faction_rep,
hacking: sl.hacking_mult, hacking: sl.mults.hacking,
hackingExp: sl.hacking_exp_mult, hackingExp: sl.mults.hacking_exp,
strength: sl.strength_mult, strength: sl.mults.strength,
strengthExp: sl.strength_exp_mult, strengthExp: sl.mults.strength_exp,
workMoney: sl.work_money_mult, workMoney: sl.mults.work_money,
}, },
timeWorked: sl.currentTaskTime, timeWorked: sl.currentTaskTime,

@ -4,44 +4,44 @@ import { CONSTANTS } from "../../Constants";
import { IPlayer } from "../IPlayer"; import { IPlayer } from "../IPlayer";
export const calculateEntropy = (player: IPlayer, stacks = 1): IMap<number> => { export const calculateEntropy = (player: IPlayer, stacks = 1): IMap<number> => {
const multipliers: IMap<number> = { const multipliers: Record<string, number> = {
hacking_chance_mult: player.hacking_chance_mult, hacking_chance: player.mults.hacking_chance,
hacking_speed_mult: player.hacking_speed_mult, hacking_speed: player.mults.hacking_speed,
hacking_money_mult: player.hacking_money_mult, hacking_money: player.mults.hacking_money,
hacking_grow_mult: player.hacking_grow_mult, hacking_grow: player.mults.hacking_grow,
hacking_mult: player.hacking_mult, hacking: player.mults.hacking,
strength_mult: player.strength_mult, strength: player.mults.strength,
defense_mult: player.defense_mult, defense: player.mults.defense,
dexterity_mult: player.dexterity_mult, dexterity: player.mults.dexterity,
agility_mult: player.agility_mult, agility: player.mults.agility,
charisma_mult: player.charisma_mult, charisma: player.mults.charisma,
hacking_exp_mult: player.hacking_exp_mult, hacking_exp: player.mults.hacking_exp,
strength_exp_mult: player.strength_exp_mult, strength_exp: player.mults.strength_exp,
defense_exp_mult: player.defense_exp_mult, defense_exp: player.mults.defense_exp,
dexterity_exp_mult: player.dexterity_exp_mult, dexterity_exp: player.mults.dexterity_exp,
agility_exp_mult: player.agility_exp_mult, agility_exp: player.mults.agility_exp,
charisma_exp_mult: player.charisma_exp_mult, charisma_exp: player.mults.charisma_exp,
company_rep_mult: player.company_rep_mult, company_rep: player.mults.company_rep,
faction_rep_mult: player.faction_rep_mult, faction_rep: player.mults.faction_rep,
crime_money_mult: player.crime_money_mult, crime_money: player.mults.crime_money,
crime_success_mult: player.crime_success_mult, crime_success: player.mults.crime_success,
hacknet_node_money_mult: player.hacknet_node_money_mult, hacknet_node_money: player.mults.hacknet_node_money,
hacknet_node_purchase_cost_mult: player.hacknet_node_purchase_cost_mult, hacknet_node_purchase_cost: player.mults.hacknet_node_purchase_cost,
hacknet_node_ram_cost_mult: player.hacknet_node_ram_cost_mult, hacknet_node_ram_cost: player.mults.hacknet_node_ram_cost,
hacknet_node_core_cost_mult: player.hacknet_node_core_cost_mult, hacknet_node_core_cost: player.mults.hacknet_node_core_cost,
hacknet_node_level_cost_mult: player.hacknet_node_level_cost_mult, hacknet_node_level_cost: player.mults.hacknet_node_level_cost,
work_money_mult: player.work_money_mult, work_money: player.mults.work_money,
bladeburner_max_stamina_mult: player.bladeburner_max_stamina_mult, bladeburner_max_stamina: player.mults.bladeburner_max_stamina,
bladeburner_stamina_gain_mult: player.bladeburner_stamina_gain_mult, bladeburner_stamina_gain: player.mults.bladeburner_stamina_gain,
bladeburner_analysis_mult: player.bladeburner_analysis_mult, bladeburner_analysis: player.mults.bladeburner_analysis,
bladeburner_success_chance_mult: player.bladeburner_success_chance_mult, bladeburner_success_chance: player.mults.bladeburner_success_chance,
}; };
for (const [mult, val] of Object.entries(multipliers)) { for (const [mult, val] of Object.entries(multipliers)) {

@ -3,6 +3,7 @@
import { IPlayerOwnedAugmentation } from "../Augmentation/PlayerOwnedAugmentation"; import { IPlayerOwnedAugmentation } from "../Augmentation/PlayerOwnedAugmentation";
import { ITaskTracker } from "./ITaskTracker"; import { ITaskTracker } from "./ITaskTracker";
import { Multipliers } from "./Multipliers";
export interface IPerson { export interface IPerson {
// Stats // Stats
@ -25,27 +26,7 @@ export interface IPerson {
charisma_exp: number; charisma_exp: number;
intelligence_exp: number; intelligence_exp: number;
// Multipliers mults: Multipliers;
hacking_exp_mult: number;
strength_exp_mult: number;
defense_exp_mult: number;
dexterity_exp_mult: number;
agility_exp_mult: number;
charisma_exp_mult: number;
hacking_mult: number;
strength_mult: number;
defense_mult: number;
dexterity_mult: number;
agility_mult: number;
charisma_mult: number;
company_rep_mult: number;
faction_rep_mult: number;
crime_money_mult: number;
crime_success_mult: number;
bladeburner_analysis_mult: number;
augmentations: IPlayerOwnedAugmentation[]; augmentations: IPlayerOwnedAugmentation[];

@ -30,6 +30,7 @@ import { ISkillProgress } from "./formulas/skill";
import { PlayerAchievement } from "../Achievements/Achievements"; import { PlayerAchievement } from "../Achievements/Achievements";
import { IPerson } from "./IPerson"; import { IPerson } from "./IPerson";
import { Work } from "src/Work/Work"; import { Work } from "src/Work/Work";
import { Multipliers } from "./Multipliers";
export interface IPlayer extends IPerson { export interface IPlayer extends IPerson {
bitNodeN: number; bitNodeN: number;
@ -88,37 +89,7 @@ export interface IPlayer extends IPerson {
charisma_exp: number; charisma_exp: number;
intelligence_exp: number; intelligence_exp: number;
// Multipliers mults: Multipliers;
hacking_chance_mult: number;
hacking_speed_mult: number;
hacking_money_mult: number;
hacking_grow_mult: number;
hacking_mult: number;
hacking_exp_mult: number;
strength_mult: number;
strength_exp_mult: number;
defense_mult: number;
defense_exp_mult: number;
dexterity_mult: number;
dexterity_exp_mult: number;
agility_mult: number;
agility_exp_mult: number;
charisma_mult: number;
charisma_exp_mult: number;
hacknet_node_money_mult: number;
hacknet_node_purchase_cost_mult: number;
hacknet_node_ram_cost_mult: number;
hacknet_node_core_cost_mult: number;
hacknet_node_level_cost_mult: number;
company_rep_mult: number;
faction_rep_mult: number;
work_money_mult: number;
crime_success_mult: number;
crime_money_mult: number;
bladeburner_max_stamina_mult: number;
bladeburner_stamina_gain_mult: number;
bladeburner_analysis_mult: number;
bladeburner_success_chance_mult: number;
currentWork: Work | null; currentWork: Work | null;
focus: boolean; focus: boolean;

@ -1,3 +1,5 @@
import { AugmentationStats } from "../ScriptEditor/NetscriptDefinitions";
export interface Multipliers { export interface Multipliers {
hacking_chance: number; hacking_chance: number;
hacking_speed: number; hacking_speed: number;
@ -65,3 +67,38 @@ export const defaultMultipliers = (): Multipliers => {
bladeburner_success_chance: 1, bladeburner_success_chance: 1,
}; };
}; };
export const mergeMultipliers = (m0: Multipliers, m1: AugmentationStats): Multipliers => {
return {
hacking_chance: m0.hacking_chance * (m1.hacking_chance ?? 1),
hacking_speed: m0.hacking_speed * (m1.hacking_speed ?? 1),
hacking_money: m0.hacking_money * (m1.hacking_money ?? 1),
hacking_grow: m0.hacking_grow * (m1.hacking_grow ?? 1),
hacking: m0.hacking * (m1.hacking ?? 1),
hacking_exp: m0.hacking_exp * (m1.hacking_exp ?? 1),
strength: m0.strength * (m1.strength ?? 1),
strength_exp: m0.strength_exp * (m1.strength_exp ?? 1),
defense: m0.defense * (m1.defense ?? 1),
defense_exp: m0.defense_exp * (m1.defense_exp ?? 1),
dexterity: m0.dexterity * (m1.dexterity ?? 1),
dexterity_exp: m0.dexterity_exp * (m1.dexterity_exp ?? 1),
agility: m0.agility * (m1.agility ?? 1),
agility_exp: m0.agility_exp * (m1.agility_exp ?? 1),
charisma: m0.charisma * (m1.charisma ?? 1),
charisma_exp: m0.charisma_exp * (m1.charisma_exp ?? 1),
hacknet_node_money: m0.hacknet_node_money * (m1.hacknet_node_money ?? 1),
hacknet_node_purchase_cost: m0.hacknet_node_purchase_cost * (m1.hacknet_node_purchase_cost ?? 1),
hacknet_node_ram_cost: m0.hacknet_node_ram_cost * (m1.hacknet_node_ram_cost ?? 1),
hacknet_node_core_cost: m0.hacknet_node_core_cost * (m1.hacknet_node_core_cost ?? 1),
hacknet_node_level_cost: m0.hacknet_node_level_cost * (m1.hacknet_node_level_cost ?? 1),
company_rep: m0.company_rep * (m1.company_rep ?? 1),
faction_rep: m0.faction_rep * (m1.faction_rep ?? 1),
work_money: m0.work_money * (m1.work_money ?? 1),
crime_success: m0.crime_success * (m1.crime_success ?? 1),
crime_money: m0.crime_money * (m1.crime_money ?? 1),
bladeburner_max_stamina: m0.bladeburner_max_stamina * (m1.bladeburner_max_stamina ?? 1),
bladeburner_stamina_gain: m0.bladeburner_stamina_gain * (m1.bladeburner_stamina_gain ?? 1),
bladeburner_analysis: m0.bladeburner_analysis * (m1.bladeburner_analysis ?? 1),
bladeburner_success_chance: m0.bladeburner_success_chance * (m1.bladeburner_success_chance ?? 1),
};
};

@ -7,6 +7,7 @@ import { CONSTANTS } from "../Constants";
import { calculateSkill } from "./formulas/skill"; import { calculateSkill } from "./formulas/skill";
import { calculateIntelligenceBonus } from "./formulas/intelligence"; import { calculateIntelligenceBonus } from "./formulas/intelligence";
import { IPerson } from "./IPerson"; import { IPerson } from "./IPerson";
import { defaultMultipliers, mergeMultipliers, Multipliers } from "./Multipliers";
// Base class representing a person-like object // Base class representing a person-like object
export abstract class Person implements IPerson { export abstract class Person implements IPerson {
@ -34,46 +35,7 @@ export abstract class Person implements IPerson {
charisma_exp = 0; charisma_exp = 0;
intelligence_exp = 0; intelligence_exp = 0;
/** mults = defaultMultipliers();
* Multipliers
*/
hacking_mult = 1;
strength_mult = 1;
defense_mult = 1;
dexterity_mult = 1;
agility_mult = 1;
charisma_mult = 1;
hacking_exp_mult = 1;
strength_exp_mult = 1;
defense_exp_mult = 1;
dexterity_exp_mult = 1;
agility_exp_mult = 1;
charisma_exp_mult = 1;
hacking_chance_mult = 1;
hacking_speed_mult = 1;
hacking_money_mult = 1;
hacking_grow_mult = 1;
company_rep_mult = 1;
faction_rep_mult = 1;
crime_money_mult = 1;
crime_success_mult = 1;
work_money_mult = 1;
hacknet_node_money_mult = 1;
hacknet_node_purchase_cost_mult = 1;
hacknet_node_ram_cost_mult = 1;
hacknet_node_core_cost_mult = 1;
hacknet_node_level_cost_mult = 1;
bladeburner_max_stamina_mult = 1;
bladeburner_stamina_gain_mult = 1;
bladeburner_analysis_mult = 1;
bladeburner_success_chance_mult = 1;
/** /**
* Augmentations * Augmentations
@ -101,13 +63,7 @@ export abstract class Person implements IPerson {
* Updates this object's multipliers for the given augmentation * Updates this object's multipliers for the given augmentation
*/ */
applyAugmentation(aug: Augmentation): void { applyAugmentation(aug: Augmentation): void {
for (const mult of Object.keys(aug.mults)) { this.mults = mergeMultipliers(this.mults, aug.mults);
if ((this as any)[mult] == null) {
console.warn(`Augmentation has unrecognized multiplier property: ${mult}`);
} else {
(this as any)[mult] *= aug.mults[mult];
}
}
} }
/** /**
@ -132,7 +88,7 @@ export abstract class Person implements IPerson {
this.agility / CONSTANTS.MaxSkillLevel + this.agility / CONSTANTS.MaxSkillLevel +
this.charisma / CONSTANTS.MaxSkillLevel)) / this.charisma / CONSTANTS.MaxSkillLevel)) /
5.5; 5.5;
return t * this.faction_rep_mult; return t * this.mults.faction_rep;
} }
/** /**
@ -140,7 +96,7 @@ export abstract class Person implements IPerson {
* when doing Hacking Work for a faction * when doing Hacking Work for a faction
*/ */
getFactionHackingWorkRepGain(): number { getFactionHackingWorkRepGain(): number {
return (this.hacking / CONSTANTS.MaxSkillLevel) * this.faction_rep_mult; return (this.hacking / CONSTANTS.MaxSkillLevel) * this.mults.faction_rep;
} }
/** /**
@ -156,45 +112,14 @@ export abstract class Person implements IPerson {
this.dexterity / CONSTANTS.MaxSkillLevel + this.dexterity / CONSTANTS.MaxSkillLevel +
this.agility / CONSTANTS.MaxSkillLevel)) / this.agility / CONSTANTS.MaxSkillLevel)) /
4.5; 4.5;
return t * this.faction_rep_mult; return t * this.mults.faction_rep;
} }
/** /**
* Reset all multipliers to 1 * Reset all multipliers to 1
*/ */
resetMultipliers(): void { resetMultipliers(): void {
this.hacking_mult = 1; this.mults = defaultMultipliers();
this.strength_mult = 1;
this.defense_mult = 1;
this.dexterity_mult = 1;
this.agility_mult = 1;
this.charisma_mult = 1;
this.hacking_exp_mult = 1;
this.strength_exp_mult = 1;
this.defense_exp_mult = 1;
this.dexterity_exp_mult = 1;
this.agility_exp_mult = 1;
this.charisma_exp_mult = 1;
this.company_rep_mult = 1;
this.faction_rep_mult = 1;
this.crime_money_mult = 1;
this.crime_success_mult = 1;
this.work_money_mult = 1;
this.hacknet_node_money_mult = 1;
this.hacknet_node_purchase_cost_mult = 1;
this.hacknet_node_ram_cost_mult = 1;
this.hacknet_node_core_cost_mult = 1;
this.hacknet_node_level_cost_mult = 1;
this.bladeburner_max_stamina_mult = 1;
this.bladeburner_stamina_gain_mult = 1;
this.bladeburner_analysis_mult = 1;
this.bladeburner_success_chance_mult = 1;
} }
/** /**
@ -203,32 +128,32 @@ export abstract class Person implements IPerson {
updateStatLevels(): void { updateStatLevels(): void {
this.hacking = Math.max( this.hacking = Math.max(
1, 1,
Math.floor(this.calculateStat(this.hacking_exp, this.hacking_mult * BitNodeMultipliers.HackingLevelMultiplier)), Math.floor(this.calculateStat(this.hacking_exp, this.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier)),
); );
this.strength = Math.max( this.strength = Math.max(
1, 1,
Math.floor( Math.floor(
this.calculateStat(this.strength_exp, this.strength_mult * BitNodeMultipliers.StrengthLevelMultiplier), this.calculateStat(this.strength_exp, this.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier),
), ),
); );
this.defense = Math.max( this.defense = Math.max(
1, 1,
Math.floor(this.calculateStat(this.defense_exp, this.defense_mult * BitNodeMultipliers.DefenseLevelMultiplier)), Math.floor(this.calculateStat(this.defense_exp, this.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier)),
); );
this.dexterity = Math.max( this.dexterity = Math.max(
1, 1,
Math.floor( Math.floor(
this.calculateStat(this.dexterity_exp, this.dexterity_mult * BitNodeMultipliers.DexterityLevelMultiplier), this.calculateStat(this.dexterity_exp, this.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier),
), ),
); );
this.agility = Math.max( this.agility = Math.max(
1, 1,
Math.floor(this.calculateStat(this.agility_exp, this.agility_mult * BitNodeMultipliers.AgilityLevelMultiplier)), Math.floor(this.calculateStat(this.agility_exp, this.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier)),
); );
this.charisma = Math.max( this.charisma = Math.max(
1, 1,
Math.floor( Math.floor(
this.calculateStat(this.charisma_exp, this.charisma_mult * BitNodeMultipliers.CharismaLevelMultiplier), this.calculateStat(this.charisma_exp, this.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier),
), ),
); );

@ -39,6 +39,7 @@ import { getRandomInt } from "../../utils/helpers/getRandomInt";
import { ITaskTracker } from "../ITaskTracker"; import { ITaskTracker } from "../ITaskTracker";
import { CONSTANTS } from "../../Constants"; import { CONSTANTS } from "../../Constants";
import { Work } from "src/Work/Work"; import { Work } from "src/Work/Work";
import { defaultMultipliers, Multipliers } from "../Multipliers";
export class PlayerObject implements IPlayer { export class PlayerObject implements IPlayer {
// Class members // Class members
@ -102,37 +103,7 @@ export class PlayerObject implements IPlayer {
charisma_exp: number; charisma_exp: number;
intelligence_exp: number; intelligence_exp: number;
// Multipliers mults: Multipliers;
hacking_chance_mult: number;
hacking_speed_mult: number;
hacking_money_mult: number;
hacking_grow_mult: number;
hacking_mult: number;
hacking_exp_mult: number;
strength_mult: number;
strength_exp_mult: number;
defense_mult: number;
defense_exp_mult: number;
dexterity_mult: number;
dexterity_exp_mult: number;
agility_mult: number;
agility_exp_mult: number;
charisma_mult: number;
charisma_exp_mult: number;
hacknet_node_money_mult: number;
hacknet_node_purchase_cost_mult: number;
hacknet_node_ram_cost_mult: number;
hacknet_node_core_cost_mult: number;
hacknet_node_level_cost_mult: number;
company_rep_mult: number;
faction_rep_mult: number;
work_money_mult: number;
crime_success_mult: number;
crime_money_mult: number;
bladeburner_max_stamina_mult: number;
bladeburner_stamina_gain_mult: number;
bladeburner_analysis_mult: number;
bladeburner_success_chance_mult: number;
currentWork: Work | null; currentWork: Work | null;
focus: boolean; focus: boolean;
@ -246,12 +217,6 @@ export class PlayerObject implements IPlayer {
//Special stats //Special stats
this.intelligence = 0; this.intelligence = 0;
//Hacking multipliers
this.hacking_chance_mult = 1;
this.hacking_speed_mult = 1;
this.hacking_money_mult = 1;
this.hacking_grow_mult = 1;
//Experience and multipliers //Experience and multipliers
this.hacking_exp = 0; this.hacking_exp = 0;
this.strength_exp = 0; this.strength_exp = 0;
@ -261,22 +226,7 @@ export class PlayerObject implements IPlayer {
this.charisma_exp = 0; this.charisma_exp = 0;
this.intelligence_exp = 0; this.intelligence_exp = 0;
this.hacking_mult = 1; this.mults = defaultMultipliers();
this.strength_mult = 1;
this.defense_mult = 1;
this.dexterity_mult = 1;
this.agility_mult = 1;
this.charisma_mult = 1;
this.hacking_exp_mult = 1;
this.strength_exp_mult = 1;
this.defense_exp_mult = 1;
this.dexterity_exp_mult = 1;
this.agility_exp_mult = 1;
this.charisma_exp_mult = 1;
this.company_rep_mult = 1;
this.faction_rep_mult = 1;
//Money //Money
this.money = 1000 + CONSTANTS.Donations; this.money = 1000 + CONSTANTS.Donations;
@ -315,21 +265,6 @@ export class PlayerObject implements IPlayer {
this.numPeopleKilled = 0; this.numPeopleKilled = 0;
this.karma = 0; this.karma = 0;
this.crime_money_mult = 1;
this.crime_success_mult = 1;
//Flags/variables for working (Company, Faction, Creating Program, Taking Class)
this.focus = false;
this.work_money_mult = 1;
//Hacknet Node multipliers
this.hacknet_node_money_mult = 1;
this.hacknet_node_purchase_cost_mult = 1;
this.hacknet_node_ram_cost_mult = 1;
this.hacknet_node_core_cost_mult = 1;
this.hacknet_node_level_cost_mult = 1;
//Stock Market //Stock Market
this.hasWseAccount = false; this.hasWseAccount = false;
this.hasTixApiAccess = false; this.hasTixApiAccess = false;
@ -344,10 +279,6 @@ export class PlayerObject implements IPlayer {
//Bladeburner //Bladeburner
this.bladeburner = null; this.bladeburner = null;
this.bladeburner_max_stamina_mult = 1;
this.bladeburner_stamina_gain_mult = 1;
this.bladeburner_analysis_mult = 1; //Field Analysis Only
this.bladeburner_success_chance_mult = 1;
// Sleeves & Re-sleeving // Sleeves & Re-sleeving
this.sleeves = []; this.sleeves = [];
@ -375,6 +306,7 @@ export class PlayerObject implements IPlayer {
this.achievements = []; this.achievements = [];
this.terminalCommandHistory = []; this.terminalCommandHistory = [];
this.focus = false;
this.currentWork = null; this.currentWork = null;
// Let's get a hash of some semi-random stuff so we have something unique. // Let's get a hash of some semi-random stuff so we have something unique.

@ -52,6 +52,7 @@ import { IPerson } from "../IPerson";
import { Player } from "../../Player"; import { Player } from "../../Player";
import { isCompanyWork } from "../../Work/CompanyWork"; import { isCompanyWork } from "../../Work/CompanyWork";
import { defaultMultipliers } from "../Multipliers";
export function init(this: IPlayer): void { export function init(this: IPlayer): void {
/* Initialize Player's home computer */ /* Initialize Player's home computer */
@ -196,29 +197,33 @@ export function calculateSkillProgress(this: IPlayer, exp: number, mult = 1): IS
export function updateSkillLevels(this: IPlayer): void { export function updateSkillLevels(this: IPlayer): void {
this.hacking = Math.max( this.hacking = Math.max(
1, 1,
Math.floor(this.calculateSkill(this.hacking_exp, this.hacking_mult * BitNodeMultipliers.HackingLevelMultiplier)), Math.floor(this.calculateSkill(this.hacking_exp, this.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier)),
); );
this.strength = Math.max( this.strength = Math.max(
1, 1,
Math.floor(this.calculateSkill(this.strength_exp, this.strength_mult * BitNodeMultipliers.StrengthLevelMultiplier)), Math.floor(
this.calculateSkill(this.strength_exp, this.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier),
),
); );
this.defense = Math.max( this.defense = Math.max(
1, 1,
Math.floor(this.calculateSkill(this.defense_exp, this.defense_mult * BitNodeMultipliers.DefenseLevelMultiplier)), Math.floor(this.calculateSkill(this.defense_exp, this.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier)),
); );
this.dexterity = Math.max( this.dexterity = Math.max(
1, 1,
Math.floor( Math.floor(
this.calculateSkill(this.dexterity_exp, this.dexterity_mult * BitNodeMultipliers.DexterityLevelMultiplier), this.calculateSkill(this.dexterity_exp, this.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier),
), ),
); );
this.agility = Math.max( this.agility = Math.max(
1, 1,
Math.floor(this.calculateSkill(this.agility_exp, this.agility_mult * BitNodeMultipliers.AgilityLevelMultiplier)), Math.floor(this.calculateSkill(this.agility_exp, this.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier)),
); );
this.charisma = Math.max( this.charisma = Math.max(
1, 1,
Math.floor(this.calculateSkill(this.charisma_exp, this.charisma_mult * BitNodeMultipliers.CharismaLevelMultiplier)), Math.floor(
this.calculateSkill(this.charisma_exp, this.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier),
),
); );
if (this.intelligence > 0) { if (this.intelligence > 0) {
@ -233,43 +238,7 @@ export function updateSkillLevels(this: IPlayer): void {
} }
export function resetMultipliers(this: IPlayer): void { export function resetMultipliers(this: IPlayer): void {
this.hacking_chance_mult = 1; this.mults = defaultMultipliers();
this.hacking_speed_mult = 1;
this.hacking_money_mult = 1;
this.hacking_grow_mult = 1;
this.hacking_mult = 1;
this.strength_mult = 1;
this.defense_mult = 1;
this.dexterity_mult = 1;
this.agility_mult = 1;
this.charisma_mult = 1;
this.hacking_exp_mult = 1;
this.strength_exp_mult = 1;
this.defense_exp_mult = 1;
this.dexterity_exp_mult = 1;
this.agility_exp_mult = 1;
this.charisma_exp_mult = 1;
this.company_rep_mult = 1;
this.faction_rep_mult = 1;
this.crime_money_mult = 1;
this.crime_success_mult = 1;
this.hacknet_node_money_mult = 1;
this.hacknet_node_purchase_cost_mult = 1;
this.hacknet_node_ram_cost_mult = 1;
this.hacknet_node_core_cost_mult = 1;
this.hacknet_node_level_cost_mult = 1;
this.work_money_mult = 1;
this.bladeburner_max_stamina_mult = 1;
this.bladeburner_stamina_gain_mult = 1;
this.bladeburner_analysis_mult = 1;
this.bladeburner_success_chance_mult = 1;
} }
export function hasProgram(this: IPlayer, programName: string): boolean { export function hasProgram(this: IPlayer, programName: string): boolean {
@ -345,7 +314,7 @@ export function gainHackingExp(this: IPerson, exp: number): void {
this.hacking_exp = 0; this.hacking_exp = 0;
} }
this.hacking = calculateSkillF(this.hacking_exp, this.hacking_mult * BitNodeMultipliers.HackingLevelMultiplier); this.hacking = calculateSkillF(this.hacking_exp, this.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier);
} }
export function gainStrengthExp(this: IPerson, exp: number): void { export function gainStrengthExp(this: IPerson, exp: number): void {
@ -358,7 +327,7 @@ export function gainStrengthExp(this: IPerson, exp: number): void {
this.strength_exp = 0; this.strength_exp = 0;
} }
this.strength = calculateSkillF(this.strength_exp, this.strength_mult * BitNodeMultipliers.StrengthLevelMultiplier); this.strength = calculateSkillF(this.strength_exp, this.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier);
} }
export function gainDefenseExp(this: IPerson, exp: number): void { export function gainDefenseExp(this: IPerson, exp: number): void {
@ -371,7 +340,7 @@ export function gainDefenseExp(this: IPerson, exp: number): void {
this.defense_exp = 0; this.defense_exp = 0;
} }
this.defense = calculateSkillF(this.defense_exp, this.defense_mult * BitNodeMultipliers.DefenseLevelMultiplier); this.defense = calculateSkillF(this.defense_exp, this.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier);
const ratio = this.hp / this.max_hp; const ratio = this.hp / this.max_hp;
this.max_hp = Math.floor(10 + this.defense / 10); this.max_hp = Math.floor(10 + this.defense / 10);
this.hp = Math.round(this.max_hp * ratio); this.hp = Math.round(this.max_hp * ratio);
@ -389,7 +358,7 @@ export function gainDexterityExp(this: IPerson, exp: number): void {
this.dexterity = calculateSkillF( this.dexterity = calculateSkillF(
this.dexterity_exp, this.dexterity_exp,
this.dexterity_mult * BitNodeMultipliers.DexterityLevelMultiplier, this.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier,
); );
} }
@ -403,7 +372,7 @@ export function gainAgilityExp(this: IPerson, exp: number): void {
this.agility_exp = 0; this.agility_exp = 0;
} }
this.agility = calculateSkillF(this.agility_exp, this.agility_mult * BitNodeMultipliers.AgilityLevelMultiplier); this.agility = calculateSkillF(this.agility_exp, this.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier);
} }
export function gainCharismaExp(this: IPerson, exp: number): void { export function gainCharismaExp(this: IPerson, exp: number): void {
@ -416,7 +385,7 @@ export function gainCharismaExp(this: IPerson, exp: number): void {
this.charisma_exp = 0; this.charisma_exp = 0;
} }
this.charisma = calculateSkillF(this.charisma_exp, this.charisma_mult * BitNodeMultipliers.CharismaLevelMultiplier); this.charisma = calculateSkillF(this.charisma_exp, this.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier);
} }
export function gainIntelligenceExp(this: IPerson, exp: number): void { export function gainIntelligenceExp(this: IPerson, exp: number): void {
@ -431,12 +400,12 @@ export function gainIntelligenceExp(this: IPerson, exp: number): void {
} }
export function gainStats(this: IPerson, retValue: ITaskTracker): void { export function gainStats(this: IPerson, retValue: ITaskTracker): void {
this.gainHackingExp(retValue.hack * this.hacking_exp_mult); this.gainHackingExp(retValue.hack * this.mults.hacking_exp);
this.gainStrengthExp(retValue.str * this.strength_exp_mult); this.gainStrengthExp(retValue.str * this.mults.strength_exp);
this.gainDefenseExp(retValue.def * this.defense_exp_mult); this.gainDefenseExp(retValue.def * this.mults.defense_exp);
this.gainDexterityExp(retValue.dex * this.dexterity_exp_mult); this.gainDexterityExp(retValue.dex * this.mults.dexterity_exp);
this.gainAgilityExp(retValue.agi * this.agility_exp_mult); this.gainAgilityExp(retValue.agi * this.mults.agility_exp);
this.gainCharismaExp(retValue.cha * this.charisma_exp_mult); this.gainCharismaExp(retValue.cha * this.mults.charisma_exp);
this.gainIntelligenceExp(retValue.int); this.gainIntelligenceExp(retValue.int);
} }

@ -169,14 +169,14 @@ export class Sleeve extends Person {
this.resetTaskStatus(p); this.resetTaskStatus(p);
} }
this.gainRatesForTask.hack = crime.hacking_exp * this.hacking_exp_mult * BitNodeMultipliers.CrimeExpGain; this.gainRatesForTask.hack = crime.hacking_exp * this.mults.hacking_exp * BitNodeMultipliers.CrimeExpGain;
this.gainRatesForTask.str = crime.strength_exp * this.strength_exp_mult * BitNodeMultipliers.CrimeExpGain; this.gainRatesForTask.str = crime.strength_exp * this.mults.strength_exp * BitNodeMultipliers.CrimeExpGain;
this.gainRatesForTask.def = crime.defense_exp * this.defense_exp_mult * BitNodeMultipliers.CrimeExpGain; this.gainRatesForTask.def = crime.defense_exp * this.mults.defense_exp * BitNodeMultipliers.CrimeExpGain;
this.gainRatesForTask.dex = crime.dexterity_exp * this.dexterity_exp_mult * BitNodeMultipliers.CrimeExpGain; this.gainRatesForTask.dex = crime.dexterity_exp * this.mults.dexterity_exp * BitNodeMultipliers.CrimeExpGain;
this.gainRatesForTask.agi = crime.agility_exp * this.agility_exp_mult * BitNodeMultipliers.CrimeExpGain; this.gainRatesForTask.agi = crime.agility_exp * this.mults.agility_exp * BitNodeMultipliers.CrimeExpGain;
this.gainRatesForTask.cha = crime.charisma_exp * this.charisma_exp_mult * BitNodeMultipliers.CrimeExpGain; this.gainRatesForTask.cha = crime.charisma_exp * this.mults.charisma_exp * BitNodeMultipliers.CrimeExpGain;
this.gainRatesForTask.int = crime.intelligence_exp; this.gainRatesForTask.int = crime.intelligence_exp;
this.gainRatesForTask.money = crime.money * this.crime_money_mult * BitNodeMultipliers.CrimeMoney; this.gainRatesForTask.money = crime.money * this.mults.crime_money * BitNodeMultipliers.CrimeMoney;
this.currentTaskLocation = String(this.gainRatesForTask.money); this.currentTaskLocation = String(this.gainRatesForTask.money);
@ -478,7 +478,7 @@ export class Sleeve extends Person {
); );
const favorMult = 1 + company.favor / 100; const favorMult = 1 + company.favor / 100;
return jobPerformance * this.company_rep_mult * favorMult; return jobPerformance * this.mults.company_rep * favorMult;
} else { } else {
return 0; return 0;
} }
@ -804,22 +804,22 @@ export class Sleeve extends Person {
switch (this.className.toLowerCase()) { switch (this.className.toLowerCase()) {
case "study computer science": case "study computer science":
this.gainRatesForTask.hack = this.gainRatesForTask.hack =
CONSTANTS.ClassStudyComputerScienceBaseExp * totalExpMult * this.hacking_exp_mult; CONSTANTS.ClassStudyComputerScienceBaseExp * totalExpMult * this.mults.hacking_exp;
break; break;
case "data structures": case "data structures":
this.gainRatesForTask.hack = CONSTANTS.ClassDataStructuresBaseExp * totalExpMult * this.hacking_exp_mult; this.gainRatesForTask.hack = CONSTANTS.ClassDataStructuresBaseExp * totalExpMult * this.mults.hacking_exp;
break; break;
case "networks": case "networks":
this.gainRatesForTask.hack = CONSTANTS.ClassNetworksBaseExp * totalExpMult * this.hacking_exp_mult; this.gainRatesForTask.hack = CONSTANTS.ClassNetworksBaseExp * totalExpMult * this.mults.hacking_exp;
break; break;
case "algorithms": case "algorithms":
this.gainRatesForTask.hack = CONSTANTS.ClassAlgorithmsBaseExp * totalExpMult * this.hacking_exp_mult; this.gainRatesForTask.hack = CONSTANTS.ClassAlgorithmsBaseExp * totalExpMult * this.mults.hacking_exp;
break; break;
case "management": case "management":
this.gainRatesForTask.cha = CONSTANTS.ClassManagementBaseExp * totalExpMult * this.charisma_exp_mult; this.gainRatesForTask.cha = CONSTANTS.ClassManagementBaseExp * totalExpMult * this.mults.charisma_exp;
break; break;
case "leadership": case "leadership":
this.gainRatesForTask.cha = CONSTANTS.ClassLeadershipBaseExp * totalExpMult * this.charisma_exp_mult; this.gainRatesForTask.cha = CONSTANTS.ClassLeadershipBaseExp * totalExpMult * this.mults.charisma_exp;
break; break;
default: default:
break; break;
@ -856,13 +856,13 @@ export class Sleeve extends Person {
const totalExpMultiplier = p.hashManager.getTrainingMult() * expMult; const totalExpMultiplier = p.hashManager.getTrainingMult() * expMult;
const sanitizedStat: string = this.gymStatType.toLowerCase(); const sanitizedStat: string = this.gymStatType.toLowerCase();
if (sanitizedStat.includes("str")) { if (sanitizedStat.includes("str")) {
this.gainRatesForTask.str = baseGymExp * totalExpMultiplier * this.strength_exp_mult; this.gainRatesForTask.str = baseGymExp * totalExpMultiplier * this.mults.strength_exp;
} else if (sanitizedStat.includes("def")) { } else if (sanitizedStat.includes("def")) {
this.gainRatesForTask.def = baseGymExp * totalExpMultiplier * this.defense_exp_mult; this.gainRatesForTask.def = baseGymExp * totalExpMultiplier * this.mults.defense_exp;
} else if (sanitizedStat.includes("dex")) { } else if (sanitizedStat.includes("dex")) {
this.gainRatesForTask.dex = baseGymExp * totalExpMultiplier * this.dexterity_exp_mult; this.gainRatesForTask.dex = baseGymExp * totalExpMultiplier * this.mults.dexterity_exp;
} else if (sanitizedStat.includes("agi")) { } else if (sanitizedStat.includes("agi")) {
this.gainRatesForTask.agi = baseGymExp * totalExpMultiplier * this.agility_exp_mult; this.gainRatesForTask.agi = baseGymExp * totalExpMultiplier * this.mults.agility_exp;
} }
return; return;
@ -906,37 +906,37 @@ export class Sleeve extends Person {
this.gainRatesForTask.money = this.gainRatesForTask.money =
companyPosition.baseSalary * companyPosition.baseSalary *
company.salaryMultiplier * company.salaryMultiplier *
this.work_money_mult * this.mults.work_money *
BitNodeMultipliers.CompanyWorkMoney; BitNodeMultipliers.CompanyWorkMoney;
this.gainRatesForTask.hack = this.gainRatesForTask.hack =
companyPosition.hackingExpGain * companyPosition.hackingExpGain *
company.expMultiplier * company.expMultiplier *
this.hacking_exp_mult * this.mults.hacking_exp *
BitNodeMultipliers.CompanyWorkExpGain; BitNodeMultipliers.CompanyWorkExpGain;
this.gainRatesForTask.str = this.gainRatesForTask.str =
companyPosition.strengthExpGain * companyPosition.strengthExpGain *
company.expMultiplier * company.expMultiplier *
this.strength_exp_mult * this.mults.strength_exp *
BitNodeMultipliers.CompanyWorkExpGain; BitNodeMultipliers.CompanyWorkExpGain;
this.gainRatesForTask.def = this.gainRatesForTask.def =
companyPosition.defenseExpGain * companyPosition.defenseExpGain *
company.expMultiplier * company.expMultiplier *
this.defense_exp_mult * this.mults.defense_exp *
BitNodeMultipliers.CompanyWorkExpGain; BitNodeMultipliers.CompanyWorkExpGain;
this.gainRatesForTask.dex = this.gainRatesForTask.dex =
companyPosition.dexterityExpGain * companyPosition.dexterityExpGain *
company.expMultiplier * company.expMultiplier *
this.dexterity_exp_mult * this.mults.dexterity_exp *
BitNodeMultipliers.CompanyWorkExpGain; BitNodeMultipliers.CompanyWorkExpGain;
this.gainRatesForTask.agi = this.gainRatesForTask.agi =
companyPosition.agilityExpGain * companyPosition.agilityExpGain *
company.expMultiplier * company.expMultiplier *
this.agility_exp_mult * this.mults.agility_exp *
BitNodeMultipliers.CompanyWorkExpGain; BitNodeMultipliers.CompanyWorkExpGain;
this.gainRatesForTask.cha = this.gainRatesForTask.cha =
companyPosition.charismaExpGain * companyPosition.charismaExpGain *
company.expMultiplier * company.expMultiplier *
this.charisma_exp_mult * this.mults.charisma_exp *
BitNodeMultipliers.CompanyWorkExpGain; BitNodeMultipliers.CompanyWorkExpGain;
this.currentTaskLocation = companyName; this.currentTaskLocation = companyName;
@ -970,28 +970,28 @@ export class Sleeve extends Person {
return false; return false;
} }
this.factionWorkType = FactionWorkType.HACKING; this.factionWorkType = FactionWorkType.HACKING;
this.gainRatesForTask.hack = 0.15 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain; this.gainRatesForTask.hack = 0.15 * this.mults.hacking_exp * BitNodeMultipliers.FactionWorkExpGain;
} else if (sanitizedWorkType.includes("field")) { } else if (sanitizedWorkType.includes("field")) {
if (!factionInfo.offerFieldWork) { if (!factionInfo.offerFieldWork) {
return false; return false;
} }
this.factionWorkType = FactionWorkType.FIELD; this.factionWorkType = FactionWorkType.FIELD;
this.gainRatesForTask.hack = 0.1 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain; this.gainRatesForTask.hack = 0.1 * this.mults.hacking_exp * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.str = 0.1 * this.strength_exp_mult * BitNodeMultipliers.FactionWorkExpGain; this.gainRatesForTask.str = 0.1 * this.mults.strength_exp * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.def = 0.1 * this.defense_exp_mult * BitNodeMultipliers.FactionWorkExpGain; this.gainRatesForTask.def = 0.1 * this.mults.defense_exp * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.dex = 0.1 * this.dexterity_exp_mult * BitNodeMultipliers.FactionWorkExpGain; this.gainRatesForTask.dex = 0.1 * this.mults.dexterity_exp * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.agi = 0.1 * this.agility_exp_mult * BitNodeMultipliers.FactionWorkExpGain; this.gainRatesForTask.agi = 0.1 * this.mults.agility_exp * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.cha = 0.1 * this.charisma_exp_mult * BitNodeMultipliers.FactionWorkExpGain; this.gainRatesForTask.cha = 0.1 * this.mults.charisma_exp * BitNodeMultipliers.FactionWorkExpGain;
} else if (sanitizedWorkType.includes("security")) { } else if (sanitizedWorkType.includes("security")) {
if (!factionInfo.offerSecurityWork) { if (!factionInfo.offerSecurityWork) {
return false; return false;
} }
this.factionWorkType = FactionWorkType.SECURITY; this.factionWorkType = FactionWorkType.SECURITY;
this.gainRatesForTask.hack = 0.1 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain; this.gainRatesForTask.hack = 0.1 * this.mults.hacking_exp * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.str = 0.15 * this.strength_exp_mult * BitNodeMultipliers.FactionWorkExpGain; this.gainRatesForTask.str = 0.15 * this.mults.strength_exp * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.def = 0.15 * this.defense_exp_mult * BitNodeMultipliers.FactionWorkExpGain; this.gainRatesForTask.def = 0.15 * this.mults.defense_exp * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.dex = 0.15 * this.dexterity_exp_mult * BitNodeMultipliers.FactionWorkExpGain; this.gainRatesForTask.dex = 0.15 * this.mults.dexterity_exp * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.agi = 0.15 * this.agility_exp_mult * BitNodeMultipliers.FactionWorkExpGain; this.gainRatesForTask.agi = 0.15 * this.mults.agility_exp * BitNodeMultipliers.FactionWorkExpGain;
} else { } else {
return false; return false;
} }
@ -1102,8 +1102,8 @@ export class Sleeve extends Person {
switch (action) { switch (action) {
case "Field analysis": case "Field analysis":
time = this.getBladeburnerActionTime(p, "General", action); time = this.getBladeburnerActionTime(p, "General", action);
this.gainRatesForTask.hack = 20 * this.hacking_exp_mult; this.gainRatesForTask.hack = 20 * this.mults.hacking_exp;
this.gainRatesForTask.cha = 20 * this.charisma_exp_mult; this.gainRatesForTask.cha = 20 * this.mults.charisma_exp;
break; break;
case "Recruitment": case "Recruitment":
time = this.getBladeburnerActionTime(p, "General", action); time = this.getBladeburnerActionTime(p, "General", action);

@ -54,32 +54,38 @@ export function MoreStatsModal(props: IProps): React.ReactElement {
<br /> <br />
<StatsTable <StatsTable
rows={[ rows={[
[<>Hacking Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.hacking_mult)], [<>Hacking Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.hacking)],
[<>Hacking Experience multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.hacking_exp_mult)], [<>Hacking Experience multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.hacking_exp)],
[<>Strength Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.strength_mult)], [<>Strength Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.strength)],
[<>Strength Experience multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.strength_exp_mult)], [
[<>Defense Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.defense_mult)], <>Strength Experience multiplier:&nbsp;</>,
[<>Defense Experience multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.defense_exp_mult)], numeralWrapper.formatPercentage(props.sleeve.mults.strength_exp),
[<>Dexterity Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.dexterity_mult)], ],
[<>Defense Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.defense)],
[<>Defense Experience multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.defense_exp)],
[<>Dexterity Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.dexterity)],
[ [
<>Dexterity Experience multiplier:&nbsp;</>, <>Dexterity Experience multiplier:&nbsp;</>,
numeralWrapper.formatPercentage(props.sleeve.dexterity_exp_mult), numeralWrapper.formatPercentage(props.sleeve.mults.dexterity_exp),
],
[<>Agility Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.agility)],
[<>Agility Experience multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.agility_exp)],
[<>Charisma Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.charisma)],
[
<>Charisma Experience multiplier:&nbsp;</>,
numeralWrapper.formatPercentage(props.sleeve.mults.charisma_exp),
], ],
[<>Agility Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.agility_mult)],
[<>Agility Experience multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.agility_exp_mult)],
[<>Charisma Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.charisma_mult)],
[<>Charisma Experience multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.charisma_exp_mult)],
[ [
<>Faction Reputation Gain multiplier:&nbsp;</>, <>Faction Reputation Gain multiplier:&nbsp;</>,
numeralWrapper.formatPercentage(props.sleeve.faction_rep_mult), numeralWrapper.formatPercentage(props.sleeve.mults.faction_rep),
], ],
[ [
<>Company Reputation Gain multiplier:&nbsp;</>, <>Company Reputation Gain multiplier:&nbsp;</>,
numeralWrapper.formatPercentage(props.sleeve.company_rep_mult), numeralWrapper.formatPercentage(props.sleeve.mults.company_rep),
], ],
[<>Salary multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.work_money_mult)], [<>Salary multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.work_money)],
[<>Crime Money multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.crime_money_mult)], [<>Crime Money multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.crime_money)],
[<>Crime Success multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.crime_success_mult)], [<>Crime Success multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.crime_success)],
]} ]}
title="Multipliers:" title="Multipliers:"
/> />

@ -15,7 +15,7 @@ function mult(f: Faction): number {
export function getHackingWorkRepGain(p: IPlayer, f: Faction): number { export function getHackingWorkRepGain(p: IPlayer, f: Faction): number {
return ( return (
((p.hacking + p.intelligence / 3) / CONSTANTS.MaxSkillLevel) * ((p.hacking + p.intelligence / 3) / CONSTANTS.MaxSkillLevel) *
p.faction_rep_mult * p.mults.faction_rep *
p.getIntelligenceBonus(1) * p.getIntelligenceBonus(1) *
mult(f) * mult(f) *
CalculateShareMult() CalculateShareMult()
@ -27,7 +27,7 @@ export function getFactionSecurityWorkRepGain(p: IPlayer, f: Faction): number {
(0.9 * (p.strength + p.defense + p.dexterity + p.agility + (p.hacking + p.intelligence) * CalculateShareMult())) / (0.9 * (p.strength + p.defense + p.dexterity + p.agility + (p.hacking + p.intelligence) * CalculateShareMult())) /
CONSTANTS.MaxSkillLevel / CONSTANTS.MaxSkillLevel /
4.5; 4.5;
return t * p.faction_rep_mult * mult(f) * p.getIntelligenceBonus(1); return t * p.mults.faction_rep * mult(f) * p.getIntelligenceBonus(1);
} }
export function getFactionFieldWorkRepGain(p: IPlayer, f: Faction): number { export function getFactionFieldWorkRepGain(p: IPlayer, f: Faction): number {
@ -41,5 +41,5 @@ export function getFactionFieldWorkRepGain(p: IPlayer, f: Faction): number {
(p.hacking + p.intelligence) * CalculateShareMult())) / (p.hacking + p.intelligence) * CalculateShareMult())) /
CONSTANTS.MaxSkillLevel / CONSTANTS.MaxSkillLevel /
5.5; 5.5;
return t * p.faction_rep_mult * mult(f) * p.getIntelligenceBonus(1); return t * p.mults.faction_rep * mult(f) * p.getIntelligenceBonus(1);
} }

@ -296,7 +296,7 @@ export function prestigeSourceFile(flume: boolean): void {
hserver.level = 100; hserver.level = 100;
hserver.cores = 10; hserver.cores = 10;
hserver.cache = 5; hserver.cache = 5;
hserver.updateHashRate(Player.hacknet_node_money_mult); hserver.updateHashRate(Player.mults.hacknet_node_money);
hserver.updateHashCapacity(); hserver.updateHashCapacity();
updateHashManagerCapacity(Player); updateHashManagerCapacity(Player);
} }

@ -16,51 +16,22 @@ interface Player {
agility: number; agility: number;
charisma: number; charisma: number;
intelligence: number; intelligence: number;
hacking_chance_mult: number;
hacking_speed_mult: number;
hacking_money_mult: number;
hacking_grow_mult: number;
hacking_exp: number; hacking_exp: number;
strength_exp: number; strength_exp: number;
defense_exp: number; defense_exp: number;
dexterity_exp: number; dexterity_exp: number;
agility_exp: number; agility_exp: number;
charisma_exp: number; charisma_exp: number;
hacking_mult: number; mults: Multipliers;
strength_mult: number;
defense_mult: number;
dexterity_mult: number;
agility_mult: number;
charisma_mult: number;
hacking_exp_mult: number;
strength_exp_mult: number;
defense_exp_mult: number;
dexterity_exp_mult: number;
agility_exp_mult: number;
charisma_exp_mult: number;
company_rep_mult: number;
faction_rep_mult: number;
numPeopleKilled: number; numPeopleKilled: number;
money: number; money: number;
city: string; city: string;
location: string; location: string;
companyName: string; companyName: string;
crime_money_mult: number;
crime_success_mult: number;
work_money_mult: number;
hacknet_node_money_mult: number;
hacknet_node_purchase_cost_mult: number;
hacknet_node_ram_cost_mult: number;
hacknet_node_core_cost_mult: number;
hacknet_node_level_cost_mult: number;
hasWseAccount: boolean; hasWseAccount: boolean;
hasTixApiAccess: boolean; hasTixApiAccess: boolean;
has4SData: boolean; has4SData: boolean;
has4SDataTixApi: boolean; has4SDataTixApi: boolean;
bladeburner_max_stamina_mult: number;
bladeburner_stamina_gain_mult: number;
bladeburner_analysis_mult: number;
bladeburner_success_chance_mult: number;
bitNodeN: number; bitNodeN: number;
totalPlaytime: number; totalPlaytime: number;
playtimeSinceLastAug: number; playtimeSinceLastAug: number;
@ -73,6 +44,42 @@ interface Player {
entropy: number; entropy: number;
} }
/**
* @public
*/
export interface Multipliers {
hacking_chance: number;
hacking_speed: number;
hacking_money: number;
hacking_grow: number;
hacking: number;
hacking_exp: number;
strength: number;
strength_exp: number;
defense: number;
defense_exp: number;
dexterity: number;
dexterity_exp: number;
agility: number;
agility_exp: number;
charisma: number;
charisma_exp: number;
hacknet_node_money: number;
hacknet_node_purchase_cost: number;
hacknet_node_ram_cost: number;
hacknet_node_core_cost: number;
hacknet_node_level_cost: number;
company_rep: number;
faction_rep: number;
work_money: number;
crime_success: number;
crime_money: number;
bladeburner_max_stamina: number;
bladeburner_stamina_gain: number;
bladeburner_analysis: number;
bladeburner_success_chance: number;
}
/** /**
* @public * @public
*/ */
@ -169,65 +176,65 @@ export interface CrimeStats {
*/ */
export interface AugmentationStats { export interface AugmentationStats {
/** Multiplier to hacking skill */ /** Multiplier to hacking skill */
hacking_mult?: number; hacking?: number;
/** Multiplier to strength skill */ /** Multiplier to strength skill */
strength_mult?: number; strength?: number;
/** Multiplier to defense skill */ /** Multiplier to defense skill */
defense_mult?: number; defense?: number;
/** Multiplier to dexterity skill */ /** Multiplier to dexterity skill */
dexterity_mult?: number; dexterity?: number;
/** Multiplier to agility skill */ /** Multiplier to agility skill */
agility_mult?: number; agility?: number;
/** Multiplier to charisma skill */ /** Multiplier to charisma skill */
charisma_mult?: number; charisma?: number;
/** Multiplier to hacking experience gain rate */ /** Multiplier to hacking experience gain rate */
hacking_exp_mult?: number; hacking_exp?: number;
/** Multiplier to strength experience gain rate */ /** Multiplier to strength experience gain rate */
strength_exp_mult?: number; strength_exp?: number;
/** Multiplier to defense experience gain rate */ /** Multiplier to defense experience gain rate */
defense_exp_mult?: number; defense_exp?: number;
/** Multiplier to dexterity experience gain rate */ /** Multiplier to dexterity experience gain rate */
dexterity_exp_mult?: number; dexterity_exp?: number;
/** Multiplier to agility experience gain rate */ /** Multiplier to agility experience gain rate */
agility_exp_mult?: number; agility_exp?: number;
/** Multiplier to charisma experience gain rate */ /** Multiplier to charisma experience gain rate */
charisma_exp_mult?: number; charisma_exp?: number;
/** Multiplier to chance of successfully performing a hack */ /** Multiplier to chance of successfully performing a hack */
hacking_chance_mult?: number; hacking_chance?: number;
/** Multiplier to hacking speed */ /** Multiplier to hacking speed */
hacking_speed_mult?: number; hacking_speed?: number;
/** Multiplier to amount of money the player gains from hacking */ /** Multiplier to amount of money the player gains from hacking */
hacking_money_mult?: number; hacking_money?: number;
/** Multiplier to amount of money injected into servers using grow */ /** Multiplier to amount of money injected into servers using grow */
hacking_grow_mult?: number; hacking_grow?: number;
/** Multiplier to amount of reputation gained when working */ /** Multiplier to amount of reputation gained when working */
company_rep_mult?: number; company_rep?: number;
/** Multiplier to amount of reputation gained when working */ /** Multiplier to amount of reputation gained when working */
faction_rep_mult?: number; faction_rep?: number;
/** Multiplier to amount of money gained from crimes */ /** Multiplier to amount of money gained from crimes */
crime_money_mult?: number; crime_money?: number;
/** Multiplier to crime success rate */ /** Multiplier to crime success rate */
crime_success_mult?: number; crime_success?: number;
/** Multiplier to amount of money gained from working */ /** Multiplier to amount of money gained from working */
work_money_mult?: number; work_money?: number;
/** Multiplier to amount of money produced by Hacknet Nodes */ /** Multiplier to amount of money produced by Hacknet Nodes */
hacknet_node_money_mult?: number; hacknet_node_money?: number;
/** Multiplier to cost of purchasing a Hacknet Node */ /** Multiplier to cost of purchasing a Hacknet Node */
hacknet_node_purchase_cost_mult?: number; hacknet_node_purchase_cost?: number;
/** Multiplier to cost of ram for a Hacknet Node */ /** Multiplier to cost of ram for a Hacknet Node */
hacknet_node_ram_cost_mult?: number; hacknet_node_ram_cost?: number;
/** Multiplier to cost of core for a Hacknet Node */ /** Multiplier to cost of core for a Hacknet Node */
hacknet_node_core_cost_mult?: number; hacknet_node_core_cost?: number;
/** Multiplier to cost of leveling up a Hacknet Node */ /** Multiplier to cost of leveling up a Hacknet Node */
hacknet_node_level_cost_mult?: number; hacknet_node_level_cost?: number;
/** Multiplier to Bladeburner max stamina */ /** Multiplier to Bladeburner max stamina */
bladeburner_max_stamina_mult?: number; bladeburner_max_stamina?: number;
/** Multiplier to Bladeburner stamina gain rate */ /** Multiplier to Bladeburner stamina gain rate */
bladeburner_stamina_gain_mult?: number; bladeburner_stamina_gain?: number;
/** Multiplier to effectiveness in Bladeburner Field Analysis */ /** Multiplier to effectiveness in Bladeburner Field Analysis */
bladeburner_analysis_mult?: number; bladeburner_analysis?: number;
/** Multiplier to success chance in Bladeburner contracts/operations */ /** Multiplier to success chance in Bladeburner contracts/operations */
bladeburner_success_chance_mult?: number; bladeburner_success_chance?: number;
} }
/** /**

@ -58,7 +58,7 @@ export function numCycleForGrowth(server: Server, growth: number, p: IPlayer, co
const cycles = const cycles =
Math.log(growth) / Math.log(growth) /
(Math.log(ajdGrowthRate) * (Math.log(ajdGrowthRate) *
p.hacking_grow_mult * p.mults.hacking_grow *
serverGrowthPercentage * serverGrowthPercentage *
BitNodeMultipliers.ServerGrowthRate * BitNodeMultipliers.ServerGrowthRate *
coreBonus); coreBonus);
@ -130,7 +130,7 @@ export function numCycleForGrowthCorrected(
const serverGrowthPercentage = server.serverGrowth / 100.0; const serverGrowthPercentage = server.serverGrowth / 100.0;
const coreMultiplier = 1 + (cores - 1) / 16; const coreMultiplier = 1 + (cores - 1) / 16;
const threadMultiplier = const threadMultiplier =
serverGrowthPercentage * p.hacking_grow_mult * coreMultiplier * BitNodeMultipliers.ServerGrowthRate; serverGrowthPercentage * p.mults.hacking_grow * coreMultiplier * BitNodeMultipliers.ServerGrowthRate;
/* To understand what is done below we need to do some math. I hope the explanation is clear enough. /* To understand what is done below we need to do some math. I hope the explanation is clear enough.
* First of, the names will be shortened for ease of manipulation: * First of, the names will be shortened for ease of manipulation:

@ -20,5 +20,5 @@ export function calculateServerGrowth(server: Server, threads: number, p: IPlaye
//Apply serverGrowth for the calculated number of growth cycles //Apply serverGrowth for the calculated number of growth cycles
const coreBonus = 1 + (cores - 1) / 16; const coreBonus = 1 + (cores - 1) / 16;
return Math.pow(adjGrowthRate, numServerGrowthCyclesAdjusted * p.hacking_grow_mult * coreBonus); return Math.pow(adjGrowthRate, numServerGrowthCyclesAdjusted * p.mults.hacking_grow * coreBonus);
} }

@ -20,32 +20,32 @@ export function applySourceFile(srcFile: PlayerOwnedSourceFile): void {
} }
const incMult = 1 + mult / 100; const incMult = 1 + mult / 100;
const decMult = 1 - mult / 100; const decMult = 1 - mult / 100;
Player.hacking_chance_mult *= incMult; Player.mults.hacking_chance *= incMult;
Player.hacking_speed_mult *= incMult; Player.mults.hacking_speed *= incMult;
Player.hacking_money_mult *= incMult; Player.mults.hacking_money *= incMult;
Player.hacking_grow_mult *= incMult; Player.mults.hacking_grow *= incMult;
Player.hacking_mult *= incMult; Player.mults.hacking *= incMult;
Player.strength_mult *= incMult; Player.mults.strength *= incMult;
Player.defense_mult *= incMult; Player.mults.defense *= incMult;
Player.dexterity_mult *= incMult; Player.mults.dexterity *= incMult;
Player.agility_mult *= incMult; Player.mults.agility *= incMult;
Player.charisma_mult *= incMult; Player.mults.charisma *= incMult;
Player.hacking_exp_mult *= incMult; Player.mults.hacking_exp *= incMult;
Player.strength_exp_mult *= incMult; Player.mults.strength_exp *= incMult;
Player.defense_exp_mult *= incMult; Player.mults.defense_exp *= incMult;
Player.dexterity_exp_mult *= incMult; Player.mults.dexterity_exp *= incMult;
Player.agility_exp_mult *= incMult; Player.mults.agility_exp *= incMult;
Player.charisma_exp_mult *= incMult; Player.mults.charisma_exp *= incMult;
Player.company_rep_mult *= incMult; Player.mults.company_rep *= incMult;
Player.faction_rep_mult *= incMult; Player.mults.faction_rep *= incMult;
Player.crime_money_mult *= incMult; Player.mults.crime_money *= incMult;
Player.crime_success_mult *= incMult; Player.mults.crime_success *= incMult;
Player.hacknet_node_money_mult *= incMult; Player.mults.hacknet_node_money *= incMult;
Player.hacknet_node_purchase_cost_mult *= decMult; Player.mults.hacknet_node_purchase_cost *= decMult;
Player.hacknet_node_ram_cost_mult *= decMult; Player.mults.hacknet_node_ram_cost *= decMult;
Player.hacknet_node_core_cost_mult *= decMult; Player.mults.hacknet_node_core_cost *= decMult;
Player.hacknet_node_level_cost_mult *= decMult; Player.mults.hacknet_node_level_cost *= decMult;
Player.work_money_mult *= incMult; Player.mults.work_money *= incMult;
break; break;
} }
case 2: { case 2: {
@ -55,9 +55,9 @@ export function applySourceFile(srcFile: PlayerOwnedSourceFile): void {
mult += 24 / Math.pow(2, i); mult += 24 / Math.pow(2, i);
} }
const incMult = 1 + mult / 100; const incMult = 1 + mult / 100;
Player.crime_money_mult *= incMult; Player.mults.crime_money *= incMult;
Player.crime_success_mult *= incMult; Player.mults.crime_success *= incMult;
Player.charisma_mult *= incMult; Player.mults.charisma *= incMult;
break; break;
} }
case 3: { case 3: {
@ -67,8 +67,8 @@ export function applySourceFile(srcFile: PlayerOwnedSourceFile): void {
mult += 8 / Math.pow(2, i); mult += 8 / Math.pow(2, i);
} }
const incMult = 1 + mult / 100; const incMult = 1 + mult / 100;
Player.charisma_mult *= incMult; Player.mults.charisma *= incMult;
Player.work_money_mult *= incMult; Player.mults.work_money *= incMult;
break; break;
} }
case 4: { case 4: {
@ -83,12 +83,12 @@ export function applySourceFile(srcFile: PlayerOwnedSourceFile): void {
mult += 8 / Math.pow(2, i); mult += 8 / Math.pow(2, i);
} }
const incMult = 1 + mult / 100; const incMult = 1 + mult / 100;
Player.hacking_chance_mult *= incMult; Player.mults.hacking_chance *= incMult;
Player.hacking_speed_mult *= incMult; Player.mults.hacking_speed *= incMult;
Player.hacking_money_mult *= incMult; Player.mults.hacking_money *= incMult;
Player.hacking_grow_mult *= incMult; Player.mults.hacking_grow *= incMult;
Player.hacking_mult *= incMult; Player.mults.hacking *= incMult;
Player.hacking_exp_mult *= incMult; Player.mults.hacking_exp *= incMult;
break; break;
} }
case 6: { case 6: {
@ -98,14 +98,14 @@ export function applySourceFile(srcFile: PlayerOwnedSourceFile): void {
mult += 8 / Math.pow(2, i); mult += 8 / Math.pow(2, i);
} }
const incMult = 1 + mult / 100; const incMult = 1 + mult / 100;
Player.strength_exp_mult *= incMult; Player.mults.strength_exp *= incMult;
Player.defense_exp_mult *= incMult; Player.mults.defense_exp *= incMult;
Player.dexterity_exp_mult *= incMult; Player.mults.dexterity_exp *= incMult;
Player.agility_exp_mult *= incMult; Player.mults.agility_exp *= incMult;
Player.strength_mult *= incMult; Player.mults.strength *= incMult;
Player.defense_mult *= incMult; Player.mults.defense *= incMult;
Player.dexterity_mult *= incMult; Player.mults.dexterity *= incMult;
Player.agility_mult *= incMult; Player.mults.agility *= incMult;
break; break;
} }
case 7: { case 7: {
@ -115,10 +115,10 @@ export function applySourceFile(srcFile: PlayerOwnedSourceFile): void {
mult += 8 / Math.pow(2, i); mult += 8 / Math.pow(2, i);
} }
const incMult = 1 + mult / 100; const incMult = 1 + mult / 100;
Player.bladeburner_max_stamina_mult *= incMult; Player.mults.bladeburner_max_stamina *= incMult;
Player.bladeburner_stamina_gain_mult *= incMult; Player.mults.bladeburner_stamina_gain *= incMult;
Player.bladeburner_analysis_mult *= incMult; Player.mults.bladeburner_analysis *= incMult;
Player.bladeburner_success_chance_mult *= incMult; Player.mults.bladeburner_success_chance *= incMult;
break; break;
} }
case 8: { case 8: {
@ -128,7 +128,7 @@ export function applySourceFile(srcFile: PlayerOwnedSourceFile): void {
mult += 12 / Math.pow(2, i); mult += 12 / Math.pow(2, i);
} }
const incMult = 1 + mult / 100; const incMult = 1 + mult / 100;
Player.hacking_grow_mult *= incMult; Player.mults.hacking_grow *= incMult;
break; break;
} }
case 9: { case 9: {
@ -139,11 +139,11 @@ export function applySourceFile(srcFile: PlayerOwnedSourceFile): void {
} }
const incMult = 1 + mult / 100; const incMult = 1 + mult / 100;
const decMult = 1 - mult / 100; const decMult = 1 - mult / 100;
Player.hacknet_node_core_cost_mult *= decMult; Player.mults.hacknet_node_core_cost *= decMult;
Player.hacknet_node_level_cost_mult *= decMult; Player.mults.hacknet_node_level_cost *= decMult;
Player.hacknet_node_money_mult *= incMult; Player.mults.hacknet_node_money *= incMult;
Player.hacknet_node_purchase_cost_mult *= decMult; Player.mults.hacknet_node_purchase_cost *= decMult;
Player.hacknet_node_ram_cost_mult *= decMult; Player.mults.hacknet_node_ram_cost *= decMult;
break; break;
} }
case 10: { case 10: {
@ -158,8 +158,8 @@ export function applySourceFile(srcFile: PlayerOwnedSourceFile): void {
mult += 32 / Math.pow(2, i); mult += 32 / Math.pow(2, i);
} }
const incMult = 1 + mult / 100; const incMult = 1 + mult / 100;
Player.work_money_mult *= incMult; Player.mults.work_money *= incMult;
Player.company_rep_mult *= incMult; Player.mults.company_rep *= incMult;
break; break;
} }
case 12: // The Recursion case 12: // The Recursion

@ -36,12 +36,12 @@ export function calculateClassEarnings(player: IPlayer, work: ClassWork): WorkSt
return { return {
money: cost, money: cost,
reputation: 0, reputation: 0,
hackExp: hackExp * player.hacking_exp_mult * BitNodeMultipliers.ClassGymExpGain, hackExp: hackExp * player.mults.hacking_exp * BitNodeMultipliers.ClassGymExpGain,
strExp: strExp * player.strength_exp_mult * BitNodeMultipliers.ClassGymExpGain, strExp: strExp * player.mults.strength_exp * BitNodeMultipliers.ClassGymExpGain,
defExp: defExp * player.defense_exp_mult * BitNodeMultipliers.ClassGymExpGain, defExp: defExp * player.mults.defense_exp * BitNodeMultipliers.ClassGymExpGain,
dexExp: dexExp * player.dexterity_exp_mult * BitNodeMultipliers.ClassGymExpGain, dexExp: dexExp * player.mults.dexterity_exp * BitNodeMultipliers.ClassGymExpGain,
agiExp: agiExp * player.agility_exp_mult * BitNodeMultipliers.ClassGymExpGain, agiExp: agiExp * player.mults.agility_exp * BitNodeMultipliers.ClassGymExpGain,
chaExp: chaExp * player.charisma_exp_mult * BitNodeMultipliers.ClassGymExpGain, chaExp: chaExp * player.mults.charisma_exp * BitNodeMultipliers.ClassGymExpGain,
intExp: 0, intExp: 0,
}; };
} }

@ -42,45 +42,45 @@ export const calculateCompanyWorkStats = (player: IPlayer, company: Company): Wo
focusBonus * focusBonus *
companyPosition.baseSalary * companyPosition.baseSalary *
company.salaryMultiplier * company.salaryMultiplier *
player.work_money_mult * player.mults.work_money *
BitNodeMultipliers.CompanyWorkMoney * BitNodeMultipliers.CompanyWorkMoney *
bn11Mult, bn11Mult,
reputation: focusBonus * jobPerformance * player.company_rep_mult * favorMult, reputation: focusBonus * jobPerformance * player.mults.company_rep * favorMult,
hackExp: hackExp:
focusBonus * focusBonus *
companyPosition.hackingExpGain * companyPosition.hackingExpGain *
company.expMultiplier * company.expMultiplier *
player.hacking_exp_mult * player.mults.hacking_exp *
BitNodeMultipliers.CompanyWorkExpGain, BitNodeMultipliers.CompanyWorkExpGain,
strExp: strExp:
focusBonus * focusBonus *
companyPosition.strengthExpGain * companyPosition.strengthExpGain *
company.expMultiplier * company.expMultiplier *
player.strength_exp_mult * player.mults.strength_exp *
BitNodeMultipliers.CompanyWorkExpGain, BitNodeMultipliers.CompanyWorkExpGain,
defExp: defExp:
focusBonus * focusBonus *
companyPosition.defenseExpGain * companyPosition.defenseExpGain *
company.expMultiplier * company.expMultiplier *
player.defense_exp_mult * player.mults.defense_exp *
BitNodeMultipliers.CompanyWorkExpGain, BitNodeMultipliers.CompanyWorkExpGain,
dexExp: dexExp:
focusBonus * focusBonus *
companyPosition.dexterityExpGain * companyPosition.dexterityExpGain *
company.expMultiplier * company.expMultiplier *
player.dexterity_exp_mult * player.mults.dexterity_exp *
BitNodeMultipliers.CompanyWorkExpGain, BitNodeMultipliers.CompanyWorkExpGain,
agiExp: agiExp:
focusBonus * focusBonus *
companyPosition.agilityExpGain * companyPosition.agilityExpGain *
company.expMultiplier * company.expMultiplier *
player.agility_exp_mult * player.mults.agility_exp *
BitNodeMultipliers.CompanyWorkExpGain, BitNodeMultipliers.CompanyWorkExpGain,
chaExp: chaExp:
focusBonus * focusBonus *
companyPosition.charismaExpGain * companyPosition.charismaExpGain *
company.expMultiplier * company.expMultiplier *
player.charisma_exp_mult * player.mults.charisma_exp *
BitNodeMultipliers.CompanyWorkExpGain, BitNodeMultipliers.CompanyWorkExpGain,
intExp: 0, intExp: 0,
}; };

@ -36,17 +36,17 @@ export function calculateFactionExp(player: IPlayer, tpe: FactionWorkType): Work
money: 0, money: 0,
reputation: 0, reputation: 0,
hackExp: hackExp:
(focusBonus * (baseStats.hackExp * player.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain)) / gameCPS, (focusBonus * (baseStats.hackExp * player.mults.hacking_exp * BitNodeMultipliers.FactionWorkExpGain)) / gameCPS,
strExp: strExp:
(focusBonus * (baseStats.strExp * player.strength_exp_mult * BitNodeMultipliers.FactionWorkExpGain)) / gameCPS, (focusBonus * (baseStats.strExp * player.mults.strength_exp * BitNodeMultipliers.FactionWorkExpGain)) / gameCPS,
defExp: defExp:
(focusBonus * (baseStats.defExp * player.defense_exp_mult * BitNodeMultipliers.FactionWorkExpGain)) / gameCPS, (focusBonus * (baseStats.defExp * player.mults.defense_exp * BitNodeMultipliers.FactionWorkExpGain)) / gameCPS,
dexExp: dexExp:
(focusBonus * (baseStats.dexExp * player.dexterity_exp_mult * BitNodeMultipliers.FactionWorkExpGain)) / gameCPS, (focusBonus * (baseStats.dexExp * player.mults.dexterity_exp * BitNodeMultipliers.FactionWorkExpGain)) / gameCPS,
agiExp: agiExp:
(focusBonus * (baseStats.agiExp * player.agility_exp_mult * BitNodeMultipliers.FactionWorkExpGain)) / gameCPS, (focusBonus * (baseStats.agiExp * player.mults.agility_exp * BitNodeMultipliers.FactionWorkExpGain)) / gameCPS,
chaExp: chaExp:
(focusBonus * (baseStats.chaExp * player.charisma_exp_mult * BitNodeMultipliers.FactionWorkExpGain)) / gameCPS, (focusBonus * (baseStats.chaExp * player.mults.charisma_exp * BitNodeMultipliers.FactionWorkExpGain)) / gameCPS,
intExp: 0, intExp: 0,
}; };
} }

@ -377,21 +377,21 @@ export function CharacterStats(): React.ReactElement {
rows={[ rows={[
{ {
mult: "Hacking Chance", mult: "Hacking Chance",
value: player.hacking_chance_mult, value: player.mults.hacking_chance,
}, },
{ {
mult: "Hacking Speed", mult: "Hacking Speed",
value: player.hacking_speed_mult, value: player.mults.hacking_speed,
}, },
{ {
mult: "Hacking Money", mult: "Hacking Money",
value: player.hacking_money_mult, value: player.mults.hacking_money,
effValue: player.hacking_money_mult * BitNodeMultipliers.ScriptHackMoney, effValue: player.mults.hacking_money * BitNodeMultipliers.ScriptHackMoney,
}, },
{ {
mult: "Hacking Growth", mult: "Hacking Growth",
value: player.hacking_grow_mult, value: player.mults.hacking_grow,
effValue: player.hacking_grow_mult * BitNodeMultipliers.ServerGrowthRate, effValue: player.mults.hacking_grow * BitNodeMultipliers.ServerGrowthRate,
}, },
]} ]}
color={Settings.theme.hack} color={Settings.theme.hack}
@ -400,13 +400,13 @@ export function CharacterStats(): React.ReactElement {
rows={[ rows={[
{ {
mult: "Hacking Level", mult: "Hacking Level",
value: player.hacking_mult, value: player.mults.hacking,
effValue: player.hacking_mult * BitNodeMultipliers.HackingLevelMultiplier, effValue: player.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier,
}, },
{ {
mult: "Hacking Experience", mult: "Hacking Experience",
value: player.hacking_exp_mult, value: player.mults.hacking_exp,
effValue: player.hacking_exp_mult * BitNodeMultipliers.HackExpGain, effValue: player.mults.hacking_exp * BitNodeMultipliers.HackExpGain,
}, },
]} ]}
color={Settings.theme.hack} color={Settings.theme.hack}
@ -415,12 +415,12 @@ export function CharacterStats(): React.ReactElement {
rows={[ rows={[
{ {
mult: "Strength Level", mult: "Strength Level",
value: player.strength_mult, value: player.mults.strength,
effValue: player.strength_mult * BitNodeMultipliers.StrengthLevelMultiplier, effValue: player.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier,
}, },
{ {
mult: "Strength Experience", mult: "Strength Experience",
value: player.strength_exp_mult, value: player.mults.strength_exp,
}, },
]} ]}
color={Settings.theme.combat} color={Settings.theme.combat}
@ -429,12 +429,12 @@ export function CharacterStats(): React.ReactElement {
rows={[ rows={[
{ {
mult: "Defense Level", mult: "Defense Level",
value: player.defense_mult, value: player.mults.defense,
effValue: player.defense_mult * BitNodeMultipliers.DefenseLevelMultiplier, effValue: player.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier,
}, },
{ {
mult: "Defense Experience", mult: "Defense Experience",
value: player.defense_exp_mult, value: player.mults.defense_exp,
}, },
]} ]}
color={Settings.theme.combat} color={Settings.theme.combat}
@ -443,12 +443,12 @@ export function CharacterStats(): React.ReactElement {
rows={[ rows={[
{ {
mult: "Dexterity Level", mult: "Dexterity Level",
value: player.dexterity_mult, value: player.mults.dexterity,
effValue: player.dexterity_mult * BitNodeMultipliers.DexterityLevelMultiplier, effValue: player.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier,
}, },
{ {
mult: "Dexterity Experience", mult: "Dexterity Experience",
value: player.dexterity_exp_mult, value: player.mults.dexterity_exp,
}, },
]} ]}
color={Settings.theme.combat} color={Settings.theme.combat}
@ -457,12 +457,12 @@ export function CharacterStats(): React.ReactElement {
rows={[ rows={[
{ {
mult: "Agility Level", mult: "Agility Level",
value: player.agility_mult, value: player.mults.agility,
effValue: player.agility_mult * BitNodeMultipliers.AgilityLevelMultiplier, effValue: player.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier,
}, },
{ {
mult: "Agility Experience", mult: "Agility Experience",
value: player.agility_exp_mult, value: player.mults.agility_exp,
}, },
]} ]}
color={Settings.theme.combat} color={Settings.theme.combat}
@ -471,12 +471,12 @@ export function CharacterStats(): React.ReactElement {
rows={[ rows={[
{ {
mult: "Charisma Level", mult: "Charisma Level",
value: player.charisma_mult, value: player.mults.charisma,
effValue: player.charisma_mult * BitNodeMultipliers.CharismaLevelMultiplier, effValue: player.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier,
}, },
{ {
mult: "Charisma Experience", mult: "Charisma Experience",
value: player.charisma_exp_mult, value: player.mults.charisma_exp,
}, },
]} ]}
color={Settings.theme.cha} color={Settings.theme.cha}
@ -489,24 +489,24 @@ export function CharacterStats(): React.ReactElement {
rows={[ rows={[
{ {
mult: "Hacknet Node Production", mult: "Hacknet Node Production",
value: player.hacknet_node_money_mult, value: player.mults.hacknet_node_money,
effValue: player.hacknet_node_money_mult * BitNodeMultipliers.HacknetNodeMoney, effValue: player.mults.hacknet_node_money * BitNodeMultipliers.HacknetNodeMoney,
}, },
{ {
mult: "Hacknet Node Purchase Cost", mult: "Hacknet Node Purchase Cost",
value: player.hacknet_node_purchase_cost_mult, value: player.mults.hacknet_node_purchase_cost,
}, },
{ {
mult: "Hacknet Node RAM Upgrade Cost", mult: "Hacknet Node RAM Upgrade Cost",
value: player.hacknet_node_ram_cost_mult, value: player.mults.hacknet_node_ram_cost,
}, },
{ {
mult: "Hacknet Node Core Purchase Cost", mult: "Hacknet Node Core Purchase Cost",
value: player.hacknet_node_core_cost_mult, value: player.mults.hacknet_node_core_cost,
}, },
{ {
mult: "Hacknet Node Level Upgrade Cost", mult: "Hacknet Node Level Upgrade Cost",
value: player.hacknet_node_level_cost_mult, value: player.mults.hacknet_node_level_cost,
}, },
]} ]}
color={Settings.theme.primary} color={Settings.theme.primary}
@ -515,19 +515,19 @@ export function CharacterStats(): React.ReactElement {
rows={[ rows={[
{ {
mult: "Company Reputation Gain", mult: "Company Reputation Gain",
value: player.company_rep_mult, value: player.mults.company_rep,
color: Settings.theme.rep, color: Settings.theme.rep,
}, },
{ {
mult: "Faction Reputation Gain", mult: "Faction Reputation Gain",
value: player.faction_rep_mult, value: player.mults.faction_rep,
effValue: player.faction_rep_mult * BitNodeMultipliers.FactionWorkRepGain, effValue: player.mults.faction_rep * BitNodeMultipliers.FactionWorkRepGain,
color: Settings.theme.rep, color: Settings.theme.rep,
}, },
{ {
mult: "Salary", mult: "Salary",
value: player.work_money_mult, value: player.mults.work_money,
effValue: player.work_money_mult * BitNodeMultipliers.CompanyWorkMoney, effValue: player.mults.work_money * BitNodeMultipliers.CompanyWorkMoney,
color: Settings.theme.money, color: Settings.theme.money,
}, },
]} ]}
@ -537,12 +537,12 @@ export function CharacterStats(): React.ReactElement {
rows={[ rows={[
{ {
mult: "Crime Success Chance", mult: "Crime Success Chance",
value: player.crime_success_mult, value: player.mults.crime_success,
}, },
{ {
mult: "Crime Money", mult: "Crime Money",
value: player.crime_money_mult, value: player.mults.crime_money,
effValue: player.crime_money_mult * BitNodeMultipliers.CrimeMoney, effValue: player.mults.crime_money * BitNodeMultipliers.CrimeMoney,
color: Settings.theme.money, color: Settings.theme.money,
}, },
]} ]}
@ -553,19 +553,19 @@ export function CharacterStats(): React.ReactElement {
rows={[ rows={[
{ {
mult: "Bladeburner Success Chance", mult: "Bladeburner Success Chance",
value: player.bladeburner_success_chance_mult, value: player.mults.bladeburner_success_chance,
}, },
{ {
mult: "Bladeburner Max Stamina", mult: "Bladeburner Max Stamina",
value: player.bladeburner_max_stamina_mult, value: player.mults.bladeburner_max_stamina,
}, },
{ {
mult: "Bladeburner Stamina Gain", mult: "Bladeburner Stamina Gain",
value: player.bladeburner_stamina_gain_mult, value: player.mults.bladeburner_stamina_gain,
}, },
{ {
mult: "Bladeburner Field Analysis", mult: "Bladeburner Field Analysis",
value: player.bladeburner_analysis_mult, value: player.mults.bladeburner_analysis,
}, },
]} ]}
color={Settings.theme.primary} color={Settings.theme.primary}

@ -293,27 +293,27 @@ export function CharacterOverview({ save, killScripts }: IProps): React.ReactEle
const hackingProgress = player.calculateSkillProgress( const hackingProgress = player.calculateSkillProgress(
player.hacking_exp, player.hacking_exp,
player.hacking_mult * BitNodeMultipliers.HackingLevelMultiplier, player.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier,
); );
const strengthProgress = player.calculateSkillProgress( const strengthProgress = player.calculateSkillProgress(
player.strength_exp, player.strength_exp,
player.strength_mult * BitNodeMultipliers.StrengthLevelMultiplier, player.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier,
); );
const defenseProgress = player.calculateSkillProgress( const defenseProgress = player.calculateSkillProgress(
player.defense_exp, player.defense_exp,
player.defense_mult * BitNodeMultipliers.DefenseLevelMultiplier, player.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier,
); );
const dexterityProgress = player.calculateSkillProgress( const dexterityProgress = player.calculateSkillProgress(
player.dexterity_exp, player.dexterity_exp,
player.dexterity_mult * BitNodeMultipliers.DexterityLevelMultiplier, player.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier,
); );
const agilityProgress = player.calculateSkillProgress( const agilityProgress = player.calculateSkillProgress(
player.agility_exp, player.agility_exp,
player.agility_mult * BitNodeMultipliers.AgilityLevelMultiplier, player.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier,
); );
const charismaProgress = player.calculateSkillProgress( const charismaProgress = player.calculateSkillProgress(
player.charisma_exp, player.charisma_exp,
player.charisma_mult * BitNodeMultipliers.CharismaLevelMultiplier, player.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier,
); );
return ( return (