diff --git a/src/Corporation/Corporation.tsx b/src/Corporation/Corporation.tsx index e2de46372..d35b1dd64 100644 --- a/src/Corporation/Corporation.tsx +++ b/src/Corporation/Corporation.tsx @@ -294,8 +294,10 @@ export class Corporation { for (let i = 0; i < this.divisions.length; ++i) { const industry = this.divisions[i]; for (const city in industry.warehouses) { - if (industry.warehouses.hasOwnProperty(city) && industry.warehouses[city] instanceof Warehouse) { - industry.warehouses[city].updateSize(this, industry); + const warehouse = industry.warehouses[city] + if(warehouse === 0) continue + if (industry.warehouses.hasOwnProperty(city) && warehouse instanceof Warehouse) { + warehouse.updateSize(this, industry); } } } diff --git a/src/Corporation/IDivision.ts b/src/Corporation/IDivision.ts deleted file mode 100644 index 53b63e1cf..000000000 --- a/src/Corporation/IDivision.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { IOfficeSpace } from "./IOfficeSpace"; -import { IMap } from "../types"; - -export interface IDivision { - name: string; - offices: IMap; -} diff --git a/src/Corporation/IIndustry.ts b/src/Corporation/IIndustry.ts index 37368f464..dd82016d3 100644 --- a/src/Corporation/IIndustry.ts +++ b/src/Corporation/IIndustry.ts @@ -9,12 +9,12 @@ export interface IIndustry { name: string; type: string; sciResearch: Material; - researched: any; - reqMats: any; + researched: {[key: string]: boolean | undefined}; + reqMats: {[key: string]: number | undefined}; prodMats: string[]; - products: any; + products: {[key: string]: Product | undefined}; makesProducts: boolean; awareness: number; @@ -40,9 +40,8 @@ export interface IIndustry { state: string; newInd: boolean; - warehouses: any; - offices: any; - + warehouses: {[key: string]: Warehouse | 0}; + offices: {[key: string]: OfficeSpace | 0}; init(): void; getProductDescriptionText(): string; @@ -57,7 +56,7 @@ export interface IIndustry { processProducts(marketCycles: number, corporation: ICorporation): [number, number]; processProduct(marketCycles: number, product: Product, corporation: ICorporation): number; 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; getBusinessFactor(office: OfficeSpace): number; getAdvertisingFactors(): [number, number, number, number]; diff --git a/src/Corporation/IOfficeSpace.ts b/src/Corporation/IOfficeSpace.ts deleted file mode 100644 index 2138e5e19..000000000 --- a/src/Corporation/IOfficeSpace.ts +++ /dev/null @@ -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; -} diff --git a/src/Corporation/Industry.ts b/src/Corporation/Industry.ts index 18e3dbd11..92d3ff004 100644 --- a/src/Corporation/Industry.ts +++ b/src/Corporation/Industry.ts @@ -20,6 +20,7 @@ import { isString } from "../../utils/helpers/isString"; import { MaterialSizes } from "./MaterialSizes"; import { Warehouse } from "./Warehouse"; import { ICorporation } from "./ICorporation"; +import { IIndustry } from "./IIndustry"; import { IndustryUpgrade, IndustryUpgrades } from "./IndustryUpgrades"; @@ -27,21 +28,21 @@ import { formatNumber } from "../../utils/StringHelperFunctions"; interface IParams { name?: string; - corp?: any; + corp?: ICorporation; type?: string; } -export class Industry { +export class Industry implements IIndustry { name = ""; type = Industries.Agriculture; sciResearch = new Material({name: "Scientific Research"}); - researched: any = {}; - reqMats: any = {}; + researched: {[key: string]: boolean | undefined} = {}; + reqMats: {[key: string]: number | undefined} = {}; //An array of the name of materials being produced prodMats: string[] = []; - products: any = {}; + products: {[key: string]: Product | undefined} = {}; makesProducts = false; awareness = 0; @@ -69,16 +70,16 @@ export class Industry { thisCycleExpenses: any; //Upgrades - upgrades: number[] = []; + upgrades: number[] = Array(Object.keys(IndustryUpgrades).length).fill(0); state = "START"; newInd = true; //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 - offices: any = { + offices: {[key: string]: OfficeSpace | 0} = { [CityName.Aevum]: 0, [CityName.Chongqing]: 0, [CityName.Sector12]: new OfficeSpace({ @@ -100,11 +101,7 @@ export class Industry { this.thisCycleRevenue = new Decimal(0); this.thisCycleExpenses = new Decimal(0); - //Upgrades - 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 + this.warehouses = { [CityName.Aevum]: 0, [CityName.Chongqing]: 0, [CityName.Sector12]: new Warehouse({ @@ -394,6 +391,7 @@ export class Industry { for (const prodName in this.products) { if (this.products.hasOwnProperty(prodName)) { const prod = this.products[prodName]; + if(prod === undefined) continue; warehouse.sizeUsed += (prod.data[warehouse.loc][0] * prod.siz); if (prod.data[warehouse.loc][0] > 0) { warehouse.breakdown += (prodName + ": " + formatNumber(prod.data[warehouse.loc][0] * prod.siz, 0) + "
"); @@ -426,8 +424,10 @@ export class Industry { // Process offices (and the employees in them) let employeeSalary = 0; for (const officeLoc in this.offices) { - if (this.offices[officeLoc] instanceof OfficeSpace) { - employeeSalary += this.offices[officeLoc].process(marketCycles, {industry:this, corporation:corporation}); + const office = this.offices[officeLoc]; + if(office === 0) continue; + if (office instanceof OfficeSpace) { + employeeSalary += office.process(marketCycles, corporation, this); } } this.thisCycleExpenses = this.thisCycleExpenses.plus(employeeSalary); @@ -476,6 +476,7 @@ export class Industry { //for every material this industry requires or produces if (this.warehouses[CorporationConstants.Cities[i]] instanceof Warehouse) { const wh = this.warehouses[CorporationConstants.Cities[i]]; + if(wh === 0) continue; for (const name in reqMats) { if (reqMats.hasOwnProperty(name)) { wh.materials[name].processMarket(); @@ -502,6 +503,7 @@ export class Industry { for (const name in this.products) { if (this.products.hasOwnProperty(name)) { const product = this.products[name]; + if(product === undefined) continue; let change = getRandomInt(0, 3) * 0.0004; if (change === 0) continue; @@ -531,6 +533,7 @@ export class Industry { continue; } const warehouse = this.warehouses[city]; + if(warehouse === 0) continue; for (const matName in warehouse.materials) { if (warehouse.materials.hasOwnProperty(matName)) { const mat = warehouse.materials[matName]; @@ -541,10 +544,13 @@ export class Industry { } 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) { const warehouse = this.warehouses[city]; + if(warehouse === 0) continue; switch(this.state) { @@ -557,7 +563,10 @@ export class Industry { let buyAmt, maxAmt; if (warehouse.smartSupplyEnabled && Object.keys(ind.reqMats).includes(matName)) { //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; } else { buyAmt = (mat.buy * CorporationConstants.SecsPerMarketCycle * marketCycles); @@ -608,6 +617,7 @@ export class Industry { } for (const reqMatName in this.reqMats) { const normQty = this.reqMats[reqMatName]; + if(normQty === undefined) continue; totalMatSize -= (MaterialSizes[reqMatName] * normQty); } // If not enough space in warehouse, limit the amount of produced materials @@ -625,7 +635,9 @@ export class Industry { let producableFrac = 1; for (const reqMatName in this.reqMats) { 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) { producableFrac = Math.min(producableFrac, warehouse.materials[reqMatName].qty / req); } @@ -636,7 +648,9 @@ export class Industry { // Make our materials if they are producable if (producableFrac > 0 && prod > 0) { 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].prd = 0; warehouse.materials[reqMatName].prd -= reqMatQtyNeeded / (CorporationConstants.SecsPerMarketCycle * marketCycles); @@ -725,7 +739,7 @@ export class Industry { } else if (mat.marketTa1) { sCost = mat.bCost + markupLimit; } 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); } else { sCost = mat.sCost; @@ -757,8 +771,8 @@ export class Industry { let sellAmt; if (isString(mat.sllman[1])) { //Dynamically evaluated - let tmp = mat.sllman[1].replace(/MAX/g, maxSell); - tmp = tmp.replace(/PROD/g, mat.prd); + let tmp = (mat.sllman[1] as string).replace(/MAX/g, maxSell+''); + tmp = tmp.replace(/PROD/g, mat.prd+''); try { sellAmt = eval(tmp); } catch(e) { @@ -773,7 +787,7 @@ export class Industry { sellAmt = maxSell; } else { //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); @@ -801,9 +815,10 @@ export class Industry { mat.totalExp = 0; //Reset export for (let expI = 0; expI < mat.exp.length; ++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 { - amt = eval(amt); + amt = eval(amtStr); } catch(e) { dialogBoxCreate("Calculating export for " + mat.name + " in " + this.name + "'s " + city + " division failed with " + @@ -889,9 +904,11 @@ export class Industry { if (this.state === "PRODUCTION") { for (const prodName in this.products) { const prod = this.products[prodName]; + if(prod === undefined) continue; if (!prod.fin) { const city = prod.createCity; const office = this.offices[city]; + if(office === 0) continue; // Designing/Creating a Product is based mostly off Engineers const engrProd = office.employeeProd[EmployeePositions.Engineer]; @@ -930,7 +947,10 @@ export class Industry { processProduct(marketCycles=1, product: Product, corporation: ICorporation): number { let totalProfit = 0; 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) { 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 office = refs.office; const upgN = upgrade[0]; diff --git a/src/Corporation/Material.ts b/src/Corporation/Material.ts index 7ce69dc43..9c5d1ca19 100644 --- a/src/Corporation/Material.ts +++ b/src/Corporation/Material.ts @@ -57,8 +57,8 @@ export class Material { // Flags to keep track of whether production and/or sale of this material is limited // [Whether production/sale is limited, limit amount] - prdman: any[] = [false, 0]; // Production - sllman: any[] = [false, 0]; // Sale + prdman: [boolean, number] = [false, 0]; // Production + sllman: [boolean, string | number] = [false, 0]; // Sale // Flags that signal whether automatic sale pricing through Market TA is enabled marketTa1 = false; diff --git a/src/Corporation/OfficeSpace.ts b/src/Corporation/OfficeSpace.ts index 299156ee5..ed3655f50 100644 --- a/src/Corporation/OfficeSpace.ts +++ b/src/Corporation/OfficeSpace.ts @@ -61,9 +61,7 @@ export class OfficeSpace { return (this.employees.length) >= this.size; } - process(marketCycles = 1, parentRefs: {industry: IIndustry; corporation: ICorporation}): number { - const industry = parentRefs.industry; - + process(marketCycles = 1, corporation: ICorporation, industry: IIndustry): number { // HRBuddy AutoRecruitment and training if (industry.hasResearch("HRBuddy-Recruitment") && !this.atCapacity()) { const emp = this.hireRandomEmployee(); @@ -88,9 +86,9 @@ export class OfficeSpace { // Calculate changes in Morale/Happiness/Energy for Employees 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); - } else if (parentRefs.corporation.funds > 0 && industry.lastCycleRevenue > 0) { + } else if (corporation.funds > 0 && industry.lastCycleRevenue > 0) { perfMult = Math.pow(1.01, marketCycles); } @@ -121,13 +119,11 @@ export class OfficeSpace { salaryPaid += salary; } - this.calculateEmployeeProductivity(parentRefs); + this.calculateEmployeeProductivity(corporation, industry); return salaryPaid; } - calculateEmployeeProductivity(parentRefs: {corporation: ICorporation; industry: IIndustry}): void { - const company = parentRefs.corporation, industry = parentRefs.industry; - + calculateEmployeeProductivity(corporation: ICorporation, industry: IIndustry): void { //Reset for (const name in this.employeeProd) { this.employeeProd[name] = 0; @@ -136,7 +132,7 @@ export class OfficeSpace { let total = 0; for (let i = 0; i < this.employees.length; ++i) { const employee = this.employees[i]; - const prod = employee.calculateProductivity(company, industry); + const prod = employee.calculateProductivity(corporation, industry); this.employeeProd[employee.pos] += prod; total += prod; } @@ -144,7 +140,7 @@ export class OfficeSpace { } //Takes care of UI as well - findEmployees(player: IPlayer, parentRefs: {corporation: ICorporation}): void { + findEmployees(player: IPlayer, corporation: ICorporation): void { if (this.atCapacity()) { return; } if (document.getElementById("cmpy-mgmt-hire-employee-popup") != null) {return;} @@ -200,7 +196,7 @@ export class OfficeSpace { "Efficiency: " + formatNumber(employee.eff, 1) + "
" + "Salary: " + numeralWrapper.format(employee.sal, '$0.000a') + " \ s
", clickListener: () => { - office.hireEmployee(player, employee, parentRefs); + office.hireEmployee(player, employee, corporation); removeElementById("cmpy-mgmt-hire-employee-popup"); return false; }, @@ -227,8 +223,7 @@ export class OfficeSpace { createPopup("cmpy-mgmt-hire-employee-popup", elems); } - hireEmployee(player: IPlayer, employee: Employee, parentRefs: {corporation: ICorporation}): void { - const corporation = parentRefs.corporation; + hireEmployee(player: IPlayer, employee: Employee, corporation: ICorporation): void { const yesBtn = yesNoTxtInpBoxGetYesButton(), noBtn = yesNoTxtInpBoxGetNoButton(); yesBtn.innerHTML = "Hire"; diff --git a/src/Corporation/Product.ts b/src/Corporation/Product.ts index c63a79507..3ac15ff6d 100644 --- a/src/Corporation/Product.ts +++ b/src/Corporation/Product.ts @@ -1,5 +1,6 @@ import { EmployeePositions } from "./EmployeePositions"; import { MaterialSizes } from "./MaterialSizes"; +import { IIndustry } from "./IIndustry"; import { ProductRatingWeights, IProductRatingWeight } from "./ProductRatingWeights"; @@ -30,17 +31,6 @@ interface IConstructorParams { req?: IMap; } -// Interface for an Industry object - Used for type checking method arguments -interface IIndustry { - awareness: number; - popularity: number; - reqMats: IMap; - sciFac: number; - sciResearch: any; - type: string; -} - - export class Product { // Product name @@ -137,7 +127,7 @@ export class Product { } // @param industry - Industry object. Reference to industry that makes this Product - finishProduct(employeeProd: IMap, industry: IIndustry): void { + finishProduct(employeeProd: {[key: string]: number}, industry: IIndustry): void { this.fin = true; //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 (const matName in industry.reqMats) { 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 this.siz = 0; 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; } diff --git a/src/Corporation/Warehouse.ts b/src/Corporation/Warehouse.ts index ec912fa28..100573c05 100644 --- a/src/Corporation/Warehouse.ts +++ b/src/Corporation/Warehouse.ts @@ -1,4 +1,6 @@ import { Material } from "./Material"; +import { ICorporation } from "./ICorporation"; +import { IIndustry } from "./IIndustry"; import { MaterialSizes } from "./MaterialSizes"; import { IMap } from "../types"; import { numeralWrapper } from "../ui/numeralFormat"; @@ -7,13 +9,9 @@ import { Generic_fromJSON, Reviver } from "../../utils/JSONReviver"; import { exceptionAlert } from "../../utils/helpers/exceptionAlert"; -interface IParent { - getStorageMultiplier(): number; -} - interface IConstructorParams { - corp?: IParent; - industry?: IParent; + corp?: ICorporation; + industry?: IIndustry; loc?: string; size?: number; } @@ -92,7 +90,7 @@ export class Warehouse { } } - updateSize(corporation: IParent, industry: IParent): void { + updateSize(corporation: ICorporation, industry: IIndustry): void { try { this.size = (this.level * 100) * corporation.getStorageMultiplier() diff --git a/src/Corporation/ui/CityTabs.tsx b/src/Corporation/ui/CityTabs.tsx index 347d6b8e2..17cc606f1 100644 --- a/src/Corporation/ui/CityTabs.tsx +++ b/src/Corporation/ui/CityTabs.tsx @@ -4,7 +4,6 @@ import React from "react"; import { CityTab } from "./CityTab"; import { ExpandNewCityPopup } from "./ExpandNewCityPopup"; import { createPopup } from "../../ui/React/createPopup"; -import { IDivision } from "../IDivision"; import { ICorporation } from "../ICorporation"; import { CorporationRouting } from "./Routing"; @@ -20,11 +19,12 @@ export function CityTabs(props: IProps): React.ReactElement { const division = props.routing.currentDivision; function openExpandNewCityModal(): void { + if(division === null) return; const popupId = "cmpy-mgmt-expand-city-popup"; createPopup(popupId, ExpandNewCityPopup, { popupId: popupId, corp: props.corp, - division: division as IDivision, + division: division, cityStateSetter: props.cityStateSetter, }); } diff --git a/src/Corporation/ui/ExpandNewCityPopup.tsx b/src/Corporation/ui/ExpandNewCityPopup.tsx index ba02f6c81..b9ef280ad 100644 --- a/src/Corporation/ui/ExpandNewCityPopup.tsx +++ b/src/Corporation/ui/ExpandNewCityPopup.tsx @@ -1,5 +1,5 @@ import React, { useRef } from "react"; -import { IDivision } from "../IDivision"; +import { IIndustry } from "../IIndustry"; import { numeralWrapper } from "../../ui/numeralFormat"; import { CorporationConstants } from "../data/Constants"; import { removePopup } from "../../ui/React/createPopup"; @@ -10,7 +10,7 @@ import { ICorporation } from "../ICorporation"; interface IProps { popupId: string; corp: ICorporation; - division: IDivision; + division: IIndustry; cityStateSetter: (city: string) => void; } diff --git a/src/Corporation/ui/HeaderTabs.tsx b/src/Corporation/ui/HeaderTabs.tsx index 3dff46d4d..67b368977 100644 --- a/src/Corporation/ui/HeaderTabs.tsx +++ b/src/Corporation/ui/HeaderTabs.tsx @@ -3,7 +3,7 @@ // divisions, see an overview of your corporation, or create a new industry import React from "react"; import { HeaderTab } from "./HeaderTab"; -import { IDivision } from "../IDivision"; +import { IIndustry } from "../IIndustry"; import { NewIndustryPopup } from "./NewIndustryPopup"; import { createPopup } from "../../ui/React/createPopup"; import { ICorporation } from "../ICorporation"; @@ -40,7 +40,7 @@ export function HeaderTabs(props: IProps): React.ReactElement { text={props.corp.name} /> { - props.corp.divisions.map((division: IDivision) => { diff --git a/src/Corporation/ui/IndustryOffice.tsx b/src/Corporation/ui/IndustryOffice.tsx index 1e872373a..faa35b039 100644 --- a/src/Corporation/ui/IndustryOffice.tsx +++ b/src/Corporation/ui/IndustryOffice.tsx @@ -133,6 +133,7 @@ export function IndustryOffice(props: IProps): React.ReactElement { const division = props.routing.currentDivision; // Validated in constructor if(division === null) return(<>); const office = division.offices[props.currentCity]; // Validated in constructor + if(office === 0) return (<>); const vechain = (props.corp.unlockUpgrades[4] === 1); // Has Vechain upgrade function switchModeOnClick(): void { @@ -159,6 +160,8 @@ export function IndustryOffice(props: IProps): React.ReactElement { // Helper functions for (re-)assigning employees to different positions function assignEmployee(to: string): void { + if(office === 0) return; + if(division === null) return; if (numUnassigned <= 0) { console.warn("Cannot assign employee. No unassigned employees available"); return; @@ -193,11 +196,13 @@ export function IndustryOffice(props: IProps): React.ReactElement { setNumUnassigned(n => n-1); office.assignEmployeeToJob(to); - office.calculateEmployeeProductivity({ corporation: props.corp, industry:division }); + office.calculateEmployeeProductivity(props.corp, division); props.corp.rerender(props.player); } function unassignEmployee(from: string): void { + if(office === 0) return; + if(division === null) return; function logWarning(pos: string): void { 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); office.unassignEmployeeFromJob(from); - office.calculateEmployeeProductivity({ corporation: props.corp, industry:division }); + office.calculateEmployeeProductivity(props.corp, division); props.corp.rerender(props.player); } @@ -436,6 +441,7 @@ export function IndustryOffice(props: IProps): React.ReactElement { const division = props.routing.currentDivision; // Validated in constructor if(division === null) return (<>); const office = division.offices[props.currentCity]; // Validated in constructor + if(office === 0) return (<>); function switchModeOnClick(): void { setEmployeeManualAssignMode(false); @@ -455,6 +461,7 @@ export function IndustryOffice(props: IProps): React.ReactElement { } function employeeSelectorOnChange(e: React.ChangeEvent): void { + if(office === 0) return; const name = getSelectText(e.target); for (let i = 0; i < office.employees.length; ++i) { 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 if(division === null) return (<>); const office = division.offices[props.currentCity]; // Validated in constructor - + if(office === 0) return (<>); const buttonStyle = { fontSize: "13px", } @@ -564,7 +571,8 @@ export function IndustryOffice(props: IProps): React.ReactElement { } function hireEmployeeButtonOnClick(): void { - office.findEmployees(props.player, { corporation: corp, industry: division }); + if(office === 0) return; + office.findEmployees(props.player, corp); } // Autohire employee button @@ -575,12 +583,14 @@ export function IndustryOffice(props: IProps): React.ReactElement { autohireEmployeeButtonClass += " std-button"; } function autohireEmployeeButtonOnClick(): void { + if(office === 0) return; if (office.atCapacity()) return; office.hireRandomEmployee(); props.corp.rerender(props.player); } function openUpgradeOfficeSizePopup(): void { + if(office === 0) return; const popupId = "cmpy-mgmt-upgrade-office-size-popup"; createPopup(popupId, UpgradeOfficeSizePopup, { office: office, @@ -591,6 +601,7 @@ export function IndustryOffice(props: IProps): React.ReactElement { } function openThrowPartyPopup(): void { + if(office === 0) return; const popupId = "cmpy-mgmt-throw-office-party-popup"; createPopup(popupId, ThrowPartyPopup, { office: office, diff --git a/src/Corporation/ui/IndustryOverview.tsx b/src/Corporation/ui/IndustryOverview.tsx index 5aad72ba0..d9bfec9c1 100644 --- a/src/Corporation/ui/IndustryOverview.tsx +++ b/src/Corporation/ui/IndustryOverview.tsx @@ -248,6 +248,7 @@ export function IndustryOverview(props: IProps): React.ReactElement { } function onClick(): void { + if(office === 0) return; if(division === null) return; if (corp.funds.lt(cost)) { dialogBoxCreate("Insufficient funds"); diff --git a/src/Corporation/ui/IndustryWarehouse.tsx b/src/Corporation/ui/IndustryWarehouse.tsx index cf436ba08..521115f72 100644 --- a/src/Corporation/ui/IndustryWarehouse.tsx +++ b/src/Corporation/ui/IndustryWarehouse.tsx @@ -292,7 +292,7 @@ function MaterialComponent(props: IMaterialProps): React.ReactElement { if (isString(mat.sllman[1])) { sellButtonText = `Sell (${numeralWrapper.format(mat.sll, nfB)}/${mat.sllman[1]})` } 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) { @@ -432,6 +432,7 @@ export function IndustryWarehouse(props: IProps): React.ReactElement { const division = props.routing.currentDivision; // Validated in render() if(division === null) return (<>); const warehouse = division.warehouses[props.currentCity]; // Validated in render() + if(warehouse === 0) return (<>); // General Storage information at the top const sizeUsageStyle = { @@ -444,6 +445,8 @@ export function IndustryWarehouse(props: IProps): React.ReactElement { const canAffordUpgrade = (corp.funds.gt(sizeUpgradeCost)); const upgradeWarehouseClass = canAffordUpgrade ? "std-button" : "a-link-button-inactive"; function upgradeWarehouseOnClick(): void { + if(division === null) return; + if(warehouse === 0) return; ++warehouse.level; warehouse.updateSize(corp, division); corp.funds = corp.funds.minus(sizeUpgradeCost); @@ -510,6 +513,7 @@ export function IndustryWarehouse(props: IProps): React.ReactElement { // Smart Supply Checkbox const smartSupplyCheckboxId = "cmpy-mgmt-smart-supply-checkbox"; function smartSupplyOnChange(e: React.ChangeEvent): void { + if(warehouse === 0) return; warehouse.smartSupplyEnabled = e.target.checked; corp.rerender(props.player); } @@ -535,14 +539,15 @@ export function IndustryWarehouse(props: IProps): React.ReactElement { const products = []; if (division.makesProducts && Object.keys(division.products).length > 0) { for (const productName in division.products) { - if (division.products[productName] instanceof Product) { + const product = division.products[productName]; + if (product instanceof Product) { products.push(); } } diff --git a/src/Corporation/ui/Overview.tsx b/src/Corporation/ui/Overview.tsx index 2a3cdc314..39e9ad6b6 100644 --- a/src/Corporation/ui/Overview.tsx +++ b/src/Corporation/ui/Overview.tsx @@ -36,7 +36,7 @@ interface GeneralBtns { export function Overview(props: IProps): React.ReactElement { // Generic Function for Creating a button interface ICreateButtonProps { - text: string + text: string; class?: string; display?: string; tooltip?: string; diff --git a/src/Corporation/ui/Routing.ts b/src/Corporation/ui/Routing.ts index b3ae08967..b39d8d164 100644 --- a/src/Corporation/ui/Routing.ts +++ b/src/Corporation/ui/Routing.ts @@ -1,4 +1,3 @@ -import { IMap } from "../../types"; import { ICorporation } from "../ICorporation"; import { IIndustry } from "../IIndustry"; diff --git a/src/Corporation/ui/SellMaterialPopup.tsx b/src/Corporation/ui/SellMaterialPopup.tsx index e209c8125..4b4828ba0 100644 --- a/src/Corporation/ui/SellMaterialPopup.tsx +++ b/src/Corporation/ui/SellMaterialPopup.tsx @@ -22,7 +22,7 @@ interface IProps { // Create a popup that let the player manage sales of a material export function SellMaterialPopup(props: IProps): React.ReactElement { - const [amt, setAmt] = useState(props.mat.sllman[1] ? props.mat.sllman[1] : ''); + const [amt, setAmt] = useState(props.mat.sllman[1] ? props.mat.sllman[1]+'' : ''); const [price, setPrice] = useState(initialPrice(props.mat)); function sellMaterial(): void { diff --git a/src/Corporation/ui/ThrowPartyPopup.tsx b/src/Corporation/ui/ThrowPartyPopup.tsx index fa37c3574..0b18186c7 100644 --- a/src/Corporation/ui/ThrowPartyPopup.tsx +++ b/src/Corporation/ui/ThrowPartyPopup.tsx @@ -2,11 +2,11 @@ import React, { useState } from 'react'; import { removePopup } from "../../ui/React/createPopup"; import { numeralWrapper } from "../../ui/numeralFormat"; import { dialogBoxCreate } from "../../../utils/DialogBox"; -import { IOfficeSpace } from "../IOfficeSpace"; +import { OfficeSpace } from "../OfficeSpace"; import { ICorporation } from "../ICorporation"; interface IProps { - office: IOfficeSpace; + office: OfficeSpace; corp: ICorporation; 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; if(cost !== null && (isNaN(cost) || cost < 0)) return

Invalid value entered!

if(cost === null) cost = 0; diff --git a/src/Corporation/ui/UpgradeOfficeSizePopup.tsx b/src/Corporation/ui/UpgradeOfficeSizePopup.tsx index ceddedccd..a7b948140 100644 --- a/src/Corporation/ui/UpgradeOfficeSizePopup.tsx +++ b/src/Corporation/ui/UpgradeOfficeSizePopup.tsx @@ -3,12 +3,12 @@ import { removePopup } from "../../ui/React/createPopup"; import { numeralWrapper } from "../../ui/numeralFormat"; import { dialogBoxCreate } from "../../../utils/DialogBox"; import { CorporationConstants } from "../data/Constants"; -import { IOfficeSpace } from "../IOfficeSpace"; +import { OfficeSpace } from "../OfficeSpace"; import { ICorporation } from "../ICorporation"; import { IPlayer } from "../../PersonObjects/IPlayer"; interface IProps { - office: IOfficeSpace; + office: OfficeSpace; corp: ICorporation; popupId: string; player: IPlayer;