diff --git a/src/Gang/Gang.ts b/src/Gang/Gang.ts index eba5a2efc..7cd4141af 100644 --- a/src/Gang/Gang.ts +++ b/src/Gang/Gang.ts @@ -14,7 +14,6 @@ import { getRandomInt } from "../utils/helpers/getRandomInt"; import { GangMemberUpgrade } from "./GangMemberUpgrade"; import { GangConstants } from "./data/Constants"; -import { CONSTANTS } from "../Constants"; import { GangMemberTasks } from "./GangMemberTasks"; import { IAscensionResult } from "./IAscensionResult"; @@ -33,8 +32,11 @@ export class Gang { isHackingGang: boolean; + /** Respect gain rate, per cycle */ respectGainRate: number; + /** Wanted level gain rate, per cycle */ wantedGainRate: number; + /** Money gain rate, per cycle */ moneyGainRate: number; storedCycles: number; @@ -80,19 +82,16 @@ export class Gang { return AllGangs[this.facName].territory; } + /** Main process function called by the engine loop every game cycle */ process(numCycles = 1): void { - // Run every cycle - const CyclesPerSecond = 1000 / CONSTANTS.MilliPerCycle; - if (isNaN(numCycles)) { console.error(`NaN passed into Gang.process(): ${numCycles}`); } this.storedCycles += numCycles; + if (this.storedCycles < GangConstants.minCyclesToProcess) return; - // Only process if there are at least 2 seconds, and at most 5 seconds - // works out as 5 * 5 for 25x per cycle during bonus time - if (this.storedCycles < 2 * CyclesPerSecond) return; - const cycles = Math.min(this.storedCycles, 5 * CyclesPerSecond); + // Calculate how many cycles to actually process. + const cycles = Math.min(this.storedCycles, GangConstants.maxCyclesToProcess); try { this.processGains(cycles); @@ -104,50 +103,56 @@ export class Gang { } } - processGains(numCycles = 1): void { - // Get gains per cycle - let moneyGains = 0; - let respectGains = 0; - let wantedLevelGains = 0; + /** Process respect/wanted/money gains + * @param numCycles The number of cycles to process. */ + processGains(numCycles: number): void { + let moneyGainPerCycle = 0; + let wantedLevelGainPerCycle = 0; + let respectGainsTotal = 0; + /** Number of members performing actions that lower wanted level */ let justice = 0; - for (let i = 0; i < this.members.length; ++i) { - respectGains += this.members[i].earnRespect(numCycles, this); - moneyGains += this.members[i].calculateMoneyGain(this); - const wantedLevelGain = this.members[i].calculateWantedLevelGain(this); - wantedLevelGains += wantedLevelGain; - if (this.members[i].getTask().baseWanted < 0) justice++; // this member is lowering wanted. + + for (const member of this.members) { + respectGainsTotal += member.earnRespect(numCycles, this); + moneyGainPerCycle += member.calculateMoneyGain(this); + wantedLevelGainPerCycle += member.calculateWantedLevelGain(this); + if (member.getTask().baseWanted < 0) justice++; } - this.respectGainRate = respectGains; - this.wantedGainRate = wantedLevelGains; - this.moneyGainRate = moneyGains; - const gain = respectGains; - this.respect += gain; + + this.respectGainRate = respectGainsTotal / numCycles; + this.wantedGainRate = wantedLevelGainPerCycle; + this.moneyGainRate = moneyGainPerCycle; + this.respect += respectGainsTotal; + // Faction reputation gains is respect gain divided by some constant - const fac = Factions[this.facName]; - if (!fac) { + const gangFaction = Factions[this.facName]; + if (!gangFaction) { dialogBoxCreate( "ERROR: Could not get Faction associates with your gang. This is a bug, please report to game dev", ); throw new Error("Could not find the faction associated with this gang."); } - const favorMult = 1 + fac.favor / 100; + const favorMult = 1 + gangFaction.favor / 100; - fac.playerReputation += (Player.mults.faction_rep * gain * favorMult) / GangConstants.GangRespectToReputationRatio; + gangFaction.playerReputation += + (Player.mults.faction_rep * respectGainsTotal * favorMult) / GangConstants.GangRespectToReputationRatio; - if (!(this.wanted === 1 && wantedLevelGains < 0)) { + if (!(this.wanted === 1 && wantedLevelGainPerCycle < 0)) { const oldWanted = this.wanted; - let newWanted = oldWanted + wantedLevelGains * numCycles; + let newWanted = oldWanted + wantedLevelGainPerCycle * numCycles; newWanted = newWanted * (1 - justice * 0.001); // safeguard // Prevent overflow - if (wantedLevelGains <= 0 && newWanted > oldWanted) newWanted = 1; + if (wantedLevelGainPerCycle <= 0 && newWanted > oldWanted) newWanted = 1; this.wanted = newWanted; if (this.wanted < 1) this.wanted = 1; } - Player.gainMoney(moneyGains * numCycles, "gang"); + Player.gainMoney(moneyGainPerCycle * numCycles, "gang"); } - processTerritoryAndPowerGains(numCycles = 1): void { + /** Process Territory and Power + * @param numCycles The number of cycles to process. */ + processTerritoryAndPowerGains(numCycles: number): void { function calculateTerritoryGain(winGang: string, loseGang: string): number { const powerBonus = Math.max(1, 1 + Math.log(AllGangs[winGang].power / AllGangs[loseGang].power) / Math.log(50)); const gains = Math.min(AllGangs[loseGang].territory, powerBonus * 0.0001 * (Math.random() + 0.5)); @@ -250,10 +255,12 @@ export class Gang { } } - processExperienceGains(numCycles = 1): void { - for (let i = 0; i < this.members.length; ++i) { - this.members[i].gainExperience(numCycles); - this.members[i].updateSkillLevels(); + /** Process member experience gain + * @param numCycles The number of cycles to process. */ + processExperienceGains(numCycles: number): void { + for (const member of this.members) { + member.gainExperience(numCycles); + member.updateSkillLevels(); } } diff --git a/src/Gang/data/Constants.ts b/src/Gang/data/Constants.ts index 2c4f072cf..f19c322de 100644 --- a/src/Gang/data/Constants.ts +++ b/src/Gang/data/Constants.ts @@ -1,3 +1,4 @@ +import { CONSTANTS } from "../../Constants"; import { FactionNames } from "../../Faction/data/FactionNames"; export const GangConstants = { @@ -18,4 +19,8 @@ export const GangConstants = { FactionNames.TheBlackHand, ] as string[], GangKarmaRequirement: -54000, + /** Normal number of game cycles processed at once (2 seconds) */ + minCyclesToProcess: 2000 / CONSTANTS.MilliPerCycle, + /** Maximum number of cycles to process at once during bonus time (5 seconds) */ + maxCyclesToProcess: 5000 / CONSTANTS.MilliPerCycle, };