mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-24 07:02:26 +01:00
TYPESAFETY: Strict internal typing for AugmentationName (#608)
This commit is contained in:
parent
12b5c00d14
commit
a4b826683e
@ -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<string, Achievement> = {
|
||||
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: {
|
||||
|
@ -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}
|
||||
<br />+{f(mults.hacking - 1)} all skills
|
||||
</>
|
||||
);
|
||||
desc += `\n+${f(mults.hacking - 1)} all skills`;
|
||||
} else {
|
||||
if (mults.hacking !== 1)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{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}
|
||||
<br />+{f(mults.strength - 1)} combat skills
|
||||
</>
|
||||
);
|
||||
desc += `\n+${f(mults.strength - 1)} combat skills`;
|
||||
} else {
|
||||
if (mults.strength !== 1)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{f(mults.strength - 1)} strength skill
|
||||
</>
|
||||
);
|
||||
if (mults.defense !== 1)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{f(mults.defense - 1)} defense skill
|
||||
</>
|
||||
);
|
||||
if (mults.dexterity !== 1)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{f(mults.dexterity - 1)} dexterity skill
|
||||
</>
|
||||
);
|
||||
if (mults.agility !== 1)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{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}
|
||||
<br />+{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}
|
||||
<br />+{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}
|
||||
<br />+{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}
|
||||
<br />+{f(mults.strength_exp - 1)} combat exp
|
||||
</>
|
||||
);
|
||||
desc += `\n+${f(mults.strength_exp - 1)} combat exp`;
|
||||
} else {
|
||||
if (mults.strength_exp !== 1)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{f(mults.strength_exp - 1)} strength exp
|
||||
</>
|
||||
);
|
||||
if (mults.defense_exp !== 1)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{f(mults.defense_exp - 1)} defense exp
|
||||
</>
|
||||
);
|
||||
if (mults.dexterity_exp !== 1)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{f(mults.dexterity_exp - 1)} dexterity exp
|
||||
</>
|
||||
);
|
||||
if (mults.agility_exp !== 1)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{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}
|
||||
<br />+{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}
|
||||
<br />+{f(mults.hacking_speed - 1)} faster hack(), grow(), and weaken()
|
||||
</>
|
||||
);
|
||||
if (mults.hacking_chance !== 1)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{f(mults.hacking_chance - 1)} hack() success chance
|
||||
</>
|
||||
);
|
||||
if (mults.hacking_money !== 1)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{f(mults.hacking_money - 1)} hack() power
|
||||
</>
|
||||
);
|
||||
if (mults.hacking_grow !== 1)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{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}
|
||||
<br />+{f(mults.faction_rep - 1)} reputation from factions and companies
|
||||
</>
|
||||
);
|
||||
} else {
|
||||
if (mults.faction_rep !== 1)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{f(mults.faction_rep - 1)} reputation from factions
|
||||
</>
|
||||
);
|
||||
if (mults.company_rep !== 1)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{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}
|
||||
<br />+{f(mults.crime_money - 1)} crime money
|
||||
</>
|
||||
);
|
||||
if (mults.crime_success !== 1)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{f(mults.crime_success - 1)} crime success rate
|
||||
</>
|
||||
);
|
||||
if (mults.work_money !== 1)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{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}
|
||||
<br />+{f(mults.hacknet_node_money - 1)} hacknet production
|
||||
</>
|
||||
);
|
||||
if (mults.hacknet_node_purchase_cost !== 1)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />-{f(-(mults.hacknet_node_purchase_cost - 1))} hacknet nodes cost
|
||||
</>
|
||||
);
|
||||
if (mults.hacknet_node_level_cost !== 1)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />-{f(-(mults.hacknet_node_level_cost - 1))} hacknet nodes upgrade cost
|
||||
</>
|
||||
);
|
||||
|
||||
if (mults.bladeburner_max_stamina !== 1)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{f(mults.bladeburner_max_stamina - 1)} Bladeburner Max Stamina
|
||||
</>
|
||||
);
|
||||
if (mults.bladeburner_stamina_gain !== 1)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{f(mults.bladeburner_stamina_gain - 1)} Bladeburner Stamina gain
|
||||
</>
|
||||
);
|
||||
if (mults.bladeburner_analysis !== 1)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{f(mults.bladeburner_analysis - 1)} Bladeburner Field Analysis effectiveness
|
||||
</>
|
||||
);
|
||||
if (mults.bladeburner_success_chance !== 1)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />+{f(mults.bladeburner_success_chance - 1)} Bladeburner Contracts and Operations success chance
|
||||
</>
|
||||
);
|
||||
if (startingMoney)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />
|
||||
Start with <Money money={startingMoney} /> after installing Augmentations.
|
||||
</>
|
||||
);
|
||||
|
||||
if (programs)
|
||||
desc = (
|
||||
<>
|
||||
{desc}
|
||||
<br />
|
||||
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;
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
constructorsForReviver.Augmentation = Augmentation;
|
||||
|
@ -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 };
|
||||
}
|
||||
|
1917
src/Augmentation/Augmentations.ts
Normal file
1917
src/Augmentation/Augmentations.ts
Normal file
File diff suppressed because it is too large
Load Diff
119
src/Augmentation/CircadianModulator.ts
Normal file
119
src/Augmentation/CircadianModulator.ts
Normal file
@ -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<AugmentationCtorParams, "name"> {
|
||||
//Time-Based Augment Test
|
||||
const randomBonuses = getRandomBonus();
|
||||
|
||||
const UnstableCircadianModulatorParams: Omit<AugmentationCtorParams, "name"> = {
|
||||
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<Multipliers>;
|
||||
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())];
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +0,0 @@
|
||||
import { Augmentation } from "./Augmentation";
|
||||
|
||||
export const StaticAugmentations: Record<string, Augmentation> = {};
|
File diff suppressed because it is too large
Load Diff
@ -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 => {
|
||||
<Typography variant="h5" color={Settings.theme.info}>
|
||||
NeuroFlux Governor - Level {level}
|
||||
</Typography>
|
||||
<Typography color={Settings.theme.info}>
|
||||
{StaticAugmentations[AugmentationName.NeuroFluxGovernor].stats}
|
||||
</Typography>
|
||||
<Typography color={Settings.theme.info}>{Augmentations[AugmentationName.NeuroFluxGovernor].stats}</Typography>
|
||||
<Typography color={Settings.theme.info}>
|
||||
The power of {AugmentationName.NeuroFluxGovernor} increases with blood donations from players in real life.
|
||||
Learn more <Link onClick={openBloodDonation}>here</Link>
|
||||
|
@ -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 {
|
||||
</Typography>
|
||||
<Typography sx={{ maxHeight: 350, overflowY: "scroll" }}>
|
||||
{(() => {
|
||||
const aug = StaticAugmentations[selectedAug.name];
|
||||
const aug = Augmentations[selectedAug.name];
|
||||
|
||||
const info = typeof aug.info === "string" ? <span>{aug.info}</span> : aug.info;
|
||||
const tooltip = (
|
||||
|
@ -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",
|
||||
|
@ -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) => (
|
||||
<PurchasableAugmentation key={augName} parent={props} augName={augName} owned={false} />
|
||||
))}
|
||||
{props.ownedAugNames.map((augName: string) => (
|
||||
{props.ownedAugNames.map((augName) => (
|
||||
<PurchasableAugmentation key={augName} parent={props} augName={augName} owned={true} />
|
||||
))}
|
||||
</Container>
|
||||
@ -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" ? <span>{aug.info}</span> : aug.info;
|
||||
@ -209,8 +211,8 @@ export function PurchasableAugmentation(props: IPurchasableAugProps): React.Reac
|
||||
title={
|
||||
<>
|
||||
<Typography variant="h5">
|
||||
{props.augName}
|
||||
{props.augName === AugmentationName.NeuroFluxGovernor && ` - Level ${aug.getLevel()}`}
|
||||
{aug.name}
|
||||
{aug.name === AugmentationName.NeuroFluxGovernor && ` - Level ${augLevel + 1}`}
|
||||
</Typography>
|
||||
<Typography>{description}</Typography>
|
||||
</>
|
||||
@ -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}`}
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
|
||||
|
@ -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
|
||||
<br />
|
||||
<br />
|
||||
Would you like to purchase the {aug.name} Augmentation for
|
||||
<Money money={aug.getCost().moneyCost} />?
|
||||
<Money money={getAugCost(aug).moneyCost} />?
|
||||
<br />
|
||||
<br />
|
||||
</Typography>
|
||||
|
@ -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) {
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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<keyof BitNodeMultipliers, number> = {}) {
|
||||
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;
|
||||
}
|
||||
|
@ -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]) => (
|
||||
<StatsRow
|
||||
@ -101,7 +103,7 @@ const BNMultTable = (props: IBNMultTableProps): React.ReactElement => {
|
||||
|
||||
interface IMultsProps {
|
||||
n: number;
|
||||
mults: IBitNodeMultipliers;
|
||||
mults: BitNodeMultipliers;
|
||||
}
|
||||
|
||||
function GeneralMults({ mults }: IMultsProps): React.ReactElement {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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<string, Division>();
|
||||
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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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<string, Faction> = {};
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 &&
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -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 (
|
||||
<Tooltip
|
||||
|
@ -34,7 +34,7 @@ import { HacknetNode } from "../../Hacknet/HacknetNode";
|
||||
import { HacknetServer } from "../../Hacknet/HacknetServer";
|
||||
import { GetServer } from "../../Server/AllServers";
|
||||
import { ArcadeRoot } from "../../Arcade/ui/ArcadeRoot";
|
||||
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||
import { currentNodeMults } from "../../BitNode/BitNodeMultipliers";
|
||||
|
||||
interface SpecialLocationProps {
|
||||
loc: Location;
|
||||
@ -75,7 +75,7 @@ export function SpecialLocation(props: SpecialLocationProps): React.ReactElement
|
||||
}
|
||||
|
||||
function renderBladeburner(): React.ReactElement {
|
||||
if (!Player.canAccessBladeburner() || BitNodeMultipliers.BladeburnerRank === 0) {
|
||||
if (!Player.canAccessBladeburner() || currentNodeMults.BladeburnerRank === 0) {
|
||||
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 && <></>) || <CreateCorporation />;
|
||||
return (currentNodeMults.CorporationSoftcap < 0.15 && <></>) || <CreateCorporation />;
|
||||
}
|
||||
case LocationName.Sector12NSA: {
|
||||
return renderBladeburner();
|
||||
|
@ -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");
|
||||
|
@ -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<NSFull> = {
|
||||
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<NSFull> = {
|
||||
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<NSFull> = {
|
||||
},
|
||||
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<NSFull> = {
|
||||
});
|
||||
},
|
||||
getFavorToDonate: () => () => {
|
||||
return Math.floor(CONSTANTS.BaseFavorToDonate * BitNodeMultipliers.RepToDonateToFaction);
|
||||
return Math.floor(CONSTANTS.BaseFavorToDonate * currentNodeMults.RepToDonateToFaction);
|
||||
},
|
||||
getPlayer: () => () => {
|
||||
const data = {
|
||||
|
@ -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<INetscriptBladeburner> {
|
||||
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<INetscriptBladeburner> {
|
||||
},
|
||||
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) {
|
||||
|
@ -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<NSCorporation> {
|
||||
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) {
|
||||
|
@ -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<IGrafting> {
|
||||
const checkGraftingAPIAccess = (ctx: NetscriptContext): void => {
|
||||
@ -22,27 +23,26 @@ export function NetscriptGrafting(): InternalAPI<IGrafting> {
|
||||
}
|
||||
};
|
||||
|
||||
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<IGrafting> {
|
||||
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<IGrafting> {
|
||||
|
||||
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;
|
||||
|
@ -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<ISingularity> {
|
||||
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<ISingularity> {
|
||||
},
|
||||
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<ISingularity> {
|
||||
}
|
||||
}
|
||||
|
||||
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<ISingularity> {
|
||||
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,
|
||||
|
@ -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<NetscriptSleeve> {
|
||||
const checkSleeveAPIAccess = function (ctx: NetscriptContext) {
|
||||
@ -198,7 +199,7 @@ export function NetscriptSleeve(): InternalAPI<NetscriptSleeve> {
|
||||
},
|
||||
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<NetscriptSleeve> {
|
||||
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<NetscriptSleeve> {
|
||||
},
|
||||
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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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<string, GraftableAugmentation> => {
|
||||
const gAugs: Record<string, GraftableAugmentation> = {};
|
||||
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:
|
||||
|
@ -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);
|
||||
|
@ -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 }[];
|
||||
|
@ -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)}`;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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<CompletedProgramName, Program> = {
|
||||
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) {
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
);
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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();
|
||||
|
@ -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 (
|
||||
<Container maxWidth="lg" disableGutters sx={{ mx: 0 }}>
|
||||
<Typography variant="h4">Stats</Typography>
|
||||
@ -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 && (
|
||||
<MultiplierTable
|
||||
rows={[
|
||||
{
|
||||
|
@ -24,7 +24,7 @@ interface IProps {
|
||||
|
||||
export function AugmentationAccordion(props: IProps): React.ReactElement {
|
||||
const [open, setOpen] = useState(false);
|
||||
let displayName = props.aug.name;
|
||||
let displayName: string = props.aug.name;
|
||||
if (props.level != null) {
|
||||
if (props.aug.name === AugmentationName.NeuroFluxGovernor) {
|
||||
displayName += ` - Level ${props.level}`;
|
||||
|
@ -24,7 +24,7 @@ import { Router } from "../GameRoot";
|
||||
import { Page } from "../Router";
|
||||
import { Player } from "@player";
|
||||
import { StatsProgressOverviewCell } from "./StatsProgressBar";
|
||||
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||
import { currentNodeMults } from "../../BitNode/BitNodeMultipliers";
|
||||
|
||||
import { Box, Tooltip } from "@mui/material";
|
||||
|
||||
@ -73,12 +73,12 @@ const formattedVals: Record<RowName, () => string> = {
|
||||
|
||||
const skillMultUpdaters: Record<SkillRowName, () => 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,
|
||||
};
|
||||
|
||||
|
@ -28,13 +28,17 @@ class EnumHelper<EnumObj extends object, EnumMember extends Member<EnumObj> & 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 */
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user