Narrow down corporation types

This commit is contained in:
Olivier Gagnon 2021-08-31 14:47:07 -04:00
parent 2624e13c34
commit d65cbf07f4
20 changed files with 118 additions and 126 deletions

@ -294,8 +294,10 @@ export class Corporation {
for (let i = 0; i < this.divisions.length; ++i) { for (let i = 0; i < this.divisions.length; ++i) {
const industry = this.divisions[i]; const industry = this.divisions[i];
for (const city in industry.warehouses) { for (const city in industry.warehouses) {
if (industry.warehouses.hasOwnProperty(city) && industry.warehouses[city] instanceof Warehouse) { const warehouse = industry.warehouses[city]
industry.warehouses[city].updateSize(this, industry); if(warehouse === 0) continue
if (industry.warehouses.hasOwnProperty(city) && warehouse instanceof Warehouse) {
warehouse.updateSize(this, industry);
} }
} }
} }

@ -1,7 +0,0 @@
import { IOfficeSpace } from "./IOfficeSpace";
import { IMap } from "../types";
export interface IDivision {
name: string;
offices: IMap<IOfficeSpace | number>;
}

@ -9,12 +9,12 @@ export interface IIndustry {
name: string; name: string;
type: string; type: string;
sciResearch: Material; sciResearch: Material;
researched: any; researched: {[key: string]: boolean | undefined};
reqMats: any; reqMats: {[key: string]: number | undefined};
prodMats: string[]; prodMats: string[];
products: any; products: {[key: string]: Product | undefined};
makesProducts: boolean; makesProducts: boolean;
awareness: number; awareness: number;
@ -40,9 +40,8 @@ export interface IIndustry {
state: string; state: string;
newInd: boolean; newInd: boolean;
warehouses: any; warehouses: {[key: string]: Warehouse | 0};
offices: any; offices: {[key: string]: OfficeSpace | 0};
init(): void; init(): void;
getProductDescriptionText(): string; getProductDescriptionText(): string;
@ -57,7 +56,7 @@ export interface IIndustry {
processProducts(marketCycles: number, corporation: ICorporation): [number, number]; processProducts(marketCycles: number, corporation: ICorporation): [number, number];
processProduct(marketCycles: number, product: Product, corporation: ICorporation): number; processProduct(marketCycles: number, product: Product, corporation: ICorporation): number;
discontinueProduct(product: Product): void; discontinueProduct(product: Product): void;
upgrade(upgrade: IndustryUpgrade, refs: {corporation: any; office: OfficeSpace}): void; upgrade(upgrade: IndustryUpgrade, refs: {corporation: ICorporation; office: OfficeSpace}): void;
getOfficeProductivity(office: OfficeSpace, params?: any): number; getOfficeProductivity(office: OfficeSpace, params?: any): number;
getBusinessFactor(office: OfficeSpace): number; getBusinessFactor(office: OfficeSpace): number;
getAdvertisingFactors(): [number, number, number, number]; getAdvertisingFactors(): [number, number, number, number];

@ -1,15 +0,0 @@
export interface IOfficeSpace {
loc: string;
cost: number;
size: number;
comf: number;
beau: number;
tier: any;
minEne: number;
maxEne: number;
minHap: number;
maxHap: number;
maxMor: number;
employees: any;
employeeProd: any;
}

@ -20,6 +20,7 @@ import { isString } from "../../utils/helpers/isString";
import { MaterialSizes } from "./MaterialSizes"; import { MaterialSizes } from "./MaterialSizes";
import { Warehouse } from "./Warehouse"; import { Warehouse } from "./Warehouse";
import { ICorporation } from "./ICorporation"; import { ICorporation } from "./ICorporation";
import { IIndustry } from "./IIndustry";
import { import {
IndustryUpgrade, IndustryUpgrade,
IndustryUpgrades } from "./IndustryUpgrades"; IndustryUpgrades } from "./IndustryUpgrades";
@ -27,21 +28,21 @@ import { formatNumber } from "../../utils/StringHelperFunctions";
interface IParams { interface IParams {
name?: string; name?: string;
corp?: any; corp?: ICorporation;
type?: string; type?: string;
} }
export class Industry { export class Industry implements IIndustry {
name = ""; name = "";
type = Industries.Agriculture; type = Industries.Agriculture;
sciResearch = new Material({name: "Scientific Research"}); sciResearch = new Material({name: "Scientific Research"});
researched: any = {}; researched: {[key: string]: boolean | undefined} = {};
reqMats: any = {}; reqMats: {[key: string]: number | undefined} = {};
//An array of the name of materials being produced //An array of the name of materials being produced
prodMats: string[] = []; prodMats: string[] = [];
products: any = {}; products: {[key: string]: Product | undefined} = {};
makesProducts = false; makesProducts = false;
awareness = 0; awareness = 0;
@ -69,16 +70,16 @@ export class Industry {
thisCycleExpenses: any; thisCycleExpenses: any;
//Upgrades //Upgrades
upgrades: number[] = []; upgrades: number[] = Array(Object.keys(IndustryUpgrades).length).fill(0);
state = "START"; state = "START";
newInd = true; newInd = true;
//Maps locations to warehouses. 0 if no warehouse at that location //Maps locations to warehouses. 0 if no warehouse at that location
warehouses: any; warehouses: {[key: string]: Warehouse | 0};
//Maps locations to offices. 0 if no office at that location //Maps locations to offices. 0 if no office at that location
offices: any = { offices: {[key: string]: OfficeSpace | 0} = {
[CityName.Aevum]: 0, [CityName.Aevum]: 0,
[CityName.Chongqing]: 0, [CityName.Chongqing]: 0,
[CityName.Sector12]: new OfficeSpace({ [CityName.Sector12]: new OfficeSpace({
@ -100,11 +101,7 @@ export class Industry {
this.thisCycleRevenue = new Decimal(0); this.thisCycleRevenue = new Decimal(0);
this.thisCycleExpenses = new Decimal(0); this.thisCycleExpenses = new Decimal(0);
//Upgrades this.warehouses = {
const numUpgrades = Object.keys(IndustryUpgrades).length;
this.upgrades = Array(numUpgrades).fill(0);
this.warehouses = { //Maps locations to warehouses. 0 if no warehouse at that location
[CityName.Aevum]: 0, [CityName.Aevum]: 0,
[CityName.Chongqing]: 0, [CityName.Chongqing]: 0,
[CityName.Sector12]: new Warehouse({ [CityName.Sector12]: new Warehouse({
@ -394,6 +391,7 @@ export class Industry {
for (const prodName in this.products) { for (const prodName in this.products) {
if (this.products.hasOwnProperty(prodName)) { if (this.products.hasOwnProperty(prodName)) {
const prod = this.products[prodName]; const prod = this.products[prodName];
if(prod === undefined) continue;
warehouse.sizeUsed += (prod.data[warehouse.loc][0] * prod.siz); warehouse.sizeUsed += (prod.data[warehouse.loc][0] * prod.siz);
if (prod.data[warehouse.loc][0] > 0) { if (prod.data[warehouse.loc][0] > 0) {
warehouse.breakdown += (prodName + ": " + formatNumber(prod.data[warehouse.loc][0] * prod.siz, 0) + "<br>"); warehouse.breakdown += (prodName + ": " + formatNumber(prod.data[warehouse.loc][0] * prod.siz, 0) + "<br>");
@ -426,8 +424,10 @@ export class Industry {
// Process offices (and the employees in them) // Process offices (and the employees in them)
let employeeSalary = 0; let employeeSalary = 0;
for (const officeLoc in this.offices) { for (const officeLoc in this.offices) {
if (this.offices[officeLoc] instanceof OfficeSpace) { const office = this.offices[officeLoc];
employeeSalary += this.offices[officeLoc].process(marketCycles, {industry:this, corporation:corporation}); if(office === 0) continue;
if (office instanceof OfficeSpace) {
employeeSalary += office.process(marketCycles, corporation, this);
} }
} }
this.thisCycleExpenses = this.thisCycleExpenses.plus(employeeSalary); this.thisCycleExpenses = this.thisCycleExpenses.plus(employeeSalary);
@ -476,6 +476,7 @@ export class Industry {
//for every material this industry requires or produces //for every material this industry requires or produces
if (this.warehouses[CorporationConstants.Cities[i]] instanceof Warehouse) { if (this.warehouses[CorporationConstants.Cities[i]] instanceof Warehouse) {
const wh = this.warehouses[CorporationConstants.Cities[i]]; const wh = this.warehouses[CorporationConstants.Cities[i]];
if(wh === 0) continue;
for (const name in reqMats) { for (const name in reqMats) {
if (reqMats.hasOwnProperty(name)) { if (reqMats.hasOwnProperty(name)) {
wh.materials[name].processMarket(); wh.materials[name].processMarket();
@ -502,6 +503,7 @@ export class Industry {
for (const name in this.products) { for (const name in this.products) {
if (this.products.hasOwnProperty(name)) { if (this.products.hasOwnProperty(name)) {
const product = this.products[name]; const product = this.products[name];
if(product === undefined) continue;
let change = getRandomInt(0, 3) * 0.0004; let change = getRandomInt(0, 3) * 0.0004;
if (change === 0) continue; if (change === 0) continue;
@ -531,6 +533,7 @@ export class Industry {
continue; continue;
} }
const warehouse = this.warehouses[city]; const warehouse = this.warehouses[city];
if(warehouse === 0) continue;
for (const matName in warehouse.materials) { for (const matName in warehouse.materials) {
if (warehouse.materials.hasOwnProperty(matName)) { if (warehouse.materials.hasOwnProperty(matName)) {
const mat = warehouse.materials[matName]; const mat = warehouse.materials[matName];
@ -541,10 +544,13 @@ export class Industry {
} }
for (let i = 0; i < CorporationConstants.Cities.length; ++i) { for (let i = 0; i < CorporationConstants.Cities.length; ++i) {
const city = CorporationConstants.Cities[i], office = this.offices[city]; const city = CorporationConstants.Cities[i];
const office = this.offices[city];
if(office === 0) continue;
if (this.warehouses[city] instanceof Warehouse) { if (this.warehouses[city] instanceof Warehouse) {
const warehouse = this.warehouses[city]; const warehouse = this.warehouses[city];
if(warehouse === 0) continue;
switch(this.state) { switch(this.state) {
@ -557,7 +563,10 @@ export class Industry {
let buyAmt, maxAmt; let buyAmt, maxAmt;
if (warehouse.smartSupplyEnabled && Object.keys(ind.reqMats).includes(matName)) { if (warehouse.smartSupplyEnabled && Object.keys(ind.reqMats).includes(matName)) {
//Smart supply tracker is stored as per second rate //Smart supply tracker is stored as per second rate
mat.buy = ind.reqMats[matName] * warehouse.smartSupplyStore; const reqMat = ind.reqMats[matName];
if(reqMat === undefined)
throw new Error(`reqMat "${matName}" is undefined`);
mat.buy = reqMat * warehouse.smartSupplyStore;
buyAmt = mat.buy * CorporationConstants.SecsPerMarketCycle * marketCycles; buyAmt = mat.buy * CorporationConstants.SecsPerMarketCycle * marketCycles;
} else { } else {
buyAmt = (mat.buy * CorporationConstants.SecsPerMarketCycle * marketCycles); buyAmt = (mat.buy * CorporationConstants.SecsPerMarketCycle * marketCycles);
@ -608,6 +617,7 @@ export class Industry {
} }
for (const reqMatName in this.reqMats) { for (const reqMatName in this.reqMats) {
const normQty = this.reqMats[reqMatName]; const normQty = this.reqMats[reqMatName];
if(normQty === undefined) continue;
totalMatSize -= (MaterialSizes[reqMatName] * normQty); totalMatSize -= (MaterialSizes[reqMatName] * normQty);
} }
// If not enough space in warehouse, limit the amount of produced materials // If not enough space in warehouse, limit the amount of produced materials
@ -625,7 +635,9 @@ export class Industry {
let producableFrac = 1; let producableFrac = 1;
for (const reqMatName in this.reqMats) { for (const reqMatName in this.reqMats) {
if (this.reqMats.hasOwnProperty(reqMatName)) { if (this.reqMats.hasOwnProperty(reqMatName)) {
const req = this.reqMats[reqMatName] * prod; const reqMat = this.reqMats[reqMatName];
if(reqMat === undefined) continue;
const req = reqMat * prod;
if (warehouse.materials[reqMatName].qty < req) { if (warehouse.materials[reqMatName].qty < req) {
producableFrac = Math.min(producableFrac, warehouse.materials[reqMatName].qty / req); producableFrac = Math.min(producableFrac, warehouse.materials[reqMatName].qty / req);
} }
@ -636,7 +648,9 @@ export class Industry {
// Make our materials if they are producable // Make our materials if they are producable
if (producableFrac > 0 && prod > 0) { if (producableFrac > 0 && prod > 0) {
for (const reqMatName in this.reqMats) { for (const reqMatName in this.reqMats) {
const reqMatQtyNeeded = (this.reqMats[reqMatName] * prod * producableFrac); const reqMat = this.reqMats[reqMatName];
if(reqMat === undefined) continue;
const reqMatQtyNeeded = (reqMat * prod * producableFrac);
warehouse.materials[reqMatName].qty -= reqMatQtyNeeded; warehouse.materials[reqMatName].qty -= reqMatQtyNeeded;
warehouse.materials[reqMatName].prd = 0; warehouse.materials[reqMatName].prd = 0;
warehouse.materials[reqMatName].prd -= reqMatQtyNeeded / (CorporationConstants.SecsPerMarketCycle * marketCycles); warehouse.materials[reqMatName].prd -= reqMatQtyNeeded / (CorporationConstants.SecsPerMarketCycle * marketCycles);
@ -725,7 +739,7 @@ export class Industry {
} else if (mat.marketTa1) { } else if (mat.marketTa1) {
sCost = mat.bCost + markupLimit; sCost = mat.bCost + markupLimit;
} else if (isString(mat.sCost)) { } else if (isString(mat.sCost)) {
sCost = mat.sCost.replace(/MP/g, mat.bCost); sCost = (mat.sCost as string).replace(/MP/g, mat.bCost+'');
sCost = eval(sCost); sCost = eval(sCost);
} else { } else {
sCost = mat.sCost; sCost = mat.sCost;
@ -757,8 +771,8 @@ export class Industry {
let sellAmt; let sellAmt;
if (isString(mat.sllman[1])) { if (isString(mat.sllman[1])) {
//Dynamically evaluated //Dynamically evaluated
let tmp = mat.sllman[1].replace(/MAX/g, maxSell); let tmp = (mat.sllman[1] as string).replace(/MAX/g, maxSell+'');
tmp = tmp.replace(/PROD/g, mat.prd); tmp = tmp.replace(/PROD/g, mat.prd+'');
try { try {
sellAmt = eval(tmp); sellAmt = eval(tmp);
} catch(e) { } catch(e) {
@ -773,7 +787,7 @@ export class Industry {
sellAmt = maxSell; sellAmt = maxSell;
} else { } else {
//Player's input value is just a number //Player's input value is just a number
sellAmt = Math.min(maxSell, mat.sllman[1]); sellAmt = Math.min(maxSell, mat.sllman[1] as number);
} }
sellAmt = (sellAmt * CorporationConstants.SecsPerMarketCycle * marketCycles); sellAmt = (sellAmt * CorporationConstants.SecsPerMarketCycle * marketCycles);
@ -801,9 +815,10 @@ export class Industry {
mat.totalExp = 0; //Reset export mat.totalExp = 0; //Reset export
for (let expI = 0; expI < mat.exp.length; ++expI) { for (let expI = 0; expI < mat.exp.length; ++expI) {
const exp = mat.exp[expI]; const exp = mat.exp[expI];
let amt = exp.amt.replace(/MAX/g, mat.qty / (CorporationConstants.SecsPerMarketCycle * marketCycles)); const amtStr = exp.amt.replace(/MAX/g, (mat.qty / (CorporationConstants.SecsPerMarketCycle * marketCycles))+'');
let amt = 0;
try { try {
amt = eval(amt); amt = eval(amtStr);
} catch(e) { } catch(e) {
dialogBoxCreate("Calculating export for " + mat.name + " in " + dialogBoxCreate("Calculating export for " + mat.name + " in " +
this.name + "'s " + city + " division failed with " + this.name + "'s " + city + " division failed with " +
@ -889,9 +904,11 @@ export class Industry {
if (this.state === "PRODUCTION") { if (this.state === "PRODUCTION") {
for (const prodName in this.products) { for (const prodName in this.products) {
const prod = this.products[prodName]; const prod = this.products[prodName];
if(prod === undefined) continue;
if (!prod.fin) { if (!prod.fin) {
const city = prod.createCity; const city = prod.createCity;
const office = this.offices[city]; const office = this.offices[city];
if(office === 0) continue;
// Designing/Creating a Product is based mostly off Engineers // Designing/Creating a Product is based mostly off Engineers
const engrProd = office.employeeProd[EmployeePositions.Engineer]; const engrProd = office.employeeProd[EmployeePositions.Engineer];
@ -930,7 +947,10 @@ export class Industry {
processProduct(marketCycles=1, product: Product, corporation: ICorporation): number { processProduct(marketCycles=1, product: Product, corporation: ICorporation): number {
let totalProfit = 0; let totalProfit = 0;
for (let i = 0; i < CorporationConstants.Cities.length; ++i) { for (let i = 0; i < CorporationConstants.Cities.length; ++i) {
const city = CorporationConstants.Cities[i], office = this.offices[city], warehouse = this.warehouses[city]; const city = CorporationConstants.Cities[i];
const office = this.offices[city];
if(office === 0) continue;
const warehouse = this.warehouses[city];
if (warehouse instanceof Warehouse) { if (warehouse instanceof Warehouse) {
switch(this.state) { switch(this.state) {
@ -1135,7 +1155,7 @@ export class Industry {
} }
} }
upgrade(upgrade: IndustryUpgrade, refs: {corporation: any; office: OfficeSpace}): void { upgrade(upgrade: IndustryUpgrade, refs: {corporation: ICorporation; office: OfficeSpace}): void {
const corporation = refs.corporation; const corporation = refs.corporation;
const office = refs.office; const office = refs.office;
const upgN = upgrade[0]; const upgN = upgrade[0];

@ -57,8 +57,8 @@ export class Material {
// Flags to keep track of whether production and/or sale of this material is limited // Flags to keep track of whether production and/or sale of this material is limited
// [Whether production/sale is limited, limit amount] // [Whether production/sale is limited, limit amount]
prdman: any[] = [false, 0]; // Production prdman: [boolean, number] = [false, 0]; // Production
sllman: any[] = [false, 0]; // Sale sllman: [boolean, string | number] = [false, 0]; // Sale
// Flags that signal whether automatic sale pricing through Market TA is enabled // Flags that signal whether automatic sale pricing through Market TA is enabled
marketTa1 = false; marketTa1 = false;

@ -61,9 +61,7 @@ export class OfficeSpace {
return (this.employees.length) >= this.size; return (this.employees.length) >= this.size;
} }
process(marketCycles = 1, parentRefs: {industry: IIndustry; corporation: ICorporation}): number { process(marketCycles = 1, corporation: ICorporation, industry: IIndustry): number {
const industry = parentRefs.industry;
// HRBuddy AutoRecruitment and training // HRBuddy AutoRecruitment and training
if (industry.hasResearch("HRBuddy-Recruitment") && !this.atCapacity()) { if (industry.hasResearch("HRBuddy-Recruitment") && !this.atCapacity()) {
const emp = this.hireRandomEmployee(); const emp = this.hireRandomEmployee();
@ -88,9 +86,9 @@ export class OfficeSpace {
// Calculate changes in Morale/Happiness/Energy for Employees // Calculate changes in Morale/Happiness/Energy for Employees
let perfMult=1; //Multiplier for employee morale/happiness/energy based on company performance let perfMult=1; //Multiplier for employee morale/happiness/energy based on company performance
if (parentRefs.corporation.funds < 0 && industry.lastCycleRevenue < 0) { if (corporation.funds < 0 && industry.lastCycleRevenue < 0) {
perfMult = Math.pow(0.99, marketCycles); perfMult = Math.pow(0.99, marketCycles);
} else if (parentRefs.corporation.funds > 0 && industry.lastCycleRevenue > 0) { } else if (corporation.funds > 0 && industry.lastCycleRevenue > 0) {
perfMult = Math.pow(1.01, marketCycles); perfMult = Math.pow(1.01, marketCycles);
} }
@ -121,13 +119,11 @@ export class OfficeSpace {
salaryPaid += salary; salaryPaid += salary;
} }
this.calculateEmployeeProductivity(parentRefs); this.calculateEmployeeProductivity(corporation, industry);
return salaryPaid; return salaryPaid;
} }
calculateEmployeeProductivity(parentRefs: {corporation: ICorporation; industry: IIndustry}): void { calculateEmployeeProductivity(corporation: ICorporation, industry: IIndustry): void {
const company = parentRefs.corporation, industry = parentRefs.industry;
//Reset //Reset
for (const name in this.employeeProd) { for (const name in this.employeeProd) {
this.employeeProd[name] = 0; this.employeeProd[name] = 0;
@ -136,7 +132,7 @@ export class OfficeSpace {
let total = 0; let total = 0;
for (let i = 0; i < this.employees.length; ++i) { for (let i = 0; i < this.employees.length; ++i) {
const employee = this.employees[i]; const employee = this.employees[i];
const prod = employee.calculateProductivity(company, industry); const prod = employee.calculateProductivity(corporation, industry);
this.employeeProd[employee.pos] += prod; this.employeeProd[employee.pos] += prod;
total += prod; total += prod;
} }
@ -144,7 +140,7 @@ export class OfficeSpace {
} }
//Takes care of UI as well //Takes care of UI as well
findEmployees(player: IPlayer, parentRefs: {corporation: ICorporation}): void { findEmployees(player: IPlayer, corporation: ICorporation): void {
if (this.atCapacity()) { return; } if (this.atCapacity()) { return; }
if (document.getElementById("cmpy-mgmt-hire-employee-popup") != null) {return;} if (document.getElementById("cmpy-mgmt-hire-employee-popup") != null) {return;}
@ -200,7 +196,7 @@ export class OfficeSpace {
"Efficiency: " + formatNumber(employee.eff, 1) + "<br>" + "Efficiency: " + formatNumber(employee.eff, 1) + "<br>" +
"Salary: " + numeralWrapper.format(employee.sal, '$0.000a') + " \ s<br>", "Salary: " + numeralWrapper.format(employee.sal, '$0.000a') + " \ s<br>",
clickListener: () => { clickListener: () => {
office.hireEmployee(player, employee, parentRefs); office.hireEmployee(player, employee, corporation);
removeElementById("cmpy-mgmt-hire-employee-popup"); removeElementById("cmpy-mgmt-hire-employee-popup");
return false; return false;
}, },
@ -227,8 +223,7 @@ export class OfficeSpace {
createPopup("cmpy-mgmt-hire-employee-popup", elems); createPopup("cmpy-mgmt-hire-employee-popup", elems);
} }
hireEmployee(player: IPlayer, employee: Employee, parentRefs: {corporation: ICorporation}): void { hireEmployee(player: IPlayer, employee: Employee, corporation: ICorporation): void {
const corporation = parentRefs.corporation;
const yesBtn = yesNoTxtInpBoxGetYesButton(), const yesBtn = yesNoTxtInpBoxGetYesButton(),
noBtn = yesNoTxtInpBoxGetNoButton(); noBtn = yesNoTxtInpBoxGetNoButton();
yesBtn.innerHTML = "Hire"; yesBtn.innerHTML = "Hire";

@ -1,5 +1,6 @@
import { EmployeePositions } from "./EmployeePositions"; import { EmployeePositions } from "./EmployeePositions";
import { MaterialSizes } from "./MaterialSizes"; import { MaterialSizes } from "./MaterialSizes";
import { IIndustry } from "./IIndustry";
import { ProductRatingWeights, import { ProductRatingWeights,
IProductRatingWeight } from "./ProductRatingWeights"; IProductRatingWeight } from "./ProductRatingWeights";
@ -30,17 +31,6 @@ interface IConstructorParams {
req?: IMap<number>; req?: IMap<number>;
} }
// Interface for an Industry object - Used for type checking method arguments
interface IIndustry {
awareness: number;
popularity: number;
reqMats: IMap<number>;
sciFac: number;
sciResearch: any;
type: string;
}
export class Product { export class Product {
// Product name // Product name
@ -137,7 +127,7 @@ export class Product {
} }
// @param industry - Industry object. Reference to industry that makes this Product // @param industry - Industry object. Reference to industry that makes this Product
finishProduct(employeeProd: IMap<number>, industry: IIndustry): void { finishProduct(employeeProd: {[key: string]: number}, industry: IIndustry): void {
this.fin = true; this.fin = true;
//Calculate properties //Calculate properties
@ -199,7 +189,9 @@ export class Product {
//For now, just set it to be the same as the requirements to make materials //For now, just set it to be the same as the requirements to make materials
for (const matName in industry.reqMats) { for (const matName in industry.reqMats) {
if (industry.reqMats.hasOwnProperty(matName)) { if (industry.reqMats.hasOwnProperty(matName)) {
this.reqMats[matName] = industry.reqMats[matName]; const reqMat = industry.reqMats[matName];
if(reqMat === undefined) continue;
this.reqMats[matName] = reqMat;
} }
} }
@ -207,18 +199,10 @@ export class Product {
//For now, just set it to be the same size as the requirements to make materials //For now, just set it to be the same size as the requirements to make materials
this.siz = 0; this.siz = 0;
for (const matName in industry.reqMats) { for (const matName in industry.reqMats) {
this.siz += MaterialSizes[matName] * industry.reqMats[matName]; const reqMat = industry.reqMats[matName];
if(reqMat === undefined) continue;
this.siz += MaterialSizes[matName] * reqMat;
} }
//Delete unneeded variables
// @ts-ignore
delete this.prog;
// @ts-ignore
delete this.createCity;
// @ts-ignore
delete this.designCost;
// @ts-ignore
delete this.advCost;
} }

@ -1,4 +1,6 @@
import { Material } from "./Material"; import { Material } from "./Material";
import { ICorporation } from "./ICorporation";
import { IIndustry } from "./IIndustry";
import { MaterialSizes } from "./MaterialSizes"; import { MaterialSizes } from "./MaterialSizes";
import { IMap } from "../types"; import { IMap } from "../types";
import { numeralWrapper } from "../ui/numeralFormat"; import { numeralWrapper } from "../ui/numeralFormat";
@ -7,13 +9,9 @@ import { Generic_fromJSON,
Reviver } from "../../utils/JSONReviver"; Reviver } from "../../utils/JSONReviver";
import { exceptionAlert } from "../../utils/helpers/exceptionAlert"; import { exceptionAlert } from "../../utils/helpers/exceptionAlert";
interface IParent {
getStorageMultiplier(): number;
}
interface IConstructorParams { interface IConstructorParams {
corp?: IParent; corp?: ICorporation;
industry?: IParent; industry?: IIndustry;
loc?: string; loc?: string;
size?: number; size?: number;
} }
@ -92,7 +90,7 @@ export class Warehouse {
} }
} }
updateSize(corporation: IParent, industry: IParent): void { updateSize(corporation: ICorporation, industry: IIndustry): void {
try { try {
this.size = (this.level * 100) this.size = (this.level * 100)
* corporation.getStorageMultiplier() * corporation.getStorageMultiplier()

@ -4,7 +4,6 @@ import React from "react";
import { CityTab } from "./CityTab"; import { CityTab } from "./CityTab";
import { ExpandNewCityPopup } from "./ExpandNewCityPopup"; import { ExpandNewCityPopup } from "./ExpandNewCityPopup";
import { createPopup } from "../../ui/React/createPopup"; import { createPopup } from "../../ui/React/createPopup";
import { IDivision } from "../IDivision";
import { ICorporation } from "../ICorporation"; import { ICorporation } from "../ICorporation";
import { CorporationRouting } from "./Routing"; import { CorporationRouting } from "./Routing";
@ -20,11 +19,12 @@ export function CityTabs(props: IProps): React.ReactElement {
const division = props.routing.currentDivision; const division = props.routing.currentDivision;
function openExpandNewCityModal(): void { function openExpandNewCityModal(): void {
if(division === null) return;
const popupId = "cmpy-mgmt-expand-city-popup"; const popupId = "cmpy-mgmt-expand-city-popup";
createPopup(popupId, ExpandNewCityPopup, { createPopup(popupId, ExpandNewCityPopup, {
popupId: popupId, popupId: popupId,
corp: props.corp, corp: props.corp,
division: division as IDivision, division: division,
cityStateSetter: props.cityStateSetter, cityStateSetter: props.cityStateSetter,
}); });
} }

@ -1,5 +1,5 @@
import React, { useRef } from "react"; import React, { useRef } from "react";
import { IDivision } from "../IDivision"; import { IIndustry } from "../IIndustry";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { CorporationConstants } from "../data/Constants"; import { CorporationConstants } from "../data/Constants";
import { removePopup } from "../../ui/React/createPopup"; import { removePopup } from "../../ui/React/createPopup";
@ -10,7 +10,7 @@ import { ICorporation } from "../ICorporation";
interface IProps { interface IProps {
popupId: string; popupId: string;
corp: ICorporation; corp: ICorporation;
division: IDivision; division: IIndustry;
cityStateSetter: (city: string) => void; cityStateSetter: (city: string) => void;
} }

@ -3,7 +3,7 @@
// divisions, see an overview of your corporation, or create a new industry // divisions, see an overview of your corporation, or create a new industry
import React from "react"; import React from "react";
import { HeaderTab } from "./HeaderTab"; import { HeaderTab } from "./HeaderTab";
import { IDivision } from "../IDivision"; import { IIndustry } from "../IIndustry";
import { NewIndustryPopup } from "./NewIndustryPopup"; import { NewIndustryPopup } from "./NewIndustryPopup";
import { createPopup } from "../../ui/React/createPopup"; import { createPopup } from "../../ui/React/createPopup";
import { ICorporation } from "../ICorporation"; import { ICorporation } from "../ICorporation";
@ -40,7 +40,7 @@ export function HeaderTabs(props: IProps): React.ReactElement {
text={props.corp.name} text={props.corp.name}
/> />
{ {
props.corp.divisions.map((division: IDivision) => <HeaderTab props.corp.divisions.map((division: IIndustry) => <HeaderTab
current={props.routing.isOn(division.name)} current={props.routing.isOn(division.name)}
key={division.name} key={division.name}
onClick={() => { onClick={() => {

@ -133,6 +133,7 @@ export function IndustryOffice(props: IProps): React.ReactElement {
const division = props.routing.currentDivision; // Validated in constructor const division = props.routing.currentDivision; // Validated in constructor
if(division === null) return(<></>); if(division === null) return(<></>);
const office = division.offices[props.currentCity]; // Validated in constructor const office = division.offices[props.currentCity]; // Validated in constructor
if(office === 0) return (<></>);
const vechain = (props.corp.unlockUpgrades[4] === 1); // Has Vechain upgrade const vechain = (props.corp.unlockUpgrades[4] === 1); // Has Vechain upgrade
function switchModeOnClick(): void { function switchModeOnClick(): void {
@ -159,6 +160,8 @@ export function IndustryOffice(props: IProps): React.ReactElement {
// Helper functions for (re-)assigning employees to different positions // Helper functions for (re-)assigning employees to different positions
function assignEmployee(to: string): void { function assignEmployee(to: string): void {
if(office === 0) return;
if(division === null) return;
if (numUnassigned <= 0) { if (numUnassigned <= 0) {
console.warn("Cannot assign employee. No unassigned employees available"); console.warn("Cannot assign employee. No unassigned employees available");
return; return;
@ -193,11 +196,13 @@ export function IndustryOffice(props: IProps): React.ReactElement {
setNumUnassigned(n => n-1); setNumUnassigned(n => n-1);
office.assignEmployeeToJob(to); office.assignEmployeeToJob(to);
office.calculateEmployeeProductivity({ corporation: props.corp, industry:division }); office.calculateEmployeeProductivity(props.corp, division);
props.corp.rerender(props.player); props.corp.rerender(props.player);
} }
function unassignEmployee(from: string): void { function unassignEmployee(from: string): void {
if(office === 0) return;
if(division === null) return;
function logWarning(pos: string): void { function logWarning(pos: string): void {
console.warn(`Cannot unassign from ${pos} because there is nobody assigned to that position`); console.warn(`Cannot unassign from ${pos} because there is nobody assigned to that position`);
} }
@ -237,7 +242,7 @@ export function IndustryOffice(props: IProps): React.ReactElement {
setNumUnassigned(n => n+1); setNumUnassigned(n => n+1);
office.unassignEmployeeFromJob(from); office.unassignEmployeeFromJob(from);
office.calculateEmployeeProductivity({ corporation: props.corp, industry:division }); office.calculateEmployeeProductivity(props.corp, division);
props.corp.rerender(props.player); props.corp.rerender(props.player);
} }
@ -436,6 +441,7 @@ export function IndustryOffice(props: IProps): React.ReactElement {
const division = props.routing.currentDivision; // Validated in constructor const division = props.routing.currentDivision; // Validated in constructor
if(division === null) return (<></>); if(division === null) return (<></>);
const office = division.offices[props.currentCity]; // Validated in constructor const office = division.offices[props.currentCity]; // Validated in constructor
if(office === 0) return (<></>);
function switchModeOnClick(): void { function switchModeOnClick(): void {
setEmployeeManualAssignMode(false); setEmployeeManualAssignMode(false);
@ -455,6 +461,7 @@ export function IndustryOffice(props: IProps): React.ReactElement {
} }
function employeeSelectorOnChange(e: React.ChangeEvent<HTMLSelectElement>): void { function employeeSelectorOnChange(e: React.ChangeEvent<HTMLSelectElement>): void {
if(office === 0) return;
const name = getSelectText(e.target); const name = getSelectText(e.target);
for (let i = 0; i < office.employees.length; ++i) { for (let i = 0; i < office.employees.length; ++i) {
if (name === office.employees[i].name) { if (name === office.employees[i].name) {
@ -547,7 +554,7 @@ export function IndustryOffice(props: IProps): React.ReactElement {
const division = props.routing.currentDivision; // Validated in constructor const division = props.routing.currentDivision; // Validated in constructor
if(division === null) return (<></>); if(division === null) return (<></>);
const office = division.offices[props.currentCity]; // Validated in constructor const office = division.offices[props.currentCity]; // Validated in constructor
if(office === 0) return (<></>);
const buttonStyle = { const buttonStyle = {
fontSize: "13px", fontSize: "13px",
} }
@ -564,7 +571,8 @@ export function IndustryOffice(props: IProps): React.ReactElement {
} }
function hireEmployeeButtonOnClick(): void { function hireEmployeeButtonOnClick(): void {
office.findEmployees(props.player, { corporation: corp, industry: division }); if(office === 0) return;
office.findEmployees(props.player, corp);
} }
// Autohire employee button // Autohire employee button
@ -575,12 +583,14 @@ export function IndustryOffice(props: IProps): React.ReactElement {
autohireEmployeeButtonClass += " std-button"; autohireEmployeeButtonClass += " std-button";
} }
function autohireEmployeeButtonOnClick(): void { function autohireEmployeeButtonOnClick(): void {
if(office === 0) return;
if (office.atCapacity()) return; if (office.atCapacity()) return;
office.hireRandomEmployee(); office.hireRandomEmployee();
props.corp.rerender(props.player); props.corp.rerender(props.player);
} }
function openUpgradeOfficeSizePopup(): void { function openUpgradeOfficeSizePopup(): void {
if(office === 0) return;
const popupId = "cmpy-mgmt-upgrade-office-size-popup"; const popupId = "cmpy-mgmt-upgrade-office-size-popup";
createPopup(popupId, UpgradeOfficeSizePopup, { createPopup(popupId, UpgradeOfficeSizePopup, {
office: office, office: office,
@ -591,6 +601,7 @@ export function IndustryOffice(props: IProps): React.ReactElement {
} }
function openThrowPartyPopup(): void { function openThrowPartyPopup(): void {
if(office === 0) return;
const popupId = "cmpy-mgmt-throw-office-party-popup"; const popupId = "cmpy-mgmt-throw-office-party-popup";
createPopup(popupId, ThrowPartyPopup, { createPopup(popupId, ThrowPartyPopup, {
office: office, office: office,

@ -248,6 +248,7 @@ export function IndustryOverview(props: IProps): React.ReactElement {
} }
function onClick(): void { function onClick(): void {
if(office === 0) return;
if(division === null) return; if(division === null) return;
if (corp.funds.lt(cost)) { if (corp.funds.lt(cost)) {
dialogBoxCreate("Insufficient funds"); dialogBoxCreate("Insufficient funds");

@ -292,7 +292,7 @@ function MaterialComponent(props: IMaterialProps): React.ReactElement {
if (isString(mat.sllman[1])) { if (isString(mat.sllman[1])) {
sellButtonText = `Sell (${numeralWrapper.format(mat.sll, nfB)}/${mat.sllman[1]})` sellButtonText = `Sell (${numeralWrapper.format(mat.sll, nfB)}/${mat.sllman[1]})`
} else { } else {
sellButtonText = `Sell (${numeralWrapper.format(mat.sll, nfB)}/${numeralWrapper.format(mat.sllman[1], nfB)})`; sellButtonText = `Sell (${numeralWrapper.format(mat.sll, nfB)}/${numeralWrapper.format(mat.sllman[1] as number, nfB)})`;
} }
if (mat.marketTa2) { if (mat.marketTa2) {
@ -432,6 +432,7 @@ export function IndustryWarehouse(props: IProps): React.ReactElement {
const division = props.routing.currentDivision; // Validated in render() const division = props.routing.currentDivision; // Validated in render()
if(division === null) return (<></>); if(division === null) return (<></>);
const warehouse = division.warehouses[props.currentCity]; // Validated in render() const warehouse = division.warehouses[props.currentCity]; // Validated in render()
if(warehouse === 0) return (<></>);
// General Storage information at the top // General Storage information at the top
const sizeUsageStyle = { const sizeUsageStyle = {
@ -444,6 +445,8 @@ export function IndustryWarehouse(props: IProps): React.ReactElement {
const canAffordUpgrade = (corp.funds.gt(sizeUpgradeCost)); const canAffordUpgrade = (corp.funds.gt(sizeUpgradeCost));
const upgradeWarehouseClass = canAffordUpgrade ? "std-button" : "a-link-button-inactive"; const upgradeWarehouseClass = canAffordUpgrade ? "std-button" : "a-link-button-inactive";
function upgradeWarehouseOnClick(): void { function upgradeWarehouseOnClick(): void {
if(division === null) return;
if(warehouse === 0) return;
++warehouse.level; ++warehouse.level;
warehouse.updateSize(corp, division); warehouse.updateSize(corp, division);
corp.funds = corp.funds.minus(sizeUpgradeCost); corp.funds = corp.funds.minus(sizeUpgradeCost);
@ -510,6 +513,7 @@ export function IndustryWarehouse(props: IProps): React.ReactElement {
// Smart Supply Checkbox // Smart Supply Checkbox
const smartSupplyCheckboxId = "cmpy-mgmt-smart-supply-checkbox"; const smartSupplyCheckboxId = "cmpy-mgmt-smart-supply-checkbox";
function smartSupplyOnChange(e: React.ChangeEvent<HTMLInputElement>): void { function smartSupplyOnChange(e: React.ChangeEvent<HTMLInputElement>): void {
if(warehouse === 0) return;
warehouse.smartSupplyEnabled = e.target.checked; warehouse.smartSupplyEnabled = e.target.checked;
corp.rerender(props.player); corp.rerender(props.player);
} }
@ -535,14 +539,15 @@ export function IndustryWarehouse(props: IProps): React.ReactElement {
const products = []; const products = [];
if (division.makesProducts && Object.keys(division.products).length > 0) { if (division.makesProducts && Object.keys(division.products).length > 0) {
for (const productName in division.products) { for (const productName in division.products) {
if (division.products[productName] instanceof Product) { const product = division.products[productName];
if (product instanceof Product) {
products.push(<ProductComponent products.push(<ProductComponent
player={props.player} player={props.player}
city={props.currentCity} city={props.currentCity}
corp={corp} corp={corp}
division={division} division={division}
key={productName} key={productName}
product={division.products[productName]} product={product}
/>); />);
} }
} }

@ -36,7 +36,7 @@ interface GeneralBtns {
export function Overview(props: IProps): React.ReactElement { export function Overview(props: IProps): React.ReactElement {
// Generic Function for Creating a button // Generic Function for Creating a button
interface ICreateButtonProps { interface ICreateButtonProps {
text: string text: string;
class?: string; class?: string;
display?: string; display?: string;
tooltip?: string; tooltip?: string;

@ -1,4 +1,3 @@
import { IMap } from "../../types";
import { ICorporation } from "../ICorporation"; import { ICorporation } from "../ICorporation";
import { IIndustry } from "../IIndustry"; import { IIndustry } from "../IIndustry";

@ -22,7 +22,7 @@ interface IProps {
// Create a popup that let the player manage sales of a material // Create a popup that let the player manage sales of a material
export function SellMaterialPopup(props: IProps): React.ReactElement { export function SellMaterialPopup(props: IProps): React.ReactElement {
const [amt, setAmt] = useState<string>(props.mat.sllman[1] ? props.mat.sllman[1] : ''); const [amt, setAmt] = useState<string>(props.mat.sllman[1] ? props.mat.sllman[1]+'' : '');
const [price, setPrice] = useState<string>(initialPrice(props.mat)); const [price, setPrice] = useState<string>(initialPrice(props.mat));
function sellMaterial(): void { function sellMaterial(): void {

@ -2,11 +2,11 @@ import React, { useState } from 'react';
import { removePopup } from "../../ui/React/createPopup"; import { removePopup } from "../../ui/React/createPopup";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { dialogBoxCreate } from "../../../utils/DialogBox"; import { dialogBoxCreate } from "../../../utils/DialogBox";
import { IOfficeSpace } from "../IOfficeSpace"; import { OfficeSpace } from "../OfficeSpace";
import { ICorporation } from "../ICorporation"; import { ICorporation } from "../ICorporation";
interface IProps { interface IProps {
office: IOfficeSpace; office: OfficeSpace;
corp: ICorporation; corp: ICorporation;
popupId: string; popupId: string;
} }
@ -38,7 +38,7 @@ export function ThrowPartyPopup(props: IProps): React.ReactElement {
} }
} }
function EffectText(props: {cost: number | null; office: IOfficeSpace}): React.ReactElement { function EffectText(props: {cost: number | null; office: OfficeSpace}): React.ReactElement {
let cost = props.cost; let cost = props.cost;
if(cost !== null && (isNaN(cost) || cost < 0)) return <p>Invalid value entered!</p> if(cost !== null && (isNaN(cost) || cost < 0)) return <p>Invalid value entered!</p>
if(cost === null) cost = 0; if(cost === null) cost = 0;

@ -3,12 +3,12 @@ import { removePopup } from "../../ui/React/createPopup";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { dialogBoxCreate } from "../../../utils/DialogBox"; import { dialogBoxCreate } from "../../../utils/DialogBox";
import { CorporationConstants } from "../data/Constants"; import { CorporationConstants } from "../data/Constants";
import { IOfficeSpace } from "../IOfficeSpace"; import { OfficeSpace } from "../OfficeSpace";
import { ICorporation } from "../ICorporation"; import { ICorporation } from "../ICorporation";
import { IPlayer } from "../../PersonObjects/IPlayer"; import { IPlayer } from "../../PersonObjects/IPlayer";
interface IProps { interface IProps {
office: IOfficeSpace; office: OfficeSpace;
corp: ICorporation; corp: ICorporation;
popupId: string; popupId: string;
player: IPlayer; player: IPlayer;