import { BladeburnerConstants } from "./data/Constants"; import { getRandomInt } from "../../utils/helpers/getRandomInt"; import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver"; import { addOffset } from "../../utils/helpers/addOffset"; interface IChangePopulationByCountParams { estChange: number; estOffset: number; } interface IChangePopulationByPercentageParams { nonZero: boolean; changeEstEqually: boolean; } export class City { /** * Name of the city. */ name = ""; /** * Population of the city. */ pop = 0; /** * Population estimation of the city. */ popEst = 0; /** * Number of communities in the city. */ comms = 0; /** * Estimated number of communities in the city. */ commsEst = 0; /** * Chaos level of the city. */ chaos = 0; constructor(name: string = BladeburnerConstants.CityNames[2]) { this.name = name; // Synthoid population and estimate this.pop = getRandomInt(BladeburnerConstants.PopulationThreshold, 1.5 * BladeburnerConstants.PopulationThreshold); this.popEst = this.pop * (Math.random() + 0.5); // Number of Synthoid communities population and estimate this.comms = getRandomInt(5, 150) this.commsEst = this.comms + getRandomInt(-5, 5); if (this.commsEst < 0) this.commsEst = 0; this.chaos = 0; } /** * p is the percentage, not the multiplier (e.g. pass in p = 5 for 5%) */ changeChaosByPercentage(p: number): void { if (isNaN(p)) {throw new Error("NaN passed into City.chaosChaosByPercentage()");} if (p === 0) {return;} this.chaos += this.chaos * (p/100); if (this.chaos < 0) {this.chaos = 0;} } improvePopulationEstimateByCount(n: number): void { if (isNaN(n)) {throw new Error("NaN passeed into City.improvePopulationEstimateByCount()");} if (this.popEst < this.pop) { this.popEst += n; if (this.popEst > this.pop) {this.popEst = this.pop;} } else if (this.popEst > this.pop) { this.popEst -= n; if (this.popEst < this.pop) {this.popEst = this.pop;} } } /** * p is the percentage, not the multiplier (e.g. pass in p = 5 for 5%) */ improvePopulationEstimateByPercentage(p: number, skillMult=1): void { p = p*skillMult; if (isNaN(p)) {throw new Error("NaN passed into City.improvePopulationEstimateByPercentage()");} if (this.popEst < this.pop) { ++this.popEst; // In case estimate is 0 this.popEst *= (1 + (p/100)); if (this.popEst > this.pop) {this.popEst = this.pop;} } else if (this.popEst > this.pop) { this.popEst *= (1 - (p/100)); if (this.popEst < this.pop) {this.popEst = this.pop;} } } improveCommunityEstimate(n=1): void { if (isNaN(n)) {throw new Error("NaN passed into City.improveCommunityEstimate()");} if (this.commsEst < this.comms) { this.commsEst += n; if (this.commsEst > this.comms) {this.commsEst = this.comms;} } else if (this.commsEst > this.comms) { this.commsEst -= n; if (this.commsEst < this.comms) {this.commsEst = this.comms;} } } /** * @params options: * estChange(int): How much the estimate should change by * estOffset(int): Add offset to estimate (offset by percentage) */ changePopulationByCount(n: number, params: IChangePopulationByCountParams = {estChange: 0, estOffset: 0}): void { if (isNaN(n)) {throw new Error("NaN passed into City.changePopulationByCount()");} this.pop += n; if (params.estChange && !isNaN(params.estChange)) {this.popEst += params.estChange;} if (params.estOffset) { this.popEst = addOffset(this.popEst, params.estOffset); } this.popEst = Math.max(this.popEst, 0); } /** * @p is the percentage, not the multiplier. e.g. pass in p = 5 for 5% * @params options: * changeEstEqually(bool) - Change the population estimate by an equal amount * nonZero (bool) - Set to true to ensure that population always changes by at least 1 */ changePopulationByPercentage(p: number, params: IChangePopulationByPercentageParams={nonZero: false, changeEstEqually: false}): number { if (isNaN(p)) {throw new Error("NaN passed into City.changePopulationByPercentage()");} if (p === 0) {return 0;} let change = Math.round(this.pop * (p/100)); // Population always changes by at least 1 if (params.nonZero && change === 0) { p > 0 ? change = 1 : change = -1; } this.pop += change; if (params.changeEstEqually) { this.popEst += change; if (this.popEst < 0) {this.popEst = 0;} } return change; } changeChaosByCount(n: number): void { if (isNaN(n)) {throw new Error("NaN passed into City.changeChaosByCount()");} if (n === 0) {return;} this.chaos += n; if (this.chaos < 0) {this.chaos = 0;} } /** * Serialize the current object to a JSON save state. */ toJSON(): any { return Generic_toJSON("City", this); } /** * Initiatizes a City object from a JSON save state. */ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types static fromJSON(value: any): City { return Generic_fromJSON(City, value.data); } } Reviver.constructors.City = City;