diff --git a/src/Achievements/Achievements.ts b/src/Achievements/Achievements.ts index 01caa65da..7d21e352f 100644 --- a/src/Achievements/Achievements.ts +++ b/src/Achievements/Achievements.ts @@ -28,7 +28,7 @@ import { Router } from "../ui/GameRoot"; import { Page } from "../ui/Router"; import data from "./AchievementData.json"; import { isClassWork } from "../Work/ClassWork"; -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; import { workerScripts } from "../Netscript/WorkerScripts"; import { getRecordValues } from "../Types/Record"; @@ -384,7 +384,7 @@ export const achievements: Record = { Icon: "donation", Condition: () => Object.values(Factions).some( - (f) => f.favor >= Math.floor(CONSTANTS.BaseFavorToDonate * BitNodeMultipliers.RepToDonateToFaction), + (f) => f.favor >= Math.floor(CONSTANTS.BaseFavorToDonate * currentNodeMults.RepToDonateToFaction), ), }, TRAVEL: { diff --git a/src/Augmentation/Augmentation.tsx b/src/Augmentation/Augmentation.tsx index 2e05332ef..3fd899145 100644 --- a/src/Augmentation/Augmentation.tsx +++ b/src/Augmentation/Augmentation.tsx @@ -1,35 +1,24 @@ // Class definition for a single Augmentation object -import * as React from "react"; - -import { AugmentationName, CompletedProgramName, FactionName } from "@enums"; -import { Faction } from "../Faction/Faction"; -import { Factions } from "../Faction/Factions"; -import { formatPercent } from "../ui/formatNumber"; -import { Money } from "../ui/React/Money"; - -import { Generic_fromJSON, Generic_toJSON, IReviverValue, constructorsForReviver } from "../utils/JSONReviver"; import { Player } from "@player"; -import { CONSTANTS } from "../Constants"; -import { StaticAugmentations } from "./StaticAugmentations"; -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; -import { getBaseAugmentationPriceMultiplier, getGenericAugmentationPriceMultiplier } from "./AugmentationHelpers"; -import { initSoAAugmentations } from "./data/AugmentationCreator"; +import { AugmentationName, CompletedProgramName, FactionName } from "@enums"; +import { formatPercent } from "../ui/formatNumber"; import { Multipliers, defaultMultipliers } from "../PersonObjects/Multipliers"; +import { getRecordKeys } from "../Types/Record"; export interface AugmentationCosts { moneyCost: number; repCost: number; } -export interface IConstructorParams { - info: string | JSX.Element; - stats?: JSX.Element | null; +export interface AugmentationCtorParams { + info: string; + stats?: string; isSpecial?: boolean; moneyCost: number; - name: string; - prereqs?: string[]; + name: AugmentationName; + prereqs?: AugmentationName[]; repCost: number; - factions: string[]; + factions: FactionName[]; hacking?: number; strength?: number; @@ -66,85 +55,42 @@ export interface IConstructorParams { programs?: CompletedProgramName[]; } -function generateStatsDescription(mults: Multipliers, programs?: string[], startingMoney?: number): JSX.Element { +function generateStatsDescription(mults: Multipliers, programs?: string[], startingMoney?: number): string { // For a percentage that is <10, show x.xx%, otherwise show xx.x% const f = (x: number) => formatPercent(x, x - 1 < 0.1 ? 2 : 1); - let desc = <>Effects:; + let desc = "Effects:"; + // Skills if ( mults.hacking !== 1 && - mults.hacking == mults.strength && - mults.hacking == mults.defense && - mults.hacking == mults.dexterity && - mults.hacking == mults.agility && - mults.hacking == mults.charisma + mults.hacking === mults.strength && + mults.hacking === mults.defense && + mults.hacking === mults.dexterity && + mults.hacking === mults.agility && + mults.hacking === mults.charisma ) { - desc = ( - <> - {desc} -
+{f(mults.hacking - 1)} all skills - - ); + desc += `\n+${f(mults.hacking - 1)} all skills`; } else { - if (mults.hacking !== 1) - desc = ( - <> - {desc} -
+{f(mults.hacking - 1)} hacking skill - - ); - + // Not allskills + if (mults.hacking !== 1) desc += `\n+${f(mults.hacking - 1)} hacking skill`; if ( mults.strength !== 1 && - mults.strength == mults.defense && - mults.strength == mults.dexterity && - mults.strength == mults.agility + mults.strength === mults.defense && + mults.strength === mults.dexterity && + mults.strength === mults.agility ) { - desc = ( - <> - {desc} -
+{f(mults.strength - 1)} combat skills - - ); + desc += `\n+${f(mults.strength - 1)} combat skills`; } else { - if (mults.strength !== 1) - desc = ( - <> - {desc} -
+{f(mults.strength - 1)} strength skill - - ); - if (mults.defense !== 1) - desc = ( - <> - {desc} -
+{f(mults.defense - 1)} defense skill - - ); - if (mults.dexterity !== 1) - desc = ( - <> - {desc} -
+{f(mults.dexterity - 1)} dexterity skill - - ); - if (mults.agility !== 1) - desc = ( - <> - {desc} -
+{f(mults.agility - 1)} agility skill - - ); + // Not all combat + if (mults.strength !== 1) desc += `\n+${f(mults.strength - 1)} strength skill`; + if (mults.defense !== 1) desc += `\n+${f(mults.defense - 1)} defense skill`; + if (mults.dexterity !== 1) desc += `\n+${f(mults.dexterity - 1)} dexterity skill`; + if (mults.agility !== 1) desc += `\n+${f(mults.agility - 1)} agility skill`; } - if (mults.charisma !== 1) - desc = ( - <> - {desc} -
+{f(mults.charisma - 1)} charisma skill - - ); + if (mults.charisma !== 1) desc += `\n+${f(mults.charisma - 1)} charisma skill`; } + // Skill XP if ( mults.hacking_exp !== 1 && mults.hacking_exp === mults.strength_exp && @@ -153,214 +99,66 @@ function generateStatsDescription(mults: Multipliers, programs?: string[], start mults.hacking_exp === mults.agility_exp && mults.hacking_exp === mults.charisma_exp ) { - desc = ( - <> - {desc} -
+{f(mults.hacking_exp - 1)} exp for all skills - - ); + desc += `\n+${f(mults.hacking_exp - 1)} exp for all skills`; } else { - if (mults.hacking_exp !== 1) - desc = ( - <> - {desc} -
+{f(mults.hacking_exp - 1)} hacking exp - - ); - + // Not allskillxp + if (mults.hacking_exp !== 1) desc += `\n+${f(mults.hacking_exp - 1)} hacking exp`; if ( mults.strength_exp !== 1 && mults.strength_exp === mults.defense_exp && mults.strength_exp === mults.dexterity_exp && mults.strength_exp === mults.agility_exp ) { - desc = ( - <> - {desc} -
+{f(mults.strength_exp - 1)} combat exp - - ); + desc += `\n+${f(mults.strength_exp - 1)} combat exp`; } else { - if (mults.strength_exp !== 1) - desc = ( - <> - {desc} -
+{f(mults.strength_exp - 1)} strength exp - - ); - if (mults.defense_exp !== 1) - desc = ( - <> - {desc} -
+{f(mults.defense_exp - 1)} defense exp - - ); - if (mults.dexterity_exp !== 1) - desc = ( - <> - {desc} -
+{f(mults.dexterity_exp - 1)} dexterity exp - - ); - if (mults.agility_exp !== 1) - desc = ( - <> - {desc} -
+{f(mults.agility_exp - 1)} agility exp - - ); + // Not all combat + if (mults.strength_exp !== 1) desc += `\n+${f(mults.strength_exp - 1)} strength exp`; + if (mults.defense_exp !== 1) desc += `\n+${f(mults.defense_exp - 1)} defense exp`; + if (mults.dexterity_exp !== 1) desc += `\n+${f(mults.dexterity_exp - 1)} dexterity exp`; + if (mults.agility_exp !== 1) desc += `\n+${f(mults.agility_exp - 1)} agility exp`; } - if (mults.charisma_exp !== 1) - desc = ( - <> - {desc} -
+{f(mults.charisma_exp - 1)} charisma exp - - ); + if (mults.charisma_exp !== 1) desc += `\n+${f(mults.charisma_exp - 1)} charisma exp`; } - if (mults.hacking_speed !== 1) - desc = ( - <> - {desc} -
+{f(mults.hacking_speed - 1)} faster hack(), grow(), and weaken() - - ); - if (mults.hacking_chance !== 1) - desc = ( - <> - {desc} -
+{f(mults.hacking_chance - 1)} hack() success chance - - ); - if (mults.hacking_money !== 1) - desc = ( - <> - {desc} -
+{f(mults.hacking_money - 1)} hack() power - - ); - if (mults.hacking_grow !== 1) - desc = ( - <> - {desc} -
+{f(mults.hacking_grow - 1)} grow() power - - ); + if (mults.hacking_speed !== 1) desc += `\n+${f(mults.hacking_speed - 1)} faster hack(), grow(), and weaken()`; + if (mults.hacking_chance !== 1) desc += `\n+${f(mults.hacking_chance - 1)} hack() success chance`; + if (mults.hacking_money !== 1) desc += `\n+${f(mults.hacking_money - 1)} hack() power`; + if (mults.hacking_grow !== 1) desc += `\n+${f(mults.hacking_grow - 1)} grow() power`; - if (mults.faction_rep !== 1 && mults.faction_rep === mults.company_rep) { - desc = ( - <> - {desc} -
+{f(mults.faction_rep - 1)} reputation from factions and companies - - ); - } else { - if (mults.faction_rep !== 1) - desc = ( - <> - {desc} -
+{f(mults.faction_rep - 1)} reputation from factions - - ); - if (mults.company_rep !== 1) - desc = ( - <> - {desc} -
+{f(mults.company_rep - 1)} reputation from companies - - ); + // Reputation + if (mults.faction_rep !== 1 && mults.faction_rep === mults.company_rep) + desc += `\n+${f(mults.faction_rep - 1)} reputation from factions and companies`; + else { + // Not all reputation + if (mults.faction_rep !== 1) desc += `\n+${f(mults.faction_rep - 1)} reputation from factions`; + if (mults.company_rep !== 1) desc += `\n+${f(mults.company_rep - 1)} reputation from companies`; } - if (mults.crime_money !== 1) - desc = ( - <> - {desc} -
+{f(mults.crime_money - 1)} crime money - - ); - if (mults.crime_success !== 1) - desc = ( - <> - {desc} -
+{f(mults.crime_success - 1)} crime success rate - - ); - if (mults.work_money !== 1) - desc = ( - <> - {desc} -
+{f(mults.work_money - 1)} work money - - ); + if (mults.crime_money !== 1) desc += `\n+${f(mults.crime_money - 1)} crime money`; + if (mults.crime_success !== 1) desc += `\n+${f(mults.crime_success - 1)} crime success rate`; + if (mults.work_money !== 1) desc += `\n+${f(mults.work_money - 1)} work money`; - if (mults.hacknet_node_money !== 1) - desc = ( - <> - {desc} -
+{f(mults.hacknet_node_money - 1)} hacknet production - - ); - if (mults.hacknet_node_purchase_cost !== 1) - desc = ( - <> - {desc} -
-{f(-(mults.hacknet_node_purchase_cost - 1))} hacknet nodes cost - - ); - if (mults.hacknet_node_level_cost !== 1) - desc = ( - <> - {desc} -
-{f(-(mults.hacknet_node_level_cost - 1))} hacknet nodes upgrade cost - - ); - - if (mults.bladeburner_max_stamina !== 1) - desc = ( - <> - {desc} -
+{f(mults.bladeburner_max_stamina - 1)} Bladeburner Max Stamina - - ); - if (mults.bladeburner_stamina_gain !== 1) - desc = ( - <> - {desc} -
+{f(mults.bladeburner_stamina_gain - 1)} Bladeburner Stamina gain - - ); - if (mults.bladeburner_analysis !== 1) - desc = ( - <> - {desc} -
+{f(mults.bladeburner_analysis - 1)} Bladeburner Field Analysis effectiveness - - ); - if (mults.bladeburner_success_chance !== 1) - desc = ( - <> - {desc} -
+{f(mults.bladeburner_success_chance - 1)} Bladeburner Contracts and Operations success chance - - ); - if (startingMoney) - desc = ( - <> - {desc} -
- Start with after installing Augmentations. - - ); - - if (programs) - desc = ( - <> - {desc} -
- Start with {programs.join(" and ")} after installing Augmentations. - - ); + // Hacknet: costs are negative + if (mults.hacknet_node_money !== 1) desc += `\n+${f(mults.hacknet_node_money - 1)} hacknet production`; + if (mults.hacknet_node_purchase_cost !== 1) { + desc += `\n-${f(-(mults.hacknet_node_purchase_cost - 1))} hacknet nodes cost`; + } + if (mults.hacknet_node_level_cost !== 1) { + desc += `\n-${f(-(mults.hacknet_node_level_cost - 1))} hacknet nodes upgrade cost`; + } + // Bladeburner + if (mults.bladeburner_max_stamina !== 1) desc += `\n+${f(mults.bladeburner_max_stamina - 1)} Bladeburner Max Stamina`; + if (mults.bladeburner_stamina_gain !== 1) { + desc += `\n+${f(mults.bladeburner_stamina_gain - 1)} Bladeburner Stamina gain`; + } + if (mults.bladeburner_analysis !== 1) { + desc += `\n+${f(mults.bladeburner_analysis - 1)} Bladeburner Field Analysis effectiveness`; + } + if (mults.bladeburner_success_chance !== 1) { + desc += `\n+${f(mults.bladeburner_success_chance - 1)} Bladeburner Contracts and Operations success chance`; + } + if (startingMoney) desc += `\nStart with ${startingMoney} after installing Augmentations.`; + if (programs) desc += `\nStart with ${programs.join(" and ")} after installing Augmentations.`; return desc; } @@ -372,36 +170,28 @@ export class Augmentation { baseRepRequirement = 0; // Description of what this Aug is and what it does - info: string | JSX.Element; + info: string; // Description of the stats, often autogenerated, sometimes manually written. - stats: JSX.Element | null; + stats: string; // Any Augmentation not immediately available in BitNode-1 is special (e.g. Bladeburner augs) isSpecial = false; // Name of Augmentation - name = ""; + name: AugmentationName; // Array of names of all prerequisites - prereqs: string[] = []; + prereqs: AugmentationName[] = []; // Multipliers given by this Augmentation. Must match the property name in // The Player/Person classes mults: Multipliers = defaultMultipliers(); // Factions that offer this aug. - factions: string[] = []; + factions: FactionName[] = []; - constructor( - params: IConstructorParams = { - info: "", - moneyCost: 0, - name: "", - repCost: 0, - factions: [], - }, - ) { + constructor(params: AugmentationCtorParams) { this.name = params.name; this.info = params.info; this.prereqs = params.prereqs ? params.prereqs : []; @@ -417,95 +207,9 @@ export class Augmentation { } // Set multipliers - if (params.hacking) { - this.mults.hacking = params.hacking; - } - if (params.strength) { - this.mults.strength = params.strength; - } - if (params.defense) { - this.mults.defense = params.defense; - } - if (params.dexterity) { - this.mults.dexterity = params.dexterity; - } - if (params.agility) { - this.mults.agility = params.agility; - } - if (params.charisma) { - this.mults.charisma = params.charisma; - } - if (params.hacking_exp) { - this.mults.hacking_exp = params.hacking_exp; - } - if (params.strength_exp) { - this.mults.strength_exp = params.strength_exp; - } - if (params.defense_exp) { - this.mults.defense_exp = params.defense_exp; - } - if (params.dexterity_exp) { - this.mults.dexterity_exp = params.dexterity_exp; - } - if (params.agility_exp) { - this.mults.agility_exp = params.agility_exp; - } - if (params.charisma_exp) { - this.mults.charisma_exp = params.charisma_exp; - } - if (params.hacking_chance) { - this.mults.hacking_chance = params.hacking_chance; - } - if (params.hacking_speed) { - this.mults.hacking_speed = params.hacking_speed; - } - if (params.hacking_money) { - this.mults.hacking_money = params.hacking_money; - } - if (params.hacking_grow) { - this.mults.hacking_grow = params.hacking_grow; - } - if (params.company_rep) { - this.mults.company_rep = params.company_rep; - } - if (params.faction_rep) { - this.mults.faction_rep = params.faction_rep; - } - if (params.crime_money) { - this.mults.crime_money = params.crime_money; - } - if (params.crime_success) { - this.mults.crime_success = params.crime_success; - } - if (params.work_money) { - this.mults.work_money = params.work_money; - } - if (params.hacknet_node_money) { - this.mults.hacknet_node_money = params.hacknet_node_money; - } - if (params.hacknet_node_purchase_cost) { - this.mults.hacknet_node_purchase_cost = params.hacknet_node_purchase_cost; - } - if (params.hacknet_node_ram_cost) { - this.mults.hacknet_node_ram_cost = params.hacknet_node_ram_cost; - } - if (params.hacknet_node_core_cost) { - this.mults.hacknet_node_core_cost = params.hacknet_node_core_cost; - } - if (params.hacknet_node_level_cost) { - this.mults.hacknet_node_level_cost = params.hacknet_node_level_cost; - } - if (params.bladeburner_max_stamina) { - this.mults.bladeburner_max_stamina = params.bladeburner_max_stamina; - } - if (params.bladeburner_stamina_gain) { - this.mults.bladeburner_stamina_gain = params.bladeburner_stamina_gain; - } - if (params.bladeburner_analysis) { - this.mults.bladeburner_analysis = params.bladeburner_analysis; - } - if (params.bladeburner_success_chance) { - this.mults.bladeburner_success_chance = params.bladeburner_success_chance; + for (const multName of getRecordKeys(this.mults)) { + const mult = params[multName]; + if (mult) this.mults[multName] = mult; } if (params.stats === undefined) @@ -513,89 +217,14 @@ export class Augmentation { else this.stats = params.stats; } - // Adds this Augmentation to the specified Factions - addToFactions(factionList: string[]): void { - for (let i = 0; i < factionList.length; ++i) { - const faction: Faction | null = Factions[factionList[i]]; - if (faction == null) { - console.warn(`In Augmentation.addToFactions(), could not find faction with this name: ${factionList[i]}`); - continue; - } - faction.augmentations.push(this.name); - } - } - - getCost(): AugmentationCosts { - const augmentationReference = StaticAugmentations[this.name]; - let moneyCost = augmentationReference.baseCost; - let repCost = augmentationReference.baseRepRequirement; - - if (augmentationReference.name === AugmentationName.NeuroFluxGovernor) { - let nextLevel = this.getLevel(); - --nextLevel; - const multiplier = Math.pow(CONSTANTS.NeuroFluxGovernorLevelMult, nextLevel); - repCost = augmentationReference.baseRepRequirement * multiplier * BitNodeMultipliers.AugmentationRepCost; - moneyCost = augmentationReference.baseCost * multiplier * BitNodeMultipliers.AugmentationMoneyCost; - - for (let i = 0; i < Player.queuedAugmentations.length; ++i) { - moneyCost *= getBaseAugmentationPriceMultiplier(); - } - } else if (augmentationReference.factions.includes(FactionName.ShadowsOfAnarchy)) { - const soaAugmentationNames = initSoAAugmentations().map((augmentation) => augmentation.name); - const soaAugCount = soaAugmentationNames.filter((augmentationName) => - Player.hasAugmentation(augmentationName), - ).length; - moneyCost = augmentationReference.baseCost * Math.pow(CONSTANTS.SoACostMult, soaAugCount); - if (soaAugmentationNames.find((augmentationName) => augmentationName === augmentationReference.name)) { - repCost = augmentationReference.baseRepRequirement * Math.pow(CONSTANTS.SoARepMult, soaAugCount); - } - } else { - moneyCost = - augmentationReference.baseCost * - getGenericAugmentationPriceMultiplier() * - BitNodeMultipliers.AugmentationMoneyCost; - repCost = augmentationReference.baseRepRequirement * BitNodeMultipliers.AugmentationRepCost; - } - return { moneyCost, repCost }; - } - + /** Get the current level of an augmentation before buying. Currently only relevant for NFG. */ getLevel(): number { - // Get current Neuroflux level based on Player's augmentations - if (this.name === AugmentationName.NeuroFluxGovernor) { - let currLevel = 0; - for (let i = 0; i < Player.augmentations.length; ++i) { - if (Player.augmentations[i].name === AugmentationName.NeuroFluxGovernor) { - currLevel = Player.augmentations[i].level; - } - } - - // Account for purchased but uninstalled Augmentations - for (let i = 0; i < Player.queuedAugmentations.length; ++i) { - if (Player.queuedAugmentations[i].name == AugmentationName.NeuroFluxGovernor) { - ++currLevel; - } - } - return currLevel + 1; - } - return 0; - } - - // Adds this Augmentation to all Factions - addToAllFactions(): void { - for (const faction of Object.values(Factions)) { - if (!faction.getInfo().special) faction.augmentations.push(this.name); - } - } - - // Serialize the current object to a JSON save state. - toJSON(): IReviverValue { - return Generic_toJSON("Augmentation", this); - } - - // Initializes a Augmentation object from a JSON save state. - static fromJSON(value: IReviverValue): Augmentation { - return Generic_fromJSON(Augmentation, value.data); + // Only NFG currently has levels, all others will be level 0 before purchase + if (this.name !== AugmentationName.NeuroFluxGovernor) return 0; + // Owned NFG has the level baked in + const ownedNFGLevel = Player.augmentations.find((aug) => aug.name === this.name)?.level ?? 0; + // Queued NFG is queued multiple times for each level purchased + const queuedNFGLevel = Player.queuedAugmentations.filter((aug) => aug.name === this.name).length; + return ownedNFGLevel + queuedNFGLevel; } } - -constructorsForReviver.Augmentation = Augmentation; diff --git a/src/Augmentation/AugmentationHelpers.tsx b/src/Augmentation/AugmentationHelpers.tsx index 9aa547965..22455e0e1 100644 --- a/src/Augmentation/AugmentationHelpers.tsx +++ b/src/Augmentation/AugmentationHelpers.tsx @@ -1,53 +1,17 @@ import { Augmentation } from "./Augmentation"; -import { StaticAugmentations } from "./StaticAugmentations"; +import { Augmentations } from "./Augmentations"; import { PlayerOwnedAugmentation } from "./PlayerOwnedAugmentation"; -import { AugmentationName, FactionName } from "@enums"; +import { AugmentationName } from "@enums"; import { CONSTANTS } from "../Constants"; -import { Factions, factionExists } from "../Faction/Factions"; import { Player } from "@player"; import { prestigeAugmentation } from "../Prestige"; import { dialogBoxCreate } from "../ui/React/DialogBox"; - -import { - initBladeburnerAugmentations, - initChurchOfTheMachineGodAugmentations, - initGeneralAugmentations, - initSoAAugmentations, - initNeuroFluxGovernor, - initUnstableCircadianModulator, -} from "./data/AugmentationCreator"; import { Router } from "../ui/GameRoot"; import { Page } from "../ui/Router"; import { mergeMultipliers } from "../PersonObjects/Multipliers"; - -export function AddToStaticAugmentations(aug: Augmentation): void { - const name = aug.name; - StaticAugmentations[name] = aug; -} - -function createAugmentations(): void { - [ - initNeuroFluxGovernor(), - initUnstableCircadianModulator(), - ...initGeneralAugmentations(), - ...initSoAAugmentations(), - ...(factionExists(FactionName.Bladeburners) ? initBladeburnerAugmentations() : []), - ...(factionExists(FactionName.ChurchOfTheMachineGod) ? initChurchOfTheMachineGodAugmentations() : []), - ].map(resetAugmentation); -} - -function resetFactionAugmentations(): void { - for (const faction of Object.values(Factions)) faction.augmentations = []; -} - -function initAugmentations(): void { - resetFactionAugmentations(); - for (const augName of Object.getOwnPropertyNames(StaticAugmentations)) delete StaticAugmentations[augName]; - createAugmentations(); - Player.reapplyAllAugmentations(); -} +import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; export function getBaseAugmentationPriceMultiplier(): number { return CONSTANTS.MultipleAugMultiplier * [1, 0.96, 0.94, 0.93][Player.sourceFileLvl(11)]; @@ -56,18 +20,8 @@ export function getGenericAugmentationPriceMultiplier(): number { return Math.pow(getBaseAugmentationPriceMultiplier(), Player.queuedAugmentations.length); } -//Resets an Augmentation during (re-initialization) -function resetAugmentation(aug: Augmentation): void { - aug.addToFactions(aug.factions); - const name = aug.name; - if (augmentationExists(name)) { - delete StaticAugmentations[name]; - } - AddToStaticAugmentations(aug); -} - -function applyAugmentation(aug: PlayerOwnedAugmentation, reapply = false): void { - const staticAugmentation = StaticAugmentations[aug.name]; +export function applyAugmentation(aug: PlayerOwnedAugmentation, reapply = false): void { + const staticAugmentation = Augmentations[aug.name]; // Apply multipliers Player.mults = mergeMultipliers(Player.mults, staticAugmentation.mults); @@ -93,7 +47,7 @@ function applyAugmentation(aug: PlayerOwnedAugmentation, reapply = false): void } } -function installAugmentations(force?: boolean): boolean { +export function installAugmentations(force?: boolean): boolean { if (Player.queuedAugmentations.length == 0 && !force) { dialogBoxCreate("You have not purchased any Augmentations to install!"); return false; @@ -108,7 +62,7 @@ function installAugmentations(force?: boolean): boolean { } for (let i = 0; i < Player.queuedAugmentations.length; ++i) { const ownedAug = Player.queuedAugmentations[i]; - const aug = StaticAugmentations[ownedAug.name]; + const aug = Augmentations[ownedAug.name]; if (aug == null) { console.error(`Invalid augmentation: ${ownedAug.name}`); continue; @@ -137,13 +91,59 @@ function installAugmentations(force?: boolean): boolean { return true; } -function augmentationExists(name: string): boolean { - return Object.hasOwn(StaticAugmentations, name); -} - export function isRepeatableAug(aug: Augmentation | string): boolean { const augName = typeof aug === "string" ? aug : aug.name; return augName === AugmentationName.NeuroFluxGovernor; } -export { installAugmentations, initAugmentations, applyAugmentation, augmentationExists }; +export interface AugmentationCosts { + moneyCost: number; + repCost: number; +} + +export function getAugCost(aug: Augmentation): AugmentationCosts { + let moneyCost = aug.baseCost; + let repCost = aug.baseRepRequirement; + + switch (aug.name) { + // Special cost for NFG + case AugmentationName.NeuroFluxGovernor: { + const multiplier = Math.pow(CONSTANTS.NeuroFluxGovernorLevelMult, aug.getLevel()); + repCost = aug.baseRepRequirement * multiplier * currentNodeMults.AugmentationRepCost; + moneyCost = aug.baseCost * multiplier * currentNodeMults.AugmentationMoneyCost; + moneyCost *= getBaseAugmentationPriceMultiplier() ** Player.queuedAugmentations.length; + break; + } + // SOA Augments use a unique cost method + case AugmentationName.BeautyOfAphrodite: + case AugmentationName.ChaosOfDionysus: + case AugmentationName.FloodOfPoseidon: + case AugmentationName.HuntOfArtemis: + case AugmentationName.KnowledgeOfApollo: + case AugmentationName.MightOfAres: + case AugmentationName.TrickeryOfHermes: + case AugmentationName.WKSharmonizer: + case AugmentationName.WisdomOfAthena: { + const soaAugmentationNames = [ + AugmentationName.BeautyOfAphrodite, + AugmentationName.ChaosOfDionysus, + AugmentationName.FloodOfPoseidon, + AugmentationName.HuntOfArtemis, + AugmentationName.KnowledgeOfApollo, + AugmentationName.MightOfAres, + AugmentationName.TrickeryOfHermes, + AugmentationName.WKSharmonizer, + AugmentationName.WisdomOfAthena, + ]; + const soaAugCount = soaAugmentationNames.filter((augName) => Player.hasAugmentation(augName)).length; + moneyCost = aug.baseCost * Math.pow(CONSTANTS.SoACostMult, soaAugCount); + repCost = aug.baseRepRequirement * Math.pow(CONSTANTS.SoARepMult, soaAugCount); + break; + } + // Standard cost + default: + moneyCost = aug.baseCost * getGenericAugmentationPriceMultiplier() * currentNodeMults.AugmentationMoneyCost; + repCost = aug.baseRepRequirement * currentNodeMults.AugmentationRepCost; + } + return { moneyCost, repCost }; +} diff --git a/src/Augmentation/Augmentations.ts b/src/Augmentation/Augmentations.ts new file mode 100644 index 000000000..925da1f69 --- /dev/null +++ b/src/Augmentation/Augmentations.ts @@ -0,0 +1,1917 @@ +import { AugmentationName, CompletedProgramName, FactionName } from "@enums"; +import { Augmentation, AugmentationCtorParams } from "./Augmentation"; +import { getUnstableCircadianModulatorParams } from "./CircadianModulator"; +import { CONSTANTS } from "../Constants"; +import { createEnumKeyedRecord } from "../Types/Record"; + +export const Augmentations: Record = (() => { + // Used to determine strength of NFG + const donationBonus = CONSTANTS.Donations / 1e6 / 100; // 1 millionth of a percent per donation + const metadata: Record> = { + // Alphabetical + // === A === // + [AugmentationName.ADRPheromone1]: { + repCost: 3.75e3, + moneyCost: 1.75e7, + info: + "The body is genetically re-engineered so that it produces the ADR-V1 pheromone, " + + "an artificial pheromone discovered by scientists. The ADR-V1 pheromone, when excreted, " + + "triggers feelings of admiration and approval in other people.", + company_rep: 1.1, + faction_rep: 1.1, + factions: [ + FactionName.TianDiHui, + FactionName.TheSyndicate, + FactionName.NWO, + FactionName.MegaCorp, + FactionName.FourSigma, + ], + }, + [AugmentationName.ADRPheromone2]: { + repCost: 6.25e4, + moneyCost: 5.5e8, + info: + "The body is genetically re-engineered so that it produces the ADR-V2 pheromone, " + + "which is similar to but more potent than ADR-V1. This pheromone, when excreted, " + + "triggers feelings of admiration, approval, and respect in others.", + company_rep: 1.2, + faction_rep: 1.2, + factions: [ + FactionName.Silhouette, + FactionName.FourSigma, + FactionName.BachmanAssociates, + FactionName.ClarkeIncorporated, + ], + }, + [AugmentationName.ArtificialBioNeuralNetwork]: { + repCost: 2.75e5, + moneyCost: 3e9, + info: + "A network consisting of millions of nanoprocessors is embedded into the brain. " + + "The network is meant to mimic the way a biological brain solves a problem, with each " + + "nanoprocessor acting similar to the way a neuron would in a neural network. However, these " + + "nanoprocessors are programmed to perform computations much faster than organic neurons, " + + "allowing the user to solve much more complex problems at a much faster rate.", + hacking_speed: 1.03, + hacking_money: 1.15, + hacking: 1.12, + factions: [FactionName.BitRunners, FactionName.FulcrumSecretTechnologies], + }, + [AugmentationName.ArtificialSynapticPotentiation]: { + repCost: 6.25e3, + moneyCost: 8e7, + info: + "The body is injected with a chemical that artificially induces synaptic potentiation, " + + "otherwise known as the strengthening of synapses. This results in enhanced cognitive abilities.", + hacking_speed: 1.02, + hacking_chance: 1.05, + hacking_exp: 1.05, + factions: [FactionName.TheBlackHand, FactionName.NiteSec], + }, + // === B === // + [AugmentationName.BeautyOfAphrodite]: { + repCost: 1e4, + moneyCost: 1e6, + info: + "Pheromone extruder injected in the thoracodorsal nerve. Emits pleasing scent guaranteed to " + + "make conversational partners more agreeable.", + stats: "This augmentation makes the Bribe minigame easier by indicating the incorrect paths.", + isSpecial: true, + factions: [FactionName.ShadowsOfAnarchy], + }, + [AugmentationName.BigDsBigBrain]: { + isSpecial: true, + factions: [], + repCost: Infinity, + moneyCost: Infinity, + info: + "A chip containing the psyche of the greatest BitRunner to ever exists. " + + "Installing this relic significantly increases ALL of your stats. " + + "However it may have unintended consequence on the users mental well-being.", + stats: "Grants access to unimaginable power.", + hacking: 2, + strength: 2, + defense: 2, + dexterity: 2, + agility: 2, + charisma: 2, + hacking_exp: 2, + strength_exp: 2, + defense_exp: 2, + dexterity_exp: 2, + agility_exp: 2, + charisma_exp: 2, + hacking_chance: 2, + hacking_speed: 2, + hacking_money: 2, + hacking_grow: 2, + company_rep: 2, + faction_rep: 2, + crime_money: 2, + crime_success: 2, + work_money: 2, + hacknet_node_money: 2, + hacknet_node_purchase_cost: 0.5, + hacknet_node_ram_cost: 0.5, + hacknet_node_core_cost: 0.5, + hacknet_node_level_cost: 0.5, + bladeburner_max_stamina: 2, + bladeburner_stamina_gain: 2, + bladeburner_analysis: 2, + bladeburner_success_chance: 2, + + startingMoney: 1e12, + programs: [ + CompletedProgramName.bruteSsh, + CompletedProgramName.ftpCrack, + CompletedProgramName.relaySmtp, + CompletedProgramName.httpWorm, + CompletedProgramName.sqlInject, + CompletedProgramName.deepScan1, + CompletedProgramName.deepScan2, + CompletedProgramName.serverProfiler, + CompletedProgramName.autoLink, + CompletedProgramName.formulas, + ], + }, + [AugmentationName.BionicArms]: { + repCost: 6.25e4, + moneyCost: 2.75e8, + info: "Cybernetic arms created from plasteel and carbon fibers that completely replace the user's organic arms.", + strength: 1.3, + dexterity: 1.3, + factions: [FactionName.Tetrads], + }, + [AugmentationName.BionicLegs]: { + repCost: 1.5e5, + moneyCost: 3.75e8, + info: "Cybernetic legs, created from plasteel and carbon fibers, enhance running speed.", + agility: 1.6, + factions: [ + FactionName.SpeakersForTheDead, + FactionName.TheSyndicate, + FactionName.KuaiGongInternational, + FactionName.OmniTekIncorporated, + FactionName.BladeIndustries, + ], + }, + [AugmentationName.BionicSpine]: { + repCost: 4.5e4, + moneyCost: 1.25e8, + info: + "The spine is reconstructed using plasteel and carbon fibers. " + + "It is now capable of stimulating and regulating neural signals " + + "passing through the spinal cord, improving senses and reaction speed. " + + "The 'Bionic Spine' also interfaces with all other 'Bionic' implants.", + strength: 1.15, + defense: 1.15, + agility: 1.15, + dexterity: 1.15, + factions: [ + FactionName.SpeakersForTheDead, + FactionName.TheSyndicate, + FactionName.KuaiGongInternational, + FactionName.OmniTekIncorporated, + FactionName.BladeIndustries, + ], + }, + [AugmentationName.BitWire]: { + repCost: 3.75e3, + moneyCost: 1e7, + info: + "A small brain implant embedded in the cerebrum. This regulates and improves the brain's computing " + + "capabilities.", + hacking: 1.05, + factions: [FactionName.CyberSec, FactionName.NiteSec], + }, + [AugmentationName.BladeArmor]: { + repCost: 1.25e4, + moneyCost: 1.375e9, + info: + `A powered exoskeleton suit designed as armor for ${FactionName.Bladeburners} units. This ` + + "exoskeleton is incredibly adaptable and can protect the wearer from blunt, piercing, " + + "concussive, thermal, chemical, and electric trauma. It also enhances the user's " + + "physical abilities.", + strength: 1.04, + defense: 1.04, + dexterity: 1.04, + agility: 1.04, + bladeburner_stamina_gain: 1.02, + bladeburner_success_chance: 1.03, + isSpecial: true, + factions: [FactionName.Bladeburners], + }, + [AugmentationName.BladeArmorEnergyShielding]: { + repCost: 2.125e4, + moneyCost: 5.5e9, + info: + "Upgrades the BLADE-51b Tesla Armor with a plasma energy propulsion system " + + "that is capable of projecting an energy shielding force field.", + prereqs: [AugmentationName.BladeArmor], + defense: 1.05, + bladeburner_success_chance: 1.06, + isSpecial: true, + factions: [FactionName.Bladeburners], + }, + [AugmentationName.BladeArmorIPU]: { + repCost: 1.5e4, + moneyCost: 1.1e9, + info: + "Upgrades the BLADE-51b Tesla Armor with an AI Information Processing " + + "Unit that was specially designed to analyze Synthoid related data and " + + "information.", + prereqs: [AugmentationName.BladeArmor], + bladeburner_analysis: 1.15, + bladeburner_success_chance: 1.02, + isSpecial: true, + factions: [FactionName.Bladeburners], + }, + [AugmentationName.BladeArmorOmnibeam]: { + repCost: 6.25e4, + moneyCost: 2.75e10, + info: + "Upgrades the BLADE-51b Tesla Armor Unibeam augmentation to use a " + + "multiple-fiber system. This upgraded weapon uses multiple fiber laser " + + "modules that combine together to form a single, more powerful beam of up to " + + "2000MW.", + prereqs: [AugmentationName.BladeArmorUnibeam], + bladeburner_success_chance: 1.1, + isSpecial: true, + factions: [FactionName.Bladeburners], + }, + [AugmentationName.BladeArmorPowerCells]: { + repCost: 1.875e4, + moneyCost: 2.75e9, + info: + "Upgrades the BLADE-51b Tesla Armor with Ion Power Cells, which are capable of " + + "more efficiently storing and using power.", + prereqs: [AugmentationName.BladeArmor], + bladeburner_success_chance: 1.05, + bladeburner_stamina_gain: 1.02, + bladeburner_max_stamina: 1.05, + isSpecial: true, + factions: [FactionName.Bladeburners], + }, + [AugmentationName.BladeArmorUnibeam]: { + repCost: 3.125e4, + moneyCost: 1.65e10, + info: + "Upgrades the BLADE-51b Tesla Armor with a concentrated deuterium-fluoride laser " + + "weapon. It's precision and accuracy makes it useful for quickly neutralizing " + + "threats while keeping casualties to a minimum.", + prereqs: [AugmentationName.BladeArmor], + bladeburner_success_chance: 1.08, + isSpecial: true, + factions: [FactionName.Bladeburners], + }, + [AugmentationName.BladeRunner]: { + repCost: 2e4, + moneyCost: 8.25e9, + info: + `A cybernetic foot augmentation that was specifically created for ${FactionName.Bladeburners} ` + + "during the Synthoid Uprising. The organic musculature of the human foot " + + "is enhanced with flexible carbon nanotube matrices that are controlled by " + + "intelligent servo-motors.", + agility: 1.05, + bladeburner_max_stamina: 1.05, + bladeburner_stamina_gain: 1.05, + isSpecial: true, + factions: [FactionName.Bladeburners], + }, + [AugmentationName.BladesSimulacrum]: { + repCost: 1.25e3, + moneyCost: 1.5e11, + info: + "A highly-advanced matter phase-shifter module that is embedded " + + "in the brainstem and cerebellum. This augmentation allows " + + "the user to project and control a holographic simulacrum within an " + + "extremely large radius. These specially-modified holograms were specifically " + + "weaponized by Bladeburner units to be used against Synthoids.", + stats: + "This augmentation allows you to perform Bladeburner actions and other actions (such as working, committing crimes, etc.) at the same time.", + isSpecial: true, + factions: [FactionName.Bladeburners], + }, + [AugmentationName.BrachiBlades]: { + repCost: 1.25e4, + moneyCost: 9e7, + info: "A set of retractable plasteel blades that are implanted in the arm, underneath the skin.", + strength: 1.15, + defense: 1.15, + crime_success: 1.1, + crime_money: 1.15, + factions: [FactionName.TheSyndicate], + }, + // === C === // + [AugmentationName.CRTX42AA]: { + repCost: 4.5e4, + moneyCost: 2.25e8, + info: + "The CRTX42-AA gene is injected into the genome. " + + "The CRTX42-AA is an artificially-synthesized gene that targets the visual and prefrontal " + + "cortex and improves cognitive abilities.", + hacking: 1.08, + hacking_exp: 1.15, + factions: [FactionName.NiteSec], + }, + [AugmentationName.CashRoot]: { + repCost: 1.25e4, + moneyCost: 1.25e8, + info: "A collection of digital assets saved on a small chip. The chip is implanted into your wrist. A small jack in the chip allows you to connect it to a computer and upload the assets.", + startingMoney: 1e6, + programs: [CompletedProgramName.bruteSsh], + factions: [FactionName.Sector12], + }, + [AugmentationName.ChaosOfDionysus]: { + repCost: 1e4, + moneyCost: 1e6, + info: "Opto-occipito implant to process visual signals before brain interpretation.", + stats: "This augmentation makes the Backwards minigame easier by flipping the words.", + isSpecial: true, + factions: [FactionName.ShadowsOfAnarchy], + }, + [AugmentationName.CombatRib1]: { + repCost: 7.5e3, + moneyCost: 2.375e7, + info: + "The rib cage is augmented to continuously release boosters into the bloodstream " + + "which increase the oxygen-carrying capacity of blood.", + strength: 1.1, + defense: 1.1, + factions: [ + FactionName.SlumSnakes, + FactionName.TheDarkArmy, + FactionName.TheSyndicate, + FactionName.Volhaven, + FactionName.Ishima, + FactionName.OmniTekIncorporated, + FactionName.KuaiGongInternational, + FactionName.BladeIndustries, + ], + }, + [AugmentationName.CombatRib2]: { + repCost: 1.875e4, + moneyCost: 6.5e7, + info: + "An upgraded version of the 'Combat Rib' augmentation that adds potent stimulants which " + + "improve focus and endurance while decreasing reaction time and fatigue.", + prereqs: [AugmentationName.CombatRib1], + strength: 1.14, + defense: 1.14, + factions: [ + FactionName.TheDarkArmy, + FactionName.TheSyndicate, + FactionName.Volhaven, + FactionName.OmniTekIncorporated, + FactionName.KuaiGongInternational, + FactionName.BladeIndustries, + ], + }, + [AugmentationName.CombatRib3]: { + repCost: 3.5e4, + moneyCost: 1.2e8, + info: + "The latest version of the 'Combat Rib' augmentation releases advanced anabolic steroids that " + + "improve muscle mass and physical performance while being safe and free of side effects.", + prereqs: [AugmentationName.CombatRib2, AugmentationName.CombatRib1], + strength: 1.18, + defense: 1.18, + factions: [ + FactionName.TheDarkArmy, + FactionName.TheSyndicate, + FactionName.OmniTekIncorporated, + FactionName.KuaiGongInternational, + FactionName.BladeIndustries, + FactionName.TheCovenant, + ], + }, + [AugmentationName.CongruityImplant]: { + repCost: Infinity, + moneyCost: 50e12, + info: + "Developed by a pioneer in Grafting research, this implant generates pulses of stability which seem to have a nullifying effect versus the Entropy virus.\n\n" + + "Note: For unknown reasons, the lowercase 'n' appears to be an integral component to its functionality.", + stats: "This Augmentation removes the Entropy virus, and prevents it from affecting you again.", + factions: [], + }, + [AugmentationName.CordiARCReactor]: { + repCost: 1.125e6, + moneyCost: 5e9, + info: + "The thoracic cavity is equipped with a small chamber designed " + + "to hold and sustain hydrogen plasma. The plasma is used to generate " + + "fusion power through nuclear fusion, providing limitless amounts of clean " + + "energy for the body.", + strength: 1.35, + defense: 1.35, + dexterity: 1.35, + agility: 1.35, + strength_exp: 1.35, + defense_exp: 1.35, + dexterity_exp: 1.35, + agility_exp: 1.35, + factions: [FactionName.MegaCorp], + }, + [AugmentationName.CranialSignalProcessorsG1]: { + repCost: 1e4, + moneyCost: 7e7, + info: + "The first generation of Cranial Signal Processors. Cranial Signal Processors " + + "are a set of specialized microprocessors that are attached to " + + "neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations " + + "so that the brain doesn't have to.", + hacking_speed: 1.01, + hacking: 1.05, + factions: [FactionName.CyberSec, FactionName.NiteSec], + }, + [AugmentationName.CranialSignalProcessorsG2]: { + repCost: 1.875e4, + moneyCost: 1.25e8, + info: + "The second generation of Cranial Signal Processors. Cranial Signal Processors " + + "are a set of specialized microprocessors that are attached to " + + "neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations " + + "so that the brain doesn't have to.", + prereqs: [AugmentationName.CranialSignalProcessorsG1], + hacking_speed: 1.02, + hacking_chance: 1.05, + hacking: 1.07, + factions: [FactionName.CyberSec, FactionName.NiteSec], + }, + [AugmentationName.CranialSignalProcessorsG3]: { + repCost: 5e4, + moneyCost: 5.5e8, + info: + "The third generation of Cranial Signal Processors. Cranial Signal Processors " + + "are a set of specialized microprocessors that are attached to " + + "neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations " + + "so that the brain doesn't have to.", + prereqs: [AugmentationName.CranialSignalProcessorsG2, AugmentationName.CranialSignalProcessorsG1], + hacking_speed: 1.02, + hacking_money: 1.15, + hacking: 1.09, + factions: [FactionName.NiteSec, FactionName.TheBlackHand, FactionName.BitRunners], + }, + [AugmentationName.CranialSignalProcessorsG4]: { + repCost: 1.25e5, + moneyCost: 1.1e9, + info: + "The fourth generation of Cranial Signal Processors. Cranial Signal Processors " + + "are a set of specialized microprocessors that are attached to " + + "neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations " + + "so that the brain doesn't have to.", + prereqs: [ + AugmentationName.CranialSignalProcessorsG3, + AugmentationName.CranialSignalProcessorsG2, + AugmentationName.CranialSignalProcessorsG1, + ], + hacking_speed: 1.02, + hacking_money: 1.2, + hacking_grow: 1.25, + factions: [FactionName.TheBlackHand, FactionName.BitRunners], + }, + [AugmentationName.CranialSignalProcessorsG5]: { + repCost: 2.5e5, + moneyCost: 2.25e9, + info: + "The fifth generation of Cranial Signal Processors. Cranial Signal Processors " + + "are a set of specialized microprocessors that are attached to " + + "neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations " + + "so that the brain doesn't have to.", + prereqs: [ + AugmentationName.CranialSignalProcessorsG4, + AugmentationName.CranialSignalProcessorsG3, + AugmentationName.CranialSignalProcessorsG2, + AugmentationName.CranialSignalProcessorsG1, + ], + hacking: 1.3, + hacking_money: 1.25, + hacking_grow: 1.75, + factions: [FactionName.BitRunners], + }, + // === D === // + [AugmentationName.DataJack]: { + repCost: 1.125e5, + moneyCost: 4.5e8, + info: + "A brain implant that provides an interface for direct, wireless communication between a computer's main " + + "memory and the mind. This implant allows the user to not only access a computer's memory, but also alter " + + "and delete it.", + hacking_money: 1.25, + factions: [ + FactionName.BitRunners, + FactionName.TheBlackHand, + FactionName.NiteSec, + FactionName.Chongqing, + FactionName.NewTokyo, + ], + }, + [AugmentationName.DermaForce]: { + repCost: 1.5e4, + moneyCost: 5e7, + info: + "Synthetic skin that is grafted onto the body. This skin consists of " + + "millions of nanobots capable of projecting high-density muon beams, " + + "creating an energy barrier around the user.", + defense: 1.4, + factions: [FactionName.Volhaven], + }, + // === E === // + [AugmentationName.EMS4Recombination]: { + repCost: 2.5e3, + moneyCost: 2.75e8, + info: + "A DNA recombination of the EMS-4 Gene. This genetic engineering " + + "technique was originally used on Bladeburners during the Synthoid uprising " + + "to induce wakefulness and concentration, suppress fear, reduce empathy, " + + "improve reflexes, and improve memory among other things.", + bladeburner_success_chance: 1.03, + bladeburner_analysis: 1.05, + bladeburner_stamina_gain: 1.02, + isSpecial: true, + factions: [FactionName.Bladeburners], + }, + [AugmentationName.ENM]: { + repCost: 1.5e4, + moneyCost: 2.5e8, + info: + "A thin device embedded inside the arm containing a wireless module capable of connecting " + + "to nearby networks. Once connected, the Netburner Module is capable of capturing and " + + "processing all of the traffic on that network. By itself, the Embedded Netburner Module does " + + "not do much, but a variety of very powerful upgrades can be installed that allow you to fully " + + "control the traffic on a network.", + hacking: 1.08, + factions: [ + FactionName.BitRunners, + FactionName.TheBlackHand, + FactionName.NiteSec, + FactionName.ECorp, + FactionName.MegaCorp, + FactionName.FulcrumSecretTechnologies, + FactionName.NWO, + FactionName.BladeIndustries, + ], + }, + [AugmentationName.ENMAnalyzeEngine]: { + repCost: 6.25e5, + moneyCost: 6e9, + info: + "Installs the Analyze Engine for the Embedded Netburner Module, which is a CPU cluster " + + "that vastly outperforms the Netburner Module's native single-core processor.", + prereqs: [AugmentationName.ENM], + hacking_speed: 1.1, + factions: [ + FactionName.ECorp, + FactionName.MegaCorp, + FactionName.FulcrumSecretTechnologies, + FactionName.NWO, + FactionName.Daedalus, + FactionName.TheCovenant, + FactionName.Illuminati, + ], + }, + [AugmentationName.ENMCore]: { + repCost: 175e3, + moneyCost: 2.5e9, + info: + "The Core library is an implant that upgrades the firmware of the Embedded Netburner Module. " + + "This upgrade allows the Embedded Netburner Module to generate its own data on a network.", + prereqs: [AugmentationName.ENM], + hacking_speed: 1.03, + hacking_money: 1.1, + hacking_chance: 1.03, + hacking_exp: 1.07, + hacking: 1.07, + factions: [ + FactionName.BitRunners, + FactionName.TheBlackHand, + FactionName.ECorp, + FactionName.MegaCorp, + FactionName.FulcrumSecretTechnologies, + FactionName.NWO, + FactionName.BladeIndustries, + ], + }, + [AugmentationName.ENMCoreV2]: { + repCost: 1e6, + moneyCost: 4.5e9, + info: + "The Core V2 library is an implant that upgrades the firmware of the Embedded Netburner Module. " + + "This upgraded firmware allows the Embedded Netburner Module to control information on " + + "a network by re-routing traffic, spoofing IP addresses, and altering the data inside network " + + "packets.", + prereqs: [AugmentationName.ENMCore, AugmentationName.ENM], + hacking_speed: 1.05, + hacking_money: 1.3, + hacking_chance: 1.05, + hacking_exp: 1.15, + hacking: 1.08, + factions: [ + FactionName.BitRunners, + FactionName.ECorp, + FactionName.MegaCorp, + FactionName.FulcrumSecretTechnologies, + FactionName.NWO, + FactionName.BladeIndustries, + FactionName.OmniTekIncorporated, + FactionName.KuaiGongInternational, + ], + }, + [AugmentationName.ENMCoreV3]: { + repCost: 1.75e6, + moneyCost: 7.5e9, + info: + "The Core V3 library is an implant that upgrades the firmware of the Embedded Netburner Module. " + + "This upgraded firmware allows the Embedded Netburner Module to seamlessly inject code into " + + "any device on a network.", + prereqs: [AugmentationName.ENMCoreV2, AugmentationName.ENMCore, AugmentationName.ENM], + hacking_speed: 1.05, + hacking_money: 1.4, + hacking_chance: 1.1, + hacking_exp: 1.25, + hacking: 1.1, + factions: [ + FactionName.ECorp, + FactionName.MegaCorp, + FactionName.FulcrumSecretTechnologies, + FactionName.NWO, + FactionName.Daedalus, + FactionName.TheCovenant, + FactionName.Illuminati, + ], + }, + [AugmentationName.ENMDMA]: { + repCost: 1e6, + moneyCost: 7e9, + info: + "This implant installs a Direct Memory Access (DMA) controller into the " + + "Embedded Netburner Module. This allows the Module to send and receive data " + + "directly to and from the main memory of devices on a network.", + prereqs: [AugmentationName.ENM], + hacking_money: 1.4, + hacking_chance: 1.2, + factions: [ + FactionName.ECorp, + FactionName.MegaCorp, + FactionName.FulcrumSecretTechnologies, + FactionName.NWO, + FactionName.Daedalus, + FactionName.TheCovenant, + FactionName.Illuminati, + ], + }, + [AugmentationName.EnhancedMyelinSheathing]: { + repCost: 1e5, + moneyCost: 1.375e9, + info: + "Electrical signals are used to induce a new, artificial form of myelinogenesis in the human body. " + + "This process results in the proliferation of new, synthetic myelin sheaths in the nervous " + + "system. These myelin sheaths can propagate neuro-signals much faster than their organic " + + "counterparts, leading to greater processing speeds and better brain function.", + hacking_speed: 1.03, + hacking_exp: 1.1, + hacking: 1.08, + factions: [FactionName.FulcrumSecretTechnologies, FactionName.BitRunners, FactionName.TheBlackHand], + }, + [AugmentationName.EnhancedSocialInteractionImplant]: { + repCost: 3.75e5, + moneyCost: 1.375e9, + info: + "A cranial implant that greatly assists in the user's ability to analyze social situations " + + "and interactions. The system uses a wide variety of factors such as facial expression, body " + + "language, voice tone, and inflection to determine the best course of action during social " + + "situations. The implant also uses deep learning software to continuously learn new behavior " + + "patterns and how to best respond.", + charisma: 1.6, + charisma_exp: 1.6, + factions: [ + FactionName.BachmanAssociates, + FactionName.NWO, + FactionName.ClarkeIncorporated, + FactionName.OmniTekIncorporated, + FactionName.FourSigma, + ], + }, + [AugmentationName.EsperEyewear]: { + repCost: 1.25e3, + moneyCost: 1.65e8, + info: + "Ballistic-grade protective and retractable eyewear that was designed specifically " + + "for Bladeburner units. This " + + "is implanted by installing a mechanical frame in the skull's orbit. " + + "This frame interfaces with the brain and allows the user to " + + "automatically extrude and extract the eyewear. The eyewear protects " + + "against debris, shrapnel, lasers, blinding flashes, and gas. It is also " + + "embedded with a data processing chip that can be programmed to display an " + + "AR HUD to assist the user in field missions.", + bladeburner_success_chance: 1.03, + dexterity: 1.05, + isSpecial: true, + factions: [FactionName.Bladeburners], + }, + // === F === // + [AugmentationName.FloodOfPoseidon]: { + repCost: 1e4, + moneyCost: 1e6, + info: "Transtinatium VVD reticulator used in optico-sterbing recognition.", + stats: "This augmentation makes the Symbol matching minigame easier by indicating the correct choice.", + isSpecial: true, + factions: [FactionName.ShadowsOfAnarchy], + }, + [AugmentationName.FocusWire]: { + repCost: 7.5e4, + moneyCost: 9e8, + info: "A cranial implant that stops procrastination by blocking specific neural pathways in the brain.", + hacking_exp: 1.05, + strength_exp: 1.05, + defense_exp: 1.05, + dexterity_exp: 1.05, + agility_exp: 1.05, + charisma_exp: 1.05, + company_rep: 1.1, + work_money: 1.2, + factions: [ + FactionName.BachmanAssociates, + FactionName.ClarkeIncorporated, + FactionName.FourSigma, + FactionName.KuaiGongInternational, + ], + }, + // === G === // + [AugmentationName.GolemSerum]: { + repCost: 3.125e4, + moneyCost: 1.1e10, + info: + "A serum that permanently enhances many aspects of human capabilities, " + + "including strength, speed, immune system enhancements, and mitochondrial efficiency. The " + + "serum was originally developed by the Chinese military in an attempt to " + + "create super soldiers.", + strength: 1.07, + defense: 1.07, + dexterity: 1.07, + agility: 1.07, + bladeburner_stamina_gain: 1.05, + isSpecial: true, + factions: [FactionName.Bladeburners], + }, + [AugmentationName.GrapheneBionicArms]: { + repCost: 5e5, + moneyCost: 3.75e9, + info: + "An upgrade to the Bionic Arms augmentation. It infuses the " + + "prosthetic arms with an advanced graphene material " + + "to make them stronger and lighter.", + prereqs: [AugmentationName.BionicArms], + strength: 1.85, + dexterity: 1.85, + factions: [FactionName.TheDarkArmy], + }, + [AugmentationName.GrapheneBionicLegs]: { + repCost: 7.5e5, + moneyCost: 4.5e9, + info: + "An upgrade to the 'Bionic Legs' augmentation. The legs are fused " + + "with graphene, greatly enhancing jumping ability.", + prereqs: [AugmentationName.BionicLegs], + agility: 2.5, + factions: [FactionName.MegaCorp, FactionName.ECorp, FactionName.FulcrumSecretTechnologies], + }, + [AugmentationName.GrapheneBionicSpine]: { + repCost: 1.625e6, + moneyCost: 6e9, + info: + "An upgrade to the 'Bionic Spine' augmentation. The spine is fused with graphene " + + "which enhances durability and supercharges all body functions.", + prereqs: [AugmentationName.BionicSpine], + strength: 1.6, + defense: 1.6, + agility: 1.6, + dexterity: 1.6, + factions: [FactionName.FulcrumSecretTechnologies, FactionName.ECorp], + }, + [AugmentationName.GrapheneBoneLacings]: { + repCost: 1.125e6, + moneyCost: 4.25e9, + info: "Graphene is grafted and fused into the skeletal structure, enhancing bone density and tensile strength.", + strength: 1.7, + defense: 1.7, + factions: [FactionName.FulcrumSecretTechnologies, FactionName.TheCovenant], + }, + [AugmentationName.GrapheneBrachiBlades]: { + repCost: 2.25e5, + moneyCost: 2.5e9, + info: + "An upgrade to the BrachiBlades augmentation. It infuses " + + "the retractable blades with an advanced graphene material " + + "making them stronger and lighter.", + prereqs: [AugmentationName.BrachiBlades], + strength: 1.4, + defense: 1.4, + crime_success: 1.1, + crime_money: 1.3, + factions: [FactionName.SpeakersForTheDead], + }, + // === H === // + [AugmentationName.HacknetNodeCPUUpload]: { + repCost: 3.75e3, + moneyCost: 1.1e7, + info: + "Uploads the architecture and design details of a Hacknet Node's CPU into " + + "the brain. This allows the user to engineer custom hardware and software " + + "for the Hacknet Node that provides better performance.", + hacknet_node_money: 1.15, + hacknet_node_purchase_cost: 0.85, + factions: [FactionName.Netburners], + }, + [AugmentationName.HacknetNodeCacheUpload]: { + repCost: 2.5e3, + moneyCost: 5.5e6, + info: + "Uploads the architecture and design details of a Hacknet Node's main-memory cache " + + "into the brain. This allows the user to engineer custom cache hardware for the " + + "Hacknet Node that offers better performance.", + hacknet_node_money: 1.1, + hacknet_node_level_cost: 0.85, + factions: [FactionName.Netburners], + }, + [AugmentationName.HacknetNodeCoreDNI]: { + repCost: 1.25e4, + moneyCost: 6e7, + info: + "Installs a Direct-Neural Interface jack into the arm that is capable of connecting " + + "to a Hacknet Node. This lets the user access and manipulate the Node's processing logic using " + + "electrochemical signals.", + hacknet_node_money: 1.45, + factions: [FactionName.Netburners], + }, + [AugmentationName.HacknetNodeKernelDNI]: { + repCost: 7.5e3, + moneyCost: 4e7, + info: + "Installs a Direct-Neural Interface jack into the arm that is capable of connecting to a " + + "Hacknet Node. This lets the user access and manipulate the Node's kernel using " + + "electrochemical signals.", + hacknet_node_money: 1.25, + factions: [FactionName.Netburners], + }, + [AugmentationName.HacknetNodeNICUpload]: { + repCost: 1.875e3, + moneyCost: 4.5e6, + info: + "Uploads the architecture and design details of a Hacknet Node's Network Interface Card (NIC) " + + "into the brain. This allows the user to engineer a custom NIC for the Hacknet Node that " + + "offers better performance.", + hacknet_node_money: 1.1, + hacknet_node_purchase_cost: 0.9, + factions: [FactionName.Netburners], + }, + [AugmentationName.HemoRecirculator]: { + moneyCost: 4.5e7, + repCost: 1e4, + info: "A heart implant that greatly increases the body's ability to effectively use and pump blood.", + strength: 1.08, + defense: 1.08, + agility: 1.08, + dexterity: 1.08, + factions: [FactionName.Tetrads, FactionName.TheDarkArmy, FactionName.TheSyndicate], + }, + [AugmentationName.HiveMind]: { + repCost: 1.5e6, + moneyCost: 5.5e9, + info: + `A brain implant developed by ${FactionName.ECorp}. They do not reveal what ` + + "exactly the implant does, but they promise that it will greatly " + + "enhance your abilities.", + hacking_grow: 3, + stats: "", + factions: [FactionName.ECorp], + }, + [AugmentationName.HuntOfArtemis]: { + repCost: 1e4, + moneyCost: 1e6, + info: "magneto-turboencabulator based on technology by Micha Eike Siemon, increases the user's electro-magnetic sensitivity.", + stats: + "This augmentation makes the Minesweeper minigame easier by showing the location of all mines and keeping their position.", + isSpecial: true, + factions: [FactionName.ShadowsOfAnarchy], + }, + [AugmentationName.HydroflameLeftArm]: { + repCost: 1.25e6, + moneyCost: 2.5e12, + info: + "The left arm of a legendary BitRunner who ascended beyond this world. " + + "It projects a light blue energy shield that protects the exposed inner parts. " + + "Even though it contains no weapons, the advanced tungsten titanium " + + "alloy increases the user's strength to unbelievable levels.", + strength: 2.8, + factions: [FactionName.NWO], + }, + [AugmentationName.HyperionV1]: { + repCost: 1.25e4, + moneyCost: 2.75e9, + info: + "A pair of mini plasma cannons embedded into the hands. The Hyperion is capable " + + "of rapidly firing bolts of high-density plasma. The weapon is meant to " + + "be used against augmented enemies as the ionized " + + "nature of the plasma disrupts the electrical systems of Augmentations. However, " + + "it can also be effective against non-augmented enemies due to its high temperature " + + "and concussive force.", + bladeburner_success_chance: 1.06, + isSpecial: true, + factions: [FactionName.Bladeburners], + }, + [AugmentationName.HyperionV2]: { + repCost: 2.5e4, + moneyCost: 5.5e9, + info: + "A pair of mini plasma cannons embedded into the hands. This augmentation " + + "is more advanced and powerful than the original V1 model. This V2 model is " + + "more power-efficient, more accurate, and can fire plasma bolts at a much " + + "higher velocity than the V1 model.", + prereqs: [AugmentationName.HyperionV1], + bladeburner_success_chance: 1.08, + isSpecial: true, + factions: [FactionName.Bladeburners], + }, + [AugmentationName.Hypersight]: { + repCost: 1.5e5, + moneyCost: 2.75e9, + info: + "A bionic eye implant that grants sight capabilities far beyond those of a natural human. " + + "Embedded circuitry within the implant provides the ability to detect heat and movement " + + "through solid objects such as walls, thus providing 'x-ray vision'-like capabilities.", + dexterity: 1.4, + hacking_speed: 1.03, + hacking_money: 1.1, + factions: [FactionName.BladeIndustries, FactionName.KuaiGongInternational], + }, + // === I === // + [AugmentationName.INFRARet]: { + repCost: 7.5e3, + moneyCost: 3e7, + info: "A tiny chip that sits behind the retina. This implant lets the user visually detect infrared radiation.", + crime_success: 1.25, + crime_money: 1.1, + dexterity: 1.1, + factions: [FactionName.Ishima], + }, + [AugmentationName.INTERLINKED]: { + repCost: 2.5e4, + moneyCost: 5.5e9, + info: + "The DNA is genetically modified to enhance the human's body " + + "extracellular matrix (ECM). This improves the ECM's ability to " + + "structurally support the body and grants heightened strength and " + + "durability.", + strength_exp: 1.05, + defense_exp: 1.05, + dexterity_exp: 1.05, + agility_exp: 1.05, + bladeburner_max_stamina: 1.1, + isSpecial: true, + factions: [FactionName.Bladeburners], + }, + // === J === // + // === K === // + [AugmentationName.KnowledgeOfApollo]: { + repCost: 1e4, + moneyCost: 1e6, + info: "Neodynic retention fjengeln spoofer using -φ karmions, net positive effect on implantee's delta wave.", + stats: "This augmentation makes the Wire Cutting minigame easier by indicating the incorrect wires.", + isSpecial: true, + factions: [FactionName.ShadowsOfAnarchy], + }, + // === L === // + [AugmentationName.LuminCloaking1]: { + repCost: 1.5e3, + moneyCost: 5e6, + info: + "A skin implant that reinforces the skin with highly-advanced synthetic cells. These " + + "cells, when powered, have a negative refractive index. As a result, they bend light " + + "around the skin, making the user much harder to see with the naked eye.", + agility: 1.05, + crime_money: 1.1, + factions: [FactionName.SlumSnakes, FactionName.Tetrads], + }, + [AugmentationName.LuminCloaking2]: { + repCost: 5e3, + moneyCost: 3e7, + info: + "This is a more advanced version of the LuminCloaking-V1 augmentation. This skin implant " + + "reinforces the skin with highly-advanced synthetic cells. These " + + "cells, when powered, are capable of not only bending light but also of bending heat, " + + "making the user more resilient as well as stealthy.", + prereqs: [AugmentationName.LuminCloaking1], + agility: 1.1, + defense: 1.1, + crime_money: 1.25, + factions: [FactionName.SlumSnakes, FactionName.Tetrads], + }, + // === M === // + [AugmentationName.MightOfAres]: { + repCost: 1e4, + moneyCost: 1e6, + info: + "Extra-ocular neurons taken from old martial art master. Injecting them gives the user the ability to " + + "predict the enemy's attack before they even know it themselves.", + stats: + "This augmentation makes the Slash minigame easier by showing you via an indicator when the slash in coming.", + isSpecial: true, + factions: [FactionName.ShadowsOfAnarchy], + }, + // === N === // + [AugmentationName.NanofiberWeave]: { + repCost: 3.75e4, + moneyCost: 1.25e8, + info: + "Synthetic nanofibers are woven into the skin's extracellular matrix using electrospinning, " + + "which improves its regenerative and extracellular homeostasis abilities.", + strength: 1.2, + defense: 1.2, + factions: [ + FactionName.TheDarkArmy, + FactionName.TheSyndicate, + FactionName.OmniTekIncorporated, + FactionName.BladeIndustries, + FactionName.TianDiHui, + FactionName.SpeakersForTheDead, + FactionName.FulcrumSecretTechnologies, + ], + }, + [AugmentationName.Neotra]: { + repCost: 5.625e5, + moneyCost: 2.875e9, + info: + "A highly-advanced techno-organic drug that is injected into the skeletal " + + "and integumentary system. The drug permanently modifies the DNA of the " + + "body's skin and bone cells, granting them the ability to repair " + + "and restructure themselves.", + strength: 1.55, + defense: 1.55, + factions: [FactionName.BladeIndustries], + }, + [AugmentationName.NeuralAccelerator]: { + repCost: 2e5, + moneyCost: 1.75e9, + info: + "A microprocessor that accelerates the processing " + + "speed of biological neural networks. This is a cranial implant that is embedded inside the brain.", + hacking: 1.1, + hacking_exp: 1.15, + hacking_money: 1.2, + factions: [FactionName.BitRunners], + }, + [AugmentationName.NeuralRetentionEnhancement]: { + repCost: 2e4, + moneyCost: 2.5e8, + info: + "Chemical injections are used to permanently alter and strengthen the brain's neuronal " + + "circuits, strengthening the ability to retain information.", + hacking_exp: 1.25, + factions: [FactionName.NiteSec], + }, + [AugmentationName.Neuralstimulator]: { + repCost: 5e4, + moneyCost: 3e9, + info: + "A cranial implant that intelligently stimulates certain areas of the brain " + + "in order to improve cognitive functions.", + hacking_speed: 1.02, + hacking_chance: 1.1, + hacking_exp: 1.12, + factions: [ + FactionName.TheBlackHand, + FactionName.Chongqing, + FactionName.Sector12, + FactionName.NewTokyo, + FactionName.Aevum, + FactionName.Ishima, + FactionName.Volhaven, + FactionName.BachmanAssociates, + FactionName.ClarkeIncorporated, + FactionName.FourSigma, + ], + }, + [AugmentationName.Neuregen]: { + repCost: 3.75e4, + moneyCost: 3.75e8, + info: + "A drug that genetically modifies the neurons in the brain " + + "resulting in neurons that never die, continuously " + + "regenerate, and strengthen themselves.", + hacking_exp: 1.4, + factions: [FactionName.Chongqing], + }, + [AugmentationName.NeuroFluxGovernor]: { + repCost: 500, + moneyCost: 750e3, + info: + "Undetectable adamantium nanobots injected in the users bloodstream. The NeuroFlux Governor " + + "monitors and regulates all aspects of the human body, essentially 'governing' the body. " + + "By doing so, it improves the users performance for most actions.", + stats: + "This special augmentation can be leveled up infinitely. Each level of this augmentation increases MOST multipliers by 1% (+{(donationBonus * 100).toFixed(6)}%), stacking multiplicatively.", + isSpecial: true, + hacking_chance: 1.01 + donationBonus, + hacking_speed: 1.01 + donationBonus, + hacking_money: 1.01 + donationBonus, + hacking_grow: 1.01 + donationBonus, + hacking: 1.01 + donationBonus, + strength: 1.01 + donationBonus, + defense: 1.01 + donationBonus, + dexterity: 1.01 + donationBonus, + agility: 1.01 + donationBonus, + charisma: 1.01 + donationBonus, + hacking_exp: 1.01 + donationBonus, + strength_exp: 1.01 + donationBonus, + defense_exp: 1.01 + donationBonus, + dexterity_exp: 1.01 + donationBonus, + agility_exp: 1.01 + donationBonus, + charisma_exp: 1.01 + donationBonus, + company_rep: 1.01 + donationBonus, + faction_rep: 1.01 + donationBonus, + crime_money: 1.01 + donationBonus, + crime_success: 1.01 + donationBonus, + hacknet_node_money: 1.01 + donationBonus, + hacknet_node_purchase_cost: 1 / (1.01 + donationBonus), + hacknet_node_ram_cost: 1 / (1.01 + donationBonus), + hacknet_node_core_cost: 1 / (1.01 + donationBonus), + hacknet_node_level_cost: 1 / (1.01 + donationBonus), + work_money: 1.01 + donationBonus, + factions: Object.values(FactionName).filter( + (factionName) => + ![FactionName.ShadowsOfAnarchy, FactionName.Bladeburners, FactionName.ChurchOfTheMachineGod].includes( + factionName, + ), + ), + }, + [AugmentationName.Neurolink]: { + repCost: 8.75e5, + moneyCost: 4.375e9, + info: + "A brain implant that provides a high-bandwidth, direct neural link between your " + + `mind and the ${FactionName.BitRunners}' data servers, which reportedly contain ` + + "the largest database of hacking tools and information in the world.", + hacking: 1.15, + hacking_exp: 1.2, + hacking_chance: 1.1, + hacking_speed: 1.05, + programs: [CompletedProgramName.ftpCrack, CompletedProgramName.relaySmtp], + factions: [FactionName.BitRunners], + }, + [AugmentationName.NeuronalDensification]: { + repCost: 1.875e5, + moneyCost: 1.375e9, + info: + "The brain is surgically re-engineered to have increased neuronal density " + + "by decreasing the neuron gap junction. Then, the body is genetically modified " + + "to enhance the production and capabilities of its neural stem cells.", + hacking: 1.15, + hacking_exp: 1.1, + hacking_speed: 1.03, + factions: [FactionName.ClarkeIncorporated], + }, + [AugmentationName.NeuroreceptorManager]: { + repCost: 0.75e5, + moneyCost: 5.5e8, + info: + "A brain implant carefully assembled around the synapses, which " + + "micromanages the activity and levels of various neuroreceptor " + + "chemicals and modulates electrical activity to optimize concentration, " + + "allowing the user to multitask much more effectively.", + stats: + "This augmentation removes the penalty for not focusing on actions such as working in a job or working for a faction.", + factions: [FactionName.TianDiHui], + }, + [AugmentationName.Neurotrainer1]: { + repCost: 1e3, + moneyCost: 4e6, + info: + "A decentralized cranial implant that improves the brain's ability to learn. It is " + + "installed by releasing millions of nanobots into the human brain, each of which " + + "attaches to a different neural pathway to enhance the brain's ability to retain " + + "and retrieve information.", + hacking_exp: 1.1, + strength_exp: 1.1, + defense_exp: 1.1, + dexterity_exp: 1.1, + agility_exp: 1.1, + charisma_exp: 1.1, + factions: [FactionName.CyberSec, FactionName.Aevum], + }, + [AugmentationName.Neurotrainer2]: { + repCost: 1e4, + moneyCost: 4.5e7, + info: + "A decentralized cranial implant that improves the brain's ability to learn. This " + + "is a more powerful version of the Neurotrainer I augmentation, but it does not " + + "require Neurotrainer I to be installed as a prerequisite.", + hacking_exp: 1.15, + strength_exp: 1.15, + defense_exp: 1.15, + dexterity_exp: 1.15, + agility_exp: 1.15, + charisma_exp: 1.15, + factions: [FactionName.BitRunners, FactionName.NiteSec], + }, + [AugmentationName.Neurotrainer3]: { + repCost: 2.5e4, + moneyCost: 1.3e8, + info: + "A decentralized cranial implant that improves the brain's ability to learn. This " + + "is a more powerful version of the Neurotrainer I and Neurotrainer II augmentation, " + + "but it does not require either of them to be installed as a prerequisite.", + hacking_exp: 1.2, + strength_exp: 1.2, + defense_exp: 1.2, + dexterity_exp: 1.2, + agility_exp: 1.2, + charisma_exp: 1.2, + factions: [FactionName.NWO, FactionName.FourSigma], + }, + [AugmentationName.NuoptimalInjectorImplant]: { + repCost: 5e3, + moneyCost: 2e7, + info: + "This torso implant automatically injects nootropic supplements into " + + "the bloodstream to improve memory, increase focus, and provide other " + + "cognitive enhancements.", + company_rep: 1.2, + factions: [ + FactionName.TianDiHui, + FactionName.Volhaven, + FactionName.NewTokyo, + FactionName.Chongqing, + FactionName.ClarkeIncorporated, + FactionName.FourSigma, + FactionName.BachmanAssociates, + ], + }, + [AugmentationName.NutriGen]: { + repCost: 6.25e3, + moneyCost: 2.5e6, + info: + "A thermo-powered artificial nutrition generator. Endogenously " + + "synthesizes glucose, amino acids, and vitamins and redistributes them " + + "across the body. The device is powered by the body's naturally wasted " + + "energy in the form of heat.", + strength_exp: 1.2, + defense_exp: 1.2, + dexterity_exp: 1.2, + agility_exp: 1.2, + factions: [FactionName.NewTokyo], + }, + [AugmentationName.nextSENS]: { + repCost: 4.375e5, + moneyCost: 1.925e9, + info: + "The body is genetically re-engineered to maintain a state " + + "of negligible senescence, preventing the body from " + + "deteriorating with age.", + hacking: 1.2, + strength: 1.2, + defense: 1.2, + dexterity: 1.2, + agility: 1.2, + charisma: 1.2, + factions: [FactionName.ClarkeIncorporated], + }, + // === O === // + [AugmentationName.OmniTekInfoLoad]: { + repCost: 6.25e5, + moneyCost: 2.875e9, + info: + "OmniTek's data and information repository is uploaded " + + "into your brain, enhancing your programming and " + + "hacking abilities.", + hacking: 1.2, + hacking_exp: 1.25, + factions: [FactionName.OmniTekIncorporated], + }, + [AugmentationName.OrionShoulder]: { + repCost: 6.25e3, + moneyCost: 5.5e8, + info: + "A bionic shoulder augmentation for the right shoulder. Using cybernetics, " + + "the ORION-MKIV shoulder enhances the strength and dexterity " + + "of the user's right arm. It also provides protection due to its " + + "crystallized graphene plating.", + defense: 1.05, + strength: 1.05, + dexterity: 1.05, + bladeburner_success_chance: 1.04, + isSpecial: true, + factions: [FactionName.Bladeburners], + }, + // === P === // + [AugmentationName.PCDNI]: { + repCost: 3.75e5, + moneyCost: 3.75e9, + info: + "Installs a Direct-Neural Interface jack into your arm that is compatible with most " + + "computers. Connecting to a computer through this jack allows you to interface with " + + "it using the brain's electrochemical signals.", + company_rep: 1.3, + hacking: 1.08, + factions: [ + FactionName.FourSigma, + FactionName.OmniTekIncorporated, + FactionName.ECorp, + FactionName.BladeIndustries, + ], + }, + [AugmentationName.PCDNINeuralNetwork]: { + repCost: 1.5e6, + moneyCost: 7.5e9, + info: + "This is an additional installation that upgrades the functionality of the " + + "PC Direct-Neural Interface augmentation. When connected to a computer, " + + "the Neural Network upgrade allows the user to use their own brain's " + + "processing power to aid the computer in computational tasks.", + prereqs: [AugmentationName.PCDNI], + company_rep: 2, + hacking: 1.1, + hacking_speed: 1.05, + factions: [FactionName.FulcrumSecretTechnologies], + }, + [AugmentationName.PCDNIOptimizer]: { + repCost: 5e5, + moneyCost: 4.5e9, + info: + "This is a submodule upgrade to the PC Direct-Neural Interface augmentation. It " + + "improves the performance of the interface and gives the user more control options " + + "to a connected computer.", + prereqs: [AugmentationName.PCDNI], + company_rep: 1.75, + hacking: 1.1, + factions: [FactionName.FulcrumSecretTechnologies, FactionName.ECorp, FactionName.BladeIndustries], + }, + [AugmentationName.PCMatrix]: { + repCost: 100e3, + moneyCost: 2e9, + info: + "A 'Probability Computation Matrix' is installed in the frontal cortex. This implant " + + "uses advanced mathematical algorithms to rapidly identify and compute statistical " + + "outcomes of nearly every situation.", + charisma: 1.0777, + charisma_exp: 1.0777, + work_money: 1.777, + faction_rep: 1.0777, + company_rep: 1.0777, + crime_success: 1.0777, + crime_money: 1.0777, + programs: [CompletedProgramName.deepScan1, CompletedProgramName.autoLink], + factions: [FactionName.Aevum], + }, + [AugmentationName.PhotosyntheticCells]: { + repCost: 5.625e5, + moneyCost: 2.75e9, + info: + "Chloroplasts are added to epidermal stem cells and are applied " + + "to the body using a skin graft. The result is photosynthetic " + + "skin cells, allowing users to generate their own energy " + + "and nutrition using solar power.", + strength: 1.4, + defense: 1.4, + agility: 1.4, + factions: [FactionName.KuaiGongInternational], + }, + [AugmentationName.PowerRecirculator]: { + repCost: 2.5e4, + moneyCost: 1.8e8, + info: + "The body's nerves are attached with polypyrrole nanocircuits that " + + "are capable of capturing wasted energy, in the form of heat, " + + "and converting it back into usable power.", + hacking: 1.05, + strength: 1.05, + defense: 1.05, + dexterity: 1.05, + agility: 1.05, + charisma: 1.05, + hacking_exp: 1.1, + strength_exp: 1.1, + defense_exp: 1.1, + dexterity_exp: 1.1, + agility_exp: 1.1, + charisma_exp: 1.1, + factions: [FactionName.Tetrads, FactionName.TheDarkArmy, FactionName.TheSyndicate, FactionName.NWO], + }, + // === Q === // + [AugmentationName.QLink]: { + repCost: 1.875e6, + moneyCost: 2.5e13, + info: + `A brain implant that wirelessly connects you to the ${FactionName.Illuminati}'s ` + + "quantum supercomputer, allowing you to access and use its incredible " + + "computing power.", + hacking: 1.75, + hacking_speed: 2, + hacking_chance: 2.5, + hacking_money: 4, + factions: [FactionName.Illuminati], + }, + // === R === // + // === S === // + [AugmentationName.SNA]: { + repCost: 6.25e3, + moneyCost: 3e7, + info: + "A cranial implant that affects the user's personality, making them better " + + "at negotiation in social situations.", + work_money: 1.1, + company_rep: 1.15, + faction_rep: 1.15, + factions: [FactionName.TianDiHui], + }, + [AugmentationName.SPTN97]: { + repCost: 1.25e6, + moneyCost: 4.875e9, + info: + "The SPTN-97 gene is injected into the genome. The SPTN-97 gene is an " + + "artificially-synthesized gene that was developed by DARPA to create " + + "super-soldiers through genetic modification. The gene was outlawed in " + + "2056.", + strength: 1.75, + defense: 1.75, + dexterity: 1.75, + agility: 1.75, + hacking: 1.15, + factions: [FactionName.TheCovenant], + }, + [AugmentationName.ShadowsSimulacrum]: { + repCost: 3.75e4, + moneyCost: 4e8, + info: + "A crude but functional matter phase-shifter module that is embedded " + + "in the brainstem and cerebellum. This augmentation was developed by " + + "criminal organizations and allows the user to project and control holographic " + + "simulacrums within a large radius. These simulacrums are commonly used for " + + "espionage and surveillance work.", + company_rep: 1.15, + faction_rep: 1.15, + factions: [FactionName.TheSyndicate, FactionName.TheDarkArmy, FactionName.SpeakersForTheDead], + }, + [AugmentationName.SmartJaw]: { + repCost: 3.75e5, + moneyCost: 2.75e9, + info: + "A bionic jaw that contains advanced hardware and software " + + "capable of psychoanalyzing and profiling the personality of " + + "others using optical imaging software.", + charisma: 1.5, + charisma_exp: 1.5, + company_rep: 1.25, + faction_rep: 1.25, + factions: [FactionName.BachmanAssociates], + }, + [AugmentationName.SmartSonar]: { + repCost: 2.25e4, + moneyCost: 7.5e7, + info: "A cochlear implant that helps the player detect and locate enemies using sound propagation.", + dexterity: 1.1, + dexterity_exp: 1.15, + crime_money: 1.25, + factions: [FactionName.SlumSnakes], + }, + [AugmentationName.SpeechEnhancement]: { + repCost: 2.5e3, + moneyCost: 1.25e7, + info: + "An advanced neural implant that improves your speaking abilities, making " + + "you more convincing and likable in conversations and overall improving your " + + "social interactions.", + company_rep: 1.1, + charisma: 1.1, + factions: [ + FactionName.TianDiHui, + FactionName.SpeakersForTheDead, + FactionName.FourSigma, + FactionName.KuaiGongInternational, + FactionName.ClarkeIncorporated, + FactionName.BachmanAssociates, + ], + }, + [AugmentationName.SpeechProcessor]: { + repCost: 7.5e3, + moneyCost: 5e7, + info: + "A cochlear implant with an embedded computer that analyzes incoming speech. " + + "The embedded computer processes characteristics of incoming speech, such as tone " + + "and inflection, to pick up on subtle cues and aid in social interactions.", + charisma: 1.2, + factions: [ + FactionName.TianDiHui, + FactionName.Chongqing, + FactionName.Sector12, + FactionName.NewTokyo, + FactionName.Aevum, + FactionName.Ishima, + FactionName.Volhaven, + FactionName.Silhouette, + ], + }, + [AugmentationName.StaneksGift1]: { + repCost: 0, + moneyCost: 0, + info: + 'Allison "Mother" Stanek imparts you with her gift. An ' + + "experimental Augmentation implanted at the base of the neck. " + + "It allows you to overclock your entire system by carefully " + + "changing the configuration.", + isSpecial: true, + hacking_chance: 0.9, + hacking_speed: 0.9, + hacking_money: 0.9, + hacking_grow: 0.9, + hacking: 0.9, + strength: 0.9, + defense: 0.9, + dexterity: 0.9, + agility: 0.9, + charisma: 0.9, + hacking_exp: 0.9, + strength_exp: 0.9, + defense_exp: 0.9, + dexterity_exp: 0.9, + agility_exp: 0.9, + charisma_exp: 0.9, + company_rep: 0.9, + faction_rep: 0.9, + crime_money: 0.9, + crime_success: 0.9, + hacknet_node_money: 0.9, + hacknet_node_purchase_cost: 1.1, + hacknet_node_ram_cost: 1.1, + hacknet_node_core_cost: 1.1, + hacknet_node_level_cost: 1.1, + work_money: 0.9, + stats: "Its unstable nature decreases all your stats by 10%", + factions: [FactionName.ChurchOfTheMachineGod], + }, + [AugmentationName.StaneksGift2]: { + repCost: 1e6, + moneyCost: 0, + info: + "The next evolution is near, a coming together of man and machine. A synthesis greater than the birth of the human " + + "organism. Time spent with the gift has allowed for acclimatization of the invasive augment and the toll it takes upon " + + "your frame granting a 5% reduced penalty to all stats.", + prereqs: [AugmentationName.StaneksGift1], + isSpecial: true, + hacking_chance: 0.95 / 0.9, + hacking_speed: 0.95 / 0.9, + hacking_money: 0.95 / 0.9, + hacking_grow: 0.95 / 0.9, + hacking: 0.95 / 0.9, + strength: 0.95 / 0.9, + defense: 0.95 / 0.9, + dexterity: 0.95 / 0.9, + agility: 0.95 / 0.9, + charisma: 0.95 / 0.9, + hacking_exp: 0.95 / 0.9, + strength_exp: 0.95 / 0.9, + defense_exp: 0.95 / 0.9, + dexterity_exp: 0.95 / 0.9, + agility_exp: 0.95 / 0.9, + charisma_exp: 0.95 / 0.9, + company_rep: 0.95 / 0.9, + faction_rep: 0.95 / 0.9, + crime_money: 0.95 / 0.9, + crime_success: 0.95 / 0.9, + hacknet_node_money: 0.95 / 0.9, + hacknet_node_purchase_cost: 1.05 / 1.1, + hacknet_node_ram_cost: 1.05 / 1.1, + hacknet_node_core_cost: 1.05 / 1.1, + hacknet_node_level_cost: 1.05 / 1.1, + work_money: 0.95 / 0.9, + stats: "The penalty for the gift is reduced to 5%", + factions: [FactionName.ChurchOfTheMachineGod], + }, + [AugmentationName.StaneksGift3]: { + repCost: 1e8, + moneyCost: 0, + info: + "The synthesis of human and machine is nothing to fear. It is our destiny. " + + "You will become greater than the sum of our parts. As One. Embrace your gift " + + "fully and wholly free of it's accursed toll. Serenity brings tranquility in the form " + + "of no longer suffering a stat penalty. ", + prereqs: [AugmentationName.StaneksGift2, AugmentationName.StaneksGift1], + isSpecial: true, + hacking_chance: 1 / 0.95, + hacking_speed: 1 / 0.95, + hacking_money: 1 / 0.95, + hacking_grow: 1 / 0.95, + hacking: 1 / 0.95, + strength: 1 / 0.95, + defense: 1 / 0.95, + dexterity: 1 / 0.95, + agility: 1 / 0.95, + charisma: 1 / 0.95, + hacking_exp: 1 / 0.95, + strength_exp: 1 / 0.95, + defense_exp: 1 / 0.95, + dexterity_exp: 1 / 0.95, + agility_exp: 1 / 0.95, + charisma_exp: 1 / 0.95, + company_rep: 1 / 0.95, + faction_rep: 1 / 0.95, + crime_money: 1 / 0.95, + crime_success: 1 / 0.95, + hacknet_node_money: 1 / 0.95, + hacknet_node_purchase_cost: 1 / 1.05, + hacknet_node_ram_cost: 1 / 1.05, + hacknet_node_core_cost: 1 / 1.05, + hacknet_node_level_cost: 1 / 1.05, + work_money: 1 / 0.95, + stats: "Stanek's Gift has no penalty.", + factions: [FactionName.ChurchOfTheMachineGod], + }, + [AugmentationName.SubdermalArmor]: { + repCost: 8.75e5, + moneyCost: 3.25e9, + info: + "The NEMEAN Subdermal Weave is a thin, light-weight, graphene plating that houses a dilatant fluid. " + + "The material is implanted underneath the skin, and is the most advanced form of defensive enhancement " + + "that has ever been created. The dilatant fluid, despite being thin and light, is extremely effective " + + "at stopping piercing blows and reducing blunt trauma. The properties of graphene allow the plating to " + + "mitigate damage from any fire or electrical traumas.", + defense: 2.2, + factions: [ + FactionName.TheSyndicate, + FactionName.FulcrumSecretTechnologies, + FactionName.Illuminati, + FactionName.Daedalus, + FactionName.TheCovenant, + ], + }, + [AugmentationName.SynapticEnhancement]: { + repCost: 2e3, + moneyCost: 7.5e6, + info: + "A small cranial implant that continuously uses weak electrical signals to stimulate the brain and " + + "induce stronger synaptic activity. This improves the user's cognitive abilities.", + hacking_speed: 1.03, + factions: [FactionName.CyberSec, FactionName.Aevum], + }, + [AugmentationName.SynfibrilMuscle]: { + repCost: 4.375e5, + moneyCost: 1.125e9, + info: + "The myofibrils in human muscles are injected with special chemicals that react with the proteins inside " + + "the myofibrils, altering their underlying structure. The end result is muscles that are stronger and more elastic. " + + "Scientists have named these artificially enhanced units 'synfibrils'.", + strength: 1.3, + defense: 1.3, + factions: [ + FactionName.KuaiGongInternational, + FactionName.FulcrumSecretTechnologies, + FactionName.SpeakersForTheDead, + FactionName.NWO, + FactionName.TheCovenant, + FactionName.Daedalus, + FactionName.Illuminati, + FactionName.BladeIndustries, + ], + }, + [AugmentationName.SyntheticHeart]: { + moneyCost: 2.875e9, + repCost: 7.5e5, + info: + "This advanced artificial heart, created from plasteel and graphene, is capable of pumping blood " + + "more efficiently than an organic heart.", + agility: 1.5, + strength: 1.5, + factions: [ + FactionName.KuaiGongInternational, + FactionName.FulcrumSecretTechnologies, + FactionName.SpeakersForTheDead, + FactionName.NWO, + FactionName.TheCovenant, + FactionName.Daedalus, + FactionName.Illuminati, + ], + }, + // === T === // + [AugmentationName.TITN41Injection]: { + repCost: 2.5e4, + moneyCost: 1.9e8, + info: + "TITN is a series of viruses that targets and alters the sequences of human DNA in genes that " + + "control personality. The TITN-41 strain alters these genes so that the subject becomes more " + + "outgoing and sociable.", + charisma: 1.15, + charisma_exp: 1.15, + factions: [FactionName.Silhouette], + }, + [AugmentationName.Targeting1]: { + moneyCost: 1.5e7, + repCost: 5e3, + info: + "A cranial implant that is embedded within the inner ear structures and optic nerves. It regulates " + + "and enhances balance and hand-eye coordination.", + dexterity: 1.1, + factions: [ + FactionName.SlumSnakes, + FactionName.TheDarkArmy, + FactionName.TheSyndicate, + FactionName.Sector12, + FactionName.Ishima, + FactionName.OmniTekIncorporated, + FactionName.KuaiGongInternational, + FactionName.BladeIndustries, + ], + }, + [AugmentationName.Targeting2]: { + moneyCost: 4.25e7, + repCost: 8.75e3, + info: + "This upgraded version of the 'Augmented Targeting' implant is capable of augmenting " + + "reality by digitally displaying weaknesses and vital signs of threats.", + prereqs: [AugmentationName.Targeting1], + dexterity: 1.2, + factions: [ + FactionName.TheDarkArmy, + FactionName.TheSyndicate, + FactionName.Sector12, + FactionName.OmniTekIncorporated, + FactionName.KuaiGongInternational, + FactionName.BladeIndustries, + ], + }, + [AugmentationName.Targeting3]: { + moneyCost: 1.15e8, + repCost: 2.75e4, + info: "The latest version of the 'Augmented Targeting' implant adds the ability to lock-on and track threats.", + prereqs: [AugmentationName.Targeting2, AugmentationName.Targeting1], + dexterity: 1.3, + factions: [ + FactionName.TheDarkArmy, + FactionName.TheSyndicate, + FactionName.OmniTekIncorporated, + FactionName.KuaiGongInternational, + FactionName.BladeIndustries, + FactionName.TheCovenant, + ], + }, + [AugmentationName.TheBlackHand]: { + repCost: 1e5, + moneyCost: 5.5e8, + info: + "A highly advanced bionic hand. This prosthetic not only " + + "enhances strength and dexterity but it is also embedded " + + "with hardware and firmware that lets the user connect to, access, and hack " + + "devices and machines by just touching them.", + strength: 1.15, + dexterity: 1.15, + hacking: 1.1, + hacking_speed: 1.02, + hacking_money: 1.1, + factions: [FactionName.TheBlackHand], + }, + [AugmentationName.TheRedPill]: { + repCost: 2.5e6, + moneyCost: 0, + info: "It's time to leave the cave.", + stats: "", + isSpecial: true, + factions: [FactionName.Daedalus], + }, + [AugmentationName.TrickeryOfHermes]: { + repCost: 1e4, + moneyCost: 1e6, + info: "Penta-dynamo-neurovascular-valve inserted in the carpal ligament, enhances dexterity.", + stats: "This augmentation makes the Cheat Code minigame easier by allowing the opposite character.", + isSpecial: true, + factions: [FactionName.ShadowsOfAnarchy], + }, + // === U === // + [AugmentationName.UnstableCircadianModulator]: getUnstableCircadianModulatorParams(), + // === V === // + [AugmentationName.VangelisVirus]: { + repCost: 1.875e4, + moneyCost: 2.75e9, + info: + "A synthetic symbiotic virus that is injected into human brain tissue. The Vangelis virus " + + "heightens the senses and focus of its host, and also enhances its intuition.", + dexterity_exp: 1.1, + bladeburner_analysis: 1.1, + bladeburner_success_chance: 1.04, + isSpecial: true, + factions: [FactionName.Bladeburners], + }, + [AugmentationName.VangelisVirus3]: { + repCost: 3.75e4, + moneyCost: 1.1e10, + info: + "An improved version of Vangelis, a synthetic symbiotic virus that is " + + "injected into human brain tissue. On top of the benefits of the original " + + "virus, this also grants accelerated healing and enhanced " + + "reflexes.", + prereqs: [AugmentationName.VangelisVirus], + defense_exp: 1.1, + dexterity_exp: 1.1, + bladeburner_analysis: 1.15, + bladeburner_success_chance: 1.05, + isSpecial: true, + factions: [FactionName.Bladeburners], + }, + // === W === // + [AugmentationName.WKSharmonizer]: { + repCost: 1e4, + moneyCost: 1e6, + info: + `A copy of the WKS harmonizer from the MIA leader of the ${FactionName.ShadowsOfAnarchy} ` + + "injects *Γ-based cells that provides general enhancement to the body.", + stats: + "This augmentation makes many aspects of infiltration easier and more productive, via increased timer and rewards, reduced damage taken, etc.", + isSpecial: true, + factions: [FactionName.ShadowsOfAnarchy], + }, + [AugmentationName.WiredReflexes]: { + repCost: 1.25e3, + moneyCost: 2.5e6, + info: + "Synthetic nerve-enhancements are injected into all major parts of the somatic nervous system, " + + "supercharging the spread of neural signals and increasing reflex speed.", + agility: 1.05, + dexterity: 1.05, + factions: [ + FactionName.TianDiHui, + FactionName.SlumSnakes, + FactionName.Sector12, + FactionName.Volhaven, + FactionName.Aevum, + FactionName.Ishima, + FactionName.TheSyndicate, + FactionName.TheDarkArmy, + FactionName.SpeakersForTheDead, + ], + }, + [AugmentationName.WisdomOfAthena]: { + repCost: 1e4, + moneyCost: 1e6, + info: "A connective brain implant to SASHA that focuses on pattern recognition and predictive templating.", + stats: "This augmentation makes the Bracket minigame easier by removing all '[' ']'.", + isSpecial: true, + factions: [FactionName.ShadowsOfAnarchy], + }, + // === X === // + [AugmentationName.Xanipher]: { + repCost: 8.75e5, + moneyCost: 4.25e9, + info: + "A concoction of advanced nanobots that is orally ingested into the " + + "body. These nanobots induce physiological changes and significantly " + + "improve the body's functioning in all aspects.", + hacking: 1.2, + strength: 1.2, + defense: 1.2, + dexterity: 1.2, + agility: 1.2, + charisma: 1.2, + hacking_exp: 1.15, + strength_exp: 1.15, + defense_exp: 1.15, + dexterity_exp: 1.15, + agility_exp: 1.15, + charisma_exp: 1.15, + factions: [FactionName.NWO], + }, + // === Y === // + // === Z === // + [AugmentationName.ZOE]: { + isSpecial: true, + repCost: Infinity, + moneyCost: 1e12, + info: + "Zoë's Omnicerebrum Ënhancer for sleeves inserts an omnicerebrum into your sleeve. " + + "An omnicerebrum is a near perfect simulation of the human brain, allowing it to take advantage of a larger variety of augments. " + + "But you should know about this BitRunner, since you have one of these yourself!", + stats: "Allows sleeves to benefit from Stanek's Gift but it is less powerful if several are installed.", + factions: [ + /*Technically in FactionNames.ChurchOfTheMachineGod but not really for display reasons */ + ], + }, + }; + return createEnumKeyedRecord(AugmentationName, (name) => { + const params = metadata[name] as AugmentationCtorParams; + params.name = name; + return new Augmentation(params); + }); +})(); + +export function initCircadianModulator() { + const params = getUnstableCircadianModulatorParams() as AugmentationCtorParams; + params.name = AugmentationName.UnstableCircadianModulator; + Augmentations[AugmentationName.UnstableCircadianModulator] = new Augmentation(params); +} + +// new Augmentation({ +// name: AugmentationNames.UnnamedAug2, +// repCost: 500e3, +// moneyCost: 5e9, +// info: "Undecided description", +// startingMoney: 100e6, +// programs: [Programs.HTTPWormProgram.name, Programs.SQLInjectProgram.name], +// factions: [FactionNames.OmniTekIncorporated], +// }), diff --git a/src/Augmentation/CircadianModulator.ts b/src/Augmentation/CircadianModulator.ts new file mode 100644 index 000000000..dc2238861 --- /dev/null +++ b/src/Augmentation/CircadianModulator.ts @@ -0,0 +1,119 @@ +// This is in a separate file from the normal augmentation helpers to limit import impact on Augmentations.ts + +import { Multipliers } from "@nsdefs"; +import { FactionName } from "@enums"; +import { AugmentationCtorParams } from "./Augmentation"; +import { getRecordKeys } from "../Types/Record"; +import { WHRNG } from "../Casino/RNG"; + +export function getUnstableCircadianModulatorParams(): Omit { + //Time-Based Augment Test + const randomBonuses = getRandomBonus(); + + const UnstableCircadianModulatorParams: Omit = { + moneyCost: 5e9, + repCost: 3.625e5, + info: + "An experimental nanobot injection. Its unstable nature leads to " + + "unpredictable results based on your circadian rhythm.", + factions: [FactionName.SpeakersForTheDead], + }; + getRecordKeys(randomBonuses.bonuses).forEach( + (key) => (UnstableCircadianModulatorParams[key] = randomBonuses.bonuses[key]), + ); + + return UnstableCircadianModulatorParams; +} + +interface CircadianBonus { + bonuses: Partial; + description: string; +} + +function getRandomBonus(): CircadianBonus { + const bonuses = [ + { + bonuses: { + hacking_chance: 1.25, + hacking_speed: 1.1, + hacking_money: 1.25, + hacking_grow: 1.1, + }, + description: + "Increases the player's hacking chance by 25%.\n" + + "Increases the player's hacking speed by 10%.\n" + + "Increases the amount of money the player's gains from hacking by 25%.\n" + + "Improves grow() by 10%.", + }, + { + bonuses: { + hacking: 1.15, + hacking_exp: 2, + }, + description: + "Increases the player's hacking skill by 15%.\n" + + "Increases the player's hacking experience gain rate by 100%.", + }, + { + bonuses: { + strength: 1.25, + strength_exp: 2, + defense: 1.25, + defense_exp: 2, + dexterity: 1.25, + dexterity_exp: 2, + agility: 1.25, + agility_exp: 2, + }, + description: + "Increases all of the player's combat stats by 25%.\n" + + "Increases all of the player's combat stat experience gain rate by 100%.", + }, + { + bonuses: { + charisma: 1.5, + charisma_exp: 2, + }, + description: + "This augmentation increases the player's charisma by 50%.\n" + + "Increases the player's charisma experience gain rate by 100%.", + }, + { + bonuses: { + hacknet_node_money: 1.2, + hacknet_node_purchase_cost: 0.85, + hacknet_node_ram_cost: 0.85, + hacknet_node_core_cost: 0.85, + hacknet_node_level_cost: 0.85, + }, + description: + "Increases the amount of money produced by Hacknet Nodes by 20%.\n" + + "Decreases all costs related to Hacknet Node by 15%.", + }, + { + bonuses: { + company_rep: 1.25, + faction_rep: 1.15, + work_money: 1.7, + }, + description: + "Increases the amount of money the player gains from working by 70%.\n" + + "Increases the amount of reputation the player gains when working for a company by 25%.\n" + + "Increases the amount of reputation the player gains for a faction by 15%.", + }, + { + bonuses: { + crime_success: 2, + crime_money: 2, + }, + description: + "Increases the player's crime success rate by 100%.\n" + + "Increases the amount of money the player gains from crimes by 100%.", + }, + ]; + + const randomNumber = new WHRNG(Math.floor(Date.now() / 3600000)); + for (let i = 0; i < 5; i++) randomNumber.step(); + + return bonuses[Math.floor(bonuses.length * randomNumber.random())]; +} diff --git a/src/Augmentation/PlayerOwnedAugmentation.ts b/src/Augmentation/PlayerOwnedAugmentation.ts index b762b2e41..024b3a9b8 100644 --- a/src/Augmentation/PlayerOwnedAugmentation.ts +++ b/src/Augmentation/PlayerOwnedAugmentation.ts @@ -1,8 +1,10 @@ +import type { AugmentationName } from "./Enums"; + export class PlayerOwnedAugmentation { level = 1; - name = ""; + name: AugmentationName; - constructor(name = "") { + constructor(name: AugmentationName) { this.name = name; } } diff --git a/src/Augmentation/StaticAugmentations.ts b/src/Augmentation/StaticAugmentations.ts deleted file mode 100644 index 68ea0046a..000000000 --- a/src/Augmentation/StaticAugmentations.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { Augmentation } from "./Augmentation"; - -export const StaticAugmentations: Record = {}; diff --git a/src/Augmentation/data/AugmentationCreator.tsx b/src/Augmentation/data/AugmentationCreator.tsx deleted file mode 100644 index 38824b891..000000000 --- a/src/Augmentation/data/AugmentationCreator.tsx +++ /dev/null @@ -1,2184 +0,0 @@ -import React from "react"; -import { Player } from "@player"; -import { AugmentationName, CompletedProgramName, FactionName } from "@enums"; -import { Augmentation, IConstructorParams } from "../Augmentation"; -import { WHRNG } from "../../Casino/RNG"; -import { CONSTANTS } from "../../Constants"; - -interface CircadianBonus { - bonuses: { - [key: string]: number | undefined; - agility?: number; - agility_exp?: number; - charisma?: number; - charisma_exp?: number; - company_rep?: number; - crime_money?: number; - crime_success?: number; - defense?: number; - defense_exp?: number; - dexterity?: number; - dexterity_exp?: number; - faction_rep?: number; - hacking?: number; - hacking_chance?: number; - hacking_exp?: number; - hacking_grow?: number; - hacking_money?: number; - hacking_speed?: number; - hacknet_node_core_cost?: number; - hacknet_node_level_cost?: number; - hacknet_node_money?: number; - hacknet_node_purchase_cost?: number; - hacknet_node_ram_cost?: number; - strength?: number; - strength_exp?: number; - work_money?: number; - }; - description: string; -} - -function getRandomBonus(): CircadianBonus { - const bonuses = [ - { - bonuses: { - hacking_chance: 1.25, - hacking_speed: 1.1, - hacking_money: 1.25, - hacking_grow: 1.1, - }, - description: - "Increases the player's hacking chance by 25%.
" + - "Increases the player's hacking speed by 10%.
" + - "Increases the amount of money the player's gains from hacking by 25%.
" + - "Improves grow() by 10%.", - }, - { - bonuses: { - hacking: 1.15, - hacking_exp: 2, - }, - description: - "Increases the player's hacking skill by 15%.
" + - "Increases the player's hacking experience gain rate by 100%.", - }, - { - bonuses: { - strength: 1.25, - strength_exp: 2, - defense: 1.25, - defense_exp: 2, - dexterity: 1.25, - dexterity_exp: 2, - agility: 1.25, - agility_exp: 2, - }, - description: - "Increases all of the player's combat stats by 25%.
" + - "Increases all of the player's combat stat experience gain rate by 100%.", - }, - { - bonuses: { - charisma: 1.5, - charisma_exp: 2, - }, - description: - "This augmentation increases the player's charisma by 50%.
" + - "Increases the player's charisma experience gain rate by 100%.", - }, - { - bonuses: { - hacknet_node_money: 1.2, - hacknet_node_purchase_cost: 0.85, - hacknet_node_ram_cost: 0.85, - hacknet_node_core_cost: 0.85, - hacknet_node_level_cost: 0.85, - }, - description: - "Increases the amount of money produced by Hacknet Nodes by 20%.
" + - "Decreases all costs related to Hacknet Node by 15%.", - }, - { - bonuses: { - company_rep: 1.25, - faction_rep: 1.15, - work_money: 1.7, - }, - description: - "Increases the amount of money the player gains from working by 70%.
" + - "Increases the amount of reputation the player gains when working for a company by 25%.
" + - "Increases the amount of reputation the player gains for a faction by 15%.", - }, - { - bonuses: { - crime_success: 2, - crime_money: 2, - }, - description: - "Increases the player's crime success rate by 100%.
" + - "Increases the amount of money the player gains from crimes by 100%.", - }, - ]; - - const randomNumber = new WHRNG(Math.floor(Player.lastUpdate / 3600000)); - for (let i = 0; i < 5; i++) randomNumber.step(); - - return bonuses[Math.floor(bonuses.length * randomNumber.random())]; -} - -export const initSoAAugmentations = (): Augmentation[] => [ - new Augmentation({ - name: AugmentationName.WKSharmonizer, - repCost: 1e4, - moneyCost: 1e6, - info: - `A copy of the WKS harmonizer from the MIA leader of the ${FactionName.ShadowsOfAnarchy} ` + - "injects *Γ-based cells that provides general enhancement to the body.", - stats: ( - <> - This augmentation makes many aspects of infiltration easier and more productive. Such as increased timer, - rewards, reduced damage taken, etc. - - ), - isSpecial: true, - factions: [FactionName.ShadowsOfAnarchy], - }), - new Augmentation({ - name: AugmentationName.MightOfAres, - repCost: 1e4, - moneyCost: 1e6, - info: - "Extra-ocular neurons taken from old martial art master. Injecting them gives the user the ability to " + - "predict the enemy's attack before they even know it themselves.", - stats: ( - <>This augmentation makes the Slash minigame easier by showing you via an indicator when the slash in coming. - ), - isSpecial: true, - factions: [FactionName.ShadowsOfAnarchy], - }), - new Augmentation({ - name: AugmentationName.WisdomOfAthena, - repCost: 1e4, - moneyCost: 1e6, - info: "A connective brain implant to SASHA that focuses on pattern recognition and predictive templating.", - stats: <>This augmentation makes the Bracket minigame easier by removing all '[' ']'., - isSpecial: true, - factions: [FactionName.ShadowsOfAnarchy], - }), - new Augmentation({ - name: AugmentationName.ChaosOfDionysus, - repCost: 1e4, - moneyCost: 1e6, - info: "Opto-occipito implant to process visual signals before brain interpretation.", - stats: <>This augmentation makes the Backwards minigame easier by flipping the words., - isSpecial: true, - factions: [FactionName.ShadowsOfAnarchy], - }), - new Augmentation({ - name: AugmentationName.BeautyOfAphrodite, - repCost: 1e4, - moneyCost: 1e6, - info: - "Pheromone extruder injected in the thoracodorsal nerve. Emits pleasing scent guaranteed to " + - "make conversational partners more agreeable.", - stats: <>This augmentation makes the Bribe minigame easier by indicating the incorrect paths., - isSpecial: true, - factions: [FactionName.ShadowsOfAnarchy], - }), - new Augmentation({ - name: AugmentationName.TrickeryOfHermes, - repCost: 1e4, - moneyCost: 1e6, - info: "Penta-dynamo-neurovascular-valve inserted in the carpal ligament, enhances dexterity.", - stats: <>This augmentation makes the Cheat Code minigame easier by allowing the opposite character., - isSpecial: true, - factions: [FactionName.ShadowsOfAnarchy], - }), - new Augmentation({ - name: AugmentationName.FloodOfPoseidon, - repCost: 1e4, - moneyCost: 1e6, - info: "Transtinatium VVD reticulator used in optico-sterbing recognition.", - stats: <>This augmentation makes the Symbol matching minigame easier by indicating the correct choice., - isSpecial: true, - factions: [FactionName.ShadowsOfAnarchy], - }), - new Augmentation({ - name: AugmentationName.HuntOfArtemis, - repCost: 1e4, - moneyCost: 1e6, - info: "magneto-turboencabulator based on technology by Micha Eike Siemon, increases the user's electro-magnetic sensitivity.", - stats: ( - <> - This augmentation makes the Minesweeper minigame easier by showing the location of all mines and keeping their - position. - - ), - isSpecial: true, - factions: [FactionName.ShadowsOfAnarchy], - }), - new Augmentation({ - name: AugmentationName.KnowledgeOfApollo, - repCost: 1e4, - moneyCost: 1e6, - info: "Neodynic retention fjengeln spoofer using -φ karmions, net positive effect on implantee's delta wave.", - stats: <>This augmentation makes the Wire Cutting minigame easier by indicating the incorrect wires., - isSpecial: true, - factions: [FactionName.ShadowsOfAnarchy], - }), -]; - -export const initGeneralAugmentations = (): Augmentation[] => [ - new Augmentation({ - name: AugmentationName.HemoRecirculator, - moneyCost: 4.5e7, - repCost: 1e4, - info: "A heart implant that greatly increases the body's ability to effectively use and pump blood.", - strength: 1.08, - defense: 1.08, - agility: 1.08, - dexterity: 1.08, - factions: [FactionName.Tetrads, FactionName.TheDarkArmy, FactionName.TheSyndicate], - }), - new Augmentation({ - name: AugmentationName.Targeting1, - moneyCost: 1.5e7, - repCost: 5e3, - info: - "A cranial implant that is embedded within the inner ear structures and optic nerves. It regulates " + - "and enhances balance and hand-eye coordination.", - dexterity: 1.1, - factions: [ - FactionName.SlumSnakes, - FactionName.TheDarkArmy, - FactionName.TheSyndicate, - FactionName.Sector12, - FactionName.Ishima, - FactionName.OmniTekIncorporated, - FactionName.KuaiGongInternational, - FactionName.BladeIndustries, - ], - }), - new Augmentation({ - name: AugmentationName.Targeting2, - moneyCost: 4.25e7, - repCost: 8.75e3, - info: - "This upgraded version of the 'Augmented Targeting' implant is capable of augmenting " + - "reality by digitally displaying weaknesses and vital signs of threats.", - prereqs: [AugmentationName.Targeting1], - dexterity: 1.2, - factions: [ - FactionName.TheDarkArmy, - FactionName.TheSyndicate, - FactionName.Sector12, - FactionName.OmniTekIncorporated, - FactionName.KuaiGongInternational, - FactionName.BladeIndustries, - ], - }), - new Augmentation({ - name: AugmentationName.Targeting3, - moneyCost: 1.15e8, - repCost: 2.75e4, - info: "The latest version of the 'Augmented Targeting' implant adds the ability to lock-on and track threats.", - prereqs: [AugmentationName.Targeting2, AugmentationName.Targeting1], - dexterity: 1.3, - factions: [ - FactionName.TheDarkArmy, - FactionName.TheSyndicate, - FactionName.OmniTekIncorporated, - FactionName.KuaiGongInternational, - FactionName.BladeIndustries, - FactionName.TheCovenant, - ], - }), - new Augmentation({ - name: AugmentationName.SyntheticHeart, - moneyCost: 2.875e9, - repCost: 7.5e5, - info: - "This advanced artificial heart, created from plasteel and graphene, is capable of pumping blood " + - "more efficiently than an organic heart.", - agility: 1.5, - strength: 1.5, - factions: [ - FactionName.KuaiGongInternational, - FactionName.FulcrumSecretTechnologies, - FactionName.SpeakersForTheDead, - FactionName.NWO, - FactionName.TheCovenant, - FactionName.Daedalus, - FactionName.Illuminati, - ], - }), - new Augmentation({ - name: AugmentationName.SynfibrilMuscle, - repCost: 4.375e5, - moneyCost: 1.125e9, - info: - "The myofibrils in human muscles are injected with special chemicals that react with the proteins inside " + - "the myofibrils, altering their underlying structure. The end result is muscles that are stronger and more elastic. " + - "Scientists have named these artificially enhanced units 'synfibrils'.", - strength: 1.3, - defense: 1.3, - factions: [ - FactionName.KuaiGongInternational, - FactionName.FulcrumSecretTechnologies, - FactionName.SpeakersForTheDead, - FactionName.NWO, - FactionName.TheCovenant, - FactionName.Daedalus, - FactionName.Illuminati, - FactionName.BladeIndustries, - ], - }), - new Augmentation({ - name: AugmentationName.CombatRib1, - repCost: 7.5e3, - moneyCost: 2.375e7, - info: - "The rib cage is augmented to continuously release boosters into the bloodstream " + - "which increase the oxygen-carrying capacity of blood.", - strength: 1.1, - defense: 1.1, - factions: [ - FactionName.SlumSnakes, - FactionName.TheDarkArmy, - FactionName.TheSyndicate, - FactionName.Volhaven, - FactionName.Ishima, - FactionName.OmniTekIncorporated, - FactionName.KuaiGongInternational, - FactionName.BladeIndustries, - ], - }), - new Augmentation({ - name: AugmentationName.CombatRib2, - repCost: 1.875e4, - moneyCost: 6.5e7, - info: - "An upgraded version of the 'Combat Rib' augmentation that adds potent stimulants which " + - "improve focus and endurance while decreasing reaction time and fatigue.", - prereqs: [AugmentationName.CombatRib1], - strength: 1.14, - defense: 1.14, - factions: [ - FactionName.TheDarkArmy, - FactionName.TheSyndicate, - FactionName.Volhaven, - FactionName.OmniTekIncorporated, - FactionName.KuaiGongInternational, - FactionName.BladeIndustries, - ], - }), - new Augmentation({ - name: AugmentationName.CombatRib3, - repCost: 3.5e4, - moneyCost: 1.2e8, - info: - "The latest version of the 'Combat Rib' augmentation releases advanced anabolic steroids that " + - "improve muscle mass and physical performance while being safe and free of side effects.", - prereqs: [AugmentationName.CombatRib2, AugmentationName.CombatRib1], - strength: 1.18, - defense: 1.18, - factions: [ - FactionName.TheDarkArmy, - FactionName.TheSyndicate, - FactionName.OmniTekIncorporated, - FactionName.KuaiGongInternational, - FactionName.BladeIndustries, - FactionName.TheCovenant, - ], - }), - new Augmentation({ - name: AugmentationName.NanofiberWeave, - repCost: 3.75e4, - moneyCost: 1.25e8, - info: - "Synthetic nanofibers are woven into the skin's extracellular matrix using electrospinning, " + - "which improves its regenerative and extracellular homeostasis abilities.", - strength: 1.2, - defense: 1.2, - factions: [ - FactionName.TheDarkArmy, - FactionName.TheSyndicate, - FactionName.OmniTekIncorporated, - FactionName.BladeIndustries, - FactionName.TianDiHui, - FactionName.SpeakersForTheDead, - FactionName.FulcrumSecretTechnologies, - ], - }), - new Augmentation({ - name: AugmentationName.SubdermalArmor, - repCost: 8.75e5, - moneyCost: 3.25e9, - info: - "The NEMEAN Subdermal Weave is a thin, light-weight, graphene plating that houses a dilatant fluid. " + - "The material is implanted underneath the skin, and is the most advanced form of defensive enhancement " + - "that has ever been created. The dilatant fluid, despite being thin and light, is extremely effective " + - "at stopping piercing blows and reducing blunt trauma. The properties of graphene allow the plating to " + - "mitigate damage from any fire or electrical traumas.", - defense: 2.2, - factions: [ - FactionName.TheSyndicate, - FactionName.FulcrumSecretTechnologies, - FactionName.Illuminati, - FactionName.Daedalus, - FactionName.TheCovenant, - ], - }), - new Augmentation({ - name: AugmentationName.WiredReflexes, - repCost: 1.25e3, - moneyCost: 2.5e6, - info: - "Synthetic nerve-enhancements are injected into all major parts of the somatic nervous system, " + - "supercharging the spread of neural signals and increasing reflex speed.", - agility: 1.05, - dexterity: 1.05, - factions: [ - FactionName.TianDiHui, - FactionName.SlumSnakes, - FactionName.Sector12, - FactionName.Volhaven, - FactionName.Aevum, - FactionName.Ishima, - FactionName.TheSyndicate, - FactionName.TheDarkArmy, - FactionName.SpeakersForTheDead, - ], - }), - new Augmentation({ - name: AugmentationName.GrapheneBoneLacings, - repCost: 1.125e6, - moneyCost: 4.25e9, - info: "Graphene is grafted and fused into the skeletal structure, enhancing bone density and tensile strength.", - strength: 1.7, - defense: 1.7, - factions: [FactionName.FulcrumSecretTechnologies, FactionName.TheCovenant], - }), - new Augmentation({ - name: AugmentationName.BionicSpine, - repCost: 4.5e4, - moneyCost: 1.25e8, - info: - "The spine is reconstructed using plasteel and carbon fibers. " + - "It is now capable of stimulating and regulating neural signals " + - "passing through the spinal cord, improving senses and reaction speed. " + - "The 'Bionic Spine' also interfaces with all other 'Bionic' implants.", - strength: 1.15, - defense: 1.15, - agility: 1.15, - dexterity: 1.15, - factions: [ - FactionName.SpeakersForTheDead, - FactionName.TheSyndicate, - FactionName.KuaiGongInternational, - FactionName.OmniTekIncorporated, - FactionName.BladeIndustries, - ], - }), - new Augmentation({ - name: AugmentationName.GrapheneBionicSpine, - repCost: 1.625e6, - moneyCost: 6e9, - info: - "An upgrade to the 'Bionic Spine' augmentation. The spine is fused with graphene " + - "which enhances durability and supercharges all body functions.", - prereqs: [AugmentationName.BionicSpine], - strength: 1.6, - defense: 1.6, - agility: 1.6, - dexterity: 1.6, - factions: [FactionName.FulcrumSecretTechnologies, FactionName.ECorp], - }), - new Augmentation({ - name: AugmentationName.BionicLegs, - repCost: 1.5e5, - moneyCost: 3.75e8, - info: "Cybernetic legs, created from plasteel and carbon fibers, enhance running speed.", - agility: 1.6, - factions: [ - FactionName.SpeakersForTheDead, - FactionName.TheSyndicate, - FactionName.KuaiGongInternational, - FactionName.OmniTekIncorporated, - FactionName.BladeIndustries, - ], - }), - new Augmentation({ - name: AugmentationName.GrapheneBionicLegs, - repCost: 7.5e5, - moneyCost: 4.5e9, - info: - "An upgrade to the 'Bionic Legs' augmentation. The legs are fused " + - "with graphene, greatly enhancing jumping ability.", - prereqs: [AugmentationName.BionicLegs], - agility: 2.5, - factions: [FactionName.MegaCorp, FactionName.ECorp, FactionName.FulcrumSecretTechnologies], - }), - new Augmentation({ - name: AugmentationName.SpeechProcessor, - repCost: 7.5e3, - moneyCost: 5e7, - info: - "A cochlear implant with an embedded computer that analyzes incoming speech. " + - "The embedded computer processes characteristics of incoming speech, such as tone " + - "and inflection, to pick up on subtle cues and aid in social interactions.", - charisma: 1.2, - factions: [ - FactionName.TianDiHui, - FactionName.Chongqing, - FactionName.Sector12, - FactionName.NewTokyo, - FactionName.Aevum, - FactionName.Ishima, - FactionName.Volhaven, - FactionName.Silhouette, - ], - }), - new Augmentation({ - name: AugmentationName.TITN41Injection, - repCost: 2.5e4, - moneyCost: 1.9e8, - info: - "TITN is a series of viruses that targets and alters the sequences of human DNA in genes that " + - "control personality. The TITN-41 strain alters these genes so that the subject becomes more " + - "outgoing and sociable.", - charisma: 1.15, - charisma_exp: 1.15, - factions: [FactionName.Silhouette], - }), - new Augmentation({ - name: AugmentationName.EnhancedSocialInteractionImplant, - repCost: 3.75e5, - moneyCost: 1.375e9, - info: - "A cranial implant that greatly assists in the user's ability to analyze social situations " + - "and interactions. The system uses a wide variety of factors such as facial expression, body " + - "language, voice tone, and inflection to determine the best course of action during social " + - "situations. The implant also uses deep learning software to continuously learn new behavior " + - "patterns and how to best respond.", - charisma: 1.6, - charisma_exp: 1.6, - factions: [ - FactionName.BachmanAssociates, - FactionName.NWO, - FactionName.ClarkeIncorporated, - FactionName.OmniTekIncorporated, - FactionName.FourSigma, - ], - }), - new Augmentation({ - name: AugmentationName.BitWire, - repCost: 3.75e3, - moneyCost: 1e7, - info: - "A small brain implant embedded in the cerebrum. This regulates and improves the brain's computing " + - "capabilities.", - hacking: 1.05, - factions: [FactionName.CyberSec, FactionName.NiteSec], - }), - new Augmentation({ - name: AugmentationName.ArtificialBioNeuralNetwork, - repCost: 2.75e5, - moneyCost: 3e9, - info: - "A network consisting of millions of nanoprocessors is embedded into the brain. " + - "The network is meant to mimic the way a biological brain solves a problem, with each " + - "nanoprocessor acting similar to the way a neuron would in a neural network. However, these " + - "nanoprocessors are programmed to perform computations much faster than organic neurons, " + - "allowing the user to solve much more complex problems at a much faster rate.", - hacking_speed: 1.03, - hacking_money: 1.15, - hacking: 1.12, - factions: [FactionName.BitRunners, FactionName.FulcrumSecretTechnologies], - }), - new Augmentation({ - name: AugmentationName.ArtificialSynapticPotentiation, - repCost: 6.25e3, - moneyCost: 8e7, - info: - "The body is injected with a chemical that artificially induces synaptic potentiation, " + - "otherwise known as the strengthening of synapses. This results in enhanced cognitive abilities.", - hacking_speed: 1.02, - hacking_chance: 1.05, - hacking_exp: 1.05, - factions: [FactionName.TheBlackHand, FactionName.NiteSec], - }), - new Augmentation({ - name: AugmentationName.EnhancedMyelinSheathing, - repCost: 1e5, - moneyCost: 1.375e9, - info: - "Electrical signals are used to induce a new, artificial form of myelinogenesis in the human body. " + - "This process results in the proliferation of new, synthetic myelin sheaths in the nervous " + - "system. These myelin sheaths can propagate neuro-signals much faster than their organic " + - "counterparts, leading to greater processing speeds and better brain function.", - hacking_speed: 1.03, - hacking_exp: 1.1, - hacking: 1.08, - factions: [FactionName.FulcrumSecretTechnologies, FactionName.BitRunners, FactionName.TheBlackHand], - }), - new Augmentation({ - name: AugmentationName.SynapticEnhancement, - repCost: 2e3, - moneyCost: 7.5e6, - info: - "A small cranial implant that continuously uses weak electrical signals to stimulate the brain and " + - "induce stronger synaptic activity. This improves the user's cognitive abilities.", - hacking_speed: 1.03, - factions: [FactionName.CyberSec, FactionName.Aevum], - }), - new Augmentation({ - name: AugmentationName.NeuralRetentionEnhancement, - repCost: 2e4, - moneyCost: 2.5e8, - info: - "Chemical injections are used to permanently alter and strengthen the brain's neuronal " + - "circuits, strengthening the ability to retain information.", - hacking_exp: 1.25, - factions: [FactionName.NiteSec], - }), - new Augmentation({ - name: AugmentationName.DataJack, - repCost: 1.125e5, - moneyCost: 4.5e8, - info: - "A brain implant that provides an interface for direct, wireless communication between a computer's main " + - "memory and the mind. This implant allows the user to not only access a computer's memory, but also alter " + - "and delete it.", - hacking_money: 1.25, - factions: [ - FactionName.BitRunners, - FactionName.TheBlackHand, - FactionName.NiteSec, - FactionName.Chongqing, - FactionName.NewTokyo, - ], - }), - new Augmentation({ - name: AugmentationName.ENM, - repCost: 1.5e4, - moneyCost: 2.5e8, - info: - "A thin device embedded inside the arm containing a wireless module capable of connecting " + - "to nearby networks. Once connected, the Netburner Module is capable of capturing and " + - "processing all of the traffic on that network. By itself, the Embedded Netburner Module does " + - "not do much, but a variety of very powerful upgrades can be installed that allow you to fully " + - "control the traffic on a network.", - hacking: 1.08, - factions: [ - FactionName.BitRunners, - FactionName.TheBlackHand, - FactionName.NiteSec, - FactionName.ECorp, - FactionName.MegaCorp, - FactionName.FulcrumSecretTechnologies, - FactionName.NWO, - FactionName.BladeIndustries, - ], - }), - new Augmentation({ - name: AugmentationName.ENMCore, - repCost: 175e3, - moneyCost: 2.5e9, - info: - "The Core library is an implant that upgrades the firmware of the Embedded Netburner Module. " + - "This upgrade allows the Embedded Netburner Module to generate its own data on a network.", - prereqs: [AugmentationName.ENM], - hacking_speed: 1.03, - hacking_money: 1.1, - hacking_chance: 1.03, - hacking_exp: 1.07, - hacking: 1.07, - factions: [ - FactionName.BitRunners, - FactionName.TheBlackHand, - FactionName.ECorp, - FactionName.MegaCorp, - FactionName.FulcrumSecretTechnologies, - FactionName.NWO, - FactionName.BladeIndustries, - ], - }), - new Augmentation({ - name: AugmentationName.ENMCoreV2, - repCost: 1e6, - moneyCost: 4.5e9, - info: - "The Core V2 library is an implant that upgrades the firmware of the Embedded Netburner Module. " + - "This upgraded firmware allows the Embedded Netburner Module to control information on " + - "a network by re-routing traffic, spoofing IP addresses, and altering the data inside network " + - "packets.", - prereqs: [AugmentationName.ENMCore, AugmentationName.ENM], - hacking_speed: 1.05, - hacking_money: 1.3, - hacking_chance: 1.05, - hacking_exp: 1.15, - hacking: 1.08, - factions: [ - FactionName.BitRunners, - FactionName.ECorp, - FactionName.MegaCorp, - FactionName.FulcrumSecretTechnologies, - FactionName.NWO, - FactionName.BladeIndustries, - FactionName.OmniTekIncorporated, - FactionName.KuaiGongInternational, - ], - }), - new Augmentation({ - name: AugmentationName.ENMCoreV3, - repCost: 1.75e6, - moneyCost: 7.5e9, - info: - "The Core V3 library is an implant that upgrades the firmware of the Embedded Netburner Module. " + - "This upgraded firmware allows the Embedded Netburner Module to seamlessly inject code into " + - "any device on a network.", - prereqs: [AugmentationName.ENMCoreV2, AugmentationName.ENMCore, AugmentationName.ENM], - hacking_speed: 1.05, - hacking_money: 1.4, - hacking_chance: 1.1, - hacking_exp: 1.25, - hacking: 1.1, - factions: [ - FactionName.ECorp, - FactionName.MegaCorp, - FactionName.FulcrumSecretTechnologies, - FactionName.NWO, - FactionName.Daedalus, - FactionName.TheCovenant, - FactionName.Illuminati, - ], - }), - new Augmentation({ - name: AugmentationName.ENMAnalyzeEngine, - repCost: 6.25e5, - moneyCost: 6e9, - info: - "Installs the Analyze Engine for the Embedded Netburner Module, which is a CPU cluster " + - "that vastly outperforms the Netburner Module's native single-core processor.", - prereqs: [AugmentationName.ENM], - hacking_speed: 1.1, - factions: [ - FactionName.ECorp, - FactionName.MegaCorp, - FactionName.FulcrumSecretTechnologies, - FactionName.NWO, - FactionName.Daedalus, - FactionName.TheCovenant, - FactionName.Illuminati, - ], - }), - new Augmentation({ - name: AugmentationName.ENMDMA, - repCost: 1e6, - moneyCost: 7e9, - info: - "This implant installs a Direct Memory Access (DMA) controller into the " + - "Embedded Netburner Module. This allows the Module to send and receive data " + - "directly to and from the main memory of devices on a network.", - prereqs: [AugmentationName.ENM], - hacking_money: 1.4, - hacking_chance: 1.2, - factions: [ - FactionName.ECorp, - FactionName.MegaCorp, - FactionName.FulcrumSecretTechnologies, - FactionName.NWO, - FactionName.Daedalus, - FactionName.TheCovenant, - FactionName.Illuminati, - ], - }), - new Augmentation({ - name: AugmentationName.Neuralstimulator, - repCost: 5e4, - moneyCost: 3e9, - info: - "A cranial implant that intelligently stimulates certain areas of the brain " + - "in order to improve cognitive functions.", - hacking_speed: 1.02, - hacking_chance: 1.1, - hacking_exp: 1.12, - factions: [ - FactionName.TheBlackHand, - FactionName.Chongqing, - FactionName.Sector12, - FactionName.NewTokyo, - FactionName.Aevum, - FactionName.Ishima, - FactionName.Volhaven, - FactionName.BachmanAssociates, - FactionName.ClarkeIncorporated, - FactionName.FourSigma, - ], - }), - new Augmentation({ - name: AugmentationName.NeuralAccelerator, - repCost: 2e5, - moneyCost: 1.75e9, - info: - "A microprocessor that accelerates the processing " + - "speed of biological neural networks. This is a cranial implant that is embedded inside the brain.", - hacking: 1.1, - hacking_exp: 1.15, - hacking_money: 1.2, - factions: [FactionName.BitRunners], - }), - new Augmentation({ - name: AugmentationName.CranialSignalProcessorsG1, - repCost: 1e4, - moneyCost: 7e7, - info: - "The first generation of Cranial Signal Processors. Cranial Signal Processors " + - "are a set of specialized microprocessors that are attached to " + - "neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations " + - "so that the brain doesn't have to.", - hacking_speed: 1.01, - hacking: 1.05, - factions: [FactionName.CyberSec, FactionName.NiteSec], - }), - new Augmentation({ - name: AugmentationName.CranialSignalProcessorsG2, - repCost: 1.875e4, - moneyCost: 1.25e8, - info: - "The second generation of Cranial Signal Processors. Cranial Signal Processors " + - "are a set of specialized microprocessors that are attached to " + - "neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations " + - "so that the brain doesn't have to.", - prereqs: [AugmentationName.CranialSignalProcessorsG1], - hacking_speed: 1.02, - hacking_chance: 1.05, - hacking: 1.07, - factions: [FactionName.CyberSec, FactionName.NiteSec], - }), - new Augmentation({ - name: AugmentationName.CranialSignalProcessorsG3, - repCost: 5e4, - moneyCost: 5.5e8, - info: - "The third generation of Cranial Signal Processors. Cranial Signal Processors " + - "are a set of specialized microprocessors that are attached to " + - "neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations " + - "so that the brain doesn't have to.", - prereqs: [AugmentationName.CranialSignalProcessorsG2, AugmentationName.CranialSignalProcessorsG1], - hacking_speed: 1.02, - hacking_money: 1.15, - hacking: 1.09, - factions: [FactionName.NiteSec, FactionName.TheBlackHand, FactionName.BitRunners], - }), - new Augmentation({ - name: AugmentationName.CranialSignalProcessorsG4, - repCost: 1.25e5, - moneyCost: 1.1e9, - info: - "The fourth generation of Cranial Signal Processors. Cranial Signal Processors " + - "are a set of specialized microprocessors that are attached to " + - "neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations " + - "so that the brain doesn't have to.", - prereqs: [ - AugmentationName.CranialSignalProcessorsG3, - AugmentationName.CranialSignalProcessorsG2, - AugmentationName.CranialSignalProcessorsG1, - ], - hacking_speed: 1.02, - hacking_money: 1.2, - hacking_grow: 1.25, - factions: [FactionName.TheBlackHand, FactionName.BitRunners], - }), - new Augmentation({ - name: AugmentationName.CranialSignalProcessorsG5, - repCost: 2.5e5, - moneyCost: 2.25e9, - info: - "The fifth generation of Cranial Signal Processors. Cranial Signal Processors " + - "are a set of specialized microprocessors that are attached to " + - "neurons in the brain. These chips process neural signals to quickly and automatically perform specific computations " + - "so that the brain doesn't have to.", - prereqs: [ - AugmentationName.CranialSignalProcessorsG4, - AugmentationName.CranialSignalProcessorsG3, - AugmentationName.CranialSignalProcessorsG2, - AugmentationName.CranialSignalProcessorsG1, - ], - hacking: 1.3, - hacking_money: 1.25, - hacking_grow: 1.75, - factions: [FactionName.BitRunners], - }), - new Augmentation({ - name: AugmentationName.NeuronalDensification, - repCost: 1.875e5, - moneyCost: 1.375e9, - info: - "The brain is surgically re-engineered to have increased neuronal density " + - "by decreasing the neuron gap junction. Then, the body is genetically modified " + - "to enhance the production and capabilities of its neural stem cells.", - hacking: 1.15, - hacking_exp: 1.1, - hacking_speed: 1.03, - factions: [FactionName.ClarkeIncorporated], - }), - new Augmentation({ - name: AugmentationName.NuoptimalInjectorImplant, - repCost: 5e3, - moneyCost: 2e7, - info: - "This torso implant automatically injects nootropic supplements into " + - "the bloodstream to improve memory, increase focus, and provide other " + - "cognitive enhancements.", - company_rep: 1.2, - factions: [ - FactionName.TianDiHui, - FactionName.Volhaven, - FactionName.NewTokyo, - FactionName.Chongqing, - FactionName.ClarkeIncorporated, - FactionName.FourSigma, - FactionName.BachmanAssociates, - ], - }), - new Augmentation({ - name: AugmentationName.SpeechEnhancement, - repCost: 2.5e3, - moneyCost: 1.25e7, - info: - "An advanced neural implant that improves your speaking abilities, making " + - "you more convincing and likable in conversations and overall improving your " + - "social interactions.", - company_rep: 1.1, - charisma: 1.1, - factions: [ - FactionName.TianDiHui, - FactionName.SpeakersForTheDead, - FactionName.FourSigma, - FactionName.KuaiGongInternational, - FactionName.ClarkeIncorporated, - FactionName.BachmanAssociates, - ], - }), - new Augmentation({ - name: AugmentationName.FocusWire, - repCost: 7.5e4, - moneyCost: 9e8, - info: "A cranial implant that stops procrastination by blocking specific neural pathways in the brain.", - hacking_exp: 1.05, - strength_exp: 1.05, - defense_exp: 1.05, - dexterity_exp: 1.05, - agility_exp: 1.05, - charisma_exp: 1.05, - company_rep: 1.1, - work_money: 1.2, - factions: [ - FactionName.BachmanAssociates, - FactionName.ClarkeIncorporated, - FactionName.FourSigma, - FactionName.KuaiGongInternational, - ], - }), - new Augmentation({ - name: AugmentationName.PCDNI, - repCost: 3.75e5, - moneyCost: 3.75e9, - info: - "Installs a Direct-Neural Interface jack into your arm that is compatible with most " + - "computers. Connecting to a computer through this jack allows you to interface with " + - "it using the brain's electrochemical signals.", - company_rep: 1.3, - hacking: 1.08, - factions: [FactionName.FourSigma, FactionName.OmniTekIncorporated, FactionName.ECorp, FactionName.BladeIndustries], - }), - new Augmentation({ - name: AugmentationName.PCDNIOptimizer, - repCost: 5e5, - moneyCost: 4.5e9, - info: - "This is a submodule upgrade to the PC Direct-Neural Interface augmentation. It " + - "improves the performance of the interface and gives the user more control options " + - "to a connected computer.", - prereqs: [AugmentationName.PCDNI], - company_rep: 1.75, - hacking: 1.1, - factions: [FactionName.FulcrumSecretTechnologies, FactionName.ECorp, FactionName.BladeIndustries], - }), - new Augmentation({ - name: AugmentationName.PCDNINeuralNetwork, - repCost: 1.5e6, - moneyCost: 7.5e9, - info: - "This is an additional installation that upgrades the functionality of the " + - "PC Direct-Neural Interface augmentation. When connected to a computer, " + - "the Neural Network upgrade allows the user to use their own brain's " + - "processing power to aid the computer in computational tasks.", - prereqs: [AugmentationName.PCDNI], - company_rep: 2, - hacking: 1.1, - hacking_speed: 1.05, - factions: [FactionName.FulcrumSecretTechnologies], - }), - new Augmentation({ - name: AugmentationName.ADRPheromone1, - repCost: 3.75e3, - moneyCost: 1.75e7, - info: - "The body is genetically re-engineered so that it produces the ADR-V1 pheromone, " + - "an artificial pheromone discovered by scientists. The ADR-V1 pheromone, when excreted, " + - "triggers feelings of admiration and approval in other people.", - company_rep: 1.1, - faction_rep: 1.1, - factions: [ - FactionName.TianDiHui, - FactionName.TheSyndicate, - FactionName.NWO, - FactionName.MegaCorp, - FactionName.FourSigma, - ], - }), - new Augmentation({ - name: AugmentationName.ADRPheromone2, - repCost: 6.25e4, - moneyCost: 5.5e8, - info: - "The body is genetically re-engineered so that it produces the ADR-V2 pheromone, " + - "which is similar to but more potent than ADR-V1. This pheromone, when excreted, " + - "triggers feelings of admiration, approval, and respect in others.", - company_rep: 1.2, - faction_rep: 1.2, - factions: [ - FactionName.Silhouette, - FactionName.FourSigma, - FactionName.BachmanAssociates, - FactionName.ClarkeIncorporated, - ], - }), - new Augmentation({ - name: AugmentationName.ShadowsSimulacrum, - repCost: 3.75e4, - moneyCost: 4e8, - info: - "A crude but functional matter phase-shifter module that is embedded " + - "in the brainstem and cerebellum. This augmentation was developed by " + - "criminal organizations and allows the user to project and control holographic " + - "simulacrums within a large radius. These simulacrums are commonly used for " + - "espionage and surveillance work.", - company_rep: 1.15, - faction_rep: 1.15, - factions: [FactionName.TheSyndicate, FactionName.TheDarkArmy, FactionName.SpeakersForTheDead], - }), - new Augmentation({ - name: AugmentationName.HacknetNodeCPUUpload, - repCost: 3.75e3, - moneyCost: 1.1e7, - info: - "Uploads the architecture and design details of a Hacknet Node's CPU into " + - "the brain. This allows the user to engineer custom hardware and software " + - "for the Hacknet Node that provides better performance.", - hacknet_node_money: 1.15, - hacknet_node_purchase_cost: 0.85, - factions: [FactionName.Netburners], - }), - new Augmentation({ - name: AugmentationName.HacknetNodeCacheUpload, - repCost: 2.5e3, - moneyCost: 5.5e6, - info: - "Uploads the architecture and design details of a Hacknet Node's main-memory cache " + - "into the brain. This allows the user to engineer custom cache hardware for the " + - "Hacknet Node that offers better performance.", - hacknet_node_money: 1.1, - hacknet_node_level_cost: 0.85, - factions: [FactionName.Netburners], - }), - new Augmentation({ - name: AugmentationName.HacknetNodeNICUpload, - repCost: 1.875e3, - moneyCost: 4.5e6, - info: - "Uploads the architecture and design details of a Hacknet Node's Network Interface Card (NIC) " + - "into the brain. This allows the user to engineer a custom NIC for the Hacknet Node that " + - "offers better performance.", - hacknet_node_money: 1.1, - hacknet_node_purchase_cost: 0.9, - factions: [FactionName.Netburners], - }), - new Augmentation({ - name: AugmentationName.HacknetNodeKernelDNI, - repCost: 7.5e3, - moneyCost: 4e7, - info: - "Installs a Direct-Neural Interface jack into the arm that is capable of connecting to a " + - "Hacknet Node. This lets the user access and manipulate the Node's kernel using " + - "electrochemical signals.", - hacknet_node_money: 1.25, - factions: [FactionName.Netburners], - }), - new Augmentation({ - name: AugmentationName.HacknetNodeCoreDNI, - repCost: 1.25e4, - moneyCost: 6e7, - info: - "Installs a Direct-Neural Interface jack into the arm that is capable of connecting " + - "to a Hacknet Node. This lets the user access and manipulate the Node's processing logic using " + - "electrochemical signals.", - hacknet_node_money: 1.45, - factions: [FactionName.Netburners], - }), - new Augmentation({ - name: AugmentationName.Neurotrainer1, - repCost: 1e3, - moneyCost: 4e6, - info: - "A decentralized cranial implant that improves the brain's ability to learn. It is " + - "installed by releasing millions of nanobots into the human brain, each of which " + - "attaches to a different neural pathway to enhance the brain's ability to retain " + - "and retrieve information.", - hacking_exp: 1.1, - strength_exp: 1.1, - defense_exp: 1.1, - dexterity_exp: 1.1, - agility_exp: 1.1, - charisma_exp: 1.1, - factions: [FactionName.CyberSec, FactionName.Aevum], - }), - new Augmentation({ - name: AugmentationName.Neurotrainer2, - repCost: 1e4, - moneyCost: 4.5e7, - info: - "A decentralized cranial implant that improves the brain's ability to learn. This " + - "is a more powerful version of the Neurotrainer I augmentation, but it does not " + - "require Neurotrainer I to be installed as a prerequisite.", - hacking_exp: 1.15, - strength_exp: 1.15, - defense_exp: 1.15, - dexterity_exp: 1.15, - agility_exp: 1.15, - charisma_exp: 1.15, - factions: [FactionName.BitRunners, FactionName.NiteSec], - }), - new Augmentation({ - name: AugmentationName.Neurotrainer3, - repCost: 2.5e4, - moneyCost: 1.3e8, - info: - "A decentralized cranial implant that improves the brain's ability to learn. This " + - "is a more powerful version of the Neurotrainer I and Neurotrainer II augmentation, " + - "but it does not require either of them to be installed as a prerequisite.", - hacking_exp: 1.2, - strength_exp: 1.2, - defense_exp: 1.2, - dexterity_exp: 1.2, - agility_exp: 1.2, - charisma_exp: 1.2, - factions: [FactionName.NWO, FactionName.FourSigma], - }), - new Augmentation({ - name: AugmentationName.Hypersight, - repCost: 1.5e5, - moneyCost: 2.75e9, - info: - "A bionic eye implant that grants sight capabilities far beyond those of a natural human. " + - "Embedded circuitry within the implant provides the ability to detect heat and movement " + - "through solid objects such as walls, thus providing 'x-ray vision'-like capabilities.", - dexterity: 1.4, - hacking_speed: 1.03, - hacking_money: 1.1, - factions: [FactionName.BladeIndustries, FactionName.KuaiGongInternational], - }), - new Augmentation({ - name: AugmentationName.LuminCloaking1, - repCost: 1.5e3, - moneyCost: 5e6, - info: - "A skin implant that reinforces the skin with highly-advanced synthetic cells. These " + - "cells, when powered, have a negative refractive index. As a result, they bend light " + - "around the skin, making the user much harder to see with the naked eye.", - agility: 1.05, - crime_money: 1.1, - factions: [FactionName.SlumSnakes, FactionName.Tetrads], - }), - new Augmentation({ - name: AugmentationName.LuminCloaking2, - repCost: 5e3, - moneyCost: 3e7, - info: - "This is a more advanced version of the LuminCloaking-V1 augmentation. This skin implant " + - "reinforces the skin with highly-advanced synthetic cells. These " + - "cells, when powered, are capable of not only bending light but also of bending heat, " + - "making the user more resilient as well as stealthy.", - prereqs: [AugmentationName.LuminCloaking1], - agility: 1.1, - defense: 1.1, - crime_money: 1.25, - factions: [FactionName.SlumSnakes, FactionName.Tetrads], - }), - new Augmentation({ - name: AugmentationName.SmartSonar, - repCost: 2.25e4, - moneyCost: 7.5e7, - info: "A cochlear implant that helps the player detect and locate enemies using sound propagation.", - dexterity: 1.1, - dexterity_exp: 1.15, - crime_money: 1.25, - factions: [FactionName.SlumSnakes], - }), - new Augmentation({ - name: AugmentationName.PowerRecirculator, - repCost: 2.5e4, - moneyCost: 1.8e8, - info: - "The body's nerves are attached with polypyrrole nanocircuits that " + - "are capable of capturing wasted energy, in the form of heat, " + - "and converting it back into usable power.", - hacking: 1.05, - strength: 1.05, - defense: 1.05, - dexterity: 1.05, - agility: 1.05, - charisma: 1.05, - hacking_exp: 1.1, - strength_exp: 1.1, - defense_exp: 1.1, - dexterity_exp: 1.1, - agility_exp: 1.1, - charisma_exp: 1.1, - factions: [FactionName.Tetrads, FactionName.TheDarkArmy, FactionName.TheSyndicate, FactionName.NWO], - }), - new Augmentation({ - name: AugmentationName.QLink, - repCost: 1.875e6, - moneyCost: 2.5e13, - info: - `A brain implant that wirelessly connects you to the ${FactionName.Illuminati}'s ` + - "quantum supercomputer, allowing you to access and use its incredible " + - "computing power.", - hacking: 1.75, - hacking_speed: 2, - hacking_chance: 2.5, - hacking_money: 4, - factions: [FactionName.Illuminati], - }), - new Augmentation({ - name: AugmentationName.SPTN97, - repCost: 1.25e6, - moneyCost: 4.875e9, - info: - "The SPTN-97 gene is injected into the genome. The SPTN-97 gene is an " + - "artificially-synthesized gene that was developed by DARPA to create " + - "super-soldiers through genetic modification. The gene was outlawed in " + - "2056.", - strength: 1.75, - defense: 1.75, - dexterity: 1.75, - agility: 1.75, - hacking: 1.15, - factions: [FactionName.TheCovenant], - }), - new Augmentation({ - name: AugmentationName.HiveMind, - repCost: 1.5e6, - moneyCost: 5.5e9, - info: - `A brain implant developed by ${FactionName.ECorp}. They do not reveal what ` + - "exactly the implant does, but they promise that it will greatly " + - "enhance your abilities.", - hacking_grow: 3, - stats: null, - factions: [FactionName.ECorp], - }), - new Augmentation({ - name: AugmentationName.TheRedPill, - repCost: 2.5e6, - moneyCost: 0, - info: "It's time to leave the cave.", - stats: null, - isSpecial: true, - factions: [FactionName.Daedalus], - }), - new Augmentation({ - name: AugmentationName.CordiARCReactor, - repCost: 1.125e6, - moneyCost: 5e9, - info: - "The thoracic cavity is equipped with a small chamber designed " + - "to hold and sustain hydrogen plasma. The plasma is used to generate " + - "fusion power through nuclear fusion, providing limitless amounts of clean " + - "energy for the body.", - strength: 1.35, - defense: 1.35, - dexterity: 1.35, - agility: 1.35, - strength_exp: 1.35, - defense_exp: 1.35, - dexterity_exp: 1.35, - agility_exp: 1.35, - factions: [FactionName.MegaCorp], - }), - new Augmentation({ - name: AugmentationName.SmartJaw, - repCost: 3.75e5, - moneyCost: 2.75e9, - info: - "A bionic jaw that contains advanced hardware and software " + - "capable of psychoanalyzing and profiling the personality of " + - "others using optical imaging software.", - charisma: 1.5, - charisma_exp: 1.5, - company_rep: 1.25, - faction_rep: 1.25, - factions: [FactionName.BachmanAssociates], - }), - new Augmentation({ - name: AugmentationName.Neotra, - repCost: 5.625e5, - moneyCost: 2.875e9, - info: - "A highly-advanced techno-organic drug that is injected into the skeletal " + - "and integumentary system. The drug permanently modifies the DNA of the " + - "body's skin and bone cells, granting them the ability to repair " + - "and restructure themselves.", - strength: 1.55, - defense: 1.55, - factions: [FactionName.BladeIndustries], - }), - new Augmentation({ - name: AugmentationName.Xanipher, - repCost: 8.75e5, - moneyCost: 4.25e9, - info: - "A concoction of advanced nanobots that is orally ingested into the " + - "body. These nanobots induce physiological changes and significantly " + - "improve the body's functioning in all aspects.", - hacking: 1.2, - strength: 1.2, - defense: 1.2, - dexterity: 1.2, - agility: 1.2, - charisma: 1.2, - hacking_exp: 1.15, - strength_exp: 1.15, - defense_exp: 1.15, - dexterity_exp: 1.15, - agility_exp: 1.15, - charisma_exp: 1.15, - factions: [FactionName.NWO], - }), - new Augmentation({ - name: AugmentationName.HydroflameLeftArm, - repCost: 1.25e6, - moneyCost: 2.5e12, - info: - "The left arm of a legendary BitRunner who ascended beyond this world. " + - "It projects a light blue energy shield that protects the exposed inner parts. " + - "Even though it contains no weapons, the advanced tungsten titanium " + - "alloy increases the user's strength to unbelievable levels.", - strength: 2.8, - factions: [FactionName.NWO], - }), - new Augmentation({ - name: AugmentationName.nextSENS, - repCost: 4.375e5, - moneyCost: 1.925e9, - info: - "The body is genetically re-engineered to maintain a state " + - "of negligible senescence, preventing the body from " + - "deteriorating with age.", - hacking: 1.2, - strength: 1.2, - defense: 1.2, - dexterity: 1.2, - agility: 1.2, - charisma: 1.2, - factions: [FactionName.ClarkeIncorporated], - }), - new Augmentation({ - name: AugmentationName.OmniTekInfoLoad, - repCost: 6.25e5, - moneyCost: 2.875e9, - info: - "OmniTek's data and information repository is uploaded " + - "into your brain, enhancing your programming and " + - "hacking abilities.", - hacking: 1.2, - hacking_exp: 1.25, - factions: [FactionName.OmniTekIncorporated], - }), - new Augmentation({ - name: AugmentationName.PhotosyntheticCells, - repCost: 5.625e5, - moneyCost: 2.75e9, - info: - "Chloroplasts are added to epidermal stem cells and are applied " + - "to the body using a skin graft. The result is photosynthetic " + - "skin cells, allowing users to generate their own energy " + - "and nutrition using solar power.", - strength: 1.4, - defense: 1.4, - agility: 1.4, - factions: [FactionName.KuaiGongInternational], - }), - new Augmentation({ - name: AugmentationName.Neurolink, - repCost: 8.75e5, - moneyCost: 4.375e9, - info: - "A brain implant that provides a high-bandwidth, direct neural link between your " + - `mind and the ${FactionName.BitRunners}' data servers, which reportedly contain ` + - "the largest database of hacking tools and information in the world.", - hacking: 1.15, - hacking_exp: 1.2, - hacking_chance: 1.1, - hacking_speed: 1.05, - programs: [CompletedProgramName.ftpCrack, CompletedProgramName.relaySmtp], - factions: [FactionName.BitRunners], - }), - new Augmentation({ - name: AugmentationName.TheBlackHand, - repCost: 1e5, - moneyCost: 5.5e8, - info: - "A highly advanced bionic hand. This prosthetic not only " + - "enhances strength and dexterity but it is also embedded " + - "with hardware and firmware that lets the user connect to, access, and hack " + - "devices and machines by just touching them.", - strength: 1.15, - dexterity: 1.15, - hacking: 1.1, - hacking_speed: 1.02, - hacking_money: 1.1, - factions: [FactionName.TheBlackHand], - }), - new Augmentation({ - name: AugmentationName.CRTX42AA, - repCost: 4.5e4, - moneyCost: 2.25e8, - info: - "The CRTX42-AA gene is injected into the genome. " + - "The CRTX42-AA is an artificially-synthesized gene that targets the visual and prefrontal " + - "cortex and improves cognitive abilities.", - hacking: 1.08, - hacking_exp: 1.15, - factions: [FactionName.NiteSec], - }), - new Augmentation({ - name: AugmentationName.Neuregen, - repCost: 3.75e4, - moneyCost: 3.75e8, - info: - "A drug that genetically modifies the neurons in the brain " + - "resulting in neurons that never die, continuously " + - "regenerate, and strengthen themselves.", - hacking_exp: 1.4, - factions: [FactionName.Chongqing], - }), - new Augmentation({ - name: AugmentationName.CashRoot, - repCost: 1.25e4, - moneyCost: 1.25e8, - info: ( - <> - A collection of digital assets saved on a small chip. The chip is implanted into your wrist. A small jack in the - chip allows you to connect it to a computer and upload the assets. - - ), - startingMoney: 1e6, - programs: [CompletedProgramName.bruteSsh], - factions: [FactionName.Sector12], - }), - new Augmentation({ - name: AugmentationName.NutriGen, - repCost: 6.25e3, - moneyCost: 2.5e6, - info: - "A thermo-powered artificial nutrition generator. Endogenously " + - "synthesizes glucose, amino acids, and vitamins and redistributes them " + - "across the body. The device is powered by the body's naturally wasted " + - "energy in the form of heat.", - strength_exp: 1.2, - defense_exp: 1.2, - dexterity_exp: 1.2, - agility_exp: 1.2, - factions: [FactionName.NewTokyo], - }), - new Augmentation({ - name: AugmentationName.PCMatrix, - repCost: 100e3, - moneyCost: 2e9, - info: - "A 'Probability Computation Matrix' is installed in the frontal cortex. This implant " + - "uses advanced mathematical algorithms to rapidly identify and compute statistical " + - "outcomes of nearly every situation.", - charisma: 1.0777, - charisma_exp: 1.0777, - work_money: 1.777, - faction_rep: 1.0777, - company_rep: 1.0777, - crime_success: 1.0777, - crime_money: 1.0777, - programs: [CompletedProgramName.deepScan1, CompletedProgramName.autoLink], - factions: [FactionName.Aevum], - }), - new Augmentation({ - name: AugmentationName.INFRARet, - repCost: 7.5e3, - moneyCost: 3e7, - info: "A tiny chip that sits behind the retina. This implant lets the user visually detect infrared radiation.", - crime_success: 1.25, - crime_money: 1.1, - dexterity: 1.1, - factions: [FactionName.Ishima], - }), - new Augmentation({ - name: AugmentationName.DermaForce, - repCost: 1.5e4, - moneyCost: 5e7, - info: - "Synthetic skin that is grafted onto the body. This skin consists of " + - "millions of nanobots capable of projecting high-density muon beams, " + - "creating an energy barrier around the user.", - defense: 1.4, - factions: [FactionName.Volhaven], - }), - new Augmentation({ - name: AugmentationName.GrapheneBrachiBlades, - repCost: 2.25e5, - moneyCost: 2.5e9, - info: - "An upgrade to the BrachiBlades augmentation. It infuses " + - "the retractable blades with an advanced graphene material " + - "making them stronger and lighter.", - prereqs: [AugmentationName.BrachiBlades], - strength: 1.4, - defense: 1.4, - crime_success: 1.1, - crime_money: 1.3, - factions: [FactionName.SpeakersForTheDead], - }), - new Augmentation({ - name: AugmentationName.GrapheneBionicArms, - repCost: 5e5, - moneyCost: 3.75e9, - info: - "An upgrade to the Bionic Arms augmentation. It infuses the " + - "prosthetic arms with an advanced graphene material " + - "to make them stronger and lighter.", - prereqs: [AugmentationName.BionicArms], - strength: 1.85, - dexterity: 1.85, - factions: [FactionName.TheDarkArmy], - }), - new Augmentation({ - name: AugmentationName.BrachiBlades, - repCost: 1.25e4, - moneyCost: 9e7, - info: "A set of retractable plasteel blades that are implanted in the arm, underneath the skin.", - strength: 1.15, - defense: 1.15, - crime_success: 1.1, - crime_money: 1.15, - factions: [FactionName.TheSyndicate], - }), - new Augmentation({ - name: AugmentationName.BionicArms, - repCost: 6.25e4, - moneyCost: 2.75e8, - info: "Cybernetic arms created from plasteel and carbon fibers that completely replace the user's organic arms.", - strength: 1.3, - dexterity: 1.3, - factions: [FactionName.Tetrads], - }), - new Augmentation({ - name: AugmentationName.SNA, - repCost: 6.25e3, - moneyCost: 3e7, - info: - "A cranial implant that affects the user's personality, making them better " + - "at negotiation in social situations.", - work_money: 1.1, - company_rep: 1.15, - faction_rep: 1.15, - factions: [FactionName.TianDiHui], - }), - new Augmentation({ - name: AugmentationName.NeuroreceptorManager, - repCost: 0.75e5, - moneyCost: 5.5e8, - info: - "A brain implant carefully assembled around the synapses, which " + - "micromanages the activity and levels of various neuroreceptor " + - "chemicals and modulates electrical activity to optimize concentration, " + - "allowing the user to multitask much more effectively.", - stats: ( - <> - This augmentation removes the penalty for not focusing on actions such as working in a job or working for a - faction. - - ), - factions: [FactionName.TianDiHui], - }), - - // new Augmentation({ - // name: AugmentationNames.UnnamedAug2, - // repCost: 500e3, - // moneyCost: 5e9, - // info: "Undecided description", - // startingMoney: 100e6, - // programs: [Programs.HTTPWormProgram.name, Programs.SQLInjectProgram.name], - // factions: [FactionNames.OmniTekIncorporated], - // }), - - // Grafting-exclusive Augmentation - new Augmentation({ - name: AugmentationName.CongruityImplant, - repCost: Infinity, - moneyCost: 50e12, - info: ( - <> - Developed by a pioneer in Grafting research, this implant generates pulses of stability which seem to have a - nullifying effect versus the Entropy virus. -
-
- Note: For unknown reasons, the lowercase n appears to be an integral component to its - functionality. - - ), - stats: <>This Augmentation removes the Entropy virus, and prevents it from affecting you again., - factions: [], - }), - - // Sleeve exclusive augmentations - new Augmentation({ - name: AugmentationName.ZOE, - isSpecial: true, - repCost: Infinity, - moneyCost: 1e12, - info: - "Zoë's Omnicerebrum Ënhancer for sleeves inserts an omnicerebrum into your sleeve. " + - "An omnicerebrum is a near perfect simulation of the human brain, allowing it to take advantage of a larger variety of augments. " + - "But you should know about this BitRunner, since you have one of these yourself!", - stats: <>Allows sleeves to benefit from Stanek's Gift but it is less powerful if several are installed., - factions: [ - /*Technically in FactionNames.ChurchOfTheMachineGod but not really for display reasons */ - ], - }), -]; - -export const initBladeburnerAugmentations = (): Augmentation[] => [ - new Augmentation({ - name: AugmentationName.EsperEyewear, - repCost: 1.25e3, - moneyCost: 1.65e8, - info: - "Ballistic-grade protective and retractable eyewear that was designed specifically " + - "for Bladeburner units. This " + - "is implanted by installing a mechanical frame in the skull's orbit. " + - "This frame interfaces with the brain and allows the user to " + - "automatically extrude and extract the eyewear. The eyewear protects " + - "against debris, shrapnel, lasers, blinding flashes, and gas. It is also " + - "embedded with a data processing chip that can be programmed to display an " + - "AR HUD to assist the user in field missions.", - bladeburner_success_chance: 1.03, - dexterity: 1.05, - isSpecial: true, - factions: [FactionName.Bladeburners], - }), - new Augmentation({ - name: AugmentationName.EMS4Recombination, - repCost: 2.5e3, - moneyCost: 2.75e8, - info: - "A DNA recombination of the EMS-4 Gene. This genetic engineering " + - "technique was originally used on Bladeburners during the Synthoid uprising " + - "to induce wakefulness and concentration, suppress fear, reduce empathy, " + - "improve reflexes, and improve memory among other things.", - bladeburner_success_chance: 1.03, - bladeburner_analysis: 1.05, - bladeburner_stamina_gain: 1.02, - isSpecial: true, - factions: [FactionName.Bladeburners], - }), - new Augmentation({ - name: AugmentationName.OrionShoulder, - repCost: 6.25e3, - moneyCost: 5.5e8, - info: - "A bionic shoulder augmentation for the right shoulder. Using cybernetics, " + - "the ORION-MKIV shoulder enhances the strength and dexterity " + - "of the user's right arm. It also provides protection due to its " + - "crystallized graphene plating.", - defense: 1.05, - strength: 1.05, - dexterity: 1.05, - bladeburner_success_chance: 1.04, - isSpecial: true, - factions: [FactionName.Bladeburners], - }), - new Augmentation({ - name: AugmentationName.HyperionV1, - repCost: 1.25e4, - moneyCost: 2.75e9, - info: - "A pair of mini plasma cannons embedded into the hands. The Hyperion is capable " + - "of rapidly firing bolts of high-density plasma. The weapon is meant to " + - "be used against augmented enemies as the ionized " + - "nature of the plasma disrupts the electrical systems of Augmentations. However, " + - "it can also be effective against non-augmented enemies due to its high temperature " + - "and concussive force.", - bladeburner_success_chance: 1.06, - isSpecial: true, - factions: [FactionName.Bladeburners], - }), - new Augmentation({ - name: AugmentationName.HyperionV2, - repCost: 2.5e4, - moneyCost: 5.5e9, - info: - "A pair of mini plasma cannons embedded into the hands. This augmentation " + - "is more advanced and powerful than the original V1 model. This V2 model is " + - "more power-efficient, more accurate, and can fire plasma bolts at a much " + - "higher velocity than the V1 model.", - prereqs: [AugmentationName.HyperionV1], - bladeburner_success_chance: 1.08, - isSpecial: true, - factions: [FactionName.Bladeburners], - }), - new Augmentation({ - name: AugmentationName.GolemSerum, - repCost: 3.125e4, - moneyCost: 1.1e10, - info: - "A serum that permanently enhances many aspects of human capabilities, " + - "including strength, speed, immune system enhancements, and mitochondrial efficiency. The " + - "serum was originally developed by the Chinese military in an attempt to " + - "create super soldiers.", - strength: 1.07, - defense: 1.07, - dexterity: 1.07, - agility: 1.07, - bladeburner_stamina_gain: 1.05, - isSpecial: true, - factions: [FactionName.Bladeburners], - }), - new Augmentation({ - name: AugmentationName.VangelisVirus, - repCost: 1.875e4, - moneyCost: 2.75e9, - info: - "A synthetic symbiotic virus that is injected into human brain tissue. The Vangelis virus " + - "heightens the senses and focus of its host, and also enhances its intuition.", - dexterity_exp: 1.1, - bladeburner_analysis: 1.1, - bladeburner_success_chance: 1.04, - isSpecial: true, - factions: [FactionName.Bladeburners], - }), - new Augmentation({ - name: AugmentationName.VangelisVirus3, - repCost: 3.75e4, - moneyCost: 1.1e10, - info: - "An improved version of Vangelis, a synthetic symbiotic virus that is " + - "injected into human brain tissue. On top of the benefits of the original " + - "virus, this also grants accelerated healing and enhanced " + - "reflexes.", - prereqs: [AugmentationName.VangelisVirus], - defense_exp: 1.1, - dexterity_exp: 1.1, - bladeburner_analysis: 1.15, - bladeburner_success_chance: 1.05, - isSpecial: true, - factions: [FactionName.Bladeburners], - }), - new Augmentation({ - name: AugmentationName.INTERLINKED, - repCost: 2.5e4, - moneyCost: 5.5e9, - info: - "The DNA is genetically modified to enhance the human's body " + - "extracellular matrix (ECM). This improves the ECM's ability to " + - "structurally support the body and grants heightened strength and " + - "durability.", - strength_exp: 1.05, - defense_exp: 1.05, - dexterity_exp: 1.05, - agility_exp: 1.05, - bladeburner_max_stamina: 1.1, - isSpecial: true, - factions: [FactionName.Bladeburners], - }), - new Augmentation({ - name: AugmentationName.BladeRunner, - repCost: 2e4, - moneyCost: 8.25e9, - info: - `A cybernetic foot augmentation that was specifically created for ${FactionName.Bladeburners} ` + - "during the Synthoid Uprising. The organic musculature of the human foot " + - "is enhanced with flexible carbon nanotube matrices that are controlled by " + - "intelligent servo-motors.", - agility: 1.05, - bladeburner_max_stamina: 1.05, - bladeburner_stamina_gain: 1.05, - isSpecial: true, - factions: [FactionName.Bladeburners], - }), - new Augmentation({ - name: AugmentationName.BladeArmor, - repCost: 1.25e4, - moneyCost: 1.375e9, - info: - `A powered exoskeleton suit designed as armor for ${FactionName.Bladeburners} units. This ` + - "exoskeleton is incredibly adaptable and can protect the wearer from blunt, piercing, " + - "concussive, thermal, chemical, and electric trauma. It also enhances the user's " + - "physical abilities.", - strength: 1.04, - defense: 1.04, - dexterity: 1.04, - agility: 1.04, - bladeburner_stamina_gain: 1.02, - bladeburner_success_chance: 1.03, - isSpecial: true, - factions: [FactionName.Bladeburners], - }), - new Augmentation({ - name: AugmentationName.BladeArmorPowerCells, - repCost: 1.875e4, - moneyCost: 2.75e9, - info: - "Upgrades the BLADE-51b Tesla Armor with Ion Power Cells, which are capable of " + - "more efficiently storing and using power.", - prereqs: [AugmentationName.BladeArmor], - bladeburner_success_chance: 1.05, - bladeburner_stamina_gain: 1.02, - bladeburner_max_stamina: 1.05, - isSpecial: true, - factions: [FactionName.Bladeburners], - }), - new Augmentation({ - name: AugmentationName.BladeArmorEnergyShielding, - repCost: 2.125e4, - moneyCost: 5.5e9, - info: - "Upgrades the BLADE-51b Tesla Armor with a plasma energy propulsion system " + - "that is capable of projecting an energy shielding force field.", - prereqs: [AugmentationName.BladeArmor], - defense: 1.05, - bladeburner_success_chance: 1.06, - isSpecial: true, - factions: [FactionName.Bladeburners], - }), - new Augmentation({ - name: AugmentationName.BladeArmorUnibeam, - repCost: 3.125e4, - moneyCost: 1.65e10, - info: - "Upgrades the BLADE-51b Tesla Armor with a concentrated deuterium-fluoride laser " + - "weapon. It's precision and accuracy makes it useful for quickly neutralizing " + - "threats while keeping casualties to a minimum.", - prereqs: [AugmentationName.BladeArmor], - bladeburner_success_chance: 1.08, - isSpecial: true, - factions: [FactionName.Bladeburners], - }), - new Augmentation({ - name: AugmentationName.BladeArmorOmnibeam, - repCost: 6.25e4, - moneyCost: 2.75e10, - info: - "Upgrades the BLADE-51b Tesla Armor Unibeam augmentation to use a " + - "multiple-fiber system. This upgraded weapon uses multiple fiber laser " + - "modules that combine together to form a single, more powerful beam of up to " + - "2000MW.", - prereqs: [AugmentationName.BladeArmorUnibeam], - bladeburner_success_chance: 1.1, - isSpecial: true, - factions: [FactionName.Bladeburners], - }), - new Augmentation({ - name: AugmentationName.BladeArmorIPU, - repCost: 1.5e4, - moneyCost: 1.1e9, - info: - "Upgrades the BLADE-51b Tesla Armor with an AI Information Processing " + - "Unit that was specially designed to analyze Synthoid related data and " + - "information.", - prereqs: [AugmentationName.BladeArmor], - bladeburner_analysis: 1.15, - bladeburner_success_chance: 1.02, - isSpecial: true, - factions: [FactionName.Bladeburners], - }), - new Augmentation({ - name: AugmentationName.BladesSimulacrum, - repCost: 1.25e3, - moneyCost: 1.5e11, - info: - "A highly-advanced matter phase-shifter module that is embedded " + - "in the brainstem and cerebellum. This augmentation allows " + - "the user to project and control a holographic simulacrum within an " + - "extremely large radius. These specially-modified holograms were specifically " + - "weaponized by Bladeburner units to be used against Synthoids.", - stats: ( - <> - This augmentation allows you to perform Bladeburner actions and other actions (such as working, committing - crimes, etc.) at the same time. - - ), - isSpecial: true, - factions: [FactionName.Bladeburners], - }), -]; - -export const initChurchOfTheMachineGodAugmentations = (): Augmentation[] => [ - new Augmentation({ - name: AugmentationName.StaneksGift1, - repCost: 0, - moneyCost: 0, - info: - 'Allison "Mother" Stanek imparts you with her gift. An ' + - "experimental Augmentation implanted at the base of the neck. " + - "It allows you to overclock your entire system by carefully " + - "changing the configuration.", - isSpecial: true, - hacking_chance: 0.9, - hacking_speed: 0.9, - hacking_money: 0.9, - hacking_grow: 0.9, - hacking: 0.9, - strength: 0.9, - defense: 0.9, - dexterity: 0.9, - agility: 0.9, - charisma: 0.9, - hacking_exp: 0.9, - strength_exp: 0.9, - defense_exp: 0.9, - dexterity_exp: 0.9, - agility_exp: 0.9, - charisma_exp: 0.9, - company_rep: 0.9, - faction_rep: 0.9, - crime_money: 0.9, - crime_success: 0.9, - hacknet_node_money: 0.9, - hacknet_node_purchase_cost: 1.1, - hacknet_node_ram_cost: 1.1, - hacknet_node_core_cost: 1.1, - hacknet_node_level_cost: 1.1, - work_money: 0.9, - stats: <>Its unstable nature decreases all your stats by 10%, - factions: [FactionName.ChurchOfTheMachineGod], - }), - new Augmentation({ - name: AugmentationName.StaneksGift2, - repCost: 1e6, - moneyCost: 0, - info: - "The next evolution is near, a coming together of man and machine. A synthesis greater than the birth of the human " + - "organism. Time spent with the gift has allowed for acclimatization of the invasive augment and the toll it takes upon " + - "your frame granting a 5% reduced penalty to all stats.", - prereqs: [AugmentationName.StaneksGift1], - isSpecial: true, - hacking_chance: 0.95 / 0.9, - hacking_speed: 0.95 / 0.9, - hacking_money: 0.95 / 0.9, - hacking_grow: 0.95 / 0.9, - hacking: 0.95 / 0.9, - strength: 0.95 / 0.9, - defense: 0.95 / 0.9, - dexterity: 0.95 / 0.9, - agility: 0.95 / 0.9, - charisma: 0.95 / 0.9, - hacking_exp: 0.95 / 0.9, - strength_exp: 0.95 / 0.9, - defense_exp: 0.95 / 0.9, - dexterity_exp: 0.95 / 0.9, - agility_exp: 0.95 / 0.9, - charisma_exp: 0.95 / 0.9, - company_rep: 0.95 / 0.9, - faction_rep: 0.95 / 0.9, - crime_money: 0.95 / 0.9, - crime_success: 0.95 / 0.9, - hacknet_node_money: 0.95 / 0.9, - hacknet_node_purchase_cost: 1.05 / 1.1, - hacknet_node_ram_cost: 1.05 / 1.1, - hacknet_node_core_cost: 1.05 / 1.1, - hacknet_node_level_cost: 1.05 / 1.1, - work_money: 0.95 / 0.9, - stats: <>The penalty for the gift is reduced to 5%, - factions: [FactionName.ChurchOfTheMachineGod], - }), - new Augmentation({ - name: AugmentationName.StaneksGift3, - repCost: 1e8, - moneyCost: 0, - info: - "The synthesis of human and machine is nothing to fear. It is our destiny. " + - "You will become greater than the sum of our parts. As One. Embrace your gift " + - "fully and wholly free of it's accursed toll. Serenity brings tranquility in the form " + - "of no longer suffering a stat penalty. ", - prereqs: [AugmentationName.StaneksGift2, AugmentationName.StaneksGift1], - isSpecial: true, - hacking_chance: 1 / 0.95, - hacking_speed: 1 / 0.95, - hacking_money: 1 / 0.95, - hacking_grow: 1 / 0.95, - hacking: 1 / 0.95, - strength: 1 / 0.95, - defense: 1 / 0.95, - dexterity: 1 / 0.95, - agility: 1 / 0.95, - charisma: 1 / 0.95, - hacking_exp: 1 / 0.95, - strength_exp: 1 / 0.95, - defense_exp: 1 / 0.95, - dexterity_exp: 1 / 0.95, - agility_exp: 1 / 0.95, - charisma_exp: 1 / 0.95, - company_rep: 1 / 0.95, - faction_rep: 1 / 0.95, - crime_money: 1 / 0.95, - crime_success: 1 / 0.95, - hacknet_node_money: 1 / 0.95, - hacknet_node_purchase_cost: 1 / 1.05, - hacknet_node_ram_cost: 1 / 1.05, - hacknet_node_core_cost: 1 / 1.05, - hacknet_node_level_cost: 1 / 1.05, - work_money: 1 / 0.95, - stats: <>Stanek's Gift has no penalty., - factions: [FactionName.ChurchOfTheMachineGod], - }), - new Augmentation({ - name: AugmentationName.BigDsBigBrain, - isSpecial: true, - factions: [], - repCost: Infinity, - moneyCost: Infinity, - info: - "A chip containing the psyche of the greatest BitRunner to ever exists. " + - "Installing this relic significantly increases ALL of your stats. " + - "However it may have unintended consequence on the users mental well-being.", - stats: <>Grants access to unimaginable power., - hacking: 2, - strength: 2, - defense: 2, - dexterity: 2, - agility: 2, - charisma: 2, - hacking_exp: 2, - strength_exp: 2, - defense_exp: 2, - dexterity_exp: 2, - agility_exp: 2, - charisma_exp: 2, - hacking_chance: 2, - hacking_speed: 2, - hacking_money: 2, - hacking_grow: 2, - company_rep: 2, - faction_rep: 2, - crime_money: 2, - crime_success: 2, - work_money: 2, - hacknet_node_money: 2, - hacknet_node_purchase_cost: 0.5, - hacknet_node_ram_cost: 0.5, - hacknet_node_core_cost: 0.5, - hacknet_node_level_cost: 0.5, - bladeburner_max_stamina: 2, - bladeburner_stamina_gain: 2, - bladeburner_analysis: 2, - bladeburner_success_chance: 2, - - startingMoney: 1e12, - programs: [ - CompletedProgramName.bruteSsh, - CompletedProgramName.ftpCrack, - CompletedProgramName.relaySmtp, - CompletedProgramName.httpWorm, - CompletedProgramName.sqlInject, - CompletedProgramName.deepScan1, - CompletedProgramName.deepScan2, - CompletedProgramName.serverProfiler, - CompletedProgramName.autoLink, - CompletedProgramName.formulas, - ], - }), -]; - -export function initNeuroFluxGovernor(): Augmentation { - const donationBonus = CONSTANTS.Donations / 1e6 / 100; // 1 millionth of a percent per donation - return new Augmentation({ - name: AugmentationName.NeuroFluxGovernor, - repCost: 500, - moneyCost: 750e3, - info: - "Undetectable adamantium nanobots injected in the users bloodstream. The NeuroFlux Governor " + - "monitors and regulates all aspects of the human body, essentially 'governing' the body. " + - "By doing so, it improves the users performance for most actions.", - stats: ( - <> - This special augmentation can be leveled up infinitely. Each level of this augmentation increases MOST - multipliers by 1% (+{(donationBonus * 100).toFixed(6)}%), stacking multiplicatively. - - ), - isSpecial: true, - hacking_chance: 1.01 + donationBonus, - hacking_speed: 1.01 + donationBonus, - hacking_money: 1.01 + donationBonus, - hacking_grow: 1.01 + donationBonus, - hacking: 1.01 + donationBonus, - strength: 1.01 + donationBonus, - defense: 1.01 + donationBonus, - dexterity: 1.01 + donationBonus, - agility: 1.01 + donationBonus, - charisma: 1.01 + donationBonus, - hacking_exp: 1.01 + donationBonus, - strength_exp: 1.01 + donationBonus, - defense_exp: 1.01 + donationBonus, - dexterity_exp: 1.01 + donationBonus, - agility_exp: 1.01 + donationBonus, - charisma_exp: 1.01 + donationBonus, - company_rep: 1.01 + donationBonus, - faction_rep: 1.01 + donationBonus, - crime_money: 1.01 + donationBonus, - crime_success: 1.01 + donationBonus, - hacknet_node_money: 1.01 + donationBonus, - hacknet_node_purchase_cost: 1 / (1.01 + donationBonus), - hacknet_node_ram_cost: 1 / (1.01 + donationBonus), - hacknet_node_core_cost: 1 / (1.01 + donationBonus), - hacknet_node_level_cost: 1 / (1.01 + donationBonus), - work_money: 1.01 + donationBonus, - factions: Object.values(FactionName).filter( - (factionName) => - ![FactionName.ShadowsOfAnarchy, FactionName.Bladeburners, FactionName.ChurchOfTheMachineGod].includes( - factionName, - ), - ), - }); -} - -export function initUnstableCircadianModulator(): Augmentation { - //Time-Based Augment Test - const randomBonuses = getRandomBonus(); - - const UnstableCircadianModulatorParams: IConstructorParams = { - name: AugmentationName.UnstableCircadianModulator, - moneyCost: 5e9, - repCost: 3.625e5, - info: - "An experimental nanobot injection. Its unstable nature leads to " + - "unpredictable results based on your circadian rhythm.", - factions: [FactionName.SpeakersForTheDead], - }; - Object.keys(randomBonuses.bonuses).forEach( - (key) => ((UnstableCircadianModulatorParams as any)[key] = randomBonuses.bonuses[key]), - ); - - return new Augmentation(UnstableCircadianModulatorParams); -} diff --git a/src/Augmentation/ui/AugmentationsRoot.tsx b/src/Augmentation/ui/AugmentationsRoot.tsx index ca1a3d011..97801ef73 100644 --- a/src/Augmentation/ui/AugmentationsRoot.tsx +++ b/src/Augmentation/ui/AugmentationsRoot.tsx @@ -20,7 +20,7 @@ import { Settings } from "../../Settings/Settings"; import { ConfirmationModal } from "../../ui/React/ConfirmationModal"; import { Player } from "@player"; import { AugmentationName } from "@enums"; -import { StaticAugmentations } from "../StaticAugmentations"; +import { Augmentations } from "../Augmentations"; import { CONSTANTS } from "../../Constants"; import { formatNumberNoSuffix } from "../../ui/formatNumber"; import { Info } from "@mui/icons-material"; @@ -49,9 +49,7 @@ const NeuroFluxDisplay = (): React.ReactElement => { NeuroFlux Governor - Level {level} - - {StaticAugmentations[AugmentationName.NeuroFluxGovernor].stats} - + {Augmentations[AugmentationName.NeuroFluxGovernor].stats} The power of {AugmentationName.NeuroFluxGovernor} increases with blood donations from players in real life. Learn more here diff --git a/src/Augmentation/ui/InstalledAugmentations.tsx b/src/Augmentation/ui/InstalledAugmentations.tsx index e34a8c1b5..5e4e3665d 100644 --- a/src/Augmentation/ui/InstalledAugmentations.tsx +++ b/src/Augmentation/ui/InstalledAugmentations.tsx @@ -13,7 +13,7 @@ import React, { useState } from "react"; import { OwnedAugmentationsOrderSetting } from "../../Settings/SettingEnums"; import { Settings } from "../../Settings/Settings"; import { Player } from "@player"; -import { StaticAugmentations } from "../StaticAugmentations"; +import { Augmentations } from "../Augmentations"; import { AugmentationName } from "@enums"; import { useRerender } from "../../ui/React/hooks"; @@ -73,7 +73,7 @@ export function InstalledAugmentations(): React.ReactElement { {(() => { - const aug = StaticAugmentations[selectedAug.name]; + const aug = Augmentations[selectedAug.name]; const info = typeof aug.info === "string" ? {aug.info} : aug.info; const tooltip = ( diff --git a/src/Augmentation/ui/PlayerMultipliers.tsx b/src/Augmentation/ui/PlayerMultipliers.tsx index 43ac87cdb..16305a4cb 100644 --- a/src/Augmentation/ui/PlayerMultipliers.tsx +++ b/src/Augmentation/ui/PlayerMultipliers.tsx @@ -2,16 +2,16 @@ import { DoubleArrow } from "@mui/icons-material"; import { List, ListItem, ListItemText, Paper, Typography } from "@mui/material"; import * as React from "react"; import { Multipliers, defaultMultipliers, mergeMultipliers } from "../../PersonObjects/Multipliers"; -import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../../BitNode/BitNodeMultipliers"; import { Player } from "@player"; import { Settings } from "../../Settings/Settings"; import { formatPercent } from "../../ui/formatNumber"; -import { StaticAugmentations } from "../StaticAugmentations"; +import { Augmentations } from "../Augmentations"; function calculateAugmentedStats(): Multipliers { let augP: Multipliers = defaultMultipliers(); for (const aug of Player.queuedAugmentations) { - const augObj = StaticAugmentations[aug.name]; + const augObj = Augmentations[aug.name]; augP = mergeMultipliers(augP, augObj.mults); } return augP; @@ -101,7 +101,7 @@ export function PlayerMultipliers(): React.ReactElement { mult: "Hacking Money", current: Player.mults.hacking_money, augmented: Player.mults.hacking_money * mults.hacking_money, - bnMult: BitNodeMultipliers.ScriptHackMoney, + bnMult: currentNodeMults.ScriptHackMoney, }, { mult: "Hacking Growth", @@ -112,13 +112,13 @@ export function PlayerMultipliers(): React.ReactElement { mult: "Hacking Level", current: Player.mults.hacking, augmented: Player.mults.hacking * mults.hacking, - bnMult: BitNodeMultipliers.HackingLevelMultiplier, + bnMult: currentNodeMults.HackingLevelMultiplier, }, { mult: "Hacking Experience", current: Player.mults.hacking_exp, augmented: Player.mults.hacking_exp * mults.hacking_exp, - bnMult: BitNodeMultipliers.HackExpGain, + bnMult: currentNodeMults.HackExpGain, }, ].map((data: MultiplierListItemData) => Object.defineProperty(data, "color", { @@ -130,7 +130,7 @@ export function PlayerMultipliers(): React.ReactElement { mult: "Strength Level", current: Player.mults.strength, augmented: Player.mults.strength * mults.strength, - bnMult: BitNodeMultipliers.StrengthLevelMultiplier, + bnMult: currentNodeMults.StrengthLevelMultiplier, }, { mult: "Strength Experience", @@ -141,7 +141,7 @@ export function PlayerMultipliers(): React.ReactElement { mult: "Defense Level", current: Player.mults.defense, augmented: Player.mults.defense * mults.defense, - bnMult: BitNodeMultipliers.DefenseLevelMultiplier, + bnMult: currentNodeMults.DefenseLevelMultiplier, }, { mult: "Defense Experience", @@ -152,7 +152,7 @@ export function PlayerMultipliers(): React.ReactElement { mult: "Dexterity Level", current: Player.mults.dexterity, augmented: Player.mults.dexterity * mults.dexterity, - bnMult: BitNodeMultipliers.DexterityLevelMultiplier, + bnMult: currentNodeMults.DexterityLevelMultiplier, }, { mult: "Dexterity Experience", @@ -163,7 +163,7 @@ export function PlayerMultipliers(): React.ReactElement { mult: "Agility Level", current: Player.mults.agility, augmented: Player.mults.agility * mults.agility, - bnMult: BitNodeMultipliers.AgilityLevelMultiplier, + bnMult: currentNodeMults.AgilityLevelMultiplier, }, { mult: "Agility Experience", @@ -179,7 +179,7 @@ export function PlayerMultipliers(): React.ReactElement { mult: "Charisma Level", current: Player.mults.charisma, augmented: Player.mults.charisma * mults.charisma, - bnMult: BitNodeMultipliers.CharismaLevelMultiplier, + bnMult: currentNodeMults.CharismaLevelMultiplier, color: Settings.theme.cha, }, { @@ -194,7 +194,7 @@ export function PlayerMultipliers(): React.ReactElement { mult: "Hacknet Node Production", current: Player.mults.hacknet_node_money, augmented: Player.mults.hacknet_node_money * mults.hacknet_node_money, - bnMult: BitNodeMultipliers.HacknetNodeMoney, + bnMult: currentNodeMults.HacknetNodeMoney, }, { mult: "Hacknet Node Purchase Cost", @@ -226,14 +226,14 @@ export function PlayerMultipliers(): React.ReactElement { mult: "Faction Reputation Gain", current: Player.mults.faction_rep, augmented: Player.mults.faction_rep * mults.faction_rep, - bnMult: BitNodeMultipliers.FactionWorkRepGain, + bnMult: currentNodeMults.FactionWorkRepGain, color: Settings.theme.combat, }, { mult: "Salary", current: Player.mults.work_money, augmented: Player.mults.work_money * mults.work_money, - bnMult: BitNodeMultipliers.CompanyWorkMoney, + bnMult: currentNodeMults.CompanyWorkMoney, color: Settings.theme.money, }, { @@ -246,12 +246,12 @@ export function PlayerMultipliers(): React.ReactElement { mult: "Crime Money", current: Player.mults.crime_money, augmented: Player.mults.crime_money * mults.crime_money, - bnMult: BitNodeMultipliers.CrimeMoney, + bnMult: currentNodeMults.CrimeMoney, color: Settings.theme.money, }, ]; - if (Player.canAccessBladeburner() && BitNodeMultipliers.BladeburnerRank > 0) { + if (Player.canAccessBladeburner() && currentNodeMults.BladeburnerRank > 0) { rightColData.push( { mult: "Bladeburner Success Chance", diff --git a/src/Augmentation/ui/PurchasableAugmentations.tsx b/src/Augmentation/ui/PurchasableAugmentations.tsx index 8eae47392..81330a388 100644 --- a/src/Augmentation/ui/PurchasableAugmentations.tsx +++ b/src/Augmentation/ui/PurchasableAugmentations.tsx @@ -11,8 +11,9 @@ import { Settings } from "../../Settings/Settings"; import { formatMoney, formatReputation } from "../../ui/formatNumber"; import { Augmentation } from "../Augmentation"; import { AugmentationName, FactionName } from "@enums"; -import { StaticAugmentations } from "../StaticAugmentations"; +import { Augmentations } from "../Augmentations"; import { PurchaseAugmentationModal } from "./PurchaseAugmentationModal"; +import { getAugCost } from "../AugmentationHelpers"; interface IPreReqsProps { aug: Augmentation; @@ -126,8 +127,8 @@ const Requirement = (props: IReqProps): React.ReactElement => { }; interface IPurchasableAugsProps { - augNames: string[]; - ownedAugNames: string[]; + augNames: AugmentationName[]; + ownedAugNames: AugmentationName[]; canPurchase: (aug: Augmentation) => boolean; purchaseAugmentation: (aug: Augmentation, showModal: (open: boolean) => void) => void; @@ -144,10 +145,10 @@ export const PurchasableAugmentations = (props: IPurchasableAugsProps): React.Re disableGutters sx={{ mx: 0, display: "grid", gridTemplateColumns: "repeat(1, 1fr)", gap: 0.75 }} > - {props.augNames.map((augName: string) => ( + {props.augNames.map((augName) => ( ))} - {props.ownedAugNames.map((augName: string) => ( + {props.ownedAugNames.map((augName) => ( ))} @@ -156,16 +157,17 @@ export const PurchasableAugmentations = (props: IPurchasableAugsProps): React.Re interface IPurchasableAugProps { parent: IPurchasableAugsProps; - augName: string; + augName: AugmentationName; owned: boolean; } export function PurchasableAugmentation(props: IPurchasableAugProps): React.ReactElement { const [open, setOpen] = useState(false); - const aug = StaticAugmentations[props.augName]; + const aug = Augmentations[props.augName]; if (!aug) return <>; - const augCosts = aug.getCost(); + const augLevel = aug.getLevel(); + const augCosts = getAugCost(aug); const cost = props.parent.sleeveAugs ? aug.baseCost : augCosts.moneyCost; const repCost = augCosts.repCost; const info = typeof aug.info === "string" ? {aug.info} : aug.info; @@ -209,8 +211,8 @@ export function PurchasableAugmentation(props: IPurchasableAugProps): React.Reac title={ <> - {props.augName} - {props.augName === AugmentationName.NeuroFluxGovernor && ` - Level ${aug.getLevel()}`} + {aug.name} + {aug.name === AugmentationName.NeuroFluxGovernor && ` - Level ${augLevel + 1}`} {description} @@ -227,7 +229,7 @@ export function PurchasableAugmentation(props: IPurchasableAugProps): React.Reac }} > {aug.name} - {aug.name === AugmentationName.NeuroFluxGovernor && ` - Level ${aug.getLevel()}`} + {aug.name === AugmentationName.NeuroFluxGovernor && ` - Level ${augLevel + 1}`} diff --git a/src/Augmentation/ui/PurchaseAugmentationModal.tsx b/src/Augmentation/ui/PurchaseAugmentationModal.tsx index 2656fe629..b8817a248 100644 --- a/src/Augmentation/ui/PurchaseAugmentationModal.tsx +++ b/src/Augmentation/ui/PurchaseAugmentationModal.tsx @@ -3,7 +3,7 @@ import React from "react"; import { Augmentation } from "../Augmentation"; import { Faction } from "../../Faction/Faction"; import { purchaseAugmentation } from "../../Faction/FactionHelpers"; -import { isRepeatableAug } from "../AugmentationHelpers"; +import { getAugCost, isRepeatableAug } from "../AugmentationHelpers"; import { Money } from "../../ui/React/Money"; import { Modal } from "../../ui/React/Modal"; import { Player } from "@player"; @@ -33,7 +33,7 @@ export function PurchaseAugmentationModal({ aug, faction, onClose, open }: IProp

Would you like to purchase the {aug.name} Augmentation for  - ? + ?

diff --git a/src/Augmentation/ui/PurchasedAugmentations.tsx b/src/Augmentation/ui/PurchasedAugmentations.tsx index ec54ef1bf..f8689abb5 100644 --- a/src/Augmentation/ui/PurchasedAugmentations.tsx +++ b/src/Augmentation/ui/PurchasedAugmentations.tsx @@ -5,7 +5,7 @@ import { List, ListItemText, Paper, Tooltip, Typography } from "@mui/material"; import * as React from "react"; import { Player } from "@player"; -import { StaticAugmentations } from "../StaticAugmentations"; +import { Augmentations } from "../Augmentations"; import { AugmentationName } from "@enums"; export function PurchasedAugmentations(): React.ReactElement { @@ -20,10 +20,10 @@ export function PurchasedAugmentations(): React.ReactElement { } for (let i = 0; i < Player.queuedAugmentations.length; i++) { const ownedAug = Player.queuedAugmentations[i]; - let displayName = ownedAug.name; + let displayName: string = ownedAug.name; if (ownedAug.name === AugmentationName.NeuroFluxGovernor && i !== nfgIndex) continue; - const aug = StaticAugmentations[ownedAug.name]; + const aug = Augmentations[ownedAug.name]; let level = null; if (ownedAug.name === AugmentationName.NeuroFluxGovernor) { diff --git a/src/BitNode/BitNode.tsx b/src/BitNode/BitNode.tsx index 528897857..6543f02b5 100644 --- a/src/BitNode/BitNode.tsx +++ b/src/BitNode/BitNode.tsx @@ -1,7 +1,7 @@ import React from "react"; import { Player } from "@player"; -import { BitNodeMultipliers, IBitNodeMultipliers } from "./BitNodeMultipliers"; import { CityName, FactionName } from "@enums"; +import { BitNodeMultipliers, replaceCurrentNodeMults } from "./BitNodeMultipliers"; class BitNode { // A short description, or tagline, about the BitNode @@ -447,82 +447,16 @@ export function initBitNodes() { ); } -export const defaultMultipliers: IBitNodeMultipliers = { - HackingLevelMultiplier: 1, - StrengthLevelMultiplier: 1, - DefenseLevelMultiplier: 1, - DexterityLevelMultiplier: 1, - AgilityLevelMultiplier: 1, - CharismaLevelMultiplier: 1, - - ServerGrowthRate: 1, - ServerMaxMoney: 1, - ServerStartingMoney: 1, - ServerStartingSecurity: 1, - ServerWeakenRate: 1, - - HomeComputerRamCost: 1, - - PurchasedServerCost: 1, - PurchasedServerSoftcap: 1, - PurchasedServerLimit: 1, - PurchasedServerMaxRam: 1, - - CompanyWorkMoney: 1, - CrimeMoney: 1, - HacknetNodeMoney: 1, - ManualHackMoney: 1, - ScriptHackMoney: 1, - ScriptHackMoneyGain: 1, - CodingContractMoney: 1, - - ClassGymExpGain: 1, - CompanyWorkExpGain: 1, - CrimeExpGain: 1, - FactionWorkExpGain: 1, - HackExpGain: 1, - - FactionPassiveRepGain: 1, - FactionWorkRepGain: 1, - RepToDonateToFaction: 1, - - AugmentationMoneyCost: 1, - AugmentationRepCost: 1, - - InfiltrationMoney: 1, - InfiltrationRep: 1, - - FourSigmaMarketDataCost: 1, - FourSigmaMarketDataApiCost: 1, - - CorporationValuation: 1, - CorporationSoftcap: 1, - CorporationDivisions: 1, - - BladeburnerRank: 1, - BladeburnerSkillCost: 1, - - GangSoftcap: 1, - GangUniqueAugs: 1, - - DaedalusAugsRequirement: 30, - - StaneksGiftPowerMultiplier: 1, - StaneksGiftExtraSize: 0, - - WorldDaemonDifficulty: 1, -}; - +export const defaultMultipliers = new BitNodeMultipliers(); Object.freeze(defaultMultipliers); -export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultipliers { - const mults = Object.assign({}, defaultMultipliers); +export function getBitNodeMultipliers(n: number, lvl: number): BitNodeMultipliers { switch (n) { case 1: { - return mults; + return new BitNodeMultipliers(); } case 2: { - return Object.assign(mults, { + return new BitNodeMultipliers({ HackingLevelMultiplier: 0.8, ServerGrowthRate: 0.8, @@ -546,7 +480,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie }); } case 3: { - return Object.assign(mults, { + return new BitNodeMultipliers({ HackingLevelMultiplier: 0.8, ServerGrowthRate: 0.2, @@ -578,7 +512,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie }); } case 4: { - return Object.assign(mults, { + return new BitNodeMultipliers({ ServerMaxMoney: 0.1125, ServerStartingMoney: 0.75, @@ -606,7 +540,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie }); } case 5: { - return Object.assign(mults, { + return new BitNodeMultipliers({ ServerStartingSecurity: 2, ServerStartingMoney: 0.5, @@ -635,7 +569,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie }); } case 6: { - return Object.assign(mults, { + return new BitNodeMultipliers({ HackingLevelMultiplier: 0.35, ServerMaxMoney: 0.2, @@ -669,7 +603,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie }); } case 7: { - return Object.assign(mults, { + return new BitNodeMultipliers({ HackingLevelMultiplier: 0.35, ServerMaxMoney: 0.2, @@ -711,7 +645,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie }); } case 8: { - return Object.assign(mults, { + return new BitNodeMultipliers({ PurchasedServerSoftcap: 4, CompanyWorkMoney: 0, @@ -739,7 +673,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie }); } case 9: { - return Object.assign(mults, { + return new BitNodeMultipliers({ HackingLevelMultiplier: 0.5, StrengthLevelMultiplier: 0.45, DefenseLevelMultiplier: 0.45, @@ -780,7 +714,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie }); } case 10: { - return Object.assign(mults, { + return new BitNodeMultipliers({ HackingLevelMultiplier: 0.35, StrengthLevelMultiplier: 0.4, DefenseLevelMultiplier: 0.4, @@ -823,7 +757,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie }); } case 11: { - return Object.assign(mults, { + return new BitNodeMultipliers({ HackingLevelMultiplier: 0.6, ServerGrowthRate: 0.2, @@ -861,8 +795,8 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie const inc = Math.pow(1.02, lvl); const dec = 1 / inc; - return Object.assign(mults, { - DaedalusAugsRequirement: Math.floor(Math.min(mults.DaedalusAugsRequirement + inc, 40)), + return new BitNodeMultipliers({ + DaedalusAugsRequirement: Math.floor(Math.min(defaultMultipliers.DaedalusAugsRequirement + inc, 40)), HackingLevelMultiplier: dec, StrengthLevelMultiplier: dec, @@ -929,7 +863,7 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie }); } case 13: { - return Object.assign(mults, { + return new BitNodeMultipliers({ HackingLevelMultiplier: 0.25, StrengthLevelMultiplier: 0.7, DefenseLevelMultiplier: 0.7, @@ -982,5 +916,5 @@ export function getBitNodeMultipliers(n: number, lvl: number): IBitNodeMultiplie } export function initBitNodeMultipliers(): void { - Object.assign(BitNodeMultipliers, getBitNodeMultipliers(Player.bitNodeN, Player.sourceFileLvl(Player.bitNodeN) + 1)); + replaceCurrentNodeMults(getBitNodeMultipliers(Player.bitNodeN, Player.sourceFileLvl(Player.bitNodeN) + 1)); } diff --git a/src/BitNode/BitNodeMultipliers.ts b/src/BitNode/BitNodeMultipliers.ts index bb10c6fc2..7953a097d 100644 --- a/src/BitNode/BitNodeMultipliers.ts +++ b/src/BitNode/BitNodeMultipliers.ts @@ -1,168 +1,173 @@ -import { defaultMultipliers } from "./BitNode"; +import { PartialRecord, getRecordEntries } from "../Types/Record"; /** * Bitnode multipliers influence the difficulty of different aspects of the game. * Each Bitnode has a different theme/strategy to achieving the end goal, so these multipliers will can help drive the * player toward the intended strategy. Unless they really want to play the long, slow game of waiting... */ -export interface IBitNodeMultipliers { +export class BitNodeMultipliers { /** Influences how quickly the player's agility level (not exp) scales */ - AgilityLevelMultiplier: number; + AgilityLevelMultiplier = 1; /** Influences the base cost to purchase an augmentation. */ - AugmentationMoneyCost: number; + AugmentationMoneyCost = 1; /** Influences the base rep the player must have with a faction to purchase an augmentation. */ - AugmentationRepCost: number; + AugmentationRepCost = 1; /** Influences how quickly the player can gain rank within Bladeburner. */ - BladeburnerRank: number; + BladeburnerRank = 1; /** Influences the cost of skill levels from Bladeburner. */ - BladeburnerSkillCost: number; + BladeburnerSkillCost = 1; /** Influences how quickly the player's charisma level (not exp) scales */ - CharismaLevelMultiplier: number; + CharismaLevelMultiplier = 1; /** Influences the experience gained for each ability when a player completes a class. */ - ClassGymExpGain: number; + ClassGymExpGain = 1; /**Influences the amount of money gained from completing Coding Contracts. */ - CodingContractMoney: number; + CodingContractMoney = 1; /** Influences the experience gained for each ability when the player completes working their job. */ - CompanyWorkExpGain: number; + CompanyWorkExpGain = 1; /** Influences how much money the player earns when completing working their job. */ - CompanyWorkMoney: number; + CompanyWorkMoney = 1; /** Influences the valuation of corporations created by the player. */ - CorporationValuation: number; + CorporationValuation = 1; /** Influences the base experience gained for each ability when the player commits a crime. */ - CrimeExpGain: number; + CrimeExpGain = 1; /** Influences the base money gained when the player commits a crime. */ - CrimeMoney: number; + CrimeMoney = 1; /** Influences how many Augmentations you need in order to get invited to the Daedalus faction */ - DaedalusAugsRequirement: number; + DaedalusAugsRequirement = 30; /** Influences how quickly the player's defense level (not exp) scales */ - DefenseLevelMultiplier: number; + DefenseLevelMultiplier = 1; /** Influences how quickly the player's dexterity level (not exp) scales */ - DexterityLevelMultiplier: number; + DexterityLevelMultiplier = 1; /** Influences how much rep the player gains in each faction simply by being a member. */ - FactionPassiveRepGain: number; + FactionPassiveRepGain = 1; /** Influences the experience gained for each ability when the player completes work for a Faction. */ - FactionWorkExpGain: number; + FactionWorkExpGain = 1; /** Influences how much rep the player gains when performing work for a faction. */ - FactionWorkRepGain: number; + FactionWorkRepGain = 1; /** Influences how much it costs to unlock the stock market's 4S Market Data API */ - FourSigmaMarketDataApiCost: number; + FourSigmaMarketDataApiCost = 1; /** Influences how much it costs to unlock the stock market's 4S Market Data (NOT API) */ - FourSigmaMarketDataCost: number; + FourSigmaMarketDataCost = 1; /** Reduces gangs earning. */ - GangSoftcap: number; + GangSoftcap = 1; /** Percentage of unique augs that the gang has. */ - GangUniqueAugs: number; + GangUniqueAugs = 1; /** Influences the experienced gained when hacking a server. */ - HackExpGain: number; + HackExpGain = 1; /** Influences how quickly the player's hacking level (not experience) scales */ - HackingLevelMultiplier: number; + HackingLevelMultiplier = 1; /** * Influences how much money is produced by Hacknet Nodes. * Influences the hash rate of Hacknet Servers (unlocked in BitNode-9) */ - HacknetNodeMoney: number; + HacknetNodeMoney = 1; /** Influences how much money it costs to upgrade your home computer's RAM */ - HomeComputerRamCost: number; + HomeComputerRamCost = 1; /** Influences how much money is gained when the player infiltrates a company. */ - InfiltrationMoney: number; + InfiltrationMoney = 1; /** Influences how much rep the player can gain from factions when selling stolen documents and secrets */ - InfiltrationRep: number; + InfiltrationRep = 1; /** * Influences how much money can be stolen from a server when the player performs a hack against it through * the Terminal. */ - ManualHackMoney: number; + ManualHackMoney = 1; /** Influence how much it costs to purchase a server */ - PurchasedServerCost: number; + PurchasedServerCost = 1; /** Influence how much it costs to purchase a server */ - PurchasedServerSoftcap: number; + PurchasedServerSoftcap = 1; /** Influences the maximum number of purchased servers you can have */ - PurchasedServerLimit: number; + PurchasedServerLimit = 1; /** Influences the maximum allowed RAM for a purchased server */ - PurchasedServerMaxRam: number; + PurchasedServerMaxRam = 1; /** Influences the minimum favor the player must have with a faction before they can donate to gain rep. */ - RepToDonateToFaction: number; + RepToDonateToFaction = 1; /** Influences how much money can be stolen from a server when a script performs a hack against it. */ - ScriptHackMoney: number; + ScriptHackMoney = 1; /** * The amount of money actually gained when script hack a server. This is * different than the above because you can reduce the amount of money but * not gain that same amount. */ - ScriptHackMoneyGain: number; + ScriptHackMoneyGain = 1; /** Influences the growth percentage per cycle against a server. */ - ServerGrowthRate: number; + ServerGrowthRate = 1; /** Influences the maximum money that a server can grow to. */ - ServerMaxMoney: number; + ServerMaxMoney = 1; /** Influences the initial money that a server starts with. */ - ServerStartingMoney: number; + ServerStartingMoney = 1; /** Influences the initial security level (hackDifficulty) of a server. */ - ServerStartingSecurity: number; + ServerStartingSecurity = 1; /** Influences the weaken amount per invocation against a server. */ - ServerWeakenRate: number; + ServerWeakenRate = 1; /** Influences how quickly the player's strength level (not exp) scales */ - StrengthLevelMultiplier: number; + StrengthLevelMultiplier = 1; /** Influences the power of the gift. */ - StaneksGiftPowerMultiplier: number; + StaneksGiftPowerMultiplier = 1; /** Influences the size of the gift. */ - StaneksGiftExtraSize: number; + StaneksGiftExtraSize = 0; /** Influences the hacking skill required to backdoor the world daemon. */ - WorldDaemonDifficulty: number; + WorldDaemonDifficulty = 1; /** Influences profits from corporation dividends and selling shares. */ - CorporationSoftcap: number; + CorporationSoftcap = 1; /** Influences number of divisions a corporation can have. */ - CorporationDivisions: number; + CorporationDivisions = 1; - // Index signature - [key: string]: number; + constructor(a: PartialRecord = {}) { + for (const [key, value] of getRecordEntries(a)) this[key] = value; + } } -/** The multipliers that are influenced by current Bitnode progression. */ -export const BitNodeMultipliers = Object.assign({}, defaultMultipliers); +/** The multipliers currently in effect */ +export let currentNodeMults = new BitNodeMultipliers(); + +export function replaceCurrentNodeMults(mults: BitNodeMultipliers) { + currentNodeMults = mults; +} diff --git a/src/BitNode/ui/BitnodeMultipliersDescription.tsx b/src/BitNode/ui/BitnodeMultipliersDescription.tsx index 90767678e..9949a75b6 100644 --- a/src/BitNode/ui/BitnodeMultipliersDescription.tsx +++ b/src/BitNode/ui/BitnodeMultipliersDescription.tsx @@ -1,14 +1,16 @@ +import React from "react"; +import { uniqueId } from "lodash"; +import { Box, Collapse, ListItemButton, ListItemText, Paper, Table, TableBody, Typography } from "@mui/material"; import ExpandLess from "@mui/icons-material/ExpandLess"; import ExpandMore from "@mui/icons-material/ExpandMore"; -import { Box, Collapse, ListItemButton, ListItemText, Paper, Table, TableBody, Typography } from "@mui/material"; -import { uniqueId } from "lodash"; -import React from "react"; + +import { Player } from "@player"; import { SpecialServers } from "../../Server/data/SpecialServers"; import { Settings } from "../../Settings/Settings"; -import { Player } from "@player"; import { StatsRow } from "../../ui/React/StatsRow"; import { defaultMultipliers, getBitNodeMultipliers } from "../BitNode"; -import { IBitNodeMultipliers } from "../BitNodeMultipliers"; +import { BitNodeMultipliers } from "../BitNodeMultipliers"; +import { PartialRecord, getRecordEntries } from "../../Types/Record"; interface IProps { n: number; @@ -60,8 +62,8 @@ export const BitNodeMultipliersDisplay = ({ n, level }: IProps): React.ReactElem ); }; -type IBNMultRows = Record< - string, +type IBNMultRows = PartialRecord< + keyof BitNodeMultipliers, { name: string; content?: string; @@ -72,11 +74,11 @@ type IBNMultRows = Record< interface IBNMultTableProps { sectionName: string; rowData: IBNMultRows; - mults: IBitNodeMultipliers; + mults: BitNodeMultipliers; } const BNMultTable = (props: IBNMultTableProps): React.ReactElement => { - const rowsArray = Object.entries(props.rowData) + const rowsArray = getRecordEntries(props.rowData) .filter(([key]) => props.mults[key] !== defaultMultipliers[key]) .map(([key, value]) => ( { interface IMultsProps { n: number; - mults: IBitNodeMultipliers; + mults: BitNodeMultipliers; } function GeneralMults({ mults }: IMultsProps): React.ReactElement { diff --git a/src/Bladeburner/Bladeburner.tsx b/src/Bladeburner/Bladeburner.tsx index e704340e8..0de36795a 100644 --- a/src/Bladeburner/Bladeburner.tsx +++ b/src/Bladeburner/Bladeburner.tsx @@ -21,7 +21,7 @@ import { exceptionAlert } from "../utils/helpers/exceptionAlert"; import { getRandomInt } from "../utils/helpers/getRandomInt"; import { BladeburnerConstants } from "./data/Constants"; import { formatExp, formatMoney, formatPercent, formatBigNumber, formatStamina } from "../ui/formatNumber"; -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; import { addOffset } from "../utils/helpers/addOffset"; import { Factions, factionExists } from "../Faction/Factions"; import { calculateHospitalizationCost } from "../Hospital/Hospital"; @@ -1281,7 +1281,7 @@ export class Bladeburner { action.setMaxLevel(BladeburnerConstants.ContractSuccessesPerLevel); } if (action.rankGain) { - const gain = addOffset(action.rankGain * rewardMultiplier * BitNodeMultipliers.BladeburnerRank, 10); + const gain = addOffset(action.rankGain * rewardMultiplier * currentNodeMults.BladeburnerRank, 10); this.changeRank(person, gain); if (isOperation && this.logging.ops) { this.log( @@ -1365,7 +1365,7 @@ export class Bladeburner { this.blackops[action.name] = true; let rankGain = 0; if (action.rankGain) { - rankGain = addOffset(action.rankGain * BitNodeMultipliers.BladeburnerRank, 10); + rankGain = addOffset(action.rankGain * currentNodeMults.BladeburnerRank, 10); this.changeRank(person, rankGain); } teamLossMax = Math.ceil(teamCount / 2); @@ -1481,7 +1481,7 @@ export class Bladeburner { } const hackingExpGain = 20 * person.mults.hacking_exp; const charismaExpGain = 20 * person.mults.charisma_exp; - const rankGain = 0.1 * BitNodeMultipliers.BladeburnerRank; + const rankGain = 0.1 * currentNodeMults.BladeburnerRank; retValue.hackExp = hackingExpGain; retValue.chaExp = charismaExpGain; retValue.intExp = BladeburnerConstants.BaseIntGain; diff --git a/src/Bladeburner/Skill.ts b/src/Bladeburner/Skill.ts index 32c8bc8ea..3beb3c73a 100644 --- a/src/Bladeburner/Skill.ts +++ b/src/Bladeburner/Skill.ts @@ -1,4 +1,4 @@ -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; interface ISkillParams { name: string; @@ -138,10 +138,10 @@ export class Skill { //be possible for it to run with them. For the sake of not crashing the game, const recursiveMode = (currentLevel: number, count: number): number => { if (count <= 1) { - return Math.floor((this.baseCost + currentLevel * this.costInc) * BitNodeMultipliers.BladeburnerSkillCost); + return Math.floor((this.baseCost + currentLevel * this.costInc) * currentNodeMults.BladeburnerSkillCost); } else { const thisUpgrade = Math.floor( - (this.baseCost + currentLevel * this.costInc) * BitNodeMultipliers.BladeburnerSkillCost, + (this.baseCost + currentLevel * this.costInc) * currentNodeMults.BladeburnerSkillCost, ); return this.calculateCost(currentLevel + 1, count - 1) + thisUpgrade; } @@ -161,7 +161,7 @@ export class Skill { //(this.baseCost + currentLevel * this.costInc) * BitNodeMultipliers.BladeburnerSkillCost //being repeated for increasing currentLevel const preMult = (count * (2 * this.baseCost + this.costInc * (2 * currentLevel + count + 1))) / 2; - const unFloored = preMult * BitNodeMultipliers.BladeburnerSkillCost - count / 2; + const unFloored = preMult * currentNodeMults.BladeburnerSkillCost - count / 2; return Math.floor(unFloored); } } diff --git a/src/Corporation/Corporation.ts b/src/Corporation/Corporation.ts index 937519d85..e849d692a 100644 --- a/src/Corporation/Corporation.ts +++ b/src/Corporation/Corporation.ts @@ -6,7 +6,7 @@ import { CorpUpgrades } from "./data/CorporationUpgrades"; import * as corpConstants from "./data/Constants"; import { Division } from "./Division"; -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; import { showLiterature } from "../Literature/LiteratureHelpers"; import { dialogBoxCreate } from "../ui/React/DialogBox"; @@ -28,7 +28,7 @@ export class Corporation { /** Map keyed by division name */ divisions = new JSONMap(); - maxDivisions = 20 * BitNodeMultipliers.CorporationDivisions; + maxDivisions = 20 * currentNodeMults.CorporationDivisions; //Financial stats funds = 150e9; @@ -44,7 +44,7 @@ export class Corporation { shareSaleCooldown = 0; // Game cycles until player can sell shares again issueNewSharesCooldown = 0; // Game cycles until player can issue shares again dividendRate = 0; - dividendTax = 1 - BitNodeMultipliers.CorporationSoftcap + 0.15; + dividendTax = 1 - currentNodeMults.CorporationSoftcap + 0.15; issuedShares = 0; sharePrice = 0; storedCycles = 0; @@ -188,7 +188,7 @@ export class Corporation { val *= Math.pow(1.1, this.divisions.size); val -= val % 1e6; //Round down to nearest millionth } - return val * BitNodeMultipliers.CorporationValuation; + return val * currentNodeMults.CorporationValuation; } determineValuation(): void { diff --git a/src/CotMG/StaneksGift.ts b/src/CotMG/StaneksGift.ts index 4edfa4142..21ebd5df8 100644 --- a/src/CotMG/StaneksGift.ts +++ b/src/CotMG/StaneksGift.ts @@ -9,9 +9,9 @@ import { CalculateEffect } from "./formulas/effect"; import { StaneksGiftEvents } from "./StaneksGiftEvents"; import { Generic_fromJSON, Generic_toJSON, IReviverValue, constructorsForReviver } from "../utils/JSONReviver"; import { StanekConstants } from "./data/Constants"; -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; import { defaultMultipliers, mergeMultipliers, Multipliers, scaleMultipliers } from "../PersonObjects/Multipliers"; -import { StaticAugmentations } from "../Augmentation/StaticAugmentations"; +import { Augmentations } from "../Augmentation/Augmentations"; import { getKeyList } from "../utils/helpers/getKeyList"; export class StaneksGift extends BaseGift { @@ -23,7 +23,7 @@ export class StaneksGift extends BaseGift { } baseSize(): number { - return StanekConstants.BaseSize + BitNodeMultipliers.StaneksGiftExtraSize + Player.sourceFileLvl(13); + return StanekConstants.BaseSize + currentNodeMults.StaneksGiftExtraSize + Player.sourceFileLvl(13); } width(): number { @@ -226,7 +226,7 @@ export class StaneksGift extends BaseGift { sleeve.resetMultipliers(); //reapplying augmentation's multiplier for (let i = 0; i < sleeve.augmentations.length; ++i) { - const aug = StaticAugmentations[sleeve.augmentations[i].name]; + const aug = Augmentations[sleeve.augmentations[i].name]; sleeve.applyAugmentation(aug); } //applying stanek multiplier diff --git a/src/CotMG/formulas/effect.ts b/src/CotMG/formulas/effect.ts index 4c32f2a75..131fc19d4 100644 --- a/src/CotMG/formulas/effect.ts +++ b/src/CotMG/formulas/effect.ts @@ -1,4 +1,4 @@ -import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../../BitNode/BitNodeMultipliers"; export function CalculateEffect(highestCharge: number, numCharge: number, power: number, boost: number): number { return ( @@ -7,6 +7,6 @@ export function CalculateEffect(highestCharge: number, numCharge: number, power: Math.pow((numCharge + 1) / 5, 0.07) * power * boost * - BitNodeMultipliers.StaneksGiftPowerMultiplier + currentNodeMults.StaneksGiftPowerMultiplier ); } diff --git a/src/DevMenu/ui/Augmentations.tsx b/src/DevMenu/ui/Augmentations.tsx index c79e36c8a..10f3259fc 100644 --- a/src/DevMenu/ui/Augmentations.tsx +++ b/src/DevMenu/ui/Augmentations.tsx @@ -15,10 +15,10 @@ import { import { AugmentationName } from "@enums"; export function Augmentations(): React.ReactElement { - const [augmentation, setAugmentation] = useState("Augmented Targeting I"); + const [augmentation, setAugmentation] = useState(AugmentationName.Targeting1); function setAugmentationDropdown(event: SelectChangeEvent): void { - setAugmentation(event.target.value); + setAugmentation(event.target.value as AugmentationName); } function queueAug(): void { Player.queueAugmentation(augmentation); diff --git a/src/Faction/Faction.ts b/src/Faction/Faction.ts index cf4aae5ab..b303340a6 100644 --- a/src/Faction/Faction.ts +++ b/src/Faction/Faction.ts @@ -1,6 +1,8 @@ +import type { AugmentationName } from "@enums"; import { FactionInfo, FactionInfos } from "./FactionInfo"; import { favorToRep, repToFavor } from "./formulas/favor"; import { Generic_fromJSON, Generic_toJSON, IReviverValue, constructorsForReviver } from "../utils/JSONReviver"; +import { getEnumHelper } from "../utils/EnumHelper"; export class Faction { /** @@ -10,7 +12,7 @@ export class Faction { alreadyInvited = false; /** Holds names of all augmentations that this Faction offers */ - augmentations: string[] = []; + augmentations: AugmentationName[] = []; /** Amount of favor the player has with this faction. */ favor = 0; @@ -67,7 +69,11 @@ export class Faction { /** Initializes a Faction object from a JSON save state. */ static fromJSON(value: IReviverValue): Faction { - return Generic_fromJSON(Faction, value.data); + const faction = Generic_fromJSON(Faction, value.data); + // Remove invalid augs from faction. Augs are repopulated with correct augs during any reset. + const augHelper = getEnumHelper("AugmentationName"); + faction.augmentations = faction.augmentations.filter((augName) => augHelper.isMember(augName)); + return faction; } } diff --git a/src/Faction/FactionHelpers.tsx b/src/Faction/FactionHelpers.tsx index 41a296081..580a45e9f 100644 --- a/src/Faction/FactionHelpers.tsx +++ b/src/Faction/FactionHelpers.tsx @@ -1,8 +1,8 @@ -import { StaticAugmentations } from "../Augmentation/StaticAugmentations"; +import { Augmentations } from "../Augmentation/Augmentations"; import { Augmentation } from "../Augmentation/Augmentation"; import { PlayerOwnedAugmentation } from "../Augmentation/PlayerOwnedAugmentation"; import { AugmentationName, FactionName } from "@enums"; -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; import { Faction } from "./Faction"; import { Factions } from "./Factions"; @@ -18,6 +18,7 @@ import { dialogBoxCreate } from "../ui/React/DialogBox"; import { InvitationEvent } from "./ui/InvitationModal"; import { SFC32RNG } from "../Casino/RNG"; import { isFactionWork } from "../Work/FactionWork"; +import { getAugCost } from "../Augmentation/AugmentationHelpers"; export function inviteToFaction(faction: Faction): void { Player.receiveInvite(faction.name); @@ -55,7 +56,7 @@ export function hasAugmentationPrereqs(aug: Augmentation): boolean { export function purchaseAugmentation(aug: Augmentation, fac: Faction, sing = false): string { const hasPrereqs = hasAugmentationPrereqs(aug); - const augCosts = aug.getCost(); + const augCosts = getAugCost(aug); if (!hasPrereqs) { const txt = `You must first purchase or install ${aug.prereqs .filter((req) => !Player.hasAugmentation(req)) @@ -127,21 +128,21 @@ export function processPassiveFactionRepGain(numCycles: number): void { const fRep = getFactionFieldWorkRepGain(Player, faction.favor); const rate = Math.max(hRep * favorMult, sRep * favorMult, fRep * favorMult, 1 / 120); - faction.playerReputation += rate * numCycles * Player.mults.faction_rep * BitNodeMultipliers.FactionPassiveRepGain; + faction.playerReputation += rate * numCycles * Player.mults.faction_rep * currentNodeMults.FactionPassiveRepGain; } } -export const getFactionAugmentationsFiltered = (faction: Faction): string[] => { +export const getFactionAugmentationsFiltered = (faction: Faction): AugmentationName[] => { // If player has a gang with this faction, return (almost) all augmentations if (Player.hasGangWith(faction.name)) { - let augs = Object.values(StaticAugmentations); + let augs = Object.values(Augmentations); // Remove special augs augs = augs.filter((a) => !a.isSpecial && a.name !== AugmentationName.CongruityImplant); if (Player.bitNodeN === 2) { // TRP is not available outside of BN2 for Gangs - augs.push(StaticAugmentations[AugmentationName.TheRedPill]); + augs.push(Augmentations[AugmentationName.TheRedPill]); } const rng = SFC32RNG(`BN${Player.bitNodeN}.${Player.sourceFileLvl(Player.bitNodeN)}`); @@ -156,7 +157,7 @@ export const getFactionAugmentationsFiltered = (faction: Faction): string[] => { return true; } - return rng() >= 1 - BitNodeMultipliers.GangUniqueAugs; + return rng() >= 1 - currentNodeMults.GangUniqueAugs; }; augs = augs.filter(uniqueFilter); diff --git a/src/Faction/Factions.ts b/src/Faction/Factions.ts index 8e48ed1b1..49660d904 100644 --- a/src/Faction/Factions.ts +++ b/src/Faction/Factions.ts @@ -6,6 +6,8 @@ import { Faction } from "./Faction"; import { FactionInfos } from "./FactionInfo"; import { Reviver } from "../utils/JSONReviver"; +import { getRecordValues } from "../Types/Record"; +import { Augmentations, initCircadianModulator } from "../Augmentation/Augmentations"; export let Factions: Record = {}; @@ -47,4 +49,16 @@ function resetFaction(newFactionObject: Faction): void { delete Factions[factionName]; } AddToFactions(newFactionObject); + // All factions are added, this is a good place to add augs back to factions. + initCircadianModulator(); + for (const aug of getRecordValues(Augmentations)) { + for (const factionName of aug.factions) { + const faction = Factions[factionName]; + if (!faction) { + console.error(`Faction ${factionName} did not exist while adding augs to factions`); + continue; + } + faction.augmentations.push(aug.name); + } + } } diff --git a/src/Faction/formulas/donation.ts b/src/Faction/formulas/donation.ts index 57c3e5c87..a0225528f 100644 --- a/src/Faction/formulas/donation.ts +++ b/src/Faction/formulas/donation.ts @@ -1,7 +1,7 @@ import { CONSTANTS } from "../../Constants"; -import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../../BitNode/BitNodeMultipliers"; import { Person as IPerson } from "@nsdefs"; export function repFromDonation(amt: number, person: IPerson): number { - return (amt / CONSTANTS.DonateMoneyToRepDivisor) * person.mults.faction_rep * BitNodeMultipliers.FactionWorkRepGain; + return (amt / CONSTANTS.DonateMoneyToRepDivisor) * person.mults.faction_rep * currentNodeMults.FactionWorkRepGain; } diff --git a/src/Faction/ui/AugmentationsPage.tsx b/src/Faction/ui/AugmentationsPage.tsx index 55c1aa3ca..430e6cb6b 100644 --- a/src/Faction/ui/AugmentationsPage.tsx +++ b/src/Faction/ui/AugmentationsPage.tsx @@ -1,8 +1,8 @@ import { Box, Button, Tooltip, Typography, Paper, Container } from "@mui/material"; import React from "react"; -import { StaticAugmentations } from "../../Augmentation/StaticAugmentations"; -import { getGenericAugmentationPriceMultiplier } from "../../Augmentation/AugmentationHelpers"; +import { Augmentations } from "../../Augmentation/Augmentations"; +import { getAugCost, getGenericAugmentationPriceMultiplier } from "../../Augmentation/AugmentationHelpers"; import { AugmentationName, FactionName } from "@enums"; import { PurchasableAugmentations } from "../../Augmentation/ui/PurchasableAugmentations"; import { PurchaseAugmentationsOrderSetting } from "../../Settings/SettingEnums"; @@ -25,11 +25,11 @@ interface IProps { export function AugmentationsPage(props: IProps): React.ReactElement { const rerender = useRerender(); - function getAugs(): string[] { + function getAugs(): AugmentationName[] { return getFactionAugmentationsFiltered(props.faction); } - function getAugsSorted(): string[] { + function getAugsSorted(): AugmentationName[] { switch (Settings.PurchaseAugmentationsOrder) { case PurchaseAugmentationsOrderSetting.Cost: { return getAugsSortedByCost(); @@ -45,26 +45,26 @@ export function AugmentationsPage(props: IProps): React.ReactElement { } } - function getAugsSortedByCost(): string[] { + function getAugsSortedByCost(): AugmentationName[] { const augs = getAugs(); augs.sort((augName1, augName2) => { - const aug1 = StaticAugmentations[augName1], - aug2 = StaticAugmentations[augName2]; + const aug1 = Augmentations[augName1], + aug2 = Augmentations[augName2]; if (aug1 == null || aug2 == null) { throw new Error("Invalid Augmentation Names"); } - return aug1.getCost().moneyCost - aug2.getCost().moneyCost; + return getAugCost(aug1).moneyCost - getAugCost(aug2).moneyCost; }); return augs; } - function getAugsSortedByPurchasable(): string[] { + function getAugsSortedByPurchasable(): AugmentationName[] { const augs = getAugs(); - function canBuy(augName: string): boolean { - const aug = StaticAugmentations[augName]; - const augCosts = aug.getCost(); + function canBuy(augName: AugmentationName): boolean { + const aug = Augmentations[augName]; + const augCosts = getAugCost(aug); const repCost = augCosts.repCost; const hasReq = props.faction.playerReputation >= repCost; const hasRep = hasAugmentationPrereqs(aug); @@ -72,43 +72,43 @@ export function AugmentationsPage(props: IProps): React.ReactElement { return hasCost && hasReq && hasRep; } const buy = augs.filter(canBuy).sort((augName1, augName2) => { - const aug1 = StaticAugmentations[augName1], - aug2 = StaticAugmentations[augName2]; + const aug1 = Augmentations[augName1], + aug2 = Augmentations[augName2]; if (aug1 == null || aug2 == null) { throw new Error("Invalid Augmentation Names"); } - return aug1.getCost().moneyCost - aug2.getCost().moneyCost; + return getAugCost(aug1).moneyCost - getAugCost(aug2).moneyCost; }); const cantBuy = augs .filter((aug) => !canBuy(aug)) .sort((augName1, augName2) => { - const aug1 = StaticAugmentations[augName1], - aug2 = StaticAugmentations[augName2]; + const aug1 = Augmentations[augName1], + aug2 = Augmentations[augName2]; if (aug1 == null || aug2 == null) { throw new Error("Invalid Augmentation Names"); } - return aug1.getCost().repCost - aug2.getCost().repCost; + return getAugCost(aug1).repCost - getAugCost(aug2).repCost; }); return buy.concat(cantBuy); } - function getAugsSortedByReputation(): string[] { + function getAugsSortedByReputation(): AugmentationName[] { const augs = getAugs(); augs.sort((augName1, augName2) => { - const aug1 = StaticAugmentations[augName1], - aug2 = StaticAugmentations[augName2]; + const aug1 = Augmentations[augName1], + aug2 = Augmentations[augName2]; if (aug1 == null || aug2 == null) { throw new Error("Invalid Augmentation Names"); } - return aug1.getCost().repCost - aug2.getCost().repCost; + return getAugCost(aug1).repCost - getAugCost(aug2).repCost; }); return augs; } - function getAugsSortedByDefault(): string[] { + function getAugsSortedByDefault(): AugmentationName[] { return getAugs(); } @@ -123,7 +123,7 @@ export function AugmentationsPage(props: IProps): React.ReactElement { aug === AugmentationName.NeuroFluxGovernor || (!Player.augmentations.some((a) => a.name === aug) && !Player.queuedAugmentations.some((a) => a.name === aug)), ); - const owned = augs.filter((aug: string) => !purchasable.includes(aug)); + const owned = augs.filter((aug) => !purchasable.includes(aug)); const multiplierComponent = props.faction.name !== FactionName.ShadowsOfAnarchy ? ( @@ -213,7 +213,7 @@ export function AugmentationsPage(props: IProps): React.ReactElement { augNames={purchasable} ownedAugNames={owned} canPurchase={(aug) => { - const costs = aug.getCost(); + const costs = getAugCost(aug); return ( hasAugmentationPrereqs(aug) && props.faction.playerReputation >= costs.repCost && diff --git a/src/Faction/ui/FactionRoot.tsx b/src/Faction/ui/FactionRoot.tsx index 86c18bd09..989392405 100644 --- a/src/Faction/ui/FactionRoot.tsx +++ b/src/Faction/ui/FactionRoot.tsx @@ -12,7 +12,7 @@ import { Option } from "./Option"; import { CONSTANTS } from "../../Constants"; -import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../../BitNode/BitNodeMultipliers"; import { Faction } from "../Faction"; import { Router } from "../../ui/GameRoot"; @@ -107,7 +107,7 @@ function MainPage({ faction, rerender, onAugmentations }: IMainProps): React.Rea // Flags for whether special options (gang, sleeve purchases, donate, etc.) // should be shown - const favorToDonate = Math.floor(CONSTANTS.BaseFavorToDonate * BitNodeMultipliers.RepToDonateToFaction); + const favorToDonate = Math.floor(CONSTANTS.BaseFavorToDonate * currentNodeMults.RepToDonateToFaction); const canDonate = faction.favor >= favorToDonate; const canPurchaseSleeves = faction.name === FactionName.TheCovenant && Player.bitNodeN === 10; diff --git a/src/Gang/formulas/formulas.ts b/src/Gang/formulas/formulas.ts index 8d05b9247..21e8cd2b6 100644 --- a/src/Gang/formulas/formulas.ts +++ b/src/Gang/formulas/formulas.ts @@ -1,4 +1,4 @@ -import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../../BitNode/BitNodeMultipliers"; import { GangMember } from "../GangMember"; import { GangMemberTask } from "../GangMemberTask"; @@ -24,7 +24,7 @@ export function calculateRespectGain(gang: FormulaGang, member: GangMember, task statWeight -= 4 * task.difficulty; if (statWeight <= 0) return 0; const territoryMult = Math.max(0.005, Math.pow(gang.territory * 100, task.territory.respect) / 100); - const territoryPenalty = (0.2 * gang.territory + 0.8) * BitNodeMultipliers.GangSoftcap; + const territoryPenalty = (0.2 * gang.territory + 0.8) * currentNodeMults.GangSoftcap; if (isNaN(territoryMult) || territoryMult <= 0) return 0; const respectMult = calculateWantedPenalty(gang); return Math.pow(11 * task.baseRespect * statWeight * territoryMult * respectMult, territoryPenalty); @@ -68,7 +68,7 @@ export function calculateMoneyGain(gang: FormulaGang, member: GangMember, task: const territoryMult = Math.max(0.005, Math.pow(gang.territory * 100, task.territory.money) / 100); if (isNaN(territoryMult) || territoryMult <= 0) return 0; const respectMult = calculateWantedPenalty(gang); - const territoryPenalty = (0.2 * gang.territory + 0.8) * BitNodeMultipliers.GangSoftcap; + const territoryPenalty = (0.2 * gang.territory + 0.8) * currentNodeMults.GangSoftcap; return Math.pow(5 * task.baseMoney * statWeight * territoryMult * respectMult, territoryPenalty); } diff --git a/src/Hacking.ts b/src/Hacking.ts index 518129b1c..c239e4d64 100644 --- a/src/Hacking.ts +++ b/src/Hacking.ts @@ -1,4 +1,4 @@ -import { BitNodeMultipliers } from "./BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "./BitNode/BitNodeMultipliers"; import { Person as IPerson } from "@nsdefs"; import { calculateIntelligenceBonus } from "./PersonObjects/formulas/intelligence"; import { Server as IServer } from "@nsdefs"; @@ -32,7 +32,7 @@ export function calculateHackingExpGain(server: IServer, person: IPerson): numbe const diffFactor = 0.3; let expGain = baseExpGain; expGain += baseDifficulty * diffFactor; - return expGain * person.mults.hacking_exp * BitNodeMultipliers.HackExpGain; + return expGain * person.mults.hacking_exp * currentNodeMults.HackExpGain; } /** @@ -49,7 +49,7 @@ export function calculatePercentMoneyHacked(server: IServer, person: IPerson): n const difficultyMult = (100 - hackDifficulty) / 100; const skillMult = (person.skills.hacking - (requiredHackingSkill - 1)) / person.skills.hacking; const percentMoneyHacked = - (difficultyMult * skillMult * person.mults.hacking_money * BitNodeMultipliers.ScriptHackMoney) / balanceFactor; + (difficultyMult * skillMult * person.mults.hacking_money * currentNodeMults.ScriptHackMoney) / balanceFactor; return Math.min(1, Math.max(percentMoneyHacked, 0)); } diff --git a/src/Hacknet/formulas/HacknetNodes.ts b/src/Hacknet/formulas/HacknetNodes.ts index b0dfb8440..f9887736b 100644 --- a/src/Hacknet/formulas/HacknetNodes.ts +++ b/src/Hacknet/formulas/HacknetNodes.ts @@ -1,4 +1,4 @@ -import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../../BitNode/BitNodeMultipliers"; import { HacknetNodeConstants } from "../data/Constants"; export function calculateMoneyGainRate(level: number, ram: number, cores: number, mult: number): number { @@ -7,7 +7,7 @@ export function calculateMoneyGainRate(level: number, ram: number, cores: number const levelMult = level * gainPerLevel; const ramMult = Math.pow(1.035, ram - 1); const coresMult = (cores + 5) / 6; - return levelMult * ramMult * coresMult * mult * BitNodeMultipliers.HacknetNodeMoney; + return levelMult * ramMult * coresMult * mult * currentNodeMults.HacknetNodeMoney; } export function calculateLevelUpgradeCost(startingLevel: number, extraLevels = 1, costMult = 1): number { diff --git a/src/Hacknet/formulas/HacknetServers.ts b/src/Hacknet/formulas/HacknetServers.ts index 5128c87a1..73ed68be0 100644 --- a/src/Hacknet/formulas/HacknetServers.ts +++ b/src/Hacknet/formulas/HacknetServers.ts @@ -1,4 +1,4 @@ -import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../../BitNode/BitNodeMultipliers"; import { HacknetServerConstants } from "../data/Constants"; export function calculateHashGainRate( @@ -13,7 +13,7 @@ export function calculateHashGainRate( const coreMultiplier = 1 + (cores - 1) / 5; const ramRatio = 1 - ramUsed / maxRam; - return baseGain * ramMultiplier * coreMultiplier * ramRatio * mult * BitNodeMultipliers.HacknetNodeMoney; + return baseGain * ramMultiplier * coreMultiplier * ramRatio * mult * currentNodeMults.HacknetNodeMoney; } export function calculateLevelUpgradeCost(startingLevel: number, extraLevels = 1, costMult = 1): number { diff --git a/src/Infiltration/formulas/victory.ts b/src/Infiltration/formulas/victory.ts index 77f483202..f5041c137 100644 --- a/src/Infiltration/formulas/victory.ts +++ b/src/Infiltration/formulas/victory.ts @@ -1,5 +1,5 @@ import { Player } from "@player"; -import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../../BitNode/BitNodeMultipliers"; import { LocationsMetadata } from "../../Locations/data/LocationsMetadata"; import { AugmentationName } from "@enums"; import { Faction } from "../../Faction/Faction"; @@ -13,7 +13,7 @@ export function calculateSellInformationCashReward(reward: number, maxLevel: num 3e3 * levelBonus * (Player.hasAugmentation(AugmentationName.WKSharmonizer, true) ? 1.5 : 1) * - BitNodeMultipliers.InfiltrationMoney + currentNodeMults.InfiltrationMoney ); } @@ -26,7 +26,7 @@ export function calculateTradeInformationRepReward(reward: number, maxLevel: num 30 * levelBonus * (Player.hasAugmentation(AugmentationName.WKSharmonizer, true) ? 1.5 : 1) * - BitNodeMultipliers.InfiltrationRep + currentNodeMults.InfiltrationRep ); } diff --git a/src/Locations/ui/RamButton.tsx b/src/Locations/ui/RamButton.tsx index 0f97eb8e2..e0f8d2ed1 100644 --- a/src/Locations/ui/RamButton.tsx +++ b/src/Locations/ui/RamButton.tsx @@ -11,7 +11,7 @@ import { Money } from "../../ui/React/Money"; import { formatRam } from "../../ui/formatNumber"; import { MathJax } from "better-react-mathjax"; -import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../../BitNode/BitNodeMultipliers"; interface IProps { rerender: () => void; @@ -30,7 +30,7 @@ export function RamButton(props: IProps): React.ReactElement { props.rerender(); } - const bnMult = BitNodeMultipliers.HomeComputerRamCost === 1 ? "" : `\\cdot ${BitNodeMultipliers.HomeComputerRamCost}`; + const bnMult = currentNodeMults.HomeComputerRamCost === 1 ? "" : `\\cdot ${currentNodeMults.HomeComputerRamCost}`; return ( ; } const text = Player.bladeburner ? "Enter Bladeburner Headquarters" : "Apply to Bladeburner Division"; @@ -314,7 +314,7 @@ export function SpecialLocation(props: SpecialLocationProps): React.ReactElement return renderGrafting(); } case LocationName.Sector12CityHall: { - return (BitNodeMultipliers.CorporationSoftcap < 0.15 && <>) || ; + return (currentNodeMults.CorporationSoftcap < 0.15 && <>) || ; } case LocationName.Sector12NSA: { return renderBladeburner(); diff --git a/src/Netscript/NetscriptHelpers.tsx b/src/Netscript/NetscriptHelpers.tsx index cfd5e677e..27616beb2 100644 --- a/src/Netscript/NetscriptHelpers.tsx +++ b/src/Netscript/NetscriptHelpers.tsx @@ -17,7 +17,7 @@ import { } from "../Hacking"; import { netscriptCanHack } from "../Hacking/netscriptCanHack"; import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions"; -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; import { CONSTANTS } from "../Constants"; import { influenceStockThroughServerHack } from "../StockMarket/PlayerInfluencing"; import { PortNumber } from "../NetscriptPort"; @@ -506,9 +506,9 @@ function hack( server.moneyAvailable = 0; } - let moneyGained = moneyDrained * BitNodeMultipliers.ScriptHackMoneyGain; + let moneyGained = moneyDrained * currentNodeMults.ScriptHackMoneyGain; if (manual) { - moneyGained = moneyDrained * BitNodeMultipliers.ManualHackMoney; + moneyGained = moneyDrained * currentNodeMults.ManualHackMoney; } Player.gainMoney(moneyGained, "hacking"); diff --git a/src/NetscriptFunctions.ts b/src/NetscriptFunctions.ts index d666c81f0..ea84049c0 100644 --- a/src/NetscriptFunctions.ts +++ b/src/NetscriptFunctions.ts @@ -1,6 +1,6 @@ import $ from "jquery"; import { vsprintf, sprintf } from "sprintf-js"; -import { BitNodeMultipliers, IBitNodeMultipliers } from "./BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "./BitNode/BitNodeMultipliers"; import { CONSTANTS } from "./Constants"; import { calculateHackingChance, @@ -407,7 +407,7 @@ export const ns: InternalAPI = { ctx.workerScript.scriptRef.onlineExpGained += expGain; Player.gainHackingExp(expGain); // Account for hidden multiplier in Server.weaken() - return Promise.resolve(weakenAmt * BitNodeMultipliers.ServerWeakenRate); + return Promise.resolve(weakenAmt * currentNodeMults.ServerWeakenRate); }); }, weakenAnalyze: @@ -416,7 +416,7 @@ export const ns: InternalAPI = { const threads = helpers.number(ctx, "threads", _threads); const cores = helpers.number(ctx, "cores", _cores); const coreBonus = 1 + (cores - 1) / 16; - return CONSTANTS.ServerWeakenAmount * threads * coreBonus * BitNodeMultipliers.ServerWeakenRate; + return CONSTANTS.ServerWeakenAmount * threads * coreBonus * currentNodeMults.ServerWeakenRate; }, share: (ctx) => () => { helpers.log(ctx, () => "Sharing this computer."); @@ -967,7 +967,7 @@ export const ns: InternalAPI = { }, getBitNodeMultipliers: (ctx) => - (_n = Player.bitNodeN, _lvl = Player.sourceFileLvl(Player.bitNodeN) + 1): IBitNodeMultipliers => { + (_n = Player.bitNodeN, _lvl = Player.sourceFileLvl(Player.bitNodeN) + 1) => { if (Player.sourceFileLvl(5) <= 0 && Player.bitNodeN !== 5) throw helpers.makeRuntimeErrorMsg(ctx, "Requires Source-File 5 to run."); const n = Math.round(helpers.number(ctx, "n", _n)); @@ -1679,7 +1679,7 @@ export const ns: InternalAPI = { }); }, getFavorToDonate: () => () => { - return Math.floor(CONSTANTS.BaseFavorToDonate * BitNodeMultipliers.RepToDonateToFaction); + return Math.floor(CONSTANTS.BaseFavorToDonate * currentNodeMults.RepToDonateToFaction); }, getPlayer: () => () => { const data = { diff --git a/src/NetscriptFunctions/Bladeburner.ts b/src/NetscriptFunctions/Bladeburner.ts index 70de05b0c..7e198e82c 100644 --- a/src/NetscriptFunctions/Bladeburner.ts +++ b/src/NetscriptFunctions/Bladeburner.ts @@ -4,7 +4,7 @@ import type { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper"; import { Player } from "@player"; import { Bladeburner } from "../Bladeburner/Bladeburner"; -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; import { BlackOperation } from "../Bladeburner/BlackOperation"; import { helpers } from "../Netscript/NetscriptHelpers"; import { getEnumHelper } from "../utils/EnumHelper"; @@ -139,7 +139,7 @@ export function NetscriptBladeburner(): InternalAPI { const action = getBladeburnerActionObject(ctx, type, name); const level = _level === undefined ? action.level : helpers.number(ctx, "level", _level); const rewardMultiplier = Math.pow(action.rewardFac, level - 1); - return action.rankGain * rewardMultiplier * BitNodeMultipliers.BladeburnerRank; + return action.rankGain * rewardMultiplier * currentNodeMults.BladeburnerRank; }, getActionCountRemaining: (ctx) => (_type, _name) => { const bladeburner = getBladeburner(ctx); @@ -299,7 +299,7 @@ export function NetscriptBladeburner(): InternalAPI { }, joinBladeburnerDivision: (ctx) => () => { if (Player.bitNodeN === 7 || Player.sourceFileLvl(7) > 0) { - if (BitNodeMultipliers.BladeburnerRank === 0) { + if (currentNodeMults.BladeburnerRank === 0) { return false; // Disabled in this bitnode } if (Player.bladeburner) { diff --git a/src/NetscriptFunctions/Corporation.ts b/src/NetscriptFunctions/Corporation.ts index fdbd64245..aea08bbfb 100644 --- a/src/NetscriptFunctions/Corporation.ts +++ b/src/NetscriptFunctions/Corporation.ts @@ -56,7 +56,7 @@ import { IndustriesData, IndustryResearchTrees } from "../Corporation/data/Indus import * as corpConstants from "../Corporation/data/Constants"; import { ResearchMap } from "../Corporation/ResearchMap"; import { Factions } from "../Faction/Factions"; -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; import { InternalAPI, NetscriptContext, removedFunction } from "../Netscript/APIWrapper"; import { helpers } from "../Netscript/NetscriptHelpers"; import { getEnumHelper } from "../utils/EnumHelper"; @@ -70,7 +70,7 @@ export function NetscriptCorporation(): InternalAPI { if (!player.canAccessCorporation() || player.corporation) return false; if (!corporationName) return false; if (player.bitNodeN !== 3 && !selfFund) throw new Error("cannot use seed funds outside of BitNode 3"); - if (BitNodeMultipliers.CorporationSoftcap < 0.15) + if (currentNodeMults.CorporationSoftcap < 0.15) throw new Error(`You cannot create a corporation in Bitnode ${player.bitNodeN}`); if (selfFund) { diff --git a/src/NetscriptFunctions/Grafting.ts b/src/NetscriptFunctions/Grafting.ts index 4d05c8d08..40f3cf632 100644 --- a/src/NetscriptFunctions/Grafting.ts +++ b/src/NetscriptFunctions/Grafting.ts @@ -1,16 +1,17 @@ import type { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper"; -import { StaticAugmentations } from "../Augmentation/StaticAugmentations"; -import { hasAugmentationPrereqs } from "../Faction/FactionHelpers"; -import { CityName } from "@enums"; -import { GraftableAugmentation } from "../PersonObjects/Grafting/GraftableAugmentation"; -import { getGraftingAvailableAugs, calculateGraftingTimeWithBonus } from "../PersonObjects/Grafting/GraftingHelpers"; + import { Player } from "@player"; import { Grafting as IGrafting } from "@nsdefs"; +import { AugmentationName, CityName } from "@enums"; +import { Augmentations } from "../Augmentation/Augmentations"; +import { hasAugmentationPrereqs } from "../Faction/FactionHelpers"; +import { GraftableAugmentation } from "../PersonObjects/Grafting/GraftableAugmentation"; +import { getGraftingAvailableAugs, calculateGraftingTimeWithBonus } from "../PersonObjects/Grafting/GraftingHelpers"; import { Router } from "../ui/GameRoot"; import { Page } from "../ui/Router"; import { GraftingWork } from "../Work/GraftingWork"; import { helpers } from "../Netscript/NetscriptHelpers"; -import { augmentationExists } from "../Augmentation/AugmentationHelpers"; +import { getEnumHelper } from "../utils/EnumHelper"; export function NetscriptGrafting(): InternalAPI { const checkGraftingAPIAccess = (ctx: NetscriptContext): void => { @@ -22,27 +23,26 @@ export function NetscriptGrafting(): InternalAPI { } }; - const isValidGraftingAugName = (augName: string) => - getGraftingAvailableAugs().includes(augName) && augmentationExists(augName); + const isValidGraftingAugName = (augName: AugmentationName) => getGraftingAvailableAugs().includes(augName); return { getAugmentationGraftPrice: (ctx) => (_augName) => { - const augName = helpers.string(ctx, "augName", _augName); + const augName = getEnumHelper("AugmentationName").nsGetMember(ctx, _augName); checkGraftingAPIAccess(ctx); if (!isValidGraftingAugName(augName)) { throw helpers.makeRuntimeErrorMsg(ctx, `Invalid aug: ${augName}`); } - const graftableAug = new GraftableAugmentation(StaticAugmentations[augName]); + const graftableAug = new GraftableAugmentation(Augmentations[augName]); return graftableAug.cost; }, getAugmentationGraftTime: (ctx) => (_augName) => { - const augName = helpers.string(ctx, "augName", _augName); + const augName = getEnumHelper("AugmentationName").nsGetMember(ctx, _augName); checkGraftingAPIAccess(ctx); if (!isValidGraftingAugName(augName)) { throw helpers.makeRuntimeErrorMsg(ctx, `Invalid aug: ${augName}`); } - const graftableAug = new GraftableAugmentation(StaticAugmentations[augName]); + const graftableAug = new GraftableAugmentation(Augmentations[augName]); return calculateGraftingTimeWithBonus(graftableAug); }, @@ -55,7 +55,7 @@ export function NetscriptGrafting(): InternalAPI { graftAugmentation: (ctx) => (_augName, _focus = true) => { - const augName = helpers.string(ctx, "augName", _augName); + const augName = getEnumHelper("AugmentationName").nsGetMember(ctx, _augName); const focus = !!_focus; checkGraftingAPIAccess(ctx); if (Player.city !== CityName.NewTokyo) { @@ -68,7 +68,7 @@ export function NetscriptGrafting(): InternalAPI { const wasFocusing = Player.focus; - const craftableAug = new GraftableAugmentation(StaticAugmentations[augName]); + const craftableAug = new GraftableAugmentation(Augmentations[augName]); if (Player.money < craftableAug.cost) { helpers.log(ctx, () => `You don't have enough money to craft ${augName}`); return false; diff --git a/src/NetscriptFunctions/Singularity.ts b/src/NetscriptFunctions/Singularity.ts index 90a39dfbd..ec2941dd6 100644 --- a/src/NetscriptFunctions/Singularity.ts +++ b/src/NetscriptFunctions/Singularity.ts @@ -1,5 +1,4 @@ import type { Singularity as ISingularity } from "@nsdefs"; -import type { Augmentation } from "../Augmentation/Augmentation"; import type { Company } from "../Company/Company"; import type { Faction } from "../Faction/Faction"; @@ -16,8 +15,8 @@ import { } from "@enums"; import { purchaseAugmentation, joinFaction, getFactionAugmentationsFiltered } from "../Faction/FactionHelpers"; import { startWorkerScript } from "../NetscriptWorker"; -import { StaticAugmentations } from "../Augmentation/StaticAugmentations"; -import { augmentationExists, installAugmentations } from "../Augmentation/AugmentationHelpers"; +import { Augmentations } from "../Augmentation/Augmentations"; +import { getAugCost, installAugmentations } from "../Augmentation/AugmentationHelpers"; import { CONSTANTS } from "../Constants"; import { RunningScript } from "../Script/RunningScript"; import { calculateAchievements } from "../Achievements/Achievements"; @@ -31,7 +30,7 @@ import { Locations } from "../Locations/Locations"; import { GetServer } from "../Server/AllServers"; import { Programs } from "../Programs/Programs"; import { formatMoney, formatRam, formatReputation } from "../ui/formatNumber"; -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; import { Companies } from "../Company/Companies"; import { companiesMetadata } from "../Company/data/CompaniesMetadata"; import { Factions, factionExists } from "../Faction/Factions"; @@ -59,14 +58,6 @@ import { ScriptFilePath, resolveScriptFilePath } from "../Paths/ScriptFilePath"; import { root } from "../Paths/Directory"; export function NetscriptSingularity(): InternalAPI { - const getAugmentation = function (ctx: NetscriptContext, name: string): Augmentation { - if (!augmentationExists(name)) { - throw helpers.makeRuntimeErrorMsg(ctx, `Invalid augmentation: '${name}'`); - } - - return StaticAugmentations[name]; - }; - const getFaction = function (ctx: NetscriptContext, name: string): Faction { if (!factionExists(name)) { throw helpers.makeRuntimeErrorMsg(ctx, `Invalid faction name: '${name}`); @@ -127,40 +118,40 @@ export function NetscriptSingularity(): InternalAPI { }, getAugmentationPrereq: (ctx) => (_augName) => { helpers.checkSingularityAccess(ctx); - const augName = helpers.string(ctx, "augName", _augName); - const aug = getAugmentation(ctx, augName); + const augName = getEnumHelper("AugmentationName").nsGetMember(ctx, _augName); + const aug = Augmentations[augName]; return aug.prereqs.slice(); }, getAugmentationBasePrice: (ctx) => (_augName) => { helpers.checkSingularityAccess(ctx); - const augName = helpers.string(ctx, "augName", _augName); - const aug = getAugmentation(ctx, augName); - return aug.baseCost * BitNodeMultipliers.AugmentationMoneyCost; + const augName = getEnumHelper("AugmentationName").nsGetMember(ctx, _augName); + const aug = Augmentations[augName]; + return aug.baseCost * currentNodeMults.AugmentationMoneyCost; }, getAugmentationPrice: (ctx) => (_augName) => { helpers.checkSingularityAccess(ctx); - const augName = helpers.string(ctx, "augName", _augName); - const aug = getAugmentation(ctx, augName); - return aug.getCost().moneyCost; + const augName = getEnumHelper("AugmentationName").nsGetMember(ctx, _augName); + const aug = Augmentations[augName]; + return getAugCost(aug).moneyCost; }, getAugmentationRepReq: (ctx) => (_augName) => { helpers.checkSingularityAccess(ctx); - const augName = helpers.string(ctx, "augName", _augName); - const aug = getAugmentation(ctx, augName); - return aug.getCost().repCost; + const augName = getEnumHelper("AugmentationName").nsGetMember(ctx, _augName); + const aug = Augmentations[augName]; + return getAugCost(aug).repCost; }, getAugmentationStats: (ctx) => (_augName) => { helpers.checkSingularityAccess(ctx); - const augName = helpers.string(ctx, "augName", _augName); - const aug = getAugmentation(ctx, augName); + const augName = getEnumHelper("AugmentationName").nsGetMember(ctx, _augName); + const aug = Augmentations[augName]; return Object.assign({}, aug.mults); }, purchaseAugmentation: (ctx) => (_facName, _augName) => { helpers.checkSingularityAccess(ctx); const facName = helpers.string(ctx, "facName", _facName); - const augName = helpers.string(ctx, "augName", _augName); + const augName = getEnumHelper("AugmentationName").nsGetMember(ctx, _augName); const fac = getFaction(ctx, facName); - const aug = getAugmentation(ctx, augName); + const aug = Augmentations[augName]; const augs = getFactionAugmentationsFiltered(fac); @@ -190,7 +181,7 @@ export function NetscriptSingularity(): InternalAPI { } } - if (fac.playerReputation < aug.getCost().repCost) { + if (fac.playerReputation < getAugCost(aug).repCost) { helpers.log(ctx, () => `You do not have enough reputation with '${fac.name}'.`); return false; } @@ -1036,7 +1027,7 @@ export function NetscriptSingularity(): InternalAPI { helpers.log(ctx, () => `You do not have enough money to donate ${formatMoney(amt)} to '${facName}'`); return false; } - const repNeededToDonate = Math.floor(CONSTANTS.BaseFavorToDonate * BitNodeMultipliers.RepToDonateToFaction); + const repNeededToDonate = Math.floor(CONSTANTS.BaseFavorToDonate * currentNodeMults.RepToDonateToFaction); if (faction.favor < repNeededToDonate) { helpers.log( ctx, diff --git a/src/NetscriptFunctions/Sleeve.ts b/src/NetscriptFunctions/Sleeve.ts index 04df5352d..9505a1fdc 100644 --- a/src/NetscriptFunctions/Sleeve.ts +++ b/src/NetscriptFunctions/Sleeve.ts @@ -1,9 +1,9 @@ -import { Player } from "@player"; +import type { Augmentation } from "../Augmentation/Augmentation"; import type { Sleeve as NetscriptSleeve } from "@nsdefs"; -import { StaticAugmentations } from "../Augmentation/StaticAugmentations"; -import { findCrime } from "../Crime/CrimeHelpers"; -import { Augmentation } from "../Augmentation/Augmentation"; +import { Player } from "@player"; +import { Augmentations } from "../Augmentation/Augmentations"; +import { findCrime } from "../Crime/CrimeHelpers"; import { getEnumHelper } from "../utils/EnumHelper"; import { InternalAPI, NetscriptContext, removedFunction } from "../Netscript/APIWrapper"; import { isSleeveBladeburnerWork } from "../PersonObjects/Sleeve/Work/SleeveBladeburnerWork"; @@ -11,6 +11,7 @@ import { isSleeveFactionWork } from "../PersonObjects/Sleeve/Work/SleeveFactionW import { isSleeveCompanyWork } from "../PersonObjects/Sleeve/Work/SleeveCompanyWork"; import { helpers } from "../Netscript/NetscriptHelpers"; import { cloneDeep } from "lodash"; +import { getAugCost } from "../Augmentation/AugmentationHelpers"; export function NetscriptSleeve(): InternalAPI { const checkSleeveAPIAccess = function (ctx: NetscriptContext) { @@ -198,7 +199,7 @@ export function NetscriptSleeve(): InternalAPI { }, purchaseSleeveAug: (ctx) => (_sleeveNumber, _augName) => { const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber); - const augName = helpers.string(ctx, "augName", _augName); + const augName = getEnumHelper("AugmentationName").nsGetMember(ctx, _augName); checkSleeveAPIAccess(ctx); checkSleeveNumber(ctx, sleeveNumber); @@ -206,7 +207,7 @@ export function NetscriptSleeve(): InternalAPI { throw helpers.makeRuntimeErrorMsg(ctx, `Sleeve shock too high: Sleeve ${sleeveNumber}`); } - const aug = StaticAugmentations[augName]; + const aug = Augmentations[augName]; if (!aug) { throw helpers.makeRuntimeErrorMsg(ctx, `Invalid aug: ${augName}`); } @@ -215,15 +216,15 @@ export function NetscriptSleeve(): InternalAPI { }, getSleeveAugmentationPrice: (ctx) => (_augName) => { checkSleeveAPIAccess(ctx); - const augName = helpers.string(ctx, "augName", _augName); - const aug: Augmentation = StaticAugmentations[augName]; + const augName = getEnumHelper("AugmentationName").nsGetMember(ctx, _augName); + const aug: Augmentation = Augmentations[augName]; return aug.baseCost; }, getSleeveAugmentationRepReq: (ctx) => (_augName) => { checkSleeveAPIAccess(ctx); - const augName = helpers.string(ctx, "augName", _augName); - const aug: Augmentation = StaticAugmentations[augName]; - return aug.getCost().repCost; + const augName = getEnumHelper("AugmentationName").nsGetMember(ctx, _augName); + const aug: Augmentation = Augmentations[augName]; + return getAugCost(aug).repCost; }, setToBladeburnerAction: (ctx) => (_sleeveNumber, _action, _contract?) => { const sleeveNumber = helpers.number(ctx, "sleeveNumber", _sleeveNumber); diff --git a/src/PersonObjects/Grafting/GraftingHelpers.ts b/src/PersonObjects/Grafting/GraftingHelpers.ts index 5dc730b62..644282391 100644 --- a/src/PersonObjects/Grafting/GraftingHelpers.ts +++ b/src/PersonObjects/Grafting/GraftingHelpers.ts @@ -1,14 +1,16 @@ -import { StaticAugmentations } from "../../Augmentation/StaticAugmentations"; -import { GraftableAugmentation } from "./GraftableAugmentation"; import { Player } from "@player"; +import { AugmentationName, FactionName } from "@enums"; +import { Augmentations } from "../../Augmentation/Augmentations"; import { calculateIntelligenceBonus } from "../formulas/intelligence"; +import { GraftableAugmentation } from "./GraftableAugmentation"; +import { getRecordEntries } from "../../Types/Record"; -export const getGraftingAvailableAugs = (): string[] => { - const augs: string[] = []; +export const getGraftingAvailableAugs = (): AugmentationName[] => { + const augs: AugmentationName[] = []; - for (const [augName, aug] of Object.entries(StaticAugmentations)) { - if (Player.factions.includes("Bladeburners")) { - if (aug.isSpecial && !aug.factions.includes("Bladeburners")) continue; + for (const [augName, aug] of getRecordEntries(Augmentations)) { + if (Player.factions.includes(FactionName.Bladeburners)) { + if (aug.isSpecial && !aug.factions.includes(FactionName.Bladeburners)) continue; } else { if (aug.isSpecial) continue; } diff --git a/src/PersonObjects/Grafting/ui/GraftingRoot.tsx b/src/PersonObjects/Grafting/ui/GraftingRoot.tsx index b52574eff..5878ca5d7 100644 --- a/src/PersonObjects/Grafting/ui/GraftingRoot.tsx +++ b/src/PersonObjects/Grafting/ui/GraftingRoot.tsx @@ -1,13 +1,14 @@ import type { Augmentation } from "../../../Augmentation/Augmentation"; +import { Player } from "@player"; +import { AugmentationName, LocationName } from "@enums"; + import React, { useState } from "react"; import { CheckBox, CheckBoxOutlineBlank, Construction } from "@mui/icons-material"; import { Box, Button, Container, List, ListItemButton, Paper, Typography } from "@mui/material"; -import { Player } from "@player"; -import { AugmentationName, LocationName } from "@enums"; import { GraftingWork } from "../../../Work/GraftingWork"; -import { StaticAugmentations } from "../../../Augmentation/StaticAugmentations"; +import { Augmentations } from "../../../Augmentation/Augmentations"; import { CONSTANTS } from "../../../Constants"; import { hasAugmentationPrereqs } from "../../../Faction/FactionHelpers"; import { Locations } from "../../../Locations/Locations"; @@ -25,7 +26,7 @@ import { useRerender } from "../../../ui/React/hooks"; export const GraftableAugmentations = (): Record => { const gAugs: Record = {}; - for (const aug of Object.values(StaticAugmentations)) { + for (const aug of Object.values(Augmentations)) { const name = aug.name; const graftableAug = new GraftableAugmentation(aug); gAugs[name] = graftableAug; @@ -66,10 +67,10 @@ export const GraftingRoot = (): React.ReactElement => { const [selectedAug, setSelectedAug] = useState(getGraftingAvailableAugs()[0]); const [graftOpen, setGraftOpen] = useState(false); - const selectedAugmentation = StaticAugmentations[selectedAug]; + const selectedAugmentation = Augmentations[selectedAug]; const rerender = useRerender(200); - const getAugsSorted = (): string[] => { + const getAugsSorted = (): AugmentationName[] => { const augs = getGraftingAvailableAugs(); switch (Settings.PurchaseAugmentationsOrder) { case PurchaseAugmentationsOrderSetting.Cost: diff --git a/src/PersonObjects/PersonMethods.ts b/src/PersonObjects/PersonMethods.ts index 0a879dcd5..8a370df4e 100644 --- a/src/PersonObjects/PersonMethods.ts +++ b/src/PersonObjects/PersonMethods.ts @@ -1,6 +1,6 @@ import { Person } from "./Person"; import { calculateSkill } from "./formulas/skill"; -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; import { Player } from "@player"; import { WorkStats } from "@nsdefs"; @@ -14,10 +14,7 @@ export function gainHackingExp(this: Person, exp: number): void { this.exp.hacking = 0; } - this.skills.hacking = calculateSkill( - this.exp.hacking, - this.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier, - ); + this.skills.hacking = calculateSkill(this.exp.hacking, this.mults.hacking * currentNodeMults.HackingLevelMultiplier); } export function gainStrengthExp(this: Person, exp: number): void { @@ -32,7 +29,7 @@ export function gainStrengthExp(this: Person, exp: number): void { this.skills.strength = calculateSkill( this.exp.strength, - this.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier, + this.mults.strength * currentNodeMults.StrengthLevelMultiplier, ); } @@ -46,10 +43,7 @@ export function gainDefenseExp(this: Person, exp: number): void { this.exp.defense = 0; } - this.skills.defense = calculateSkill( - this.exp.defense, - this.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier, - ); + this.skills.defense = calculateSkill(this.exp.defense, this.mults.defense * currentNodeMults.DefenseLevelMultiplier); const ratio = this.hp.current / this.hp.max; this.hp.max = Math.floor(10 + this.skills.defense / 10); this.hp.current = Math.round(this.hp.max * ratio); @@ -67,7 +61,7 @@ export function gainDexterityExp(this: Person, exp: number): void { this.skills.dexterity = calculateSkill( this.exp.dexterity, - this.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier, + this.mults.dexterity * currentNodeMults.DexterityLevelMultiplier, ); } @@ -81,10 +75,7 @@ export function gainAgilityExp(this: Person, exp: number): void { this.exp.agility = 0; } - this.skills.agility = calculateSkill( - this.exp.agility, - this.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier, - ); + this.skills.agility = calculateSkill(this.exp.agility, this.mults.agility * currentNodeMults.AgilityLevelMultiplier); } export function gainCharismaExp(this: Person, exp: number): void { @@ -99,7 +90,7 @@ export function gainCharismaExp(this: Person, exp: number): void { this.skills.charisma = calculateSkill( this.exp.charisma, - this.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier, + this.mults.charisma * currentNodeMults.CharismaLevelMultiplier, ); } @@ -164,33 +155,29 @@ export function regenerateHp(this: Person, amt: number): void { export function updateSkillLevels(this: Person): void { this.skills.hacking = Math.max( 1, - Math.floor(this.calculateSkill(this.exp.hacking, this.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier)), + Math.floor(this.calculateSkill(this.exp.hacking, this.mults.hacking * currentNodeMults.HackingLevelMultiplier)), ); this.skills.strength = Math.max( 1, - Math.floor( - this.calculateSkill(this.exp.strength, this.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier), - ), + Math.floor(this.calculateSkill(this.exp.strength, this.mults.strength * currentNodeMults.StrengthLevelMultiplier)), ); this.skills.defense = Math.max( 1, - Math.floor(this.calculateSkill(this.exp.defense, this.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier)), + Math.floor(this.calculateSkill(this.exp.defense, this.mults.defense * currentNodeMults.DefenseLevelMultiplier)), ); this.skills.dexterity = Math.max( 1, Math.floor( - this.calculateSkill(this.exp.dexterity, this.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier), + this.calculateSkill(this.exp.dexterity, this.mults.dexterity * currentNodeMults.DexterityLevelMultiplier), ), ); this.skills.agility = Math.max( 1, - Math.floor(this.calculateSkill(this.exp.agility, this.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier)), + Math.floor(this.calculateSkill(this.exp.agility, this.mults.agility * currentNodeMults.AgilityLevelMultiplier)), ); this.skills.charisma = Math.max( 1, - Math.floor( - this.calculateSkill(this.exp.charisma, this.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier), - ), + Math.floor(this.calculateSkill(this.exp.charisma, this.mults.charisma * currentNodeMults.CharismaLevelMultiplier)), ); const ratio: number = Math.min(this.hp.current / this.hp.max, 1); diff --git a/src/PersonObjects/Player/PlayerObject.ts b/src/PersonObjects/Player/PlayerObject.ts index c825bbfe7..d5c7b0626 100644 --- a/src/PersonObjects/Player/PlayerObject.ts +++ b/src/PersonObjects/Player/PlayerObject.ts @@ -26,6 +26,7 @@ import { cyrb53 } from "../../utils/StringHelperFunctions"; import { getRandomInt } from "../../utils/helpers/getRandomInt"; import { CONSTANTS } from "../../Constants"; import { Person } from "../Person"; +import { getEnumHelper } from "../../utils/EnumHelper"; export class PlayerObject extends Person implements IPlayer { // Player-specific properties @@ -167,9 +168,19 @@ export class PlayerObject extends Person implements IPlayer { /** Initializes a PlayerObject object from a JSON save state. */ static fromJSON(value: IReviverValue): PlayerObject { const player = Generic_fromJSON(PlayerObject, value.data); + // Any statistics that could be infinite would be serialized as null (JSON.stringify(Infinity) is "null") player.hp = { current: player.hp?.current ?? 10, max: player.hp?.max ?? 10 }; player.money ??= 0; + // Just remove from the save file any augs that have invalid name + player.augmentations = player.augmentations.filter((ownedAug) => + getEnumHelper("AugmentationName").isMember(ownedAug.name), + ); + player.queuedAugmentations = player.queuedAugmentations.filter((ownedAug) => + getEnumHelper("AugmentationName").isMember(ownedAug.name), + ); player.updateSkillLevels(); + // Converstion code for Player.sourceFiles is here instead of normal save conversion area because it needs + // to happen earlier for use in the savegame comparison tool. if (Array.isArray(player.sourceFiles)) { // Expect pre-2.3 sourcefile format here. type OldSourceFiles = { n: number; lvl: number }[]; diff --git a/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts b/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts index 58cc95195..e04cab658 100644 --- a/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts +++ b/src/PersonObjects/Player/PlayerObjectGeneralMethods.ts @@ -1,10 +1,11 @@ +import { AugmentationName, CityName, CompletedProgramName, FactionName, LocationName, ToastVariant } from "@enums"; + import type { PlayerObject } from "./PlayerObject"; import type { ProgramFilePath } from "../../Paths/ProgramFilePath"; import { applyAugmentation } from "../../Augmentation/AugmentationHelpers"; import { PlayerOwnedAugmentation } from "../../Augmentation/PlayerOwnedAugmentation"; -import { AugmentationName, CityName, CompletedProgramName, FactionName, LocationName, ToastVariant } from "@enums"; -import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../../BitNode/BitNodeMultipliers"; import { CodingContractRewardType, ICodingContractReward } from "../../CodingContracts"; import { Company } from "../../Company/Company"; import { Companies } from "../../Company/Companies"; @@ -548,22 +549,16 @@ export function reapplyAllAugmentations(this: PlayerObject, resetMultipliers = t this.resetMultipliers(); } - for (let i = 0; i < this.augmentations.length; ++i) { - //Compatibility with new version - if (this.augmentations[i].name === "HacknetNode NIC Architecture Neural-Upload") { - this.augmentations[i].name = "Hacknet Node NIC Architecture Neural-Upload"; - } - - const playerAug = this.augmentations[i]; + for (const playerAug of this.augmentations) { const augName = playerAug.name; if (augName == AugmentationName.NeuroFluxGovernor) { - for (let j = 0; j < playerAug.level; ++j) { - applyAugmentation(this.augmentations[i], true); + for (let i = 0; i < playerAug.level; ++i) { + applyAugmentation(playerAug, true); } continue; } - applyAugmentation(this.augmentations[i], true); + applyAugmentation(playerAug, true); } this.updateSkillLevels(); @@ -644,7 +639,7 @@ export function checkForFactionInvitations(this: PlayerObject): Faction[] { !daedalusFac.isBanned && !daedalusFac.isMember && !daedalusFac.alreadyInvited && - numAugmentations >= BitNodeMultipliers.DaedalusAugsRequirement && + numAugmentations >= currentNodeMults.DaedalusAugsRequirement && this.money >= 100000000000 && (this.skills.hacking >= 2500 || (this.skills.strength >= 1500 && @@ -1080,7 +1075,7 @@ export function setBitNodeNumber(this: PlayerObject, n: number): void { this.bitNodeN = n; } -export function queueAugmentation(this: PlayerObject, name: string): void { +export function queueAugmentation(this: PlayerObject, name: AugmentationName): void { for (const aug of this.queuedAugmentations) { if (aug.name == name) { console.warn(`tried to queue ${name} twice, this may be a bug`); @@ -1152,7 +1147,7 @@ export function gainCodingContractReward( } case CodingContractRewardType.Money: default: { - const moneyGain = CONSTANTS.CodingContractBaseMoneyGain * difficulty * BitNodeMultipliers.CodingContractMoney; + const moneyGain = CONSTANTS.CodingContractBaseMoneyGain * difficulty * currentNodeMults.CodingContractMoney; this.gainMoney(moneyGain, "codingcontract"); return `Gained ${formatMoney(moneyGain)}`; } diff --git a/src/PersonObjects/Player/PlayerObjectServerMethods.ts b/src/PersonObjects/Player/PlayerObjectServerMethods.ts index eb70c71a2..94cd8ebdb 100644 --- a/src/PersonObjects/Player/PlayerObjectServerMethods.ts +++ b/src/PersonObjects/Player/PlayerObjectServerMethods.ts @@ -1,7 +1,7 @@ // Server and HacknetServer-related methods for the Player class (PlayerObject) import { CONSTANTS } from "../../Constants"; -import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../../BitNode/BitNodeMultipliers"; import { Server } from "../../Server/Server"; import { BaseServer } from "../../Server/BaseServer"; import { HacknetServer } from "../../Hacknet/HacknetServer"; @@ -35,7 +35,7 @@ export function getUpgradeHomeRamCost(this: PlayerObject): number { //Calculate cost //Have cost increase by some percentage each time RAM has been upgraded const mult = Math.pow(1.58, numUpgrades); - const cost = currentRam * CONSTANTS.BaseCostFor1GBOfRamHome * mult * BitNodeMultipliers.HomeComputerRamCost; + const cost = currentRam * CONSTANTS.BaseCostFor1GBOfRamHome * mult * currentNodeMults.HomeComputerRamCost; return cost; } diff --git a/src/PersonObjects/Sleeve/Sleeve.ts b/src/PersonObjects/Sleeve/Sleeve.ts index f15deb873..d7b65cc29 100644 --- a/src/PersonObjects/Sleeve/Sleeve.ts +++ b/src/PersonObjects/Sleeve/Sleeve.ts @@ -7,14 +7,16 @@ * Sleeves are unlocked in BitNode-10. */ +import type { SleevePerson } from "@nsdefs"; +import type { Augmentation } from "../../Augmentation/Augmentation"; +import type { Company } from "../../Company/Company"; +import type { CompanyPosition } from "../../Company/CompanyPosition"; +import type { SleeveWork } from "./Work/Work"; + import { Player } from "@player"; import { Person } from "../Person"; -import { Augmentation } from "../../Augmentation/Augmentation"; - import { Companies } from "../../Company/Companies"; -import { Company } from "../../Company/Company"; -import { CompanyPosition } from "../../Company/CompanyPosition"; import { CompanyPositions } from "../../Company/CompanyPositions"; import { Contracts } from "../../Bladeburner/data/Contracts"; import { CONSTANTS } from "../../Constants"; @@ -24,7 +26,6 @@ import { Factions } from "../../Faction/Factions"; import { Generic_fromJSON, Generic_toJSON, IReviverValue, constructorsForReviver } from "../../utils/JSONReviver"; import { formatPercent } from "../../ui/formatNumber"; -import { SleeveWork } from "./Work/Work"; import { SleeveClassWork } from "./Work/SleeveClassWork"; import { SleeveSynchroWork } from "./Work/SleeveSynchroWork"; import { SleeveRecoveryWork } from "./Work/SleeveRecoveryWork"; @@ -35,8 +36,8 @@ import { SleeveSupportWork } from "./Work/SleeveSupportWork"; import { SleeveBladeburnerWork } from "./Work/SleeveBladeburnerWork"; import { SleeveCrimeWork } from "./Work/SleeveCrimeWork"; import * as sleeveMethods from "./SleeveMethods"; -import { SleevePerson } from "@nsdefs"; import { calculateIntelligenceBonus } from "../formulas/intelligence"; +import { getEnumHelper } from "../../utils/EnumHelper"; export class Sleeve extends Person implements SleevePerson { currentWork: SleeveWork | null = null; @@ -475,8 +476,17 @@ export class Sleeve extends Person implements SleevePerson { /** Initializes a Sleeve object from a JSON save state. */ static fromJSON(value: IReviverValue): Sleeve { - if (!value.data.hp?.current || !value.data.hp?.max) value.data.hp = { current: 10, max: 10 }; - return Generic_fromJSON(Sleeve, value.data); + const sleeve = Generic_fromJSON(Sleeve, value.data); + if (!sleeve.hp?.current || !sleeve.hp?.max) sleeve.hp = { current: 10, max: 10 }; + // Remove any invalid aug names on game load + sleeve.augmentations = sleeve.augmentations.filter((ownedAug) => + getEnumHelper("AugmentationName").isMember(ownedAug.name), + ); + sleeve.queuedAugmentations = sleeve.queuedAugmentations.filter((ownedAug) => + getEnumHelper("AugmentationName").isMember(ownedAug.name), + ); + + return sleeve; } } diff --git a/src/PersonObjects/Sleeve/SleeveMethods.ts b/src/PersonObjects/Sleeve/SleeveMethods.ts index e32548681..f60d7f650 100644 --- a/src/PersonObjects/Sleeve/SleeveMethods.ts +++ b/src/PersonObjects/Sleeve/SleeveMethods.ts @@ -2,10 +2,11 @@ import { Player } from "@player"; import { AugmentationName, FactionName } from "@enums"; import { Sleeve } from "./Sleeve"; import { Augmentation } from "../../Augmentation/Augmentation"; -import { StaticAugmentations } from "../../Augmentation/StaticAugmentations"; +import { Augmentations } from "../../Augmentation/Augmentations"; import { Factions } from "../../Faction/Factions"; import { mergeMultipliers, Multipliers } from "../Multipliers"; import { getFactionAugmentationsFiltered } from "../../Faction/FactionHelpers"; +import { getAugCost } from "../../Augmentation/AugmentationHelpers"; /** Updates this object's multipliers for the given augmentation */ export function applyAugmentation(this: Sleeve, aug: Augmentation): void { @@ -61,10 +62,10 @@ export function findPurchasableAugs(this: Sleeve): Augmentation[] { const gangAugs = getFactionAugmentationsFiltered(fac); for (const augName of gangAugs) { - const aug = StaticAugmentations[augName]; + const aug = Augmentations[augName]; if (!isAvailableForSleeve(aug)) continue; - if (fac.playerReputation > aug.getCost().repCost) { + if (fac.playerReputation > getAugCost(aug).repCost) { availableAugs.push(aug); } } @@ -77,10 +78,10 @@ export function findPurchasableAugs(this: Sleeve): Augmentation[] { if (!fac) continue; for (const augName of fac.augmentations) { - const aug = StaticAugmentations[augName]; + const aug = Augmentations[augName]; if (!isAvailableForSleeve(aug)) continue; - if (fac.playerReputation > aug.getCost().repCost) { + if (fac.playerReputation > getAugCost(aug).repCost) { availableAugs.push(aug); } } @@ -88,7 +89,7 @@ export function findPurchasableAugs(this: Sleeve): Augmentation[] { // Add the stanek sleeve aug if (!ownedAugNames.includes(AugmentationName.ZOE) && Player.factions.includes(FactionName.ChurchOfTheMachineGod)) { - const aug = StaticAugmentations[AugmentationName.ZOE]; + const aug = Augmentations[AugmentationName.ZOE]; availableAugs.push(aug); } diff --git a/src/PersonObjects/formulas/reputation.ts b/src/PersonObjects/formulas/reputation.ts index 21f4bc3f5..ccfd5cc36 100644 --- a/src/PersonObjects/formulas/reputation.ts +++ b/src/PersonObjects/formulas/reputation.ts @@ -1,5 +1,5 @@ import { CONSTANTS } from "../../Constants"; -import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../../BitNode/BitNodeMultipliers"; import { CalculateShareMult } from "../../NetworkShare/Share"; import { Person as IPerson } from "@nsdefs"; import { calculateIntelligenceBonus } from "./intelligence"; @@ -9,7 +9,7 @@ function mult(favor: number): number { if (isNaN(favorMult)) { favorMult = 1; } - return favorMult * BitNodeMultipliers.FactionWorkRepGain; + return favorMult * currentNodeMults.FactionWorkRepGain; } export function getHackingWorkRepGain(p: IPerson, favor: number): number { diff --git a/src/Prestige.ts b/src/Prestige.ts index 3149edfcd..e4e87a335 100755 --- a/src/Prestige.ts +++ b/src/Prestige.ts @@ -1,6 +1,4 @@ import { AugmentationName, CityName, CompletedProgramName, FactionName, LiteratureName } from "@enums"; -import { StaticAugmentations } from "./Augmentation/StaticAugmentations"; -import { augmentationExists, initAugmentations } from "./Augmentation/AugmentationHelpers"; import { initBitNodeMultipliers } from "./BitNode/BitNode"; import { Companies, initCompanies } from "./Company/Companies"; import { resetIndustryResearchTrees } from "./Corporation/data/IndustryData"; @@ -51,15 +49,15 @@ export function prestigeAugmentation(): void { AddToAllServers(homeComp); prestigeHomeComputer(homeComp); - if (augmentationExists(AugmentationName.Neurolink) && Player.hasAugmentation(AugmentationName.Neurolink, true)) { + if (Player.hasAugmentation(AugmentationName.Neurolink, true)) { homeComp.programs.push(CompletedProgramName.ftpCrack); homeComp.programs.push(CompletedProgramName.relaySmtp); } - if (augmentationExists(AugmentationName.CashRoot) && Player.hasAugmentation(AugmentationName.CashRoot, true)) { + if (Player.hasAugmentation(AugmentationName.CashRoot, true)) { Player.setMoney(1e6); homeComp.programs.push(CompletedProgramName.bruteSsh); } - if (augmentationExists(AugmentationName.PCMatrix) && Player.hasAugmentation(AugmentationName.PCMatrix, true)) { + if (Player.hasAugmentation(AugmentationName.PCMatrix, true)) { homeComp.programs.push(CompletedProgramName.deepScan1); homeComp.programs.push(CompletedProgramName.autoLink); } @@ -86,7 +84,7 @@ export function prestigeAugmentation(): void { initFactions(); // Factions must be initialized before augmentations Player.factionInvitations = Player.factionInvitations.concat(maintainMembership); - initAugmentations(); // Calls reapplyAllAugmentations() and resets Player multipliers + Player.reapplyAllAugmentations(); Player.reapplyAllSourceFiles(); Player.hp.current = Player.hp.max; initCompanies(); @@ -136,7 +134,7 @@ export function prestigeAugmentation(): void { } // Red Pill - if (augmentationExists(AugmentationName.TheRedPill) && Player.hasAugmentation(AugmentationName.TheRedPill, true)) { + if (Player.hasAugmentation(AugmentationName.TheRedPill, true)) { const WorldDaemon = GetServer(SpecialServers.WorldDaemon); const DaedalusServer = GetServer(SpecialServers.DaedalusServer); if (WorldDaemon && DaedalusServer) { @@ -145,10 +143,7 @@ export function prestigeAugmentation(): void { } } - if ( - augmentationExists(AugmentationName.StaneksGift1) && - Player.hasAugmentation(AugmentationName.StaneksGift1, true) - ) { + if (Player.hasAugmentation(AugmentationName.StaneksGift1, true)) { joinFaction(Factions[FactionName.ChurchOfTheMachineGod]); } @@ -205,11 +200,6 @@ export function prestigeSourceFile(isFlume: boolean): void { Terminal.finishAction(true); } - // Delete all Augmentations - for (const name of Object.getOwnPropertyNames(StaticAugmentations)) { - delete StaticAugmentations[name]; - } - // Give levels of NeuroFluxGovernor for Source-File 12. Must be done here before Augmentations are recalculated if (Player.sourceFileLvl(12) > 0) { Player.augmentations.push({ @@ -220,7 +210,7 @@ export function prestigeSourceFile(isFlume: boolean): void { // Re-initialize things - This will update any changes initFactions(); // Factions must be initialized before augmentations - initAugmentations(); // Calls reapplyAllAugmentations() and resets Player multipliers + Player.reapplyAllAugmentations(); Player.reapplyAllSourceFiles(); initCompanies(); diff --git a/src/Programs/Programs.ts b/src/Programs/Programs.ts index 5b263cd8b..fbf2f1943 100644 --- a/src/Programs/Programs.ts +++ b/src/Programs/Programs.ts @@ -7,7 +7,7 @@ import { Player } from "@player"; import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions"; import { GetServer } from "../Server/AllServers"; import { formatMoney } from "../ui/formatNumber"; -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; import { BitFlumeEvent } from "../BitNode/ui/BitFlumeModal"; import { calculateHackingTime, calculateGrowTime, calculateWeakenTime } from "../Hacking"; import { CompletedProgramName, FactionName } from "@enums"; @@ -286,7 +286,7 @@ export const Programs: Record = { name: CompletedProgramName.flight, create: null, run: (): void => { - const numAugReq = BitNodeMultipliers.DaedalusAugsRequirement; + const numAugReq = currentNodeMults.DaedalusAugsRequirement; const fulfilled = Player.augmentations.length >= numAugReq && Player.money > 1e11 && Player.skills.hacking >= 2500; if (!fulfilled) { diff --git a/src/SaveObject.ts b/src/SaveObject.ts index a12e50e7c..88d9a1bcb 100644 --- a/src/SaveObject.ts +++ b/src/SaveObject.ts @@ -28,7 +28,6 @@ import { save } from "./db"; import { AwardNFG, v1APIBreak } from "./utils/v1APIBreak"; import { AugmentationName, FactionName, LocationName, ToastVariant } from "@enums"; import { PlayerOwnedAugmentation } from "./Augmentation/PlayerOwnedAugmentation"; -import { initAugmentations } from "./Augmentation/AugmentationHelpers"; import { pushGameSaved } from "./Electron"; import { defaultMonacoTheme } from "./ScriptEditor/ui/themes"; import { Faction } from "./Faction/Faction"; @@ -364,7 +363,7 @@ function evaluateVersionCompatibility(ver: string | number): void { if (typeof ver !== "number") return; if (ver < 2) { AwardNFG(10); - initAugmentations(); + Player.reapplyAllAugmentations(); Player.reapplyAllSourceFiles(); } if (ver < 3) { @@ -447,7 +446,7 @@ function evaluateVersionCompatibility(ver: string | number): void { ]; v22PlayerBreak(); - initAugmentations(); + Player.reapplyAllAugmentations(); Player.reapplyAllSourceFiles(); } @@ -679,17 +678,6 @@ function evaluateVersionCompatibility(ver: string | number): void { } //2.3 hotfix changes and 2.3.1 changes if (ver < 32) { - // Due to a bug from before 2.3, some scripts have the wrong server listed. In 2.3 this caused issues. - for (const server of GetAllServers()) { - for (const script of server.scripts.values()) { - if (script.server !== server.hostname) { - console.warn( - `Detected script ${script.filename} on ${server.hostname} with incorrect server property: ${script.server}. Repairing.`, - ); - script.server = server.hostname; - } - } - } // Sanitize corporation exports let anyExportsFailed = false; if (Player.corporation) { @@ -723,6 +711,19 @@ Error: ${e}`); "Some material exports failed to validate while loading and have been removed. See console for more info.", ); } + if (ver < 33) { + // 2.3.2 fixed what should be the last issue with scripts having the wrong server assigned.. + for (const server of GetAllServers()) { + for (const script of server.scripts.values()) { + if (script.server !== server.hostname) { + console.warn( + `Detected script ${script.filename} on ${server.hostname} with incorrect server property: ${script.server}. Repairing.`, + ); + script.server = server.hostname; + } + } + } + } } function loadGame(saveString: string): boolean { diff --git a/src/Server/AllServers.ts b/src/Server/AllServers.ts index 807d90ce6..d60a5ab97 100644 --- a/src/Server/AllServers.ts +++ b/src/Server/AllServers.ts @@ -9,7 +9,7 @@ import { createRandomIp } from "../utils/IPAddress"; import { getRandomInt } from "../utils/helpers/getRandomInt"; import { Reviver } from "../utils/JSONReviver"; import { SpecialServers } from "./data/SpecialServers"; -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; import { IPAddress, isIPAddress } from "../Types/strings"; import "../Script/RunningScript"; // For reviver side-effect @@ -159,7 +159,7 @@ export function initForeignServers(homeComputer: Server): void { } if (server.hostname === SpecialServers.WorldDaemon) { - server.requiredHackingSkill *= BitNodeMultipliers.WorldDaemonDifficulty; + server.requiredHackingSkill *= currentNodeMults.WorldDaemonDifficulty; } AddToAllServers(server); if (metadata.networkLayer !== undefined) { diff --git a/src/Server/Server.ts b/src/Server/Server.ts index e07d04aea..36702c8ba 100644 --- a/src/Server/Server.ts +++ b/src/Server/Server.ts @@ -1,7 +1,7 @@ // Class representing a single hackable Server import { BaseServer } from "./BaseServer"; -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; import { createRandomString } from "../utils/helpers/createRandomString"; import { createRandomIp } from "../utils/IPAddress"; @@ -72,12 +72,12 @@ export class Server extends BaseServer { /* Hacking information (only valid for "foreign" aka non-purchased servers) */ this.requiredHackingSkill = params.requiredHackingSkill != null ? params.requiredHackingSkill : 1; const baseMoney = params.moneyAvailable ?? 0; - this.moneyAvailable = baseMoney * BitNodeMultipliers.ServerStartingMoney; - this.moneyMax = 25 * baseMoney * BitNodeMultipliers.ServerMaxMoney; + this.moneyAvailable = baseMoney * currentNodeMults.ServerStartingMoney; + this.moneyMax = 25 * baseMoney * currentNodeMults.ServerMaxMoney; //Hack Difficulty is synonymous with server security. Base Difficulty = Starting difficulty const realDifficulty = - params.hackDifficulty != null ? params.hackDifficulty * BitNodeMultipliers.ServerStartingSecurity : 1; + params.hackDifficulty != null ? params.hackDifficulty * currentNodeMults.ServerStartingSecurity : 1; this.hackDifficulty = Math.min(realDifficulty, 100); this.baseDifficulty = this.hackDifficulty; this.minDifficulty = Math.min(Math.max(1, Math.round(realDifficulty / 3)), 100); @@ -141,7 +141,7 @@ export class Server extends BaseServer { /** Lowers the server's security level (difficulty) by the specified amount) */ weaken(amt: number): void { - this.hackDifficulty -= amt * BitNodeMultipliers.ServerWeakenRate; + this.hackDifficulty -= amt * currentNodeMults.ServerWeakenRate; this.capDifficulty(); } diff --git a/src/Server/ServerHelpers.ts b/src/Server/ServerHelpers.ts index fc4b38a9d..a30024862 100644 --- a/src/Server/ServerHelpers.ts +++ b/src/Server/ServerHelpers.ts @@ -3,7 +3,7 @@ import { Server, IConstructorParams } from "./Server"; import { BaseServer } from "./BaseServer"; import { calculateServerGrowth } from "./formulas/grow"; -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; import { CONSTANTS } from "../Constants"; import { Player } from "@player"; import { CompletedProgramName, LiteratureName } from "@enums"; @@ -66,7 +66,7 @@ export function numCycleForGrowth(server: IServer, growth: number, cores = 1): n (Math.log(ajdGrowthRate) * Player.mults.hacking_grow * serverGrowthPercentage * - BitNodeMultipliers.ServerGrowthRate * + currentNodeMults.ServerGrowthRate * coreBonus); return cycles; @@ -105,7 +105,7 @@ export function numCycleForGrowthCorrected( const serverGrowthPercentage = server.serverGrowth / 100.0; const coreMultiplier = 1 + (cores - 1) / 16; const threadMultiplier = - serverGrowthPercentage * person.mults.hacking_grow * coreMultiplier * BitNodeMultipliers.ServerGrowthRate; + serverGrowthPercentage * person.mults.hacking_grow * coreMultiplier * currentNodeMults.ServerGrowthRate; /* 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: diff --git a/src/Server/ServerPurchases.ts b/src/Server/ServerPurchases.ts index ad593b33b..849e1daaa 100644 --- a/src/Server/ServerPurchases.ts +++ b/src/Server/ServerPurchases.ts @@ -5,7 +5,7 @@ import { AddToAllServers, createUniqueRandomIp, GetServer, renameServer } from "./AllServers"; import { safelyCreateUniqueServer } from "./ServerHelpers"; -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; import { CONSTANTS } from "../Constants"; import { Player } from "@player"; @@ -34,8 +34,8 @@ export function getPurchaseServerCost(ram: number): number { return ( sanitizedRam * CONSTANTS.BaseCostFor1GBOfRamServer * - BitNodeMultipliers.PurchasedServerCost * - Math.pow(BitNodeMultipliers.PurchasedServerSoftcap, upg) + currentNodeMults.PurchasedServerCost * + Math.pow(currentNodeMults.PurchasedServerSoftcap, upg) ); } @@ -86,11 +86,11 @@ export const renamePurchasedServer = (hostname: string, newName: string): void = }; export function getPurchaseServerLimit(): number { - return Math.round(CONSTANTS.PurchasedServerLimit * BitNodeMultipliers.PurchasedServerLimit); + return Math.round(CONSTANTS.PurchasedServerLimit * currentNodeMults.PurchasedServerLimit); } export function getPurchaseServerMaxRam(): number { - const ram = Math.round(CONSTANTS.PurchasedServerMaxRam * BitNodeMultipliers.PurchasedServerMaxRam); + const ram = Math.round(CONSTANTS.PurchasedServerMaxRam * currentNodeMults.PurchasedServerMaxRam); // Round this to the nearest power of 2 return 1 << (31 - Math.clz32(ram)); diff --git a/src/Server/formulas/grow.ts b/src/Server/formulas/grow.ts index 17ed99056..ae2bd7b0e 100644 --- a/src/Server/formulas/grow.ts +++ b/src/Server/formulas/grow.ts @@ -1,5 +1,5 @@ import { CONSTANTS } from "../../Constants"; -import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../../BitNode/BitNodeMultipliers"; import { Person as IPerson, Server as IServer } from "@nsdefs"; export function calculateServerGrowth(server: IServer, threads: number, p: IPerson, cores = 1): number { @@ -17,7 +17,7 @@ export function calculateServerGrowth(server: IServer, threads: number, p: IPers //Calculate adjusted server growth rate based on parameters const serverGrowthPercentage = server.serverGrowth / 100; const numServerGrowthCyclesAdjusted = - numServerGrowthCycles * serverGrowthPercentage * BitNodeMultipliers.ServerGrowthRate; + numServerGrowthCycles * serverGrowthPercentage * currentNodeMults.ServerGrowthRate; //Apply serverGrowth for the calculated number of growth cycles const coreBonus = 1 + (cores - 1) / 16; diff --git a/src/StockMarket/StockMarketCosts.ts b/src/StockMarket/StockMarketCosts.ts index a8887298d..0ff1680e1 100644 --- a/src/StockMarket/StockMarketCosts.ts +++ b/src/StockMarket/StockMarketCosts.ts @@ -1,12 +1,12 @@ -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; import { CONSTANTS } from "../Constants"; export function getStockMarket4SDataCost(): number { - return CONSTANTS.MarketData4SCost * BitNodeMultipliers.FourSigmaMarketDataCost; + return CONSTANTS.MarketData4SCost * currentNodeMults.FourSigmaMarketDataCost; } export function getStockMarket4STixApiCost(): number { - return CONSTANTS.MarketDataTixApi4SCost * BitNodeMultipliers.FourSigmaMarketDataApiCost; + return CONSTANTS.MarketDataTixApi4SCost * currentNodeMults.FourSigmaMarketDataApiCost; } export function getStockMarketWseCost(): number { diff --git a/src/Terminal/Terminal.ts b/src/Terminal/Terminal.ts index 2a9866714..5d986bee5 100644 --- a/src/Terminal/Terminal.ts +++ b/src/Terminal/Terminal.ts @@ -74,7 +74,7 @@ import { wget } from "./commands/wget"; import { hash } from "../hash/hash"; import { apr1 } from "./commands/apr1"; import { changelog } from "./commands/changelog"; -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; import { Engine } from "../engine"; import { Directory, resolveDirectory, root } from "../Paths/Directory"; import { FilePath, isFilePath, resolveFilePath } from "../Paths/FilePath"; @@ -213,7 +213,7 @@ export class Terminal { Engine.Counters.checkFactionInvitations = 0; Engine.checkCounters(); - let moneyGained = calculatePercentMoneyHacked(server, Player) * BitNodeMultipliers.ManualHackMoney; + let moneyGained = calculatePercentMoneyHacked(server, Player) * currentNodeMults.ManualHackMoney; moneyGained = Math.floor(server.moneyAvailable * moneyGained); if (moneyGained <= 0) { diff --git a/src/Work/Formulas.ts b/src/Work/Formulas.ts index 36ae2f008..2ba890174 100644 --- a/src/Work/Formulas.ts +++ b/src/Work/Formulas.ts @@ -1,4 +1,4 @@ -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; import { Crime } from "../Crime/Crime"; import { newWorkStats, scaleWorkStats, WorkStats, multWorkStats } from "./WorkStats"; import { Person as IPerson } from "@nsdefs"; @@ -55,9 +55,9 @@ export function calculateCrimeWorkStats(person: IPerson, crime: Crime): WorkStat intExp: crime.intelligence_exp, }), person.mults, - person.mults.crime_money * BitNodeMultipliers.CrimeMoney, + person.mults.crime_money * currentNodeMults.CrimeMoney, ), - BitNodeMultipliers.CrimeExpGain, + currentNodeMults.CrimeExpGain, false, ); return gains; @@ -77,7 +77,7 @@ export const calculateFactionRep = (person: IPerson, type: FactionWorkType, favo export function calculateFactionExp(person: IPerson, type: FactionWorkType): WorkStats { return scaleWorkStats( multWorkStats(FactionWorkStats[type], person.mults), - BitNodeMultipliers.FactionWorkExpGain / gameCPS, + currentNodeMults.FactionWorkExpGain / gameCPS, ); } @@ -119,7 +119,7 @@ export const calculateCompanyWorkStats = ( const gains = scaleWorkStats( multWorkStats( { - money: companyPosition.baseSalary * company.salaryMultiplier * bn11Mult * BitNodeMultipliers.CompanyWorkMoney, + money: companyPosition.baseSalary * company.salaryMultiplier * bn11Mult * currentNodeMults.CompanyWorkMoney, hackExp: companyPosition.hackingExpGain, strExp: companyPosition.strengthExpGain, defExp: companyPosition.defenseExpGain, @@ -130,7 +130,7 @@ export const calculateCompanyWorkStats = ( worker.mults, worker.mults.work_money, ), - company.expMultiplier * BitNodeMultipliers.CompanyWorkExpGain, + company.expMultiplier * currentNodeMults.CompanyWorkExpGain, false, ); diff --git a/src/Work/GraftingWork.tsx b/src/Work/GraftingWork.tsx index 31401b61b..2bf8145bd 100644 --- a/src/Work/GraftingWork.tsx +++ b/src/Work/GraftingWork.tsx @@ -9,17 +9,17 @@ import { applyAugmentation } from "../Augmentation/AugmentationHelpers"; import { dialogBoxCreate } from "../ui/React/DialogBox"; import { constructorsForReviver, Generic_toJSON, Generic_fromJSON, IReviverValue } from "../utils/JSONReviver"; import { GraftableAugmentation } from "../PersonObjects/Grafting/GraftableAugmentation"; -import { StaticAugmentations } from "../Augmentation/StaticAugmentations"; +import { Augmentations } from "../Augmentation/Augmentations"; export const isGraftingWork = (w: Work | null): w is GraftingWork => w !== null && w.type === WorkType.GRAFTING; interface GraftingWorkParams { - augmentation: string; + augmentation: AugmentationName; singularity: boolean; } export class GraftingWork extends Work { - augmentation: string; + augmentation: AugmentationName; unitCompleted: number; constructor(params?: GraftingWorkParams) { @@ -31,7 +31,7 @@ export class GraftingWork extends Work { } unitNeeded(): number { - return new GraftableAugmentation(StaticAugmentations[this.augmentation]).time; + return new GraftableAugmentation(Augmentations[this.augmentation]).time; } process(cycles: number): boolean { diff --git a/src/engine.tsx b/src/engine.tsx index eb8aa1696..08961dc14 100644 --- a/src/engine.tsx +++ b/src/engine.tsx @@ -1,5 +1,4 @@ import { convertTimeMsToTimeElapsedString } from "./utils/StringHelperFunctions"; -import { initAugmentations } from "./Augmentation/AugmentationHelpers"; import { AugmentationName, ToastVariant } from "@enums"; import { initBitNodeMultipliers } from "./BitNode/BitNode"; import { initSourceFiles } from "./SourceFile/SourceFiles"; @@ -231,7 +230,7 @@ const Engine: { if (loadGame(saveString)) { FormatsNeedToChange.emit(); initBitNodeMultipliers(); - initAugmentations(); // Also calls Player.reapplyAllAugmentations() + Player.reapplyAllAugmentations(); Player.reapplyAllSourceFiles(); if (Player.hasWseAccount) { initSymbolToStockMap(); @@ -377,7 +376,7 @@ const Engine: { initForeignServers(Player.getHomeComputer()); initCompanies(); initFactions(); - initAugmentations(); + Player.reapplyAllAugmentations(); // Start interactive tutorial iTutorialStart(); diff --git a/src/ui/CharacterStats.tsx b/src/ui/CharacterStats.tsx index 46a916ab5..b220ee5df 100644 --- a/src/ui/CharacterStats.tsx +++ b/src/ui/CharacterStats.tsx @@ -1,8 +1,8 @@ import { Paper, Table, TableBody, Box, IconButton, Typography, Container, Tooltip } from "@mui/material"; import { MoreHoriz, Info } from "@mui/icons-material"; import React, { useState } from "react"; -import { BitNodes, defaultMultipliers, getBitNodeMultipliers } from "../BitNode/BitNode"; -import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers"; +import { BitNodes } from "../BitNode/BitNode"; +import { currentNodeMults } from "../BitNode/BitNodeMultipliers"; import { BitNodeMultipliersDisplay } from "../BitNode/ui/BitnodeMultipliersDescription"; import { HacknetServerConstants } from "../Hacknet/data/Constants"; import { getPurchaseServerLimit } from "../Server/ServerPurchases"; @@ -15,7 +15,6 @@ import { Modal } from "./React/Modal"; import { Money } from "./React/Money"; import { StatsRow } from "./React/StatsRow"; import { StatsTable } from "./React/StatsTable"; -import { isEqual } from "lodash"; import { useRerender } from "./React/hooks"; interface EmployersModalProps { @@ -211,12 +210,7 @@ export function CharacterStats(): React.ReactElement { timeRows.push(["Total", convertTimeMsToTimeElapsedString(Player.totalPlaytime)]); let showBitNodeMults = false; - if (Player.sourceFileLvl(5) > 0) { - const n = Player.bitNodeN; - const maxSfLevel = n === 12 ? Infinity : 3; - const mults = getBitNodeMultipliers(n, Math.min(Player.sourceFileLvl(n) + 1, maxSfLevel)); - showBitNodeMults = !isEqual(mults, defaultMultipliers); - } + if (Player.sourceFileLvl(5) > 0) showBitNodeMults = true; return ( Stats @@ -355,12 +349,12 @@ export function CharacterStats(): React.ReactElement { { mult: "Hacking Money", value: Player.mults.hacking_money, - effValue: Player.mults.hacking_money * BitNodeMultipliers.ScriptHackMoney, + effValue: Player.mults.hacking_money * currentNodeMults.ScriptHackMoney, }, { mult: "Hacking Growth", value: Player.mults.hacking_grow, - effValue: Player.mults.hacking_grow * BitNodeMultipliers.ServerGrowthRate, + effValue: Player.mults.hacking_grow * currentNodeMults.ServerGrowthRate, }, ]} color={Settings.theme.hack} @@ -370,12 +364,12 @@ export function CharacterStats(): React.ReactElement { { mult: "Hacking Level", value: Player.mults.hacking, - effValue: Player.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier, + effValue: Player.mults.hacking * currentNodeMults.HackingLevelMultiplier, }, { mult: "Hacking Experience", value: Player.mults.hacking_exp, - effValue: Player.mults.hacking_exp * BitNodeMultipliers.HackExpGain, + effValue: Player.mults.hacking_exp * currentNodeMults.HackExpGain, }, ]} color={Settings.theme.hack} @@ -385,7 +379,7 @@ export function CharacterStats(): React.ReactElement { { mult: "Strength Level", value: Player.mults.strength, - effValue: Player.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier, + effValue: Player.mults.strength * currentNodeMults.StrengthLevelMultiplier, }, { mult: "Strength Experience", @@ -399,7 +393,7 @@ export function CharacterStats(): React.ReactElement { { mult: "Defense Level", value: Player.mults.defense, - effValue: Player.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier, + effValue: Player.mults.defense * currentNodeMults.DefenseLevelMultiplier, }, { mult: "Defense Experience", @@ -413,7 +407,7 @@ export function CharacterStats(): React.ReactElement { { mult: "Dexterity Level", value: Player.mults.dexterity, - effValue: Player.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier, + effValue: Player.mults.dexterity * currentNodeMults.DexterityLevelMultiplier, }, { mult: "Dexterity Experience", @@ -427,7 +421,7 @@ export function CharacterStats(): React.ReactElement { { mult: "Agility Level", value: Player.mults.agility, - effValue: Player.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier, + effValue: Player.mults.agility * currentNodeMults.AgilityLevelMultiplier, }, { mult: "Agility Experience", @@ -441,7 +435,7 @@ export function CharacterStats(): React.ReactElement { { mult: "Charisma Level", value: Player.mults.charisma, - effValue: Player.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier, + effValue: Player.mults.charisma * currentNodeMults.CharismaLevelMultiplier, }, { mult: "Charisma Experience", @@ -459,7 +453,7 @@ export function CharacterStats(): React.ReactElement { { mult: "Hacknet Node Production", value: Player.mults.hacknet_node_money, - effValue: Player.mults.hacknet_node_money * BitNodeMultipliers.HacknetNodeMoney, + effValue: Player.mults.hacknet_node_money * currentNodeMults.HacknetNodeMoney, }, { mult: "Hacknet Node Purchase Cost", @@ -490,13 +484,13 @@ export function CharacterStats(): React.ReactElement { { mult: "Faction Reputation Gain", value: Player.mults.faction_rep, - effValue: Player.mults.faction_rep * BitNodeMultipliers.FactionWorkRepGain, + effValue: Player.mults.faction_rep * currentNodeMults.FactionWorkRepGain, color: Settings.theme.rep, }, { mult: "Salary", value: Player.mults.work_money, - effValue: Player.mults.work_money * BitNodeMultipliers.CompanyWorkMoney, + effValue: Player.mults.work_money * currentNodeMults.CompanyWorkMoney, color: Settings.theme.money, }, ]} @@ -511,13 +505,13 @@ export function CharacterStats(): React.ReactElement { { mult: "Crime Money", value: Player.mults.crime_money, - effValue: Player.mults.crime_money * BitNodeMultipliers.CrimeMoney, + effValue: Player.mults.crime_money * currentNodeMults.CrimeMoney, color: Settings.theme.money, }, ]} color={Settings.theme.combat} /> - {Player.canAccessBladeburner() && BitNodeMultipliers.BladeburnerRank > 0 && ( + {Player.canAccessBladeburner() && currentNodeMults.BladeburnerRank > 0 && ( string> = { const skillMultUpdaters: Record number> = { //Used by skill bars to calculate the mult - Hack: () => Player.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier, - Str: () => Player.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier, - Def: () => Player.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier, - Dex: () => Player.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier, - Agi: () => Player.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier, - Cha: () => Player.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier, + Hack: () => Player.mults.hacking * currentNodeMults.HackingLevelMultiplier, + Str: () => Player.mults.strength * currentNodeMults.StrengthLevelMultiplier, + Def: () => Player.mults.defense * currentNodeMults.DefenseLevelMultiplier, + Dex: () => Player.mults.dexterity * currentNodeMults.DexterityLevelMultiplier, + Agi: () => Player.mults.agility * currentNodeMults.AgilityLevelMultiplier, + Cha: () => Player.mults.charisma * currentNodeMults.CharismaLevelMultiplier, Int: () => 1, }; diff --git a/src/utils/EnumHelper.ts b/src/utils/EnumHelper.ts index 035535705..4c86d1d28 100644 --- a/src/utils/EnumHelper.ts +++ b/src/utils/EnumHelper.ts @@ -28,13 +28,17 @@ class EnumHelper & st if (this.isMember(toValidate)) return toValidate; // assertString is just called so if the user didn't even pass in a string, they get a different error message assertString(ctx, argName, toValidate); + // Don't display all possibilities for large enums + let allowableValues = `Allowable values: ${this.valueArray.map((val) => `"${val}"`).join(", ")}`; + if (this.valueArray.length > 10) { + console.warn( + `Provided value ${toValidate} was not a valid option for enum type ${this.name}.\n${allowableValues}`, + ); + allowableValues = `See the developer console for allowable values.`; + } throw helpers.makeRuntimeErrorMsg( ctx, - `Argument ${argName} should be a ${ - this.name - } enum member.\nProvided value: "${toValidate}".\nAllowable values: ${this.valueArray - .map((val) => `"${val}"`) - .join(", ")}`, + `Argument ${argName} should be a ${this.name} enum member.\nProvided value: "${toValidate}".\n${allowableValues}`, ); } /** Provides case insensitivty and ignores spaces and dashes, and can always match the input */ diff --git a/src/utils/v1APIBreak.ts b/src/utils/v1APIBreak.ts index 0ed72a893..7e31a27cc 100644 --- a/src/utils/v1APIBreak.ts +++ b/src/utils/v1APIBreak.ts @@ -1,7 +1,6 @@ import { AugmentationName } from "@enums"; import { PlayerOwnedAugmentation } from "../Augmentation/PlayerOwnedAugmentation"; import { Player } from "@player"; -import { Script } from "../Script/Script"; import { GetAllServers } from "../Server/AllServers"; import { resolveTextFilePath } from "../Paths/TextFilePath"; import { resolveScriptFilePath } from "../Paths/ScriptFilePath"; @@ -137,7 +136,7 @@ export function v1APIBreak(): void { console.error(`Unexpected error resolving backup path for ${script.filename}`); continue; } - server.scripts.set(filename, new Script(filename, script.code, script.server)); + server.writeToScriptFile(filename, script.code); script.code = convert(script.code); } }