formulas for gang stuff

This commit is contained in:
Olivier Gagnon
2021-12-08 18:19:30 -05:00
parent d01d75606a
commit 2af57cb01e
141 changed files with 2828 additions and 1662 deletions

View File

@@ -4,10 +4,9 @@ import { GangMemberUpgrade } from "./GangMemberUpgrade";
import { GangMemberUpgrades } from "./GangMemberUpgrades";
import { IAscensionResult } from "./IAscensionResult";
import { IPlayer } from "../PersonObjects/IPlayer";
import { AllGangs } from "./AllGangs";
import { IGang } from "./IGang";
import { Generic_fromJSON, Generic_toJSON, Reviver } from "../utils/JSONReviver";
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
import { calculateRespectGain, calculateMoneyGain, calculateWantedLevelGain } from "./formulas/formulas";
interface IMults {
hack: number;
@@ -64,7 +63,7 @@ export class GangMember {
}
calculateAscensionMult(points: number): number {
return Math.max(Math.pow(points / 2000, 0.7), 1);
return Math.max(Math.pow(points / 2000, 0.5), 1);
}
updateSkillLevels(): void {
@@ -108,71 +107,32 @@ export class GangMember {
calculateRespectGain(gang: IGang): number {
const task = this.getTask();
if (task.baseRespect === 0) return 0;
let statWeight =
(task.hackWeight / 100) * this.hack +
(task.strWeight / 100) * this.str +
(task.defWeight / 100) * this.def +
(task.dexWeight / 100) * this.dex +
(task.agiWeight / 100) * this.agi +
(task.chaWeight / 100) * this.cha;
statWeight -= 4 * task.difficulty;
if (statWeight <= 0) return 0;
const territoryMult = Math.max(
0.005,
Math.pow(AllGangs[gang.facName].territory * 100, task.territory.respect) / 100,
);
const territoryPenalty = (0.2 * gang.getTerritory() + 0.8) * BitNodeMultipliers.GangSoftcap;
if (isNaN(territoryMult) || territoryMult <= 0) return 0;
const respectMult = gang.getWantedPenalty();
return Math.pow(11 * task.baseRespect * statWeight * territoryMult * respectMult, territoryPenalty);
const g = {
respect: gang.respect,
wantedLevel: gang.wanted,
territory: gang.getTerritory(),
};
return calculateRespectGain(g, this, task);
}
calculateWantedLevelGain(gang: IGang): number {
const task = this.getTask();
if (task.baseWanted === 0) return 0;
let statWeight =
(task.hackWeight / 100) * this.hack +
(task.strWeight / 100) * this.str +
(task.defWeight / 100) * this.def +
(task.dexWeight / 100) * this.dex +
(task.agiWeight / 100) * this.agi +
(task.chaWeight / 100) * this.cha;
statWeight -= 3.5 * task.difficulty;
if (statWeight <= 0) return 0;
const territoryMult = Math.max(
0.005,
Math.pow(AllGangs[gang.facName].territory * 100, task.territory.wanted) / 100,
);
if (isNaN(territoryMult) || territoryMult <= 0) return 0;
if (task.baseWanted < 0) {
return 0.4 * task.baseWanted * statWeight * territoryMult;
}
const calc = (7 * task.baseWanted) / Math.pow(3 * statWeight * territoryMult, 0.8);
// Put an arbitrary cap on this to prevent wanted level from rising too fast if the
// denominator is very small. Might want to rethink formula later
return Math.min(100, calc);
const g = {
respect: gang.respect,
wantedLevel: gang.wanted,
territory: gang.getTerritory(),
};
return calculateWantedLevelGain(g, this, task);
}
calculateMoneyGain(gang: IGang): number {
const task = this.getTask();
if (task.baseMoney === 0) return 0;
let statWeight =
(task.hackWeight / 100) * this.hack +
(task.strWeight / 100) * this.str +
(task.defWeight / 100) * this.def +
(task.dexWeight / 100) * this.dex +
(task.agiWeight / 100) * this.agi +
(task.chaWeight / 100) * this.cha;
statWeight -= 3.2 * task.difficulty;
if (statWeight <= 0) return 0;
const territoryMult = Math.max(0.005, Math.pow(AllGangs[gang.facName].territory * 100, task.territory.money) / 100);
if (isNaN(territoryMult) || territoryMult <= 0) return 0;
const respectMult = gang.getWantedPenalty();
const territoryPenalty = (0.2 * gang.getTerritory() + 0.8) * BitNodeMultipliers.GangSoftcap;
return Math.pow(5 * task.baseMoney * statWeight * territoryMult * respectMult, territoryPenalty);
const g = {
respect: gang.respect,
wantedLevel: gang.wanted,
territory: gang.getTerritory(),
};
return calculateMoneyGain(g, this, task);
}
expMult(): IMults {
@@ -193,12 +153,36 @@ export class GangMember {
const difficultyPerCycles = difficultyMult * numCycles;
const weightDivisor = 1500;
const expMult = this.expMult();
this.hack_exp += (task.hackWeight / weightDivisor) * difficultyPerCycles * expMult.hack;
this.str_exp += (task.strWeight / weightDivisor) * difficultyPerCycles * expMult.str;
this.def_exp += (task.defWeight / weightDivisor) * difficultyPerCycles * expMult.def;
this.dex_exp += (task.dexWeight / weightDivisor) * difficultyPerCycles * expMult.dex;
this.agi_exp += (task.agiWeight / weightDivisor) * difficultyPerCycles * expMult.agi;
this.cha_exp += (task.chaWeight / weightDivisor) * difficultyPerCycles * expMult.cha;
this.hack_exp +=
(task.hackWeight / weightDivisor) *
difficultyPerCycles *
expMult.hack *
this.calculateAscensionMult(this.hack_asc_points);
this.str_exp +=
(task.strWeight / weightDivisor) *
difficultyPerCycles *
expMult.str *
this.calculateAscensionMult(this.str_asc_points);
this.def_exp +=
(task.defWeight / weightDivisor) *
difficultyPerCycles *
expMult.def *
this.calculateAscensionMult(this.def_asc_points);
this.dex_exp +=
(task.dexWeight / weightDivisor) *
difficultyPerCycles *
expMult.dex *
this.calculateAscensionMult(this.dex_asc_points);
this.agi_exp +=
(task.agiWeight / weightDivisor) *
difficultyPerCycles *
expMult.agi *
this.calculateAscensionMult(this.agi_asc_points);
this.cha_exp +=
(task.chaWeight / weightDivisor) *
difficultyPerCycles *
expMult.cha *
this.calculateAscensionMult(this.cha_asc_points);
}
recordEarnedRespect(numCycles = 1, gang: IGang): void {

View File

@@ -0,0 +1,73 @@
import { BitNodeMultipliers } from "../../BitNode/BitNodeMultipliers";
import { GangMember } from "../GangMember";
import { GangMemberTask } from "../GangMemberTask";
interface Gang {
respect: number;
territory: number;
wantedLevel: number;
}
export function calculateWantedPenalty(gang: Gang): number {
return gang.respect / (gang.respect + gang.wantedLevel);
}
export function calculateRespectGain(gang: Gang, member: GangMember, task: GangMemberTask): number {
if (task.baseRespect === 0) return 0;
let statWeight =
(task.hackWeight / 100) * member.hack +
(task.strWeight / 100) * member.str +
(task.defWeight / 100) * member.def +
(task.dexWeight / 100) * member.dex +
(task.agiWeight / 100) * member.agi +
(task.chaWeight / 100) * member.cha;
statWeight -= 4 * task.difficulty;
if (statWeight <= 0) return 0;
const territoryMult = Math.max(0.005, Math.pow(gang.territory * 100, task.territory.respect) / 100);
const territoryPenalty = (0.2 * gang.territory + 0.8) * BitNodeMultipliers.GangSoftcap;
if (isNaN(territoryMult) || territoryMult <= 0) return 0;
const respectMult = calculateWantedPenalty(gang);
return Math.pow(11 * task.baseRespect * statWeight * territoryMult * respectMult, territoryPenalty);
}
export function calculateWantedLevelGain(gang: Gang, member: GangMember, task: GangMemberTask): number {
if (task.baseWanted === 0) return 0;
let statWeight =
(task.hackWeight / 100) * member.hack +
(task.strWeight / 100) * member.str +
(task.defWeight / 100) * member.def +
(task.dexWeight / 100) * member.dex +
(task.agiWeight / 100) * member.agi +
(task.chaWeight / 100) * member.cha;
statWeight -= 3.5 * task.difficulty;
if (statWeight <= 0) return 0;
const territoryMult = Math.max(0.005, Math.pow(gang.territory * 100, task.territory.wanted) / 100);
if (isNaN(territoryMult) || territoryMult <= 0) return 0;
if (task.baseWanted < 0) {
return 0.4 * task.baseWanted * statWeight * territoryMult;
}
const calc = (7 * task.baseWanted) / Math.pow(3 * statWeight * territoryMult, 0.8);
// Put an arbitrary cap on this to prevent wanted level from rising too fast if the
// denominator is very small. Might want to rethink formula later
return Math.min(100, calc);
}
export function calculateMoneyGain(gang: Gang, member: GangMember, task: GangMemberTask): number {
if (task.baseMoney === 0) return 0;
let statWeight =
(task.hackWeight / 100) * member.hack +
(task.strWeight / 100) * member.str +
(task.defWeight / 100) * member.def +
(task.dexWeight / 100) * member.dex +
(task.agiWeight / 100) * member.agi +
(task.chaWeight / 100) * member.cha;
statWeight -= 3.2 * task.difficulty;
if (statWeight <= 0) return 0;
const territoryMult = Math.max(0.005, Math.pow(gang.territory * 100, task.territory.money) / 100);
if (isNaN(territoryMult) || territoryMult <= 0) return 0;
const respectMult = calculateWantedPenalty(gang);
const territoryPenalty = (0.2 * gang.territory + 0.8) * BitNodeMultipliers.GangSoftcap;
return Math.pow(5 * task.baseMoney * statWeight * territoryMult * respectMult, territoryPenalty);
}

View File

@@ -29,6 +29,12 @@ import {
} from "../Hacking";
import { Programs } from "../Programs/Programs";
import { Formulas as IFormulas } from "../ScriptEditor/NetscriptDefinitions";
import {
calculateRespectGain,
calculateWantedLevelGain,
calculateMoneyGain,
calculateWantedPenalty,
} from "../Gang/formulas/formulas";
export interface INetscriptFormulas {
skills: {
@@ -178,5 +184,19 @@ export function NetscriptFormulas(player: IPlayer, workerScript: WorkerScript, h
return Object.assign({}, HacknetServerConstants);
},
},
gang: {
calculateWantedPenalty(gang: any): number {
return calculateWantedPenalty(gang);
},
calculateRespectGain: function (gang: any, member: any, task: any): number {
return calculateRespectGain(gang, member, task);
},
calculateWantedLevelGain: function (gang: any, member: any, task: any): number {
return calculateWantedLevelGain(gang, member, task);
},
calculateMoneyGain: function (gang: any, member: any, task: any): number {
return calculateMoneyGain(gang, member, task);
},
},
};
}

View File

@@ -3354,6 +3354,16 @@ interface HacknetServersFormulas {
constants(): any;
}
/**
* @public
*/
interface GangFormulas {
calculateWantedPenalty(gang: GangGenInfo): number;
calculateRespectGain(gang: GangGenInfo, member: GangMemberInfo, task: GangTaskStats): number;
calculateWantedLevelGain(gang: GangGenInfo, member: GangMemberInfo, task: GangTaskStats): number;
calculateMoneyGain(gang: GangGenInfo, member: GangMemberInfo, task: GangTaskStats): number;
}
/**
* @public
*/
@@ -3362,6 +3372,7 @@ export interface Formulas {
hacking: HackingFormulas;
hacknetNodes: HacknetNodesFormulas;
hacknetServers: HacknetServersFormulas;
gang: GangFormulas;
}
/**
@@ -5156,6 +5167,9 @@ export interface NS extends Singularity {
flags(schema: [string, string | number | boolean | string[]][]): any;
}
/**
* @public
*/
export interface OfficeAPI {
employees(divisionName: string, cityName: string): string[];
assignJob(divisionName: string, cityName: string, employeeName: string, job: string): Promise<void>;
@@ -5169,6 +5183,9 @@ export interface OfficeAPI {
getEmployee(divisionName: string, cityName: string, employeeName: string): Employee;
}
/**
* @public
*/
export interface WarehouseAPI {
sellMaterial(divisionName: string, cityName: string, materialName: string, amt: number, price: number): void;
sellProduct(
@@ -5216,6 +5233,9 @@ export interface WarehouseAPI {
): void;
}
/**
* @public
*/
export interface Corporation extends WarehouseAPI, OfficeAPI {
getCorporation(): CorporationInfo;
getDivision(divisionName: string): Division;
@@ -5226,6 +5246,9 @@ export interface Corporation extends WarehouseAPI, OfficeAPI {
issueDividends(percent: number): void;
}
/**
* @public
*/
interface CorporationInfo {
name: string;
funds: number;
@@ -5240,6 +5263,9 @@ interface CorporationInfo {
state: string;
}
/**
* @public
*/
interface Employee {
name: string;
mor: number;
@@ -5255,6 +5281,9 @@ interface Employee {
pos: string;
}
/**
* @public
*/
interface Product {
name: string;
dmd: number;
@@ -5263,12 +5292,18 @@ interface Product {
sCost: string | number;
}
/**
* @public
*/
interface Material {
name: string;
qty: number;
qlt: number;
}
/**
* @public
*/
interface Warehouse {
level: number;
loc: string;
@@ -5276,6 +5311,9 @@ interface Warehouse {
sizeUsed: number;
}
/**
* @public
*/
interface Office {
loc: string;
size: number;
@@ -5288,6 +5326,9 @@ interface Office {
employeeProd: EmployeeJobs;
}
/**
* @public
*/
interface EmployeeJobs {
Operations: number;
Engineer: number;
@@ -5298,6 +5339,9 @@ interface EmployeeJobs {
Unassigned: number;
}
/**
* @public
*/
interface Division {
name: string;
type: string;