mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-12-18 20:25:45 +01:00
NETSCRIPT: Add ns.formulas.work.companyGains function (#195)
* added ns.formulas.work.companyGains. * Removed Work/Formulas folder, added Work/Formulas.ts * CompanyPosition.calculateJobPerformance now takes in a Person instead of taking in a full set of stats, and it takes INT into account. * formulas.crimeGains takes in a person object. * Renamed ns Player type to Person. * added multWorkStats, which multiplies a WorkStats object with a multipliers object. * Remove unused types in NetscriptDefinitons.d.ts * reuse formulas code in other parts of game * getSleeveInformation also returns skills Co-authored-by: Alexey <alexey.kozhemiakin@gmail.com>
This commit is contained in:
parent
5205ff2837
commit
9e869bc876
@ -1,3 +1,4 @@
|
||||
import { Person } from "../PersonObjects/Person";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
import * as names from "./data/companypositionnames";
|
||||
|
||||
@ -117,13 +118,13 @@ export class CompanyPosition {
|
||||
this.charismaExpGain = p.charismaExpGain != null ? p.charismaExpGain : 0;
|
||||
}
|
||||
|
||||
calculateJobPerformance(hack: number, str: number, def: number, dex: number, agi: number, cha: number): number {
|
||||
const hackRatio: number = (this.hackingEffectiveness * hack) / CONSTANTS.MaxSkillLevel;
|
||||
const strRatio: number = (this.strengthEffectiveness * str) / CONSTANTS.MaxSkillLevel;
|
||||
const defRatio: number = (this.defenseEffectiveness * def) / CONSTANTS.MaxSkillLevel;
|
||||
const dexRatio: number = (this.dexterityEffectiveness * dex) / CONSTANTS.MaxSkillLevel;
|
||||
const agiRatio: number = (this.agilityEffectiveness * agi) / CONSTANTS.MaxSkillLevel;
|
||||
const chaRatio: number = (this.charismaEffectiveness * cha) / CONSTANTS.MaxSkillLevel;
|
||||
calculateJobPerformance(worker: Person): number {
|
||||
const hackRatio: number = (this.hackingEffectiveness * worker.skills.hacking) / CONSTANTS.MaxSkillLevel;
|
||||
const strRatio: number = (this.strengthEffectiveness * worker.skills.strength) / CONSTANTS.MaxSkillLevel;
|
||||
const defRatio: number = (this.defenseEffectiveness * worker.skills.defense) / CONSTANTS.MaxSkillLevel;
|
||||
const dexRatio: number = (this.dexterityEffectiveness * worker.skills.dexterity) / CONSTANTS.MaxSkillLevel;
|
||||
const agiRatio: number = (this.agilityEffectiveness * worker.skills.agility) / CONSTANTS.MaxSkillLevel;
|
||||
const chaRatio: number = (this.charismaEffectiveness * worker.skills.charisma) / CONSTANTS.MaxSkillLevel;
|
||||
|
||||
let reputationGain: number =
|
||||
(this.repMultiplier * (hackRatio + strRatio + defRatio + dexRatio + agiRatio + chaRatio)) / 100;
|
||||
@ -131,7 +132,7 @@ export class CompanyPosition {
|
||||
console.error("Company reputation gain calculated to be NaN");
|
||||
reputationGain = 0;
|
||||
}
|
||||
|
||||
reputationGain += worker.skills.intelligence / CONSTANTS.MaxSkillLevel;
|
||||
return reputationGain;
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ import { Money } from "../../ui/React/Money";
|
||||
import { Router } from "../../ui/GameRoot";
|
||||
import { Box } from "@mui/material";
|
||||
import { ClassWork, ClassType, Classes } from "../../Work/ClassWork";
|
||||
import { calculateCost } from "../../Work/formulas/Class";
|
||||
import { calculateCost } from "../../Work/Formulas";
|
||||
|
||||
type IProps = {
|
||||
loc: Location;
|
||||
|
@ -15,7 +15,7 @@ import { Player } from "@player";
|
||||
import { Box } from "@mui/material";
|
||||
|
||||
import { ClassWork, ClassType, Classes } from "../../Work/ClassWork";
|
||||
import { calculateCost } from "../../Work/formulas/Class";
|
||||
import { calculateCost } from "../../Work/Formulas";
|
||||
|
||||
type IProps = {
|
||||
loc: Location;
|
||||
|
@ -600,6 +600,7 @@ export const RamCosts: RamCostTree<Omit<NSFull, "args" | "enums">> = {
|
||||
crimeGains: 0,
|
||||
classGains: 0,
|
||||
factionGains: 0,
|
||||
companyGains: 0,
|
||||
},
|
||||
},
|
||||
} as const;
|
||||
|
@ -39,17 +39,20 @@ import { favorToRep as calculateFavorToRep, repToFavor as calculateRepToFavor }
|
||||
import { repFromDonation } from "../Faction/formulas/donation";
|
||||
import { InternalAPI, NetscriptContext } from "../Netscript/APIWrapper";
|
||||
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||
import { calculateCrimeWorkStats } from "../Work/formulas/Crime";
|
||||
import { calculateCrimeWorkStats } from "../Work/Formulas";
|
||||
import { Crimes } from "../Crime/Crimes";
|
||||
import { calculateClassEarnings } from "../Work/formulas/Class";
|
||||
import { calculateCompanyWorkStats } from "../Work/Formulas";
|
||||
import { Companies } from "../Company/Companies";
|
||||
import { calculateClassEarnings } from "../Work/Formulas";
|
||||
import { ClassType } from "../Work/ClassWork";
|
||||
import { LocationName } from "../Locations/data/LocationNames";
|
||||
import { calculateFactionExp, calculateFactionRep } from "../Work/formulas/Faction";
|
||||
import { calculateFactionExp, calculateFactionRep } from "../Work/Formulas";
|
||||
import { FactionWorkType } from "../Work/data/FactionWorkType";
|
||||
|
||||
import { defaultMultipliers } from "../PersonObjects/Multipliers";
|
||||
import { checkEnum } from "../utils/helpers/checkEnum";
|
||||
import { CrimeType } from "../utils/WorkType";
|
||||
import { CompanyPositions } from "../Company/CompanyPositions";
|
||||
|
||||
export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
const checkFormulasAccess = function (ctx: NetscriptContext): void {
|
||||
@ -362,10 +365,11 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
},
|
||||
},
|
||||
work: {
|
||||
crimeGains: (ctx) => (_crimeType) => {
|
||||
crimeGains: (ctx) => (_person, _crimeType) => {
|
||||
const person = helpers.player(ctx, _person);
|
||||
const crimeType = helpers.string(ctx, "crimeType", _crimeType);
|
||||
if (!checkEnum(CrimeType, crimeType)) throw new Error(`Invalid crime type: ${crimeType}`);
|
||||
return calculateCrimeWorkStats(Crimes[crimeType]);
|
||||
return calculateCrimeWorkStats(person, Crimes[crimeType]);
|
||||
},
|
||||
classGains: (ctx) => (_person, _classType, _locationName) => {
|
||||
const person = helpers.player(ctx, _person);
|
||||
@ -382,10 +386,22 @@ export function NetscriptFormulas(): InternalAPI<IFormulas> {
|
||||
exp.reputation = rep;
|
||||
return exp;
|
||||
},
|
||||
// companyGains: (ctx) => (_player) {
|
||||
// const player = helpers.player(ctx, _player);
|
||||
|
||||
// },
|
||||
companyGains: (ctx) => (_player, _companyName, _positionName, _favor) => {
|
||||
const player = helpers.player(ctx, _player);
|
||||
CompanyPositions;
|
||||
const positionName = helpers.string(ctx, "_positionName", _positionName);
|
||||
const position = Object.values(CompanyPositions).find((c) => c.name === positionName);
|
||||
if (!position) throw new Error(`Invalid position name: ${positionName}`);
|
||||
|
||||
const companyName = helpers.string(ctx, "_companyName", _companyName);
|
||||
const company = Object.values(Companies).find((c) => c.name === companyName);
|
||||
if (!company) throw new Error(`Invalid company name: ${companyName}`);
|
||||
|
||||
const favor = helpers.number(ctx, "favor", _favor);
|
||||
|
||||
return calculateCompanyWorkStats(player, company, position, favor);
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ import { FactionWorkType } from "../Work/data/FactionWorkType";
|
||||
import { CompanyWork } from "../Work/CompanyWork";
|
||||
import { canGetBonus, onExport } from "../ExportBonus";
|
||||
import { saveObject } from "../SaveObject";
|
||||
import { calculateCrimeWorkStats } from "../Work/formulas/Crime";
|
||||
import { calculateCrimeWorkStats } from "../Work/Formulas";
|
||||
import { checkEnum } from "../utils/helpers/checkEnum";
|
||||
import { Crimes } from "../Crime/Crimes";
|
||||
import { CrimeType } from "../utils/WorkType";
|
||||
@ -1160,7 +1160,7 @@ export function NetscriptSingularity(): InternalAPI<ISingularity> {
|
||||
const crime = checkEnum(CrimeType, crimeType) ? Crimes[crimeType] : findCrime(crimeType);
|
||||
if (crime == null) throw helpers.makeRuntimeErrorMsg(ctx, `Invalid crime: '${crimeType}'`);
|
||||
|
||||
const crimeStatsWithMultipliers = calculateCrimeWorkStats(crime);
|
||||
const crimeStatsWithMultipliers = calculateCrimeWorkStats(Player, crime);
|
||||
|
||||
return Object.assign({}, crime, {
|
||||
money: crimeStatsWithMultipliers.money,
|
||||
|
@ -13,6 +13,7 @@ import { isSleeveCompanyWork } from "../PersonObjects/Sleeve/Work/SleeveCompanyW
|
||||
import { helpers } from "../Netscript/NetscriptHelpers";
|
||||
import { Crimes } from "../Crime/Crimes";
|
||||
import { CrimeType } from "../utils/WorkType";
|
||||
import { cloneDeep } from "lodash";
|
||||
|
||||
export function NetscriptSleeve(): InternalAPI<ISleeve> {
|
||||
const checkSleeveAPIAccess = function (ctx: NetscriptContext) {
|
||||
@ -200,6 +201,7 @@ export function NetscriptSleeve(): InternalAPI<ISleeve> {
|
||||
strengthExp: sl.mults.strength_exp,
|
||||
workMoney: sl.mults.work_money,
|
||||
},
|
||||
skills: cloneDeep(sl.skills),
|
||||
};
|
||||
},
|
||||
getSleeveAugmentations: (ctx) => (_sleeveNumber) => {
|
||||
|
@ -2,7 +2,7 @@ import { Generic_fromJSON, Generic_toJSON, IReviverValue, Reviver } from "../../
|
||||
import { applySleeveGains, Work, WorkType } from "./Work";
|
||||
import { ClassType } from "../../../Work/ClassWork";
|
||||
import { LocationName } from "../../../Locations/data/LocationNames";
|
||||
import { calculateClassEarnings } from "../../../Work/formulas/Class";
|
||||
import { calculateClassEarnings } from "../../../Work/Formulas";
|
||||
import { Sleeve } from "../Sleeve";
|
||||
import { scaleWorkStats, WorkStats } from "../../../Work/WorkStats";
|
||||
|
||||
|
@ -4,9 +4,11 @@ import { applySleeveGains, Work, WorkType } from "./Work";
|
||||
import { LocationName } from "../../../Locations/data/LocationNames";
|
||||
import { Companies } from "../../../Company/Companies";
|
||||
import { Company } from "../../../Company/Company";
|
||||
import { calculateCompanyWorkStats } from "../../../Work/formulas/Company";
|
||||
import { calculateCompanyWorkStats } from "../../../Work/Formulas";
|
||||
import { WorkStats } from "../../../Work/WorkStats";
|
||||
import { influenceStockThroughCompanyWork } from "../../../StockMarket/PlayerInfluencing";
|
||||
import { Player } from "@player";
|
||||
import { CompanyPositions } from "../../../Company/CompanyPositions";
|
||||
|
||||
interface SleeveCompanyWorkParams {
|
||||
companyName: string;
|
||||
@ -30,7 +32,8 @@ export class SleeveCompanyWork extends Work {
|
||||
}
|
||||
|
||||
getGainRates(sleeve: Sleeve): WorkStats {
|
||||
return calculateCompanyWorkStats(sleeve, this.getCompany());
|
||||
const company = this.getCompany();
|
||||
return calculateCompanyWorkStats(sleeve, company, CompanyPositions[Player.jobs[company.name]], company.favor);
|
||||
}
|
||||
|
||||
process(sleeve: Sleeve, cycles: number): number {
|
||||
|
@ -5,10 +5,10 @@ import { applySleeveGains, Work, WorkType } from "./Work";
|
||||
import { CrimeType } from "../../../utils/WorkType";
|
||||
import { Crimes } from "../../../Crime/Crimes";
|
||||
import { Crime } from "../../../Crime/Crime";
|
||||
import { newWorkStats, scaleWorkStats, WorkStats } from "../../../Work/WorkStats";
|
||||
import { scaleWorkStats, WorkStats } from "../../../Work/WorkStats";
|
||||
import { CONSTANTS } from "../../../Constants";
|
||||
import { BitNodeMultipliers } from "../../../BitNode/BitNodeMultipliers";
|
||||
import { checkEnum } from "../../../utils/helpers/checkEnum";
|
||||
import { calculateCrimeWorkStats } from "../../../Work/Formulas";
|
||||
|
||||
export const isSleeveCrimeWork = (w: Work | null): w is SleeveCrimeWork => w !== null && w.type === WorkType.CRIME;
|
||||
|
||||
@ -26,17 +26,7 @@ export class SleeveCrimeWork extends Work {
|
||||
}
|
||||
|
||||
getExp(sleeve: Sleeve): WorkStats {
|
||||
const crime = this.getCrime();
|
||||
return newWorkStats({
|
||||
money: crime.money * BitNodeMultipliers.CrimeMoney * sleeve.mults.crime_money,
|
||||
hackExp: crime.hacking_exp * BitNodeMultipliers.CrimeExpGain * sleeve.mults.hacking_exp,
|
||||
strExp: crime.strength_exp * BitNodeMultipliers.CrimeExpGain * sleeve.mults.strength_exp,
|
||||
defExp: crime.defense_exp * BitNodeMultipliers.CrimeExpGain * sleeve.mults.defense_exp,
|
||||
dexExp: crime.dexterity_exp * BitNodeMultipliers.CrimeExpGain * sleeve.mults.dexterity_exp,
|
||||
agiExp: crime.agility_exp * BitNodeMultipliers.CrimeExpGain * sleeve.mults.agility_exp,
|
||||
chaExp: crime.charisma_exp * BitNodeMultipliers.CrimeExpGain * sleeve.mults.charisma_exp,
|
||||
intExp: crime.intelligence_exp * BitNodeMultipliers.CrimeExpGain,
|
||||
});
|
||||
return calculateCrimeWorkStats(sleeve, this.getCrime());
|
||||
}
|
||||
|
||||
cyclesNeeded(): number {
|
||||
|
@ -5,15 +5,9 @@ import { applySleeveGains, Work, WorkType } from "./Work";
|
||||
import { FactionWorkType } from "../../../Work/data/FactionWorkType";
|
||||
import { FactionNames } from "../../../Faction/data/FactionNames";
|
||||
import { Factions } from "../../../Faction/Factions";
|
||||
import { calculateFactionExp } from "../../../Work/formulas/Faction";
|
||||
import { calculateFactionExp, calculateFactionRep } from "../../../Work/Formulas";
|
||||
import { Faction } from "../../../Faction/Faction";
|
||||
import {
|
||||
getFactionFieldWorkRepGain,
|
||||
getFactionSecurityWorkRepGain,
|
||||
getHackingWorkRepGain,
|
||||
} from "../../../PersonObjects/formulas/reputation";
|
||||
import { scaleWorkStats, WorkStats } from "../../../Work/WorkStats";
|
||||
import { BitNodeMultipliers } from "../../../BitNode/BitNodeMultipliers";
|
||||
|
||||
interface SleeveFactionWorkParams {
|
||||
factionWorkType: FactionWorkType;
|
||||
@ -38,17 +32,7 @@ export class SleeveFactionWork extends Work {
|
||||
}
|
||||
|
||||
getReputationRate(sleeve: Sleeve): number {
|
||||
const faction = this.getFaction();
|
||||
const repFormulas = {
|
||||
[FactionWorkType.HACKING]: getHackingWorkRepGain,
|
||||
[FactionWorkType.FIELD]: getFactionFieldWorkRepGain,
|
||||
[FactionWorkType.SECURITY]: getFactionSecurityWorkRepGain,
|
||||
};
|
||||
return (
|
||||
repFormulas[this.factionWorkType](sleeve, faction.favor) *
|
||||
sleeve.shockBonus() *
|
||||
BitNodeMultipliers.FactionWorkRepGain
|
||||
);
|
||||
return calculateFactionRep(sleeve, this.factionWorkType, this.getFaction().favor) * sleeve.shockBonus();
|
||||
}
|
||||
|
||||
getFaction(): Faction {
|
||||
|
89
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
89
src/ScriptEditor/NetscriptDefinitions.d.ts
vendored
@ -37,7 +37,7 @@ type ScriptArg = string | number | boolean;
|
||||
type FilenameOrPID = number | string;
|
||||
|
||||
/** @public */
|
||||
interface Player {
|
||||
interface Person {
|
||||
hp: HP;
|
||||
skills: Skills;
|
||||
exp: Skills;
|
||||
@ -641,62 +641,6 @@ export interface NodeStats {
|
||||
totalProduction: number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export interface CharacterMult {
|
||||
/** Agility stat */
|
||||
agility: number;
|
||||
/** Agility exp */
|
||||
agilityExp: number;
|
||||
/** Charisma stat */
|
||||
charisma: number;
|
||||
/** Charisma exp */
|
||||
charismaExp: number;
|
||||
/** Company reputation */
|
||||
companyRep: number;
|
||||
/** Money earned from crimes */
|
||||
crimeMoney: number;
|
||||
/** Crime success chance */
|
||||
crimeSuccess: number;
|
||||
/** Defense stat */
|
||||
defense: number;
|
||||
/** Defense exp */
|
||||
defenseExp: number;
|
||||
/** Dexterity stat */
|
||||
dexterity: number;
|
||||
/** Dexterity exp */
|
||||
dexterityExp: number;
|
||||
/** Faction reputation */
|
||||
factionRep: number;
|
||||
/** Hacking stat */
|
||||
hacking: number;
|
||||
/** Hacking exp */
|
||||
hackingExp: number;
|
||||
/** Strength stat */
|
||||
strength: number;
|
||||
/** Strength exp */
|
||||
strengthExp: number;
|
||||
/** Money earned from jobs */
|
||||
workMoney: number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export interface SleeveWorkGains {
|
||||
/** Hacking exp gained from work */
|
||||
workHackExpGain: number;
|
||||
/** Strength exp gained from work */
|
||||
workStrExpGain: number;
|
||||
/** Defense exp gained from work, */
|
||||
workDefExpGain: number;
|
||||
/** Dexterity exp gained from work */
|
||||
workDexExpGain: number;
|
||||
/** Agility exp gained from work */
|
||||
workAgiExpGain: number;
|
||||
/** Charisma exp gained from work */
|
||||
workChaExpGain: number;
|
||||
/** Money gained from work */
|
||||
workMoneyGain: number;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
export interface SourceFileLvl {
|
||||
/** The number of the source file */
|
||||
@ -966,7 +910,9 @@ export interface SleeveInformation {
|
||||
/** Does this sleeve have access to the tor router */
|
||||
tor: boolean;
|
||||
/** Sleeve multipliers */
|
||||
mult: CharacterMult;
|
||||
mult: Multipliers;
|
||||
/** Sleeve skills */
|
||||
skills: Skills;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3907,9 +3853,10 @@ export interface WorkStats {
|
||||
* @public
|
||||
*/
|
||||
interface WorkFormulas {
|
||||
crimeGains(crimeType: CrimeType | CrimeNames): WorkStats;
|
||||
classGains(player: Player, classType: string, locationName: string): WorkStats;
|
||||
factionGains(player: Player, workType: string, favor: number): WorkStats;
|
||||
crimeGains(person: Person, crimeType: CrimeType | CrimeNames): WorkStats;
|
||||
classGains(person: Person, classType: string, locationName: string): WorkStats;
|
||||
factionGains(person: Person, workType: string, favor: number): WorkStats;
|
||||
companyGains(person: Person, companyName: string, workType: string, favor: number): WorkStats;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3936,7 +3883,7 @@ interface ReputationFormulas {
|
||||
* @param amount - Amount of money donated
|
||||
* @param player - Player info from {@link NS.getPlayer | getPlayer}
|
||||
*/
|
||||
repFromDonation(amount: number, player: Player): number;
|
||||
repFromDonation(amount: number, player: Person): number;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3951,7 +3898,7 @@ interface HackingFormulas {
|
||||
* @param player - Player info from {@link NS.getPlayer | getPlayer}
|
||||
* @returns The calculated hack chance.
|
||||
*/
|
||||
hackChance(server: Server, player: Player): number;
|
||||
hackChance(server: Server, player: Person): number;
|
||||
/**
|
||||
* Calculate hack exp for one thread.
|
||||
* @remarks
|
||||
@ -3960,7 +3907,7 @@ interface HackingFormulas {
|
||||
* @param player - Player info from {@link NS.getPlayer | getPlayer}
|
||||
* @returns The calculated hack exp.
|
||||
*/
|
||||
hackExp(server: Server, player: Player): number;
|
||||
hackExp(server: Server, player: Person): number;
|
||||
/**
|
||||
* Calculate hack percent for one thread.
|
||||
* (Ex: 0.25 would steal 25% of the server's current value.)
|
||||
@ -3970,7 +3917,7 @@ interface HackingFormulas {
|
||||
* @param player - Player info from {@link NS.getPlayer | getPlayer}
|
||||
* @returns The calculated hack percent.
|
||||
*/
|
||||
hackPercent(server: Server, player: Player): number;
|
||||
hackPercent(server: Server, player: Person): number;
|
||||
/**
|
||||
* Calculate the percent a server would grow to.
|
||||
* (Ex: 3.0 would would grow the server to 300% of its current value.)
|
||||
@ -3980,28 +3927,28 @@ interface HackingFormulas {
|
||||
* @param cores - Number of cores on the computer that will execute grow.
|
||||
* @returns The calculated grow percent.
|
||||
*/
|
||||
growPercent(server: Server, threads: number, player: Player, cores?: number): number;
|
||||
growPercent(server: Server, threads: number, player: Person, cores?: number): number;
|
||||
/**
|
||||
* Calculate hack time.
|
||||
* @param server - Server info from {@link NS.getServer | getServer}
|
||||
* @param player - Player info from {@link NS.getPlayer | getPlayer}
|
||||
* @returns The calculated hack time.
|
||||
*/
|
||||
hackTime(server: Server, player: Player): number;
|
||||
hackTime(server: Server, player: Person): number;
|
||||
/**
|
||||
* Calculate grow time.
|
||||
* @param server - Server info from {@link NS.getServer | getServer}
|
||||
* @param player - Player info from {@link NS.getPlayer | getPlayer}
|
||||
* @returns The calculated grow time.
|
||||
*/
|
||||
growTime(server: Server, player: Player): number;
|
||||
growTime(server: Server, player: Person): number;
|
||||
/**
|
||||
* Calculate weaken time.
|
||||
* @param server - Server info from {@link NS.getServer | getServer}
|
||||
* @param player - Player info from {@link NS.getPlayer | getPlayer}
|
||||
* @returns The calculated weaken time.
|
||||
*/
|
||||
weakenTime(server: Server, player: Player): number;
|
||||
weakenTime(server: Server, player: Person): number;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4182,7 +4129,7 @@ interface GangFormulas {
|
||||
*/
|
||||
export interface Formulas {
|
||||
mockServer(): Server;
|
||||
mockPlayer(): Player;
|
||||
mockPlayer(): Person;
|
||||
/** Reputation formulas */
|
||||
reputation: ReputationFormulas;
|
||||
/** Skills formulas */
|
||||
@ -6758,7 +6705,7 @@ export interface NS {
|
||||
*
|
||||
* @returns Player info
|
||||
*/
|
||||
getPlayer(): Player;
|
||||
getPlayer(): Person;
|
||||
|
||||
/**
|
||||
* Get information about the sources of income for this run.
|
||||
|
@ -7,7 +7,7 @@ import { dialogBoxCreate } from "../ui/React/DialogBox";
|
||||
import { Money } from "../ui/React/Money";
|
||||
import { convertTimeMsToTimeElapsedString } from "../utils/StringHelperFunctions";
|
||||
import { Player } from "@player";
|
||||
import { calculateClassEarnings as calculateClassEarningsRate } from "./formulas/Class";
|
||||
import { calculateClassEarnings as calculateClassEarningsRate } from "./Formulas";
|
||||
import { Work, WorkType } from "./Work";
|
||||
import { applyWorkStats, newWorkStats, sumWorkStats, WorkStats } from "./WorkStats";
|
||||
|
||||
|
@ -4,7 +4,7 @@ import { Player } from "@player";
|
||||
import { Work, WorkType } from "./Work";
|
||||
import { influenceStockThroughCompanyWork } from "../StockMarket/PlayerInfluencing";
|
||||
import { LocationName } from "../Locations/data/LocationNames";
|
||||
import { calculateCompanyWorkStats } from "./formulas/Company";
|
||||
import { calculateCompanyWorkStats } from "./Formulas";
|
||||
import { Companies } from "../Company/Companies";
|
||||
import { applyWorkStats, scaleWorkStats, WorkStats } from "./WorkStats";
|
||||
import { Company } from "../Company/Company";
|
||||
@ -12,6 +12,7 @@ import { dialogBoxCreate } from "../ui/React/DialogBox";
|
||||
import { Reputation } from "../ui/React/Reputation";
|
||||
import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
import { CompanyPositions } from "../Company/CompanyPositions";
|
||||
|
||||
interface CompanyWorkParams {
|
||||
companyName: string;
|
||||
@ -38,7 +39,11 @@ export class CompanyWork extends Work {
|
||||
if (!Player.hasAugmentation(AugmentationNames.NeuroreceptorManager, true)) {
|
||||
focusBonus = Player.focus ? 1 : CONSTANTS.BaseFocusBonus;
|
||||
}
|
||||
return scaleWorkStats(calculateCompanyWorkStats(Player, this.getCompany()), focusBonus);
|
||||
const company = this.getCompany();
|
||||
return scaleWorkStats(
|
||||
calculateCompanyWorkStats(Player, company, CompanyPositions[Player.jobs[company.name]], company.favor),
|
||||
focusBonus,
|
||||
);
|
||||
}
|
||||
|
||||
process(cycles: number): boolean {
|
||||
|
@ -8,7 +8,7 @@ import { dialogBoxCreate } from "../ui/React/DialogBox";
|
||||
import { CrimeType } from "../utils/WorkType";
|
||||
import { Work, WorkType } from "./Work";
|
||||
import { scaleWorkStats, WorkStats } from "./WorkStats";
|
||||
import { calculateCrimeWorkStats } from "./formulas/Crime";
|
||||
import { calculateCrimeWorkStats } from "./Formulas";
|
||||
import { checkEnum } from "../utils/helpers/checkEnum";
|
||||
|
||||
interface CrimeWorkParams {
|
||||
@ -47,7 +47,7 @@ export class CrimeWork extends Work {
|
||||
}
|
||||
|
||||
earnings(): WorkStats {
|
||||
return calculateCrimeWorkStats(this.getCrime());
|
||||
return calculateCrimeWorkStats(Player, this.getCrime());
|
||||
}
|
||||
|
||||
commit(): void {
|
||||
|
@ -10,7 +10,7 @@ import { dialogBoxCreate } from "../ui/React/DialogBox";
|
||||
import { Reputation } from "../ui/React/Reputation";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
import { AugmentationNames } from "../Augmentation/data/AugmentationNames";
|
||||
import { calculateFactionExp, calculateFactionRep } from "./formulas/Faction";
|
||||
import { calculateFactionExp, calculateFactionRep } from "./Formulas";
|
||||
import { FactionWorkType } from "./data/FactionWorkType";
|
||||
|
||||
interface FactionWorkParams {
|
||||
|
142
src/Work/Formulas.ts
Normal file
142
src/Work/Formulas.ts
Normal file
@ -0,0 +1,142 @@
|
||||
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
|
||||
import { Crime } from "../Crime/Crime";
|
||||
import { newWorkStats, scaleWorkStats, WorkStats, multWorkStats } from "./WorkStats";
|
||||
import { Person } from "../PersonObjects/Person";
|
||||
import { CONSTANTS } from "../Constants";
|
||||
import { FactionWorkType } from "./data/FactionWorkType";
|
||||
import {
|
||||
getFactionFieldWorkRepGain,
|
||||
getFactionSecurityWorkRepGain,
|
||||
getHackingWorkRepGain,
|
||||
} from "../PersonObjects/formulas/reputation";
|
||||
import { Locations } from "../Locations/Locations";
|
||||
import { Location } from "../Locations/Location";
|
||||
import { Player } from "@player";
|
||||
import { Class, Classes, ClassType } from "./ClassWork";
|
||||
import { Server } from "../Server/Server";
|
||||
import { GetServer } from "../Server/AllServers";
|
||||
import { serverMetadata } from "../Server/data/servers";
|
||||
import { LocationName } from "../Locations/data/LocationNames";
|
||||
import { Company } from "../Company/Company";
|
||||
import { CompanyPosition } from "../Company/CompanyPosition";
|
||||
|
||||
const gameCPS = 1000 / CONSTANTS._idleSpeed; // 5 cycles per second
|
||||
export const FactionWorkStats: Record<FactionWorkType, WorkStats> = {
|
||||
[FactionWorkType.HACKING]: newWorkStats({ hackExp: 15 }),
|
||||
[FactionWorkType.FIELD]: newWorkStats({
|
||||
hackExp: 10,
|
||||
strExp: 10,
|
||||
defExp: 10,
|
||||
dexExp: 10,
|
||||
agiExp: 10,
|
||||
chaExp: 10,
|
||||
}),
|
||||
[FactionWorkType.SECURITY]: newWorkStats({
|
||||
hackExp: 5,
|
||||
strExp: 15,
|
||||
defExp: 15,
|
||||
dexExp: 15,
|
||||
agiExp: 15,
|
||||
}),
|
||||
};
|
||||
|
||||
export function calculateCrimeWorkStats(person: Person, crime: Crime): WorkStats {
|
||||
const gains = scaleWorkStats(
|
||||
multWorkStats(
|
||||
//Todo: rework crime and workstats interfaces to use the same naming convention for exp values, then we can just make a workStats directly from a crime.
|
||||
newWorkStats({
|
||||
money: crime.money,
|
||||
hackExp: crime.hacking_exp,
|
||||
strExp: crime.strength_exp,
|
||||
defExp: crime.defense_exp,
|
||||
dexExp: crime.dexterity_exp,
|
||||
agiExp: crime.agility_exp,
|
||||
chaExp: crime.charisma_exp,
|
||||
intExp: crime.intelligence_exp,
|
||||
}),
|
||||
person.mults,
|
||||
person.mults.crime_money * BitNodeMultipliers.CrimeMoney,
|
||||
),
|
||||
BitNodeMultipliers.CrimeExpGain,
|
||||
false,
|
||||
);
|
||||
return gains;
|
||||
}
|
||||
|
||||
export const calculateFactionRep = (person: Person, type: FactionWorkType, favor: number): number => {
|
||||
const repFormulas = {
|
||||
[FactionWorkType.HACKING]: getHackingWorkRepGain,
|
||||
[FactionWorkType.FIELD]: getFactionFieldWorkRepGain,
|
||||
[FactionWorkType.SECURITY]: getFactionSecurityWorkRepGain,
|
||||
};
|
||||
return repFormulas[type](person, favor);
|
||||
};
|
||||
|
||||
export function calculateFactionExp(person: Person, type: FactionWorkType): WorkStats {
|
||||
return scaleWorkStats(
|
||||
multWorkStats(FactionWorkStats[type], person.mults),
|
||||
BitNodeMultipliers.FactionWorkExpGain / gameCPS,
|
||||
);
|
||||
}
|
||||
|
||||
/** Calculate cost for a class */
|
||||
export function calculateCost(classs: Class, location: Location): number {
|
||||
const serverMeta = serverMetadata.find((s) => s.specialName === location.name);
|
||||
const server = GetServer(serverMeta ? serverMeta.hostname : "");
|
||||
const discount = (server as Server).backdoorInstalled ? 0.9 : 1;
|
||||
return classs.earnings.money * location.costMult * discount;
|
||||
}
|
||||
|
||||
export function calculateClassEarnings(person: Person, type: ClassType, locationName: LocationName): WorkStats {
|
||||
const hashManager = Player.hashManager;
|
||||
const classs = Classes[type];
|
||||
const location = Locations[locationName];
|
||||
|
||||
const hashMult = [ClassType.GymAgility, ClassType.GymDefense, ClassType.GymStrength, ClassType.GymDexterity].includes(
|
||||
type,
|
||||
)
|
||||
? hashManager.getTrainingMult()
|
||||
: hashManager.getStudyMult();
|
||||
|
||||
const earnings = multWorkStats(
|
||||
scaleWorkStats(classs.earnings, (location.expMult / gameCPS) * hashMult, false),
|
||||
person.mults,
|
||||
);
|
||||
earnings.money = calculateCost(classs, location) / gameCPS;
|
||||
return earnings;
|
||||
}
|
||||
|
||||
export const calculateCompanyWorkStats = (
|
||||
worker: Person,
|
||||
company: Company,
|
||||
companyPosition: CompanyPosition,
|
||||
favor: number,
|
||||
): WorkStats => {
|
||||
// If player has SF-11, calculate salary multiplier from favor
|
||||
const favorMult = isNaN(favor) ? 1 : 1 + favor / 100;
|
||||
const bn11Mult = Player.sourceFileLvl(11) > 0 ? favorMult : 1;
|
||||
|
||||
const gains = scaleWorkStats(
|
||||
multWorkStats(
|
||||
{
|
||||
money: companyPosition.baseSalary * company.salaryMultiplier * bn11Mult * BitNodeMultipliers.CompanyWorkMoney,
|
||||
hackExp: companyPosition.hackingExpGain,
|
||||
strExp: companyPosition.strengthExpGain,
|
||||
defExp: companyPosition.defenseExpGain,
|
||||
dexExp: companyPosition.dexterityExpGain,
|
||||
agiExp: companyPosition.agilityExpGain,
|
||||
chaExp: companyPosition.charismaExpGain,
|
||||
},
|
||||
worker.mults,
|
||||
worker.mults.work_money,
|
||||
),
|
||||
company.expMultiplier * BitNodeMultipliers.CompanyWorkExpGain,
|
||||
false,
|
||||
);
|
||||
|
||||
const jobPerformance = companyPosition.calculateJobPerformance(worker);
|
||||
|
||||
gains.reputation = jobPerformance * worker.mults.company_rep * favorMult;
|
||||
|
||||
return gains;
|
||||
};
|
@ -1,5 +1,6 @@
|
||||
import { Person } from "src/PersonObjects/Person";
|
||||
import { Player } from "@player";
|
||||
import { Multipliers } from "../PersonObjects/Multipliers";
|
||||
|
||||
export interface WorkStats {
|
||||
money: number;
|
||||
@ -13,19 +14,7 @@ export interface WorkStats {
|
||||
intExp: number;
|
||||
}
|
||||
|
||||
interface newWorkStatsParams {
|
||||
money?: number;
|
||||
reputation?: number;
|
||||
hackExp?: number;
|
||||
strExp?: number;
|
||||
defExp?: number;
|
||||
dexExp?: number;
|
||||
agiExp?: number;
|
||||
chaExp?: number;
|
||||
intExp?: number;
|
||||
}
|
||||
|
||||
export const newWorkStats = (params?: newWorkStatsParams): WorkStats => {
|
||||
export const newWorkStats = (params?: Partial<WorkStats>): WorkStats => {
|
||||
return {
|
||||
money: params?.money ?? 0,
|
||||
reputation: params?.reputation ?? 0,
|
||||
@ -39,6 +28,7 @@ export const newWorkStats = (params?: newWorkStatsParams): WorkStats => {
|
||||
};
|
||||
};
|
||||
|
||||
/** Add two workStats objects */
|
||||
export const sumWorkStats = (w0: WorkStats, w1: WorkStats): WorkStats => {
|
||||
return {
|
||||
money: w0.money + w1.money,
|
||||
@ -53,6 +43,7 @@ export const sumWorkStats = (w0: WorkStats, w1: WorkStats): WorkStats => {
|
||||
};
|
||||
};
|
||||
|
||||
/** Scale all stats on a WorkStats object by a number. Money scaling optional but defaults to true. */
|
||||
export const scaleWorkStats = (w: WorkStats, n: number, scaleMoney = true): WorkStats => {
|
||||
const m = scaleMoney ? n : 1;
|
||||
return {
|
||||
@ -107,3 +98,18 @@ export const applyWorkStatsExp = (target: Person, workStats: WorkStats, cycles:
|
||||
target.gainIntelligenceExp(gains.intExp);
|
||||
return gains;
|
||||
};
|
||||
|
||||
/** Calculate the application of a person's multipliers to a WorkStats object */
|
||||
export function multWorkStats(workStats: Partial<WorkStats>, mults: Multipliers, moneyMult = 1, repMult = 1) {
|
||||
return {
|
||||
money: (workStats.money ?? 0) * moneyMult,
|
||||
reputation: (workStats.reputation ?? 0) * repMult,
|
||||
hackExp: (workStats.hackExp ?? 0) * mults.hacking_exp,
|
||||
strExp: (workStats.strExp ?? 0) * mults.strength_exp,
|
||||
defExp: (workStats.defExp ?? 0) * mults.defense_exp,
|
||||
dexExp: (workStats.dexExp ?? 0) * mults.dexterity_exp,
|
||||
agiExp: (workStats.agiExp ?? 0) * mults.agility_exp,
|
||||
chaExp: (workStats.chaExp ?? 0) * mults.charisma_exp,
|
||||
intExp: workStats.intExp ?? 0,
|
||||
};
|
||||
}
|
||||
|
@ -1,53 +0,0 @@
|
||||
import { Locations } from "../../Locations/Locations";
|
||||
import { Location } from "../../Locations/Location";
|
||||
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { Player } from "@player";
|
||||
import { Class, Classes, ClassType } from "../ClassWork";
|
||||
import { WorkStats } from "../WorkStats";
|
||||
import { Server } from "../../Server/Server";
|
||||
import { GetServer } from "../../Server/AllServers";
|
||||
import { serverMetadata } from "../../Server/data/servers";
|
||||
import { Person } from "../../PersonObjects/Person";
|
||||
import { LocationName } from "../../Locations/data/LocationNames";
|
||||
|
||||
const gameCPS = 1000 / CONSTANTS._idleSpeed; // 5 cycles per second
|
||||
|
||||
export function calculateCost(classs: Class, location: Location): number {
|
||||
const serverMeta = serverMetadata.find((s) => s.specialName === location.name);
|
||||
const server = GetServer(serverMeta ? serverMeta.hostname : "");
|
||||
const discount = (server as Server).backdoorInstalled ? 0.9 : 1;
|
||||
return classs.earnings.money * location.costMult * discount;
|
||||
}
|
||||
|
||||
export function calculateClassEarnings(person: Person, type: ClassType, locationName: LocationName): WorkStats {
|
||||
//Find cost and exp gain per game cycle
|
||||
const hashManager = Player.hashManager;
|
||||
const classs = Classes[type];
|
||||
const location = Locations[locationName];
|
||||
|
||||
const hashMult = [ClassType.GymAgility, ClassType.GymDefense, ClassType.GymStrength, ClassType.GymDexterity].includes(
|
||||
type,
|
||||
)
|
||||
? hashManager.getTrainingMult()
|
||||
: hashManager.getStudyMult();
|
||||
|
||||
const cost = calculateCost(classs, location) / gameCPS;
|
||||
const hackExp = ((classs.earnings.hackExp * location.expMult) / gameCPS) * hashMult;
|
||||
const strExp = ((classs.earnings.strExp * location.expMult) / gameCPS) * hashMult;
|
||||
const defExp = ((classs.earnings.defExp * location.expMult) / gameCPS) * hashMult;
|
||||
const dexExp = ((classs.earnings.dexExp * location.expMult) / gameCPS) * hashMult;
|
||||
const agiExp = ((classs.earnings.agiExp * location.expMult) / gameCPS) * hashMult;
|
||||
const chaExp = ((classs.earnings.chaExp * location.expMult) / gameCPS) * hashMult;
|
||||
return {
|
||||
money: cost,
|
||||
reputation: 0,
|
||||
hackExp: hackExp * person.mults.hacking_exp * BitNodeMultipliers.ClassGymExpGain,
|
||||
strExp: strExp * person.mults.strength_exp * BitNodeMultipliers.ClassGymExpGain,
|
||||
defExp: defExp * person.mults.defense_exp * BitNodeMultipliers.ClassGymExpGain,
|
||||
dexExp: dexExp * person.mults.dexterity_exp * BitNodeMultipliers.ClassGymExpGain,
|
||||
agiExp: agiExp * person.mults.agility_exp * BitNodeMultipliers.ClassGymExpGain,
|
||||
chaExp: chaExp * person.mults.charisma_exp * BitNodeMultipliers.ClassGymExpGain,
|
||||
intExp: 0,
|
||||
};
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
import { CompanyPositions } from "../../Company/CompanyPositions";
|
||||
import { Company } from "../../Company/Company";
|
||||
import { Player } from "@player";
|
||||
import { WorkStats } from "../WorkStats";
|
||||
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { Person } from "../../PersonObjects/Person";
|
||||
|
||||
export const calculateCompanyWorkStats = (worker: Person, company: Company): WorkStats => {
|
||||
const companyPositionName = Player.jobs[company.name];
|
||||
const companyPosition = CompanyPositions[companyPositionName];
|
||||
|
||||
// If player has SF-11, calculate salary multiplier from favor
|
||||
let favorMult = 1 + company.favor / 100;
|
||||
if (isNaN(favorMult)) {
|
||||
favorMult = 1;
|
||||
}
|
||||
|
||||
let bn11Mult = 1;
|
||||
if (Player.sourceFileLvl(11) > 0) {
|
||||
bn11Mult = favorMult;
|
||||
}
|
||||
|
||||
let jobPerformance = companyPosition.calculateJobPerformance(
|
||||
worker.skills.hacking,
|
||||
worker.skills.strength,
|
||||
worker.skills.defense,
|
||||
worker.skills.dexterity,
|
||||
worker.skills.agility,
|
||||
worker.skills.charisma,
|
||||
);
|
||||
|
||||
jobPerformance += worker.skills.intelligence / CONSTANTS.MaxSkillLevel;
|
||||
|
||||
return {
|
||||
money:
|
||||
companyPosition.baseSalary *
|
||||
company.salaryMultiplier *
|
||||
worker.mults.work_money *
|
||||
BitNodeMultipliers.CompanyWorkMoney *
|
||||
bn11Mult,
|
||||
reputation: jobPerformance * worker.mults.company_rep * favorMult,
|
||||
hackExp:
|
||||
companyPosition.hackingExpGain *
|
||||
company.expMultiplier *
|
||||
worker.mults.hacking_exp *
|
||||
BitNodeMultipliers.CompanyWorkExpGain,
|
||||
strExp:
|
||||
companyPosition.strengthExpGain *
|
||||
company.expMultiplier *
|
||||
worker.mults.strength_exp *
|
||||
BitNodeMultipliers.CompanyWorkExpGain,
|
||||
defExp:
|
||||
companyPosition.defenseExpGain *
|
||||
company.expMultiplier *
|
||||
worker.mults.defense_exp *
|
||||
BitNodeMultipliers.CompanyWorkExpGain,
|
||||
dexExp:
|
||||
companyPosition.dexterityExpGain *
|
||||
company.expMultiplier *
|
||||
worker.mults.dexterity_exp *
|
||||
BitNodeMultipliers.CompanyWorkExpGain,
|
||||
agiExp:
|
||||
companyPosition.agilityExpGain *
|
||||
company.expMultiplier *
|
||||
worker.mults.agility_exp *
|
||||
BitNodeMultipliers.CompanyWorkExpGain,
|
||||
chaExp:
|
||||
companyPosition.charismaExpGain *
|
||||
company.expMultiplier *
|
||||
worker.mults.charisma_exp *
|
||||
BitNodeMultipliers.CompanyWorkExpGain,
|
||||
intExp: 0,
|
||||
};
|
||||
};
|
@ -1,23 +0,0 @@
|
||||
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||
import { Crime } from "src/Crime/Crime";
|
||||
import { newWorkStats, scaleWorkStats, WorkStats } from "../WorkStats";
|
||||
import { Player } from "@player";
|
||||
|
||||
export const calculateCrimeWorkStats = (crime: Crime): WorkStats => {
|
||||
const gains = scaleWorkStats(
|
||||
newWorkStats({
|
||||
money: crime.money * Player.mults.crime_money,
|
||||
hackExp: crime.hacking_exp * 2 * Player.mults.hacking_exp,
|
||||
strExp: crime.strength_exp * 2 * Player.mults.strength_exp,
|
||||
defExp: crime.defense_exp * 2 * Player.mults.defense_exp,
|
||||
dexExp: crime.dexterity_exp * 2 * Player.mults.dexterity_exp,
|
||||
agiExp: crime.agility_exp * 2 * Player.mults.agility_exp,
|
||||
chaExp: crime.charisma_exp * 2 * Player.mults.charisma_exp,
|
||||
intExp: crime.intelligence_exp * 2,
|
||||
}),
|
||||
BitNodeMultipliers.CrimeExpGain,
|
||||
false,
|
||||
);
|
||||
gains.money *= BitNodeMultipliers.CrimeMoney;
|
||||
return gains;
|
||||
};
|
@ -1,55 +0,0 @@
|
||||
import { Person } from "../../PersonObjects/Person";
|
||||
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
|
||||
import { CONSTANTS } from "../../Constants";
|
||||
import { FactionWorkType } from "../data/FactionWorkType";
|
||||
import { newWorkStats, WorkStats } from "../WorkStats";
|
||||
import {
|
||||
getFactionFieldWorkRepGain,
|
||||
getFactionSecurityWorkRepGain,
|
||||
getHackingWorkRepGain,
|
||||
} from "../../PersonObjects/formulas/reputation";
|
||||
|
||||
const gameCPS = 1000 / CONSTANTS._idleSpeed; // 5 cycles per second
|
||||
|
||||
export const FactionWorkStats: Record<FactionWorkType, WorkStats> = {
|
||||
[FactionWorkType.HACKING]: newWorkStats({ hackExp: 15 }),
|
||||
[FactionWorkType.FIELD]: newWorkStats({
|
||||
hackExp: 10,
|
||||
strExp: 10,
|
||||
defExp: 10,
|
||||
dexExp: 10,
|
||||
agiExp: 10,
|
||||
chaExp: 10,
|
||||
}),
|
||||
[FactionWorkType.SECURITY]: newWorkStats({
|
||||
hackExp: 5,
|
||||
strExp: 15,
|
||||
defExp: 15,
|
||||
dexExp: 15,
|
||||
agiExp: 15,
|
||||
}),
|
||||
};
|
||||
|
||||
export const calculateFactionRep = (person: Person, tpe: FactionWorkType, favor: number): number => {
|
||||
const repFormulas = {
|
||||
[FactionWorkType.HACKING]: getHackingWorkRepGain,
|
||||
[FactionWorkType.FIELD]: getFactionFieldWorkRepGain,
|
||||
[FactionWorkType.SECURITY]: getFactionSecurityWorkRepGain,
|
||||
};
|
||||
return repFormulas[tpe](person, favor);
|
||||
};
|
||||
|
||||
export function calculateFactionExp(person: Person, tpe: FactionWorkType): WorkStats {
|
||||
const baseStats = FactionWorkStats[tpe];
|
||||
return {
|
||||
money: 0,
|
||||
reputation: 0,
|
||||
hackExp: (baseStats.hackExp * person.mults.hacking_exp * BitNodeMultipliers.FactionWorkExpGain) / gameCPS,
|
||||
strExp: (baseStats.strExp * person.mults.strength_exp * BitNodeMultipliers.FactionWorkExpGain) / gameCPS,
|
||||
defExp: (baseStats.defExp * person.mults.defense_exp * BitNodeMultipliers.FactionWorkExpGain) / gameCPS,
|
||||
dexExp: (baseStats.dexExp * person.mults.dexterity_exp * BitNodeMultipliers.FactionWorkExpGain) / gameCPS,
|
||||
agiExp: (baseStats.agiExp * person.mults.agility_exp * BitNodeMultipliers.FactionWorkExpGain) / gameCPS,
|
||||
chaExp: (baseStats.chaExp * person.mults.charisma_exp * BitNodeMultipliers.FactionWorkExpGain) / gameCPS,
|
||||
intExp: 0,
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user