Merge branch 'dev' into FIX#3366

This commit is contained in:
hydroflame
2022-07-21 16:17:08 -04:00
committed by GitHub
365 changed files with 11259 additions and 11460 deletions
@@ -1,52 +1,47 @@
import { IMap } from "../../types";
import { CONSTANTS } from "../../Constants";
import { IPlayer } from "../IPlayer";
import { Multipliers } from "../Multipliers";
export const calculateEntropy = (player: IPlayer, stacks = 1): IMap<number> => {
const multipliers: IMap<number> = {
hacking_chance_mult: player.hacking_chance_mult,
hacking_speed_mult: player.hacking_speed_mult,
hacking_money_mult: player.hacking_money_mult,
hacking_grow_mult: player.hacking_grow_mult,
export const calculateEntropy = (player: IPlayer, stacks = 1): Multipliers => {
const nerf = CONSTANTS.EntropyEffect ** stacks;
return {
hacking_chance: player.mults.hacking_chance * nerf,
hacking_speed: player.mults.hacking_speed * nerf,
hacking_money: player.mults.hacking_money * nerf,
hacking_grow: player.mults.hacking_grow * nerf,
hacking_mult: player.hacking_mult,
strength_mult: player.strength_mult,
defense_mult: player.defense_mult,
dexterity_mult: player.dexterity_mult,
agility_mult: player.agility_mult,
charisma_mult: player.charisma_mult,
hacking: player.mults.hacking * nerf,
strength: player.mults.strength * nerf,
defense: player.mults.defense * nerf,
dexterity: player.mults.dexterity * nerf,
agility: player.mults.agility * nerf,
charisma: player.mults.charisma * nerf,
hacking_exp_mult: player.hacking_exp_mult,
strength_exp_mult: player.strength_exp_mult,
defense_exp_mult: player.defense_exp_mult,
dexterity_exp_mult: player.dexterity_exp_mult,
agility_exp_mult: player.agility_exp_mult,
charisma_exp_mult: player.charisma_exp_mult,
hacking_exp: player.mults.hacking_exp * nerf,
strength_exp: player.mults.strength_exp * nerf,
defense_exp: player.mults.defense_exp * nerf,
dexterity_exp: player.mults.dexterity_exp * nerf,
agility_exp: player.mults.agility_exp * nerf,
charisma_exp: player.mults.charisma_exp * nerf,
company_rep_mult: player.company_rep_mult,
faction_rep_mult: player.faction_rep_mult,
company_rep: player.mults.company_rep * nerf,
faction_rep: player.mults.faction_rep * nerf,
crime_money_mult: player.crime_money_mult,
crime_success_mult: player.crime_success_mult,
crime_money: player.mults.crime_money * nerf,
crime_success: player.mults.crime_success * nerf,
hacknet_node_money_mult: player.hacknet_node_money_mult,
hacknet_node_purchase_cost_mult: player.hacknet_node_purchase_cost_mult,
hacknet_node_ram_cost_mult: player.hacknet_node_ram_cost_mult,
hacknet_node_core_cost_mult: player.hacknet_node_core_cost_mult,
hacknet_node_level_cost_mult: player.hacknet_node_level_cost_mult,
hacknet_node_money: player.mults.hacknet_node_money * nerf,
hacknet_node_purchase_cost: player.mults.hacknet_node_purchase_cost * nerf,
hacknet_node_ram_cost: player.mults.hacknet_node_ram_cost * nerf,
hacknet_node_core_cost: player.mults.hacknet_node_core_cost * nerf,
hacknet_node_level_cost: player.mults.hacknet_node_level_cost * nerf,
work_money_mult: player.work_money_mult,
work_money: player.mults.work_money * nerf,
bladeburner_max_stamina_mult: player.bladeburner_max_stamina_mult,
bladeburner_stamina_gain_mult: player.bladeburner_stamina_gain_mult,
bladeburner_analysis_mult: player.bladeburner_analysis_mult,
bladeburner_success_chance_mult: player.bladeburner_success_chance_mult,
bladeburner_max_stamina: player.mults.bladeburner_max_stamina * nerf,
bladeburner_stamina_gain: player.mults.bladeburner_stamina_gain * nerf,
bladeburner_analysis: player.mults.bladeburner_analysis * nerf,
bladeburner_success_chance: player.mults.bladeburner_success_chance * nerf,
};
for (const [mult, val] of Object.entries(multipliers)) {
multipliers[mult] = val * CONSTANTS.EntropyEffect ** stacks;
}
return multipliers;
};
@@ -1,6 +1,7 @@
import { CheckBox, CheckBoxOutlineBlank, Construction } from "@mui/icons-material";
import { Box, Button, Container, List, ListItemButton, Paper, Typography } from "@mui/material";
import React, { useEffect, useState } from "react";
import { GraftingWork } from "../../../Work/GraftingWork";
import { Augmentation } from "../../../Augmentation/Augmentation";
import { AugmentationNames } from "../../../Augmentation/data/AugmentationNames";
import { StaticAugmentations } from "../../../Augmentation/StaticAugmentations";
@@ -19,7 +20,7 @@ import { IPlayer } from "../../IPlayer";
import { GraftableAugmentation } from "../GraftableAugmentation";
import { calculateGraftingTimeWithBonus, getGraftingAvailableAugs } from "../GraftingHelpers";
const GraftableAugmentations: IMap<GraftableAugmentation> = {};
export const GraftableAugmentations: IMap<GraftableAugmentation> = {};
const canGraft = (player: IPlayer, aug: GraftableAugmentation): boolean => {
if (player.money < aug.cost) {
@@ -154,9 +155,13 @@ export const GraftingRoot = (): React.ReactElement => {
open={graftOpen}
onClose={() => setGraftOpen(false)}
onConfirm={() => {
const graftableAug = GraftableAugmentations[selectedAug];
player.loseMoney(graftableAug.cost, "augmentations");
player.startGraftAugmentationWork(selectedAug, graftableAug.time);
player.startWork(
new GraftingWork({
augmentation: selectedAug,
singularity: false,
player: player,
}),
);
player.startFocusing();
router.toWork();
}}
+2 -21
View File
@@ -3,6 +3,7 @@
import { IPlayerOwnedAugmentation } from "../Augmentation/PlayerOwnedAugmentation";
import { ITaskTracker } from "./ITaskTracker";
import { Multipliers } from "./Multipliers";
export interface IPerson {
// Stats
@@ -25,27 +26,7 @@ export interface IPerson {
charisma_exp: number;
intelligence_exp: number;
// Multipliers
hacking_exp_mult: number;
strength_exp_mult: number;
defense_exp_mult: number;
dexterity_exp_mult: number;
agility_exp_mult: number;
charisma_exp_mult: number;
hacking_mult: number;
strength_mult: number;
defense_mult: number;
dexterity_mult: number;
agility_mult: number;
charisma_mult: number;
company_rep_mult: number;
faction_rep_mult: number;
crime_money_mult: number;
crime_success_mult: number;
bladeburner_analysis_mult: number;
mults: Multipliers;
augmentations: IPlayerOwnedAugmentation[];
+11 -124
View File
@@ -25,18 +25,16 @@ import { ICorporation } from "../Corporation/ICorporation";
import { IGang } from "../Gang/IGang";
import { IBladeburner } from "../Bladeburner/IBladeburner";
import { ICodingContractReward } from "../CodingContracts";
import { IRouter } from "../ui/Router";
import { WorkerScript } from "../Netscript/WorkerScript";
import { HacknetServer } from "../Hacknet/HacknetServer";
import { ISkillProgress } from "./formulas/skill";
import { PlayerAchievement } from "../Achievements/Achievements";
import { IPerson } from "./IPerson";
import { WorkType, ClassType, CrimeType } from "../utils/WorkType";
import { Work } from "../Work/Work";
import { Multipliers } from "./Multipliers";
export interface IPlayer extends IPerson {
bitNodeN: number;
city: CityName;
companyName: string;
corporation: ICorporation | null;
gang: IGang | null;
bladeburner: IBladeburner | null;
@@ -51,8 +49,6 @@ export interface IPlayer extends IPerson {
hasWseAccount: boolean;
hp: number;
jobs: IMap<string>;
init: () => void;
isWorking: boolean;
karma: number;
numPeopleKilled: number;
location: LocationName;
@@ -62,7 +58,7 @@ export interface IPlayer extends IPerson {
moneySourceB: MoneySourceTracker;
playtimeSinceLastAug: number;
playtimeSinceLastBitnode: number;
purchasedServers: any[];
purchasedServers: string[];
queuedAugmentations: IPlayerOwnedAugmentation[];
scriptProdSinceLastAug: number;
sleeves: Sleeve[];
@@ -92,80 +88,18 @@ export interface IPlayer extends IPerson {
charisma_exp: number;
intelligence_exp: number;
// Multipliers
hacking_chance_mult: number;
hacking_speed_mult: number;
hacking_money_mult: number;
hacking_grow_mult: number;
hacking_mult: number;
hacking_exp_mult: number;
strength_mult: number;
strength_exp_mult: number;
defense_mult: number;
defense_exp_mult: number;
dexterity_mult: number;
dexterity_exp_mult: number;
agility_mult: number;
agility_exp_mult: number;
charisma_mult: number;
charisma_exp_mult: number;
hacknet_node_money_mult: number;
hacknet_node_purchase_cost_mult: number;
hacknet_node_ram_cost_mult: number;
hacknet_node_core_cost_mult: number;
hacknet_node_level_cost_mult: number;
company_rep_mult: number;
faction_rep_mult: number;
work_money_mult: number;
crime_success_mult: number;
crime_money_mult: number;
bladeburner_max_stamina_mult: number;
bladeburner_stamina_gain_mult: number;
bladeburner_analysis_mult: number;
bladeburner_success_chance_mult: number;
mults: Multipliers;
createProgramReqLvl: number;
factionWorkType: string;
createProgramName: string;
timeWorkedCreateProgram: number;
graftAugmentationName: string;
timeWorkedGraftAugmentation: number;
crimeType: CrimeType;
committingCrimeThruSingFn: boolean;
singFnCrimeWorkerScript: WorkerScript | null;
timeNeededToCompleteWork: number;
currentWork: Work | null;
focus: boolean;
className: ClassType;
currentWorkFactionName: string;
workType: WorkType;
workCostMult: number;
workExpMult: number;
currentWorkFactionDescription: string;
timeWorked: number;
workMoneyGained: number;
workMoneyGainRate: number;
workRepGained: number;
workRepGainRate: number;
workHackExpGained: number;
workHackExpGainRate: number;
workStrExpGained: number;
workStrExpGainRate: number;
workDefExpGained: number;
workDefExpGainRate: number;
workDexExpGained: number;
workDexExpGainRate: number;
workAgiExpGained: number;
workAgiExpGainRate: number;
workChaExpGained: number;
workChaExpGainRate: number;
workMoneyLossRate: number;
entropy: number;
// Methods
work(numCycles: number): boolean;
workPartTime(numCycles: number): boolean;
workForFaction(numCycles: number): boolean;
init: () => void;
startWork(w: Work): void;
processWork(cycles: number): void;
finishWork(cancelled: boolean): void;
applyForAgentJob(sing?: boolean): boolean;
applyForBusinessConsultantJob(sing?: boolean): boolean;
applyForBusinessJob(sing?: boolean): boolean;
@@ -204,35 +138,13 @@ export interface IPlayer extends IPerson {
isAwareOfGang(): boolean;
isQualified(company: Company, position: CompanyPosition): boolean;
loseMoney(money: number, source: string): void;
process(router: IRouter, numCycles?: number): void;
reapplyAllAugmentations(resetMultipliers?: boolean): void;
reapplyAllSourceFiles(): void;
setMoney(amt: number): void;
singularityStopWork(): string;
startBladeburner(p: any): void;
startFactionWork(faction: Faction): void;
startClass(costMult: number, expMult: number, className: ClassType): void;
startBladeburner(): void;
startCorporation(corpName: string, additionalShares?: number): void;
startCrime(
router: IRouter,
crimeType: CrimeType,
hackExp: number,
strExp: number,
defExp: number,
dexExp: number,
agiExp: number,
chaExp: number,
money: number,
time: number,
singParams: any,
): void;
startFactionFieldWork(faction: Faction): void;
startFactionHackWork(faction: Faction): void;
startFactionSecurityWork(faction: Faction): void;
startFocusing(): void;
startGang(facName: string, isHacking: boolean): void;
startWork(companyName: string): void;
startWorkPartTime(companyName: string): void;
travel(to: CityName): boolean;
giveExploit(exploit: Exploit): void;
giveAchievement(achievementId: string): void;
@@ -240,45 +152,20 @@ export interface IPlayer extends IPerson {
quitJob(company: string, sing?: boolean): void;
hasJob(): boolean;
createHacknetServer(): HacknetServer;
startCreateProgramWork(programName: string, time: number, reqLevel: number): void;
queueAugmentation(augmentationName: string): void;
receiveInvite(factionName: string): void;
updateSkillLevels(): void;
gainCodingContractReward(reward: ICodingContractReward, difficulty?: number): string;
stopFocusing(): void;
finishFactionWork(cancelled: boolean, sing?: boolean): string;
finishClass(sing?: boolean): string;
finishWork(cancelled: boolean, sing?: boolean): string;
cancelationPenalty(): number;
finishWorkPartTime(sing?: boolean): string;
finishCrime(cancelled: boolean): string;
finishCreateProgramWork(cancelled: boolean): string;
resetMultipliers(): void;
prestigeAugmentation(): void;
prestigeSourceFile(): void;
calculateSkillProgress(exp: number, mult?: number): ISkillProgress;
resetWorkStatus(generalType?: WorkType, group?: string, workType?: string): void;
getWorkHackExpGain(): number;
getWorkStrExpGain(): number;
getWorkDefExpGain(): number;
getWorkDexExpGain(): number;
getWorkAgiExpGain(): number;
getWorkChaExpGain(): number;
getWorkRepGain(): number;
getWorkMoneyGain(): number;
processWorkEarnings(cycles: number): void;
hospitalize(): void;
createProgramWork(numCycles: number): boolean;
takeClass(numCycles: number): boolean;
commitCrime(numCycles: number): boolean;
checkForFactionInvitations(): Faction[];
setBitNodeNumber(n: number): void;
getMult(name: string): number;
setMult(name: string, mult: number): void;
canAccessCotMG(): boolean;
sourceFileLvl(n: number): number;
startGraftAugmentationWork(augmentationName: string, time: number): void;
graftAugmentationWork(numCycles: number): boolean;
finishGraftAugmentationWork(cancelled: boolean, singularity?: boolean): string;
applyEntropy(stacks?: number): void;
focusPenalty(): number;
}
+104
View File
@@ -0,0 +1,104 @@
import { AugmentationStats } from "../ScriptEditor/NetscriptDefinitions";
export interface Multipliers {
hacking_chance: number;
hacking_speed: number;
hacking_money: number;
hacking_grow: number;
hacking: number;
hacking_exp: number;
strength: number;
strength_exp: number;
defense: number;
defense_exp: number;
dexterity: number;
dexterity_exp: number;
agility: number;
agility_exp: number;
charisma: number;
charisma_exp: number;
hacknet_node_money: number;
hacknet_node_purchase_cost: number;
hacknet_node_ram_cost: number;
hacknet_node_core_cost: number;
hacknet_node_level_cost: number;
company_rep: number;
faction_rep: number;
work_money: number;
crime_success: number;
crime_money: number;
bladeburner_max_stamina: number;
bladeburner_stamina_gain: number;
bladeburner_analysis: number;
bladeburner_success_chance: number;
}
export const defaultMultipliers = (): Multipliers => {
return {
hacking_chance: 1,
hacking_speed: 1,
hacking_money: 1,
hacking_grow: 1,
hacking: 1,
hacking_exp: 1,
strength: 1,
strength_exp: 1,
defense: 1,
defense_exp: 1,
dexterity: 1,
dexterity_exp: 1,
agility: 1,
agility_exp: 1,
charisma: 1,
charisma_exp: 1,
hacknet_node_money: 1,
hacknet_node_purchase_cost: 1,
hacknet_node_ram_cost: 1,
hacknet_node_core_cost: 1,
hacknet_node_level_cost: 1,
company_rep: 1,
faction_rep: 1,
work_money: 1,
crime_success: 1,
crime_money: 1,
bladeburner_max_stamina: 1,
bladeburner_stamina_gain: 1,
bladeburner_analysis: 1,
bladeburner_success_chance: 1,
};
};
export const mergeMultipliers = (m0: Multipliers, m1: AugmentationStats): Multipliers => {
return {
hacking_chance: m0.hacking_chance * (m1.hacking_chance ?? 1),
hacking_speed: m0.hacking_speed * (m1.hacking_speed ?? 1),
hacking_money: m0.hacking_money * (m1.hacking_money ?? 1),
hacking_grow: m0.hacking_grow * (m1.hacking_grow ?? 1),
hacking: m0.hacking * (m1.hacking ?? 1),
hacking_exp: m0.hacking_exp * (m1.hacking_exp ?? 1),
strength: m0.strength * (m1.strength ?? 1),
strength_exp: m0.strength_exp * (m1.strength_exp ?? 1),
defense: m0.defense * (m1.defense ?? 1),
defense_exp: m0.defense_exp * (m1.defense_exp ?? 1),
dexterity: m0.dexterity * (m1.dexterity ?? 1),
dexterity_exp: m0.dexterity_exp * (m1.dexterity_exp ?? 1),
agility: m0.agility * (m1.agility ?? 1),
agility_exp: m0.agility_exp * (m1.agility_exp ?? 1),
charisma: m0.charisma * (m1.charisma ?? 1),
charisma_exp: m0.charisma_exp * (m1.charisma_exp ?? 1),
hacknet_node_money: m0.hacknet_node_money * (m1.hacknet_node_money ?? 1),
hacknet_node_purchase_cost: m0.hacknet_node_purchase_cost * (m1.hacknet_node_purchase_cost ?? 1),
hacknet_node_ram_cost: m0.hacknet_node_ram_cost * (m1.hacknet_node_ram_cost ?? 1),
hacknet_node_core_cost: m0.hacknet_node_core_cost * (m1.hacknet_node_core_cost ?? 1),
hacknet_node_level_cost: m0.hacknet_node_level_cost * (m1.hacknet_node_level_cost ?? 1),
company_rep: m0.company_rep * (m1.company_rep ?? 1),
faction_rep: m0.faction_rep * (m1.faction_rep ?? 1),
work_money: m0.work_money * (m1.work_money ?? 1),
crime_success: m0.crime_success * (m1.crime_success ?? 1),
crime_money: m0.crime_money * (m1.crime_money ?? 1),
bladeburner_max_stamina: m0.bladeburner_max_stamina * (m1.bladeburner_max_stamina ?? 1),
bladeburner_stamina_gain: m0.bladeburner_stamina_gain * (m1.bladeburner_stamina_gain ?? 1),
bladeburner_analysis: m0.bladeburner_analysis * (m1.bladeburner_analysis ?? 1),
bladeburner_success_chance: m0.bladeburner_success_chance * (m1.bladeburner_success_chance ?? 1),
};
};
+13 -88
View File
@@ -7,6 +7,7 @@ import { CONSTANTS } from "../Constants";
import { calculateSkill } from "./formulas/skill";
import { calculateIntelligenceBonus } from "./formulas/intelligence";
import { IPerson } from "./IPerson";
import { defaultMultipliers, mergeMultipliers } from "./Multipliers";
// Base class representing a person-like object
export abstract class Person implements IPerson {
@@ -34,46 +35,7 @@ export abstract class Person implements IPerson {
charisma_exp = 0;
intelligence_exp = 0;
/**
* Multipliers
*/
hacking_mult = 1;
strength_mult = 1;
defense_mult = 1;
dexterity_mult = 1;
agility_mult = 1;
charisma_mult = 1;
hacking_exp_mult = 1;
strength_exp_mult = 1;
defense_exp_mult = 1;
dexterity_exp_mult = 1;
agility_exp_mult = 1;
charisma_exp_mult = 1;
hacking_chance_mult = 1;
hacking_speed_mult = 1;
hacking_money_mult = 1;
hacking_grow_mult = 1;
company_rep_mult = 1;
faction_rep_mult = 1;
crime_money_mult = 1;
crime_success_mult = 1;
work_money_mult = 1;
hacknet_node_money_mult = 1;
hacknet_node_purchase_cost_mult = 1;
hacknet_node_ram_cost_mult = 1;
hacknet_node_core_cost_mult = 1;
hacknet_node_level_cost_mult = 1;
bladeburner_max_stamina_mult = 1;
bladeburner_stamina_gain_mult = 1;
bladeburner_analysis_mult = 1;
bladeburner_success_chance_mult = 1;
mults = defaultMultipliers();
/**
* Augmentations
@@ -101,13 +63,7 @@ export abstract class Person implements IPerson {
* Updates this object's multipliers for the given augmentation
*/
applyAugmentation(aug: Augmentation): void {
for (const mult of Object.keys(aug.mults)) {
if ((this as any)[mult] == null) {
console.warn(`Augmentation has unrecognized multiplier property: ${mult}`);
} else {
(this as any)[mult] *= aug.mults[mult];
}
}
this.mults = mergeMultipliers(this.mults, aug.mults);
}
/**
@@ -132,7 +88,7 @@ export abstract class Person implements IPerson {
this.agility / CONSTANTS.MaxSkillLevel +
this.charisma / CONSTANTS.MaxSkillLevel)) /
5.5;
return t * this.faction_rep_mult;
return t * this.mults.faction_rep;
}
/**
@@ -140,7 +96,7 @@ export abstract class Person implements IPerson {
* when doing Hacking Work for a faction
*/
getFactionHackingWorkRepGain(): number {
return (this.hacking / CONSTANTS.MaxSkillLevel) * this.faction_rep_mult;
return (this.hacking / CONSTANTS.MaxSkillLevel) * this.mults.faction_rep;
}
/**
@@ -156,45 +112,14 @@ export abstract class Person implements IPerson {
this.dexterity / CONSTANTS.MaxSkillLevel +
this.agility / CONSTANTS.MaxSkillLevel)) /
4.5;
return t * this.faction_rep_mult;
return t * this.mults.faction_rep;
}
/**
* Reset all multipliers to 1
*/
resetMultipliers(): void {
this.hacking_mult = 1;
this.strength_mult = 1;
this.defense_mult = 1;
this.dexterity_mult = 1;
this.agility_mult = 1;
this.charisma_mult = 1;
this.hacking_exp_mult = 1;
this.strength_exp_mult = 1;
this.defense_exp_mult = 1;
this.dexterity_exp_mult = 1;
this.agility_exp_mult = 1;
this.charisma_exp_mult = 1;
this.company_rep_mult = 1;
this.faction_rep_mult = 1;
this.crime_money_mult = 1;
this.crime_success_mult = 1;
this.work_money_mult = 1;
this.hacknet_node_money_mult = 1;
this.hacknet_node_purchase_cost_mult = 1;
this.hacknet_node_ram_cost_mult = 1;
this.hacknet_node_core_cost_mult = 1;
this.hacknet_node_level_cost_mult = 1;
this.bladeburner_max_stamina_mult = 1;
this.bladeburner_stamina_gain_mult = 1;
this.bladeburner_analysis_mult = 1;
this.bladeburner_success_chance_mult = 1;
this.mults = defaultMultipliers();
}
/**
@@ -203,32 +128,32 @@ export abstract class Person implements IPerson {
updateStatLevels(): void {
this.hacking = Math.max(
1,
Math.floor(this.calculateStat(this.hacking_exp, this.hacking_mult * BitNodeMultipliers.HackingLevelMultiplier)),
Math.floor(this.calculateStat(this.hacking_exp, this.mults.hacking * BitNodeMultipliers.HackingLevelMultiplier)),
);
this.strength = Math.max(
1,
Math.floor(
this.calculateStat(this.strength_exp, this.strength_mult * BitNodeMultipliers.StrengthLevelMultiplier),
this.calculateStat(this.strength_exp, this.mults.strength * BitNodeMultipliers.StrengthLevelMultiplier),
),
);
this.defense = Math.max(
1,
Math.floor(this.calculateStat(this.defense_exp, this.defense_mult * BitNodeMultipliers.DefenseLevelMultiplier)),
Math.floor(this.calculateStat(this.defense_exp, this.mults.defense * BitNodeMultipliers.DefenseLevelMultiplier)),
);
this.dexterity = Math.max(
1,
Math.floor(
this.calculateStat(this.dexterity_exp, this.dexterity_mult * BitNodeMultipliers.DexterityLevelMultiplier),
this.calculateStat(this.dexterity_exp, this.mults.dexterity * BitNodeMultipliers.DexterityLevelMultiplier),
),
);
this.agility = Math.max(
1,
Math.floor(this.calculateStat(this.agility_exp, this.agility_mult * BitNodeMultipliers.AgilityLevelMultiplier)),
Math.floor(this.calculateStat(this.agility_exp, this.mults.agility * BitNodeMultipliers.AgilityLevelMultiplier)),
);
this.charisma = Math.max(
1,
Math.floor(
this.calculateStat(this.charisma_exp, this.charisma_mult * BitNodeMultipliers.CharismaLevelMultiplier),
this.calculateStat(this.charisma_exp, this.mults.charisma * BitNodeMultipliers.CharismaLevelMultiplier),
),
);
+22 -254
View File
@@ -4,12 +4,12 @@ import * as corporationMethods from "./PlayerObjectCorporationMethods";
import * as gangMethods from "./PlayerObjectGangMethods";
import * as generalMethods from "./PlayerObjectGeneralMethods";
import * as serverMethods from "./PlayerObjectServerMethods";
import * as workMethods from "./PlayerObjectWorkMethods";
import { IMap } from "../../types";
import { Sleeve } from "../Sleeve/Sleeve";
import { IPlayerOwnedSourceFile } from "../../SourceFile/PlayerOwnedSourceFile";
import { Exploit } from "../../Exploits/Exploit";
import { WorkerScript } from "../../Netscript/WorkerScript";
import { CompanyPosition } from "../../Company/CompanyPosition";
import { Server } from "../../Server/Server";
import { BaseServer } from "../../Server/BaseServer";
@@ -17,7 +17,6 @@ import { HacknetServer } from "../../Hacknet/HacknetServer";
import { Faction } from "../../Faction/Faction";
import { Company } from "../../Company/Company";
import { Augmentation } from "../../Augmentation/Augmentation";
import { IRouter } from "../../ui/Router";
import { ICodingContractReward } from "../../CodingContracts";
import { IPlayer } from "../IPlayer";
@@ -32,21 +31,21 @@ import { HashManager } from "../../Hacknet/HashManager";
import { CityName } from "../../Locations/data/CityNames";
import { MoneySourceTracker } from "../../utils/MoneySourceTracker";
import { Reviver, Generic_toJSON, Generic_fromJSON } from "../../utils/JSONReviver";
import { Reviver, Generic_toJSON, Generic_fromJSON, IReviverValue } from "../../utils/JSONReviver";
import { ISkillProgress } from "../formulas/skill";
import { PlayerAchievement } from "../../Achievements/Achievements";
import { cyrb53 } from "../../utils/StringHelperFunctions";
import { getRandomInt } from "../../utils/helpers/getRandomInt";
import { ITaskTracker } from "../ITaskTracker";
import { CONSTANTS } from "../../Constants";
import { WorkType, ClassType, CrimeType, PlayerFactionWorkType } from "../../utils/WorkType";
import { Work } from "src/Work/Work";
import { defaultMultipliers, Multipliers } from "../Multipliers";
export class PlayerObject implements IPlayer {
// Class members
augmentations: IPlayerOwnedAugmentation[];
bitNodeN: number;
city: CityName;
companyName: string;
corporation: ICorporation | null;
gang: IGang | null;
bladeburner: IBladeburner | null;
@@ -62,7 +61,6 @@ export class PlayerObject implements IPlayer {
hp: number;
jobs: IMap<string>;
init: () => void;
isWorking: boolean;
karma: number;
numPeopleKilled: number;
location: LocationName;
@@ -72,7 +70,7 @@ export class PlayerObject implements IPlayer {
moneySourceB: MoneySourceTracker;
playtimeSinceLastAug: number;
playtimeSinceLastBitnode: number;
purchasedServers: any[];
purchasedServers: string[];
queuedAugmentations: IPlayerOwnedAugmentation[];
scriptProdSinceLastAug: number;
sleeves: Sleeve[];
@@ -104,80 +102,17 @@ export class PlayerObject implements IPlayer {
charisma_exp: number;
intelligence_exp: number;
// Multipliers
hacking_chance_mult: number;
hacking_speed_mult: number;
hacking_money_mult: number;
hacking_grow_mult: number;
hacking_mult: number;
hacking_exp_mult: number;
strength_mult: number;
strength_exp_mult: number;
defense_mult: number;
defense_exp_mult: number;
dexterity_mult: number;
dexterity_exp_mult: number;
agility_mult: number;
agility_exp_mult: number;
charisma_mult: number;
charisma_exp_mult: number;
hacknet_node_money_mult: number;
hacknet_node_purchase_cost_mult: number;
hacknet_node_ram_cost_mult: number;
hacknet_node_core_cost_mult: number;
hacknet_node_level_cost_mult: number;
company_rep_mult: number;
faction_rep_mult: number;
work_money_mult: number;
crime_success_mult: number;
crime_money_mult: number;
bladeburner_max_stamina_mult: number;
bladeburner_stamina_gain_mult: number;
bladeburner_analysis_mult: number;
bladeburner_success_chance_mult: number;
mults: Multipliers;
createProgramReqLvl: number;
factionWorkType: PlayerFactionWorkType;
createProgramName: string;
timeWorkedCreateProgram: number;
graftAugmentationName: string;
timeWorkedGraftAugmentation: number;
crimeType: CrimeType;
committingCrimeThruSingFn: boolean;
singFnCrimeWorkerScript: WorkerScript | null;
timeNeededToCompleteWork: number;
currentWork: Work | null;
focus: boolean;
className: ClassType;
currentWorkFactionName: string;
workType: WorkType;
workCostMult: number;
workExpMult: number;
currentWorkFactionDescription: string;
timeWorked: number;
workMoneyGained: number;
workMoneyGainRate: number;
workRepGained: number;
workRepGainRate: number;
workHackExpGained: number;
workHackExpGainRate: number;
workStrExpGained: number;
workStrExpGainRate: number;
workDefExpGained: number;
workDefExpGainRate: number;
workDexExpGained: number;
workDexExpGainRate: number;
workAgiExpGained: number;
workAgiExpGainRate: number;
workChaExpGained: number;
workChaExpGainRate: number;
workMoneyLossRate: number;
entropy: number;
// Methods
work: (numCycles: number) => boolean;
workPartTime: (numCycles: number) => boolean;
workForFaction: (numCycles: number) => boolean;
startWork: (w: Work) => void;
processWork: (cycles: number) => void;
finishWork: (cancelled: boolean) => void;
applyForAgentJob: (sing?: boolean) => boolean;
applyForBusinessConsultantJob: (sing?: boolean) => boolean;
applyForBusinessJob: (sing?: boolean) => boolean;
@@ -229,31 +164,10 @@ export class PlayerObject implements IPlayer {
regenerateHp: (amt: number) => void;
recordMoneySource: (amt: number, source: string) => void;
setMoney: (amt: number) => void;
singularityStopWork: () => string;
startBladeburner: (p: any) => void;
startFactionWork: (faction: Faction) => void;
startClass: (costMult: number, expMult: number, className: ClassType) => void;
startBladeburner: () => void;
startCorporation: (corpName: string, additionalShares?: number) => void;
startCrime: (
router: IRouter,
crimeType: CrimeType,
hackExp: number,
strExp: number,
defExp: number,
dexExp: number,
agiExp: number,
chaExp: number,
money: number,
time: number,
singParams: any,
) => void;
startFactionFieldWork: (faction: Faction) => void;
startFactionHackWork: (faction: Faction) => void;
startFactionSecurityWork: (faction: Faction) => void;
startFocusing: () => void;
startGang: (facName: string, isHacking: boolean) => void;
startWork: (companyName: string) => void;
startWorkPartTime: (companyName: string) => void;
takeDamage: (amt: number) => boolean;
travel: (to: CityName) => boolean;
giveExploit: (exploit: Exploit) => void;
@@ -263,50 +177,24 @@ export class PlayerObject implements IPlayer {
getCasinoWinnings: () => number;
quitJob: (company: string, sing?: boolean) => void;
hasJob: () => boolean;
process: (router: IRouter, numCycles?: number) => void;
createHacknetServer: () => HacknetServer;
startCreateProgramWork: (programName: string, time: number, reqLevel: number) => void;
queueAugmentation: (augmentationName: string) => void;
receiveInvite: (factionName: string) => void;
updateSkillLevels: () => void;
gainCodingContractReward: (reward: ICodingContractReward, difficulty?: number) => string;
stopFocusing: () => void;
finishFactionWork: (cancelled: boolean, sing?: boolean) => string;
finishClass: (sing?: boolean) => string;
finishWork: (cancelled: boolean, sing?: boolean) => string;
cancelationPenalty: () => number;
finishWorkPartTime: (sing?: boolean) => string;
finishCrime: (cancelled: boolean) => string;
finishCreateProgramWork: (cancelled: boolean) => string;
resetMultipliers: () => void;
prestigeAugmentation: () => void;
prestigeSourceFile: () => void;
calculateSkill: (exp: number, mult?: number) => number;
calculateSkillProgress: (exp: number, mult?: number) => ISkillProgress;
resetWorkStatus: (generalType?: WorkType, group?: string, workType?: string) => void;
getWorkHackExpGain: () => number;
getWorkStrExpGain: () => number;
getWorkDefExpGain: () => number;
getWorkDexExpGain: () => number;
getWorkAgiExpGain: () => number;
getWorkChaExpGain: () => number;
getWorkRepGain: () => number;
getWorkMoneyGain: () => number;
processWorkEarnings: (cycles: number) => void;
hospitalize: () => void;
createProgramWork: (numCycles: number) => boolean;
takeClass: (numCycles: number) => boolean;
commitCrime: (numCycles: number) => boolean;
checkForFactionInvitations: () => Faction[];
setBitNodeNumber: (n: number) => void;
getMult: (name: string) => number;
setMult: (name: string, mult: number) => void;
canAccessCotMG: () => boolean;
sourceFileLvl: (n: number) => number;
startGraftAugmentationWork: (augmentationName: string, time: number) => void;
graftAugmentationWork: (numCycles: number) => boolean;
finishGraftAugmentationWork: (cancelled: boolean, singularity?: boolean) => string;
applyEntropy: (stacks?: number) => void;
focusPenalty: () => number;
constructor() {
//Skills and stats
@@ -326,12 +214,6 @@ export class PlayerObject implements IPlayer {
//Special stats
this.intelligence = 0;
//Hacking multipliers
this.hacking_chance_mult = 1;
this.hacking_speed_mult = 1;
this.hacking_money_mult = 1;
this.hacking_grow_mult = 1;
//Experience and multipliers
this.hacking_exp = 0;
this.strength_exp = 0;
@@ -341,22 +223,7 @@ export class PlayerObject implements IPlayer {
this.charisma_exp = 0;
this.intelligence_exp = 0;
this.hacking_mult = 1;
this.strength_mult = 1;
this.defense_mult = 1;
this.dexterity_mult = 1;
this.agility_mult = 1;
this.charisma_mult = 1;
this.hacking_exp_mult = 1;
this.strength_exp_mult = 1;
this.defense_exp_mult = 1;
this.dexterity_exp_mult = 1;
this.agility_exp_mult = 1;
this.charisma_exp_mult = 1;
this.company_rep_mult = 1;
this.faction_rep_mult = 1;
this.mults = defaultMultipliers();
//Money
this.money = 1000 + CONSTANTS.Donations;
@@ -370,9 +237,6 @@ export class PlayerObject implements IPlayer {
// The CompanyPosition name must match a key value in CompanyPositions
this.jobs = {};
// Company at which player is CURRENTLY working (only valid when the player is actively working)
this.companyName = ""; // Name of Company. Must match a key value in Companies ma;
// Servers
this.currentServer = ""; //hostname of Server currently being accessed through termina;
this.purchasedServers = []; //hostnames of purchased server;
@@ -395,61 +259,6 @@ export class PlayerObject implements IPlayer {
this.numPeopleKilled = 0;
this.karma = 0;
this.crime_money_mult = 1;
this.crime_success_mult = 1;
//Flags/variables for working (Company, Faction, Creating Program, Taking Class)
this.isWorking = false;
this.focus = false;
this.workType = WorkType.None;
this.workCostMult = 1;
this.workExpMult = 1;
this.currentWorkFactionName = "";
this.currentWorkFactionDescription = "";
this.workHackExpGainRate = 0;
this.workStrExpGainRate = 0;
this.workDefExpGainRate = 0;
this.workDexExpGainRate = 0;
this.workAgiExpGainRate = 0;
this.workChaExpGainRate = 0;
this.workRepGainRate = 0;
this.workMoneyGainRate = 0;
this.workMoneyLossRate = 0;
this.workHackExpGained = 0;
this.workStrExpGained = 0;
this.workDefExpGained = 0;
this.workDexExpGained = 0;
this.workAgiExpGained = 0;
this.workChaExpGained = 0;
this.workRepGained = 0;
this.workMoneyGained = 0;
this.createProgramName = "";
this.createProgramReqLvl = 0;
this.graftAugmentationName = "";
this.timeWorkedGraftAugmentation = 0;
this.className = ClassType.None;
this.crimeType = CrimeType.None;
this.timeWorked = 0; //in m;
this.timeWorkedCreateProgram = 0;
this.timeNeededToCompleteWork = 0;
this.work_money_mult = 1;
//Hacknet Node multipliers
this.hacknet_node_money_mult = 1;
this.hacknet_node_purchase_cost_mult = 1;
this.hacknet_node_ram_cost_mult = 1;
this.hacknet_node_core_cost_mult = 1;
this.hacknet_node_level_cost_mult = 1;
//Stock Market
this.hasWseAccount = false;
this.hasTixApiAccess = false;
@@ -464,10 +273,6 @@ export class PlayerObject implements IPlayer {
//Bladeburner
this.bladeburner = null;
this.bladeburner_max_stamina_mult = 1;
this.bladeburner_stamina_gain_mult = 1;
this.bladeburner_analysis_mult = 1; //Field Analysis Only
this.bladeburner_success_chance_mult = 1;
// Sleeves & Re-sleeving
this.sleeves = [];
@@ -495,6 +300,9 @@ export class PlayerObject implements IPlayer {
this.achievements = [];
this.terminalCommandHistory = [];
this.focus = false;
this.currentWork = null;
// Let's get a hash of some semi-random stuff so we have something unique.
this.identifier = cyrb53(
"I-" +
@@ -528,45 +336,11 @@ export class PlayerObject implements IPlayer {
this.gainIntelligenceExp = generalMethods.gainIntelligenceExp;
this.gainStats = generalMethods.gainStats;
this.queryStatFromString = generalMethods.queryStatFromString;
this.resetWorkStatus = generalMethods.resetWorkStatus;
this.processWorkEarnings = generalMethods.processWorkEarnings;
this.startWork = generalMethods.startWork;
this.cancelationPenalty = generalMethods.cancelationPenalty;
this.work = generalMethods.work;
this.finishWork = generalMethods.finishWork;
this.startWorkPartTime = generalMethods.startWorkPartTime;
this.workPartTime = generalMethods.workPartTime;
this.finishWorkPartTime = generalMethods.finishWorkPartTime;
this.startWork = workMethods.start;
this.processWork = workMethods.process;
this.finishWork = workMethods.finish;
this.startFocusing = generalMethods.startFocusing;
this.stopFocusing = generalMethods.stopFocusing;
this.startFactionWork = generalMethods.startFactionWork;
this.startFactionHackWork = generalMethods.startFactionHackWork;
this.startFactionFieldWork = generalMethods.startFactionFieldWork;
this.startFactionSecurityWork = generalMethods.startFactionSecurityWork;
this.workForFaction = generalMethods.workForFaction;
this.finishFactionWork = generalMethods.finishFactionWork;
this.getWorkMoneyGain = generalMethods.getWorkMoneyGain;
this.getWorkHackExpGain = generalMethods.getWorkHackExpGain;
this.getWorkStrExpGain = generalMethods.getWorkStrExpGain;
this.getWorkDefExpGain = generalMethods.getWorkDefExpGain;
this.getWorkDexExpGain = generalMethods.getWorkDexExpGain;
this.getWorkAgiExpGain = generalMethods.getWorkAgiExpGain;
this.getWorkChaExpGain = generalMethods.getWorkChaExpGain;
this.getWorkRepGain = generalMethods.getWorkRepGain;
this.process = generalMethods.process;
this.startCreateProgramWork = generalMethods.startCreateProgramWork;
this.createProgramWork = generalMethods.createProgramWork;
this.finishCreateProgramWork = generalMethods.finishCreateProgramWork;
this.startGraftAugmentationWork = generalMethods.startGraftAugmentationWork;
this.graftAugmentationWork = generalMethods.craftAugmentationWork;
this.finishGraftAugmentationWork = generalMethods.finishGraftAugmentationWork;
this.startClass = generalMethods.startClass;
this.takeClass = generalMethods.takeClass;
this.finishClass = generalMethods.finishClass;
this.startCrime = generalMethods.startCrime;
this.commitCrime = generalMethods.commitCrime;
this.finishCrime = generalMethods.finishCrime;
this.singularityStopWork = generalMethods.singularityStopWork;
this.takeDamage = generalMethods.takeDamage;
this.regenerateHp = generalMethods.regenerateHp;
this.hospitalize = generalMethods.hospitalize;
@@ -622,17 +396,12 @@ export class PlayerObject implements IPlayer {
this.getUpgradeHomeRamCost = serverMethods.getUpgradeHomeRamCost;
this.getUpgradeHomeCoresCost = serverMethods.getUpgradeHomeCoresCost;
this.createHacknetServer = serverMethods.createHacknetServer;
this.factionWorkType = PlayerFactionWorkType.None;
this.committingCrimeThruSingFn = false;
this.singFnCrimeWorkerScript = null;
this.getMult = generalMethods.getMult;
this.setMult = generalMethods.setMult;
this.canAccessCotMG = generalMethods.canAccessCotMG;
this.sourceFileLvl = generalMethods.sourceFileLvl;
this.applyEntropy = augmentationMethods.applyEntropy;
this.focusPenalty = generalMethods.focusPenalty;
}
whoAmI(): string {
@@ -642,15 +411,14 @@ export class PlayerObject implements IPlayer {
/**
* Serialize the current object to a JSON save state.
*/
toJSON(): any {
toJSON(): IReviverValue {
return Generic_toJSON("PlayerObject", this);
}
/**
* Initiatizes a PlayerObject object from a JSON save state.
*/
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
static fromJSON(value: any): PlayerObject {
static fromJSON(value: IReviverValue): PlayerObject {
return Generic_fromJSON(PlayerObject, value.data);
}
}
@@ -32,8 +32,5 @@ export function applyEntropy(this: IPlayer, stacks = 1): void {
this.reapplyAllAugmentations();
this.reapplyAllSourceFiles();
const newMultipliers = calculateEntropy(this, stacks);
for (const [mult, val] of Object.entries(newMultipliers)) {
this.setMult(mult, val);
}
this.mults = calculateEntropy(this, stacks);
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,21 @@
import { Work } from "../../Work/Work";
import { IPlayer } from "../IPlayer";
export function start(this: IPlayer, w: Work): void {
if (this.currentWork !== null) {
this.currentWork.finish(this, true);
}
this.currentWork = w;
}
export function process(this: IPlayer, cycles = 1): void {
if (this.currentWork === null) return;
const finished = this.currentWork.process(this, cycles);
if (finished) {
this.finishWork(false);
}
}
export function finish(this: IPlayer, cancelled: boolean): void {
if (this.currentWork === null) return;
this.currentWork.finish(this, cancelled);
this.currentWork = null;
}
+48 -49
View File
@@ -28,15 +28,15 @@ import { CONSTANTS } from "../../Constants";
import { Faction } from "../../Faction/Faction";
import { Factions } from "../../Faction/Factions";
import { FactionWorkType } from "../../Faction/FactionWorkTypeEnum";
import { CityName } from "../../Locations/data/CityNames";
import { LocationName } from "../../Locations/data/LocationNames";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
import { Generic_fromJSON, Generic_toJSON, IReviverValue, Reviver } from "../../utils/JSONReviver";
import { BladeburnerConstants } from "../../Bladeburner/data/Constants";
import { numeralWrapper } from "../../ui/numeralFormat";
import { capitalizeFirstLetter, capitalizeEachWord } from "../../utils/StringHelperFunctions";
import { FactionWorkType } from "../../Work/data/FactionWorkType";
export class Sleeve extends Person {
/**
@@ -94,7 +94,7 @@ export class Sleeve extends Person {
/**
* Keeps track of what type of work sleeve is doing for faction, if applicable
*/
factionWorkType: FactionWorkType = FactionWorkType.None;
factionWorkType: FactionWorkType = FactionWorkType.HACKING;
/**
* Records experience gain rate for the current task
@@ -169,14 +169,14 @@ export class Sleeve extends Person {
this.resetTaskStatus(p);
}
this.gainRatesForTask.hack = crime.hacking_exp * this.hacking_exp_mult * BitNodeMultipliers.CrimeExpGain;
this.gainRatesForTask.str = crime.strength_exp * this.strength_exp_mult * BitNodeMultipliers.CrimeExpGain;
this.gainRatesForTask.def = crime.defense_exp * this.defense_exp_mult * BitNodeMultipliers.CrimeExpGain;
this.gainRatesForTask.dex = crime.dexterity_exp * this.dexterity_exp_mult * BitNodeMultipliers.CrimeExpGain;
this.gainRatesForTask.agi = crime.agility_exp * this.agility_exp_mult * BitNodeMultipliers.CrimeExpGain;
this.gainRatesForTask.cha = crime.charisma_exp * this.charisma_exp_mult * BitNodeMultipliers.CrimeExpGain;
this.gainRatesForTask.hack = crime.hacking_exp * this.mults.hacking_exp * BitNodeMultipliers.CrimeExpGain;
this.gainRatesForTask.str = crime.strength_exp * this.mults.strength_exp * BitNodeMultipliers.CrimeExpGain;
this.gainRatesForTask.def = crime.defense_exp * this.mults.defense_exp * BitNodeMultipliers.CrimeExpGain;
this.gainRatesForTask.dex = crime.dexterity_exp * this.mults.dexterity_exp * BitNodeMultipliers.CrimeExpGain;
this.gainRatesForTask.agi = crime.agility_exp * this.mults.agility_exp * BitNodeMultipliers.CrimeExpGain;
this.gainRatesForTask.cha = crime.charisma_exp * this.mults.charisma_exp * BitNodeMultipliers.CrimeExpGain;
this.gainRatesForTask.int = crime.intelligence_exp;
this.gainRatesForTask.money = crime.money * this.crime_money_mult * BitNodeMultipliers.CrimeMoney;
this.gainRatesForTask.money = crime.money * this.mults.crime_money * BitNodeMultipliers.CrimeMoney;
this.currentTaskLocation = String(this.gainRatesForTask.money);
@@ -444,11 +444,11 @@ export class Sleeve extends Person {
}
switch (this.factionWorkType) {
case FactionWorkType.Hacking:
case FactionWorkType.HACKING:
return this.getFactionHackingWorkRepGain() * (this.shock / 100) * favorMult;
case FactionWorkType.Field:
case FactionWorkType.FIELD:
return this.getFactionFieldWorkRepGain() * (this.shock / 100) * favorMult;
case FactionWorkType.Security:
case FactionWorkType.SECURITY:
return this.getFactionSecurityWorkRepGain() * (this.shock / 100) * favorMult;
default:
console.warn(`Invalid Sleeve.factionWorkType property in Sleeve.getRepGain(): ${this.factionWorkType}`);
@@ -478,7 +478,7 @@ export class Sleeve extends Person {
);
const favorMult = 1 + company.favor / 100;
return jobPerformance * this.company_rep_mult * favorMult;
return jobPerformance * this.mults.company_rep * favorMult;
} else {
return 0;
}
@@ -660,7 +660,7 @@ export class Sleeve extends Person {
this.currentTask = SleeveTaskType.Idle;
this.currentTaskTime = 0;
this.currentTaskMaxTime = 0;
this.factionWorkType = FactionWorkType.None;
this.factionWorkType = FactionWorkType.HACKING;
this.crimeType = "";
this.currentTaskLocation = "";
this.gymStatType = "";
@@ -804,22 +804,22 @@ export class Sleeve extends Person {
switch (this.className.toLowerCase()) {
case "study computer science":
this.gainRatesForTask.hack =
CONSTANTS.ClassStudyComputerScienceBaseExp * totalExpMult * this.hacking_exp_mult;
CONSTANTS.ClassStudyComputerScienceBaseExp * totalExpMult * this.mults.hacking_exp;
break;
case "data structures":
this.gainRatesForTask.hack = CONSTANTS.ClassDataStructuresBaseExp * totalExpMult * this.hacking_exp_mult;
this.gainRatesForTask.hack = CONSTANTS.ClassDataStructuresBaseExp * totalExpMult * this.mults.hacking_exp;
break;
case "networks":
this.gainRatesForTask.hack = CONSTANTS.ClassNetworksBaseExp * totalExpMult * this.hacking_exp_mult;
this.gainRatesForTask.hack = CONSTANTS.ClassNetworksBaseExp * totalExpMult * this.mults.hacking_exp;
break;
case "algorithms":
this.gainRatesForTask.hack = CONSTANTS.ClassAlgorithmsBaseExp * totalExpMult * this.hacking_exp_mult;
this.gainRatesForTask.hack = CONSTANTS.ClassAlgorithmsBaseExp * totalExpMult * this.mults.hacking_exp;
break;
case "management":
this.gainRatesForTask.cha = CONSTANTS.ClassManagementBaseExp * totalExpMult * this.charisma_exp_mult;
this.gainRatesForTask.cha = CONSTANTS.ClassManagementBaseExp * totalExpMult * this.mults.charisma_exp;
break;
case "leadership":
this.gainRatesForTask.cha = CONSTANTS.ClassLeadershipBaseExp * totalExpMult * this.charisma_exp_mult;
this.gainRatesForTask.cha = CONSTANTS.ClassLeadershipBaseExp * totalExpMult * this.mults.charisma_exp;
break;
default:
break;
@@ -911,37 +911,37 @@ export class Sleeve extends Person {
this.gainRatesForTask.money =
companyPosition.baseSalary *
company.salaryMultiplier *
this.work_money_mult *
this.mults.work_money *
BitNodeMultipliers.CompanyWorkMoney;
this.gainRatesForTask.hack =
companyPosition.hackingExpGain *
company.expMultiplier *
this.hacking_exp_mult *
this.mults.hacking_exp *
BitNodeMultipliers.CompanyWorkExpGain;
this.gainRatesForTask.str =
companyPosition.strengthExpGain *
company.expMultiplier *
this.strength_exp_mult *
this.mults.strength_exp *
BitNodeMultipliers.CompanyWorkExpGain;
this.gainRatesForTask.def =
companyPosition.defenseExpGain *
company.expMultiplier *
this.defense_exp_mult *
this.mults.defense_exp *
BitNodeMultipliers.CompanyWorkExpGain;
this.gainRatesForTask.dex =
companyPosition.dexterityExpGain *
company.expMultiplier *
this.dexterity_exp_mult *
this.mults.dexterity_exp *
BitNodeMultipliers.CompanyWorkExpGain;
this.gainRatesForTask.agi =
companyPosition.agilityExpGain *
company.expMultiplier *
this.agility_exp_mult *
this.mults.agility_exp *
BitNodeMultipliers.CompanyWorkExpGain;
this.gainRatesForTask.cha =
companyPosition.charismaExpGain *
company.expMultiplier *
this.charisma_exp_mult *
this.mults.charisma_exp *
BitNodeMultipliers.CompanyWorkExpGain;
this.currentTaskLocation = companyName;
@@ -974,29 +974,29 @@ export class Sleeve extends Person {
if (!factionInfo.offerHackingWork) {
return false;
}
this.factionWorkType = FactionWorkType.Hacking;
this.gainRatesForTask.hack = 0.15 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.factionWorkType = FactionWorkType.HACKING;
this.gainRatesForTask.hack = 0.15 * this.mults.hacking_exp * BitNodeMultipliers.FactionWorkExpGain;
} else if (sanitizedWorkType.includes("field")) {
if (!factionInfo.offerFieldWork) {
return false;
}
this.factionWorkType = FactionWorkType.Field;
this.gainRatesForTask.hack = 0.1 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.str = 0.1 * this.strength_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.def = 0.1 * this.defense_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.dex = 0.1 * this.dexterity_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.agi = 0.1 * this.agility_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.cha = 0.1 * this.charisma_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.factionWorkType = FactionWorkType.FIELD;
this.gainRatesForTask.hack = 0.1 * this.mults.hacking_exp * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.str = 0.1 * this.mults.strength_exp * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.def = 0.1 * this.mults.defense_exp * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.dex = 0.1 * this.mults.dexterity_exp * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.agi = 0.1 * this.mults.agility_exp * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.cha = 0.1 * this.mults.charisma_exp * BitNodeMultipliers.FactionWorkExpGain;
} else if (sanitizedWorkType.includes("security")) {
if (!factionInfo.offerSecurityWork) {
return false;
}
this.factionWorkType = FactionWorkType.Security;
this.gainRatesForTask.hack = 0.1 * this.hacking_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.str = 0.15 * this.strength_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.def = 0.15 * this.defense_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.dex = 0.15 * this.dexterity_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.agi = 0.15 * this.agility_exp_mult * BitNodeMultipliers.FactionWorkExpGain;
this.factionWorkType = FactionWorkType.SECURITY;
this.gainRatesForTask.hack = 0.1 * this.mults.hacking_exp * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.str = 0.15 * this.mults.strength_exp * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.def = 0.15 * this.mults.defense_exp * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.dex = 0.15 * this.mults.dexterity_exp * BitNodeMultipliers.FactionWorkExpGain;
this.gainRatesForTask.agi = 0.15 * this.mults.agility_exp * BitNodeMultipliers.FactionWorkExpGain;
} else {
return false;
}
@@ -1115,8 +1115,8 @@ export class Sleeve extends Person {
switch (action) {
case "Field analysis":
time = this.getBladeburnerActionTime(p, "General", action);
this.gainRatesForTask.hack = 20 * this.hacking_exp_mult;
this.gainRatesForTask.cha = 20 * this.charisma_exp_mult;
this.gainRatesForTask.hack = 20 * this.mults.hacking_exp;
this.gainRatesForTask.cha = 20 * this.mults.charisma_exp;
break;
case "Recruitment":
time = this.getBladeburnerActionTime(p, "General", action);
@@ -1234,7 +1234,7 @@ export class Sleeve extends Person {
this.hp -= amt;
if (this.hp <= 0) {
this.shock += 0.5;
this.shock = Math.min(1, this.shock - 0.5);
this.hp = this.max_hp;
return true;
} else {
@@ -1249,15 +1249,14 @@ export class Sleeve extends Person {
/**
* Serialize the current object to a JSON save state.
*/
toJSON(): any {
toJSON(): IReviverValue {
return Generic_toJSON("Sleeve", this);
}
/**
* Initiatizes a Sleeve object from a JSON save state.
*/
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
static fromJSON(value: any): Sleeve {
static fromJSON(value: IReviverValue): Sleeve {
return Generic_fromJSON(Sleeve, value.data);
}
}
+1 -1
View File
@@ -104,7 +104,7 @@ export function FAQModal({ open, onClose }: IProps): React.ReactElement {
<Typography variant="h4">What is Memory?</Typography>
<br />
<Typography>
Sleeve memory dictates what a sleeve's synchronization will be when its reset by switching BitNodes. For
Sleeve memory dictates what a sleeve's synchronization will be when it's reset by switching BitNodes. For
example, if a sleeve has a memory of 25, then when you switch BitNodes its synchronization will initially be
set to 25, rather than 1.
</Typography>
+23 -17
View File
@@ -54,32 +54,38 @@ export function MoreStatsModal(props: IProps): React.ReactElement {
<br />
<StatsTable
rows={[
[<>Hacking Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.hacking_mult)],
[<>Hacking Experience multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.hacking_exp_mult)],
[<>Strength Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.strength_mult)],
[<>Strength Experience multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.strength_exp_mult)],
[<>Defense Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.defense_mult)],
[<>Defense Experience multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.defense_exp_mult)],
[<>Dexterity Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.dexterity_mult)],
[<>Hacking Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.hacking)],
[<>Hacking Experience multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.hacking_exp)],
[<>Strength Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.strength)],
[
<>Strength Experience multiplier:&nbsp;</>,
numeralWrapper.formatPercentage(props.sleeve.mults.strength_exp),
],
[<>Defense Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.defense)],
[<>Defense Experience multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.defense_exp)],
[<>Dexterity Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.dexterity)],
[
<>Dexterity Experience multiplier:&nbsp;</>,
numeralWrapper.formatPercentage(props.sleeve.dexterity_exp_mult),
numeralWrapper.formatPercentage(props.sleeve.mults.dexterity_exp),
],
[<>Agility Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.agility)],
[<>Agility Experience multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.agility_exp)],
[<>Charisma Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.charisma)],
[
<>Charisma Experience multiplier:&nbsp;</>,
numeralWrapper.formatPercentage(props.sleeve.mults.charisma_exp),
],
[<>Agility Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.agility_mult)],
[<>Agility Experience multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.agility_exp_mult)],
[<>Charisma Level multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.charisma_mult)],
[<>Charisma Experience multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.charisma_exp_mult)],
[
<>Faction Reputation Gain multiplier:&nbsp;</>,
numeralWrapper.formatPercentage(props.sleeve.faction_rep_mult),
numeralWrapper.formatPercentage(props.sleeve.mults.faction_rep),
],
[
<>Company Reputation Gain multiplier:&nbsp;</>,
numeralWrapper.formatPercentage(props.sleeve.company_rep_mult),
numeralWrapper.formatPercentage(props.sleeve.mults.company_rep),
],
[<>Salary multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.work_money_mult)],
[<>Crime Money multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.crime_money_mult)],
[<>Crime Success multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.crime_success_mult)],
[<>Salary multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.work_money)],
[<>Crime Money multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.crime_money)],
[<>Crime Success multiplier:&nbsp;</>, numeralWrapper.formatPercentage(props.sleeve.mults.crime_success)],
]}
title="Multipliers:"
/>
@@ -54,7 +54,7 @@ export function SleeveAugmentationsModal(props: IProps): React.ReactElement {
canPurchase={(player, aug) => {
return player.money > aug.baseCost;
}}
purchaseAugmentation={(player, aug, _showModal) => {
purchaseAugmentation={(player, aug) => {
props.sleeve.tryBuyAugmentation(player, aug);
rerender();
}}
+4 -4
View File
@@ -1,8 +1,8 @@
import { Box, Button, Paper, Tooltip, Typography } from "@mui/material";
import React, { useState } from "react";
import { FactionWorkType } from "../../../Work/data/FactionWorkType";
import { CONSTANTS } from "../../../Constants";
import { Crimes } from "../../../Crime/Crimes";
import { FactionWorkType } from "../../../Faction/FactionWorkTypeEnum";
import { use } from "../../../ui/Context";
import { numeralWrapper } from "../../../ui/numeralFormat";
import { ProgressBar } from "../../../ui/React/Progress";
@@ -75,13 +75,13 @@ export function SleeveElem(props: IProps): React.ReactElement {
case SleeveTaskType.Faction: {
let doing = "nothing";
switch (props.sleeve.factionWorkType) {
case FactionWorkType.Field:
case FactionWorkType.FIELD:
doing = "Field work";
break;
case FactionWorkType.Hacking:
case FactionWorkType.HACKING:
doing = "Hacking contracts";
break;
case FactionWorkType.Security:
case FactionWorkType.SECURITY:
doing = "Security work";
break;
}
+1 -1
View File
@@ -91,7 +91,7 @@ export function EarningsElement(props: IProps): React.ReactElement {
const classes = useStyles();
const player = use.Player();
let data: any[][] = [];
let data: (string | JSX.Element)[][] = [];
if (props.sleeve.currentTask === SleeveTaskType.Crime) {
data = [
[
+7 -12
View File
@@ -6,10 +6,10 @@ import { Crimes } from "../../../Crime/Crimes";
import { LocationName } from "../../../Locations/data/LocationNames";
import { CityName } from "../../../Locations/data/CityNames";
import { Factions } from "../../../Faction/Factions";
import { FactionWorkType } from "../../../Faction/FactionWorkTypeEnum";
import Select, { SelectChangeEvent } from "@mui/material/Select";
import MenuItem from "@mui/material/MenuItem";
import { FactionNames } from "../../../Faction/data/FactionNames";
import { FactionWorkType } from "../../../Work/data/FactionWorkType";
const universitySelectorOptions: string[] = [
"Study Computer Science",
@@ -44,7 +44,7 @@ interface ITaskDetails {
function possibleJobs(player: IPlayer, sleeve: Sleeve): string[] {
// Array of all companies that other sleeves are working at
const forbiddenCompanies = [];
const forbiddenCompanies: string[] = [];
for (const otherSleeve of player.sleeves) {
if (sleeve === otherSleeve) {
continue;
@@ -54,13 +54,8 @@ function possibleJobs(player: IPlayer, sleeve: Sleeve): string[] {
}
}
const allJobs: string[] = Object.keys(player.jobs);
for (let i = 0; i < allJobs.length; ++i) {
if (!forbiddenCompanies.includes(allJobs[i])) {
allJobs[i];
}
}
return allJobs;
return allJobs.filter((company) => !forbiddenCompanies.includes(company));
}
function possibleFactions(player: IPlayer, sleeve: Sleeve): string[] {
@@ -240,7 +235,7 @@ const canDo: {
[CityName.Aevum, CityName.Sector12, CityName.Volhaven].includes(sleeve.city),
"Workout at Gym": (player: IPlayer, sleeve: Sleeve) =>
[CityName.Aevum, CityName.Sector12, CityName.Volhaven].includes(sleeve.city),
"Perform Bladeburner Actions": (player: IPlayer, _: Sleeve) => player.inBladeburner(),
"Perform Bladeburner Actions": (player: IPlayer) => player.inBladeburner(),
"Shock Recovery": (player: IPlayer, sleeve: Sleeve) => sleeve.shock < 100,
Synchronize: (player: IPlayer, sleeve: Sleeve) => sleeve.sync < 100,
};
@@ -254,13 +249,13 @@ function getABC(sleeve: Sleeve): [string, string, string] {
case SleeveTaskType.Faction: {
let workType = "";
switch (sleeve.factionWorkType) {
case FactionWorkType.Hacking:
case FactionWorkType.HACKING:
workType = "Hacking Contracts";
break;
case FactionWorkType.Field:
case FactionWorkType.FIELD:
workType = "Field Work";
break;
case FactionWorkType.Security:
case FactionWorkType.SECURITY:
workType = "Security Work";
break;
}
+3 -3
View File
@@ -15,7 +15,7 @@ function mult(f: Faction): number {
export function getHackingWorkRepGain(p: IPlayer, f: Faction): number {
return (
((p.hacking + p.intelligence / 3) / CONSTANTS.MaxSkillLevel) *
p.faction_rep_mult *
p.mults.faction_rep *
p.getIntelligenceBonus(1) *
mult(f) *
CalculateShareMult()
@@ -27,7 +27,7 @@ export function getFactionSecurityWorkRepGain(p: IPlayer, f: Faction): number {
(0.9 * (p.strength + p.defense + p.dexterity + p.agility + (p.hacking + p.intelligence) * CalculateShareMult())) /
CONSTANTS.MaxSkillLevel /
4.5;
return t * p.faction_rep_mult * mult(f) * p.getIntelligenceBonus(1);
return t * p.mults.faction_rep * mult(f) * p.getIntelligenceBonus(1);
}
export function getFactionFieldWorkRepGain(p: IPlayer, f: Faction): number {
@@ -41,5 +41,5 @@ export function getFactionFieldWorkRepGain(p: IPlayer, f: Faction): number {
(p.hacking + p.intelligence) * CalculateShareMult())) /
CONSTANTS.MaxSkillLevel /
5.5;
return t * p.faction_rep_mult * mult(f) * p.getIntelligenceBonus(1);
return t * p.mults.faction_rep * mult(f) * p.getIntelligenceBonus(1);
}
-81
View File
@@ -1,81 +0,0 @@
import { CONSTANTS } from "../../Constants";
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
import { IPlayer } from "../IPlayer";
import { ClassType } from "../../utils/WorkType";
export interface WorkEarnings {
workMoneyLossRate: number;
workHackExpGainRate: number;
workStrExpGainRate: number;
workDefExpGainRate: number;
workDexExpGainRate: number;
workAgiExpGainRate: number;
workChaExpGainRate: number;
}
export function calculateClassEarnings(player: IPlayer): WorkEarnings {
const gameCPS = 1000 / CONSTANTS._idleSpeed;
//Find cost and exp gain per game cycle
let cost = 0;
let hackExp = 0,
strExp = 0,
defExp = 0,
dexExp = 0,
agiExp = 0,
chaExp = 0;
const hashManager = player.hashManager;
switch (player.className) {
case ClassType.StudyComputerScience:
hackExp =
((CONSTANTS.ClassStudyComputerScienceBaseExp * player.workExpMult) / gameCPS) * hashManager.getStudyMult();
break;
case ClassType.DataStructures:
cost = (CONSTANTS.ClassDataStructuresBaseCost * player.workCostMult) / gameCPS;
hackExp = ((CONSTANTS.ClassDataStructuresBaseExp * player.workExpMult) / gameCPS) * hashManager.getStudyMult();
break;
case ClassType.Networks:
cost = (CONSTANTS.ClassNetworksBaseCost * player.workCostMult) / gameCPS;
hackExp = ((CONSTANTS.ClassNetworksBaseExp * player.workExpMult) / gameCPS) * hashManager.getStudyMult();
break;
case ClassType.Algorithms:
cost = (CONSTANTS.ClassAlgorithmsBaseCost * player.workCostMult) / gameCPS;
hackExp = ((CONSTANTS.ClassAlgorithmsBaseExp * player.workExpMult) / gameCPS) * hashManager.getStudyMult();
break;
case ClassType.Management:
cost = (CONSTANTS.ClassManagementBaseCost * player.workCostMult) / gameCPS;
chaExp = ((CONSTANTS.ClassManagementBaseExp * player.workExpMult) / gameCPS) * hashManager.getStudyMult();
break;
case ClassType.Leadership:
cost = (CONSTANTS.ClassLeadershipBaseCost * player.workCostMult) / gameCPS;
chaExp = ((CONSTANTS.ClassLeadershipBaseExp * player.workExpMult) / gameCPS) * hashManager.getStudyMult();
break;
case ClassType.GymStrength:
cost = (CONSTANTS.ClassGymBaseCost * player.workCostMult) / gameCPS;
strExp = (player.workExpMult / gameCPS) * hashManager.getTrainingMult();
break;
case ClassType.GymDefense:
cost = (CONSTANTS.ClassGymBaseCost * player.workCostMult) / gameCPS;
defExp = (player.workExpMult / gameCPS) * hashManager.getTrainingMult();
break;
case ClassType.GymDexterity:
cost = (CONSTANTS.ClassGymBaseCost * player.workCostMult) / gameCPS;
dexExp = (player.workExpMult / gameCPS) * hashManager.getTrainingMult();
break;
case ClassType.GymAgility:
cost = (CONSTANTS.ClassGymBaseCost * player.workCostMult) / gameCPS;
agiExp = (player.workExpMult / gameCPS) * hashManager.getTrainingMult();
break;
default:
throw new Error("ERR: Invalid/unrecognized class name");
}
return {
workMoneyLossRate: cost,
workHackExpGainRate: hackExp * player.hacking_exp_mult * BitNodeMultipliers.ClassGymExpGain,
workStrExpGainRate: strExp * player.strength_exp_mult * BitNodeMultipliers.ClassGymExpGain,
workDefExpGainRate: defExp * player.defense_exp_mult * BitNodeMultipliers.ClassGymExpGain,
workDexExpGainRate: dexExp * player.dexterity_exp_mult * BitNodeMultipliers.ClassGymExpGain,
workAgiExpGainRate: agiExp * player.agility_exp_mult * BitNodeMultipliers.ClassGymExpGain,
workChaExpGainRate: chaExp * player.charisma_exp_mult * BitNodeMultipliers.ClassGymExpGain,
};
}