2022-12-30 02:28:53 +01:00
|
|
|
import { CorpMaterialName } from "@nsdefs";
|
2022-07-15 01:00:10 +02:00
|
|
|
import { Generic_fromJSON, Generic_toJSON, IReviverValue, Reviver } from "../utils/JSONReviver";
|
2022-12-30 02:28:53 +01:00
|
|
|
import { materialNames } from "./data/Constants";
|
2021-08-31 19:04:33 +02:00
|
|
|
import { Export } from "./Export";
|
2022-12-30 02:28:53 +01:00
|
|
|
import { MaterialInfo } from "./MaterialInfo";
|
2018-12-09 14:36:18 +01:00
|
|
|
|
|
|
|
interface IConstructorParams {
|
2022-12-30 02:28:53 +01:00
|
|
|
name: CorpMaterialName;
|
2018-12-09 14:36:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
export class Material {
|
2021-09-05 01:09:30 +02:00
|
|
|
// Name of material
|
2022-12-30 02:28:53 +01:00
|
|
|
name: CorpMaterialName;
|
2018-12-09 14:36:18 +01:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
// Amount of material owned
|
|
|
|
qty = 0;
|
2018-12-09 14:36:18 +01:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
// Material's "quality". Unbounded
|
|
|
|
qlt = 0;
|
2018-12-09 14:36:18 +01:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
// How much demand the Material has in the market, and the range of possible
|
|
|
|
// values for this "demand"
|
|
|
|
dmd = 0;
|
|
|
|
dmdR: number[] = [0, 0];
|
2018-12-09 14:36:18 +01:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
// How much competition there is for this Material in the market, and the range
|
|
|
|
// of possible values for this "competition"
|
|
|
|
cmp = 0;
|
|
|
|
cmpR: number[] = [0, 0];
|
2018-12-09 14:36:18 +01:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
// Maximum volatility of this Materials stats
|
|
|
|
mv = 0;
|
2018-12-09 14:36:18 +01:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
// Markup. Determines how high of a price you can charge on the material
|
|
|
|
// compared to the market price without suffering loss in # of sales
|
|
|
|
// Quality is divided by this to determine markup limits
|
|
|
|
// e,g, If mku is 10 and quality is 100 then you can markup prices by 100/10 = 10
|
|
|
|
mku = 0;
|
2018-12-09 14:36:18 +01:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
// How much of this material is being bought, sold, imported and produced every second
|
|
|
|
buy = 0;
|
|
|
|
sll = 0;
|
|
|
|
prd = 0;
|
|
|
|
imp = 0;
|
2018-12-09 14:36:18 +01:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
// Exports of this material to another warehouse/industry
|
|
|
|
exp: Export[] = [];
|
2018-12-09 14:36:18 +01:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
// Total amount of this material exported in the last cycle
|
|
|
|
totalExp = 0;
|
2018-12-09 14:36:18 +01:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
// Cost / sec to buy this material. AKA Market Price
|
|
|
|
bCost = 0;
|
2018-12-09 14:36:18 +01:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
// Cost / sec to sell this material
|
|
|
|
sCost: string | number = 0;
|
2018-12-09 14:36:18 +01:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
// Flags to keep track of whether production and/or sale of this material is limited
|
|
|
|
// [Whether production/sale is limited, limit amount]
|
|
|
|
prdman: [boolean, number] = [false, 0]; // Production
|
|
|
|
sllman: [boolean, string | number] = [false, 0]; // Sale
|
2018-12-09 14:36:18 +01:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
// Flags that signal whether automatic sale pricing through Market TA is enabled
|
|
|
|
marketTa1 = false;
|
|
|
|
marketTa2 = false;
|
|
|
|
marketTa2Price = 0;
|
2018-12-09 14:36:18 +01:00
|
|
|
|
2022-01-22 13:32:35 +01:00
|
|
|
// Determines the maximum amount of this material that can be sold in one market cycle
|
|
|
|
maxsll = 0;
|
|
|
|
|
2022-12-30 02:28:53 +01:00
|
|
|
constructor(params?: IConstructorParams) {
|
|
|
|
this.name = params?.name ?? materialNames[0];
|
|
|
|
this.dmd = MaterialInfo[this.name].demandBase;
|
|
|
|
this.dmdR = MaterialInfo[this.name].demandRange;
|
|
|
|
this.cmp = MaterialInfo[this.name].competitionBase;
|
|
|
|
this.cmpR = MaterialInfo[this.name].competitionRange;
|
|
|
|
this.bCost = MaterialInfo[this.name].baseCost;
|
|
|
|
this.mv = MaterialInfo[this.name].maxVolatility;
|
|
|
|
this.mku = MaterialInfo[this.name].baseMarkup;
|
2021-09-05 01:09:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
getMarkupLimit(): number {
|
|
|
|
return this.qlt / this.mku;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Process change in demand, competition, and buy cost of this material
|
|
|
|
processMarket(): void {
|
|
|
|
// The price will change in accordance with demand and competition.
|
|
|
|
// e.g. If demand goes up, then so does price. If competition goes up, price goes down
|
|
|
|
const priceVolatility: number = (Math.random() * this.mv) / 300;
|
|
|
|
const priceChange: number = 1 + priceVolatility;
|
|
|
|
|
|
|
|
//This 1st random check determines whether competition increases or decreases
|
|
|
|
const compVolatility: number = (Math.random() * this.mv) / 100;
|
|
|
|
const compChange: number = 1 + compVolatility;
|
|
|
|
if (Math.random() < 0.5) {
|
|
|
|
this.cmp *= compChange;
|
|
|
|
if (this.cmp > this.cmpR[1]) {
|
|
|
|
this.cmp = this.cmpR[1];
|
|
|
|
}
|
|
|
|
this.bCost *= 1 / priceChange; // Competition increases, so price goes down
|
|
|
|
} else {
|
|
|
|
this.cmp *= 1 / compChange;
|
|
|
|
if (this.cmp < this.cmpR[0]) {
|
|
|
|
this.cmp = this.cmpR[0];
|
|
|
|
}
|
|
|
|
this.bCost *= priceChange; // Competition decreases, so price goes up
|
2018-12-09 14:36:18 +01:00
|
|
|
}
|
2021-05-01 09:17:31 +02:00
|
|
|
|
2021-09-05 01:09:30 +02:00
|
|
|
// This 2nd random check determines whether demand increases or decreases
|
|
|
|
const dmdVolatility: number = (Math.random() * this.mv) / 100;
|
|
|
|
const dmdChange: number = 1 + dmdVolatility;
|
|
|
|
if (Math.random() < 0.5) {
|
|
|
|
this.dmd *= dmdChange;
|
|
|
|
if (this.dmd > this.dmdR[1]) {
|
|
|
|
this.dmd = this.dmdR[1];
|
|
|
|
}
|
|
|
|
this.bCost *= priceChange; // Demand increases, so price goes up
|
|
|
|
} else {
|
|
|
|
this.dmd *= 1 / dmdChange;
|
|
|
|
if (this.dmd < this.dmdR[0]) {
|
|
|
|
this.dmd = this.dmdR[0];
|
|
|
|
}
|
|
|
|
this.bCost *= 1 / priceChange;
|
2021-05-01 09:17:31 +02:00
|
|
|
}
|
2021-09-05 01:09:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Serialize the current object to a JSON save state.
|
2022-07-15 01:00:10 +02:00
|
|
|
toJSON(): IReviverValue {
|
2021-09-05 01:09:30 +02:00
|
|
|
return Generic_toJSON("Material", this);
|
|
|
|
}
|
|
|
|
|
2022-10-09 07:25:31 +02:00
|
|
|
// Initializes a Material object from a JSON save state.
|
2022-07-15 01:00:10 +02:00
|
|
|
static fromJSON(value: IReviverValue): Material {
|
2022-12-30 02:28:53 +01:00
|
|
|
// Gracefully load save files from when Scientific Research was considered a Material (pre 2.2).
|
|
|
|
if (value.data.name === "Scientific Research") return value.data.qty;
|
2023-01-02 21:06:44 +01:00
|
|
|
if (value.data.name === "RealEstate") value.data.name = "Real Estate";
|
|
|
|
if (value.data.name === "AICores") value.data.name = "AI Cores";
|
2021-09-05 01:09:30 +02:00
|
|
|
return Generic_fromJSON(Material, value.data);
|
|
|
|
}
|
2018-12-09 14:36:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Reviver.constructors.Material = Material;
|