No more use of any in Corporations.

This commit is contained in:
Olivier Gagnon 2021-08-31 13:04:33 -04:00
parent a2379b21ec
commit 7c9c4d3f4d
25 changed files with 240 additions and 119 deletions

@ -14,7 +14,6 @@ import { IPlayer } from "../PersonObjects/I
import { Page, routing } from "../ui/navigationTracking"; import { Page, routing } from "../ui/navigationTracking";
import { dialogBoxCreate } from "../../utils/DialogBox"; import { dialogBoxCreate } from "../../utils/DialogBox";
import { Reviver, import { Reviver,
Generic_toJSON, Generic_toJSON,

@ -6,6 +6,8 @@ import { EmployeePositions } from "./EmployeePositions";
import { ICorporation } from "./ICorporation"; import { ICorporation } from "./ICorporation";
import { numeralWrapper } from "../ui/numeralFormat"; import { numeralWrapper } from "../ui/numeralFormat";
import { formatNumber } from "../../utils/StringHelperFunctions"; import { formatNumber } from "../../utils/StringHelperFunctions";
import { OfficeSpace } from "./OfficeSpace";
import { IIndustry } from "./IIndustry";
interface IParams { interface IParams {
name?: string; name?: string;
@ -57,7 +59,7 @@ export class Employee {
} }
//Returns the amount the employee needs to be paid //Returns the amount the employee needs to be paid
process(marketCycles = 1, office: any): number { process(marketCycles = 1, office: OfficeSpace): number {
const gain = 0.003 * marketCycles, const gain = 0.003 * marketCycles,
det = gain * Math.random(); det = gain * Math.random();
this.exp += gain; this.exp += gain;
@ -87,7 +89,7 @@ export class Employee {
return salary; return salary;
} }
calculateProductivity(corporation: ICorporation, industry: any): number { calculateProductivity(corporation: ICorporation, industry: IIndustry): number {
const effCre = this.cre * corporation.getEmployeeCreMultiplier() * industry.getEmployeeCreMultiplier(), const effCre = this.cre * corporation.getEmployeeCreMultiplier() * industry.getEmployeeCreMultiplier(),
effCha = this.cha * corporation.getEmployeeChaMultiplier() * industry.getEmployeeChaMultiplier(), effCha = this.cha * corporation.getEmployeeChaMultiplier() * industry.getEmployeeChaMultiplier(),
effInt = this.int * corporation.getEmployeeIntMultiplier() * industry.getEmployeeIntMultiplier(), effInt = this.int * corporation.getEmployeeIntMultiplier() * industry.getEmployeeIntMultiplier(),
@ -138,7 +140,7 @@ export class Employee {
} }
//'panel' is the DOM element on which to create the UI //'panel' is the DOM element on which to create the UI
createUI(panel: any, corporation: ICorporation, industry: any): void { createUI(panel: HTMLElement, corporation: ICorporation, industry: IIndustry): void {
const effCre = this.cre * corporation.getEmployeeCreMultiplier() * industry.getEmployeeCreMultiplier(), const effCre = this.cre * corporation.getEmployeeCreMultiplier() * industry.getEmployeeCreMultiplier(),
effCha = this.cha * corporation.getEmployeeChaMultiplier() * industry.getEmployeeChaMultiplier(), effCha = this.cha * corporation.getEmployeeChaMultiplier() * industry.getEmployeeChaMultiplier(),
effInt = this.int * corporation.getEmployeeIntMultiplier() * industry.getEmployeeIntMultiplier(), effInt = this.int * corporation.getEmployeeIntMultiplier() * industry.getEmployeeIntMultiplier(),

@ -0,0 +1,5 @@
export interface Export {
ind: string;
city: string;
amt: string;
}

@ -0,0 +1,78 @@
import { Material } from "./Material";
import { Warehouse } from "./Warehouse";
import { ICorporation } from "./ICorporation";
import { OfficeSpace } from "./OfficeSpace";
import { Product } from "./Product";
import { IndustryUpgrade } from "./IndustryUpgrades";
export interface IIndustry {
name: string;
type: string;
sciResearch: Material;
researched: any;
reqMats: any;
prodMats: string[];
products: any;
makesProducts: boolean;
awareness: number;
popularity: number;
startingCost: number;
reFac: number;
sciFac: number;
hwFac: number;
robFac: number;
aiFac: number;
advFac: number;
prodMult: number;
// Decimal
lastCycleRevenue: any;
lastCycleExpenses: any;
thisCycleRevenue: any;
thisCycleExpenses: any;
upgrades: number[];
state: string;
newInd: boolean;
warehouses: any;
offices: any;
init(): void;
getProductDescriptionText(): string;
getMaximumNumberProducts(): number;
hasMaximumNumberProducts(): boolean;
calculateProductionFactors(): void;
updateWarehouseSizeUsed(warehouse: Warehouse): void;
process(marketCycles: number, state: string, corporation: ICorporation): void;
processMaterialMarket(): void;
processProductMarket(marketCycles: number): void;
processMaterials(marketCycles: number, corporation: ICorporation): [number, number];
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;
getOfficeProductivity(office: OfficeSpace, params?: any): number;
getBusinessFactor(office: OfficeSpace): number;
getAdvertisingFactors(): [number, number, number, number];
getMarketFactor(mat: {dmd: number; cmp: number}): number;
hasResearch(name: string): boolean;
updateResearchTree(): void;
getAdvertisingMultiplier(): number;
getEmployeeChaMultiplier(): number;
getEmployeeCreMultiplier(): number;
getEmployeeEffMultiplier(): number;
getEmployeeIntMultiplier(): number;
getProductionMultiplier(): number;
getProductProductionMultiplier(): number;
getSalesMultiplier(): number;
getScientificResearchMultiplier(): number;
getStorageMultiplier(): number;
toJSON(): any;
}

@ -1,6 +1,7 @@
import { Generic_fromJSON, import { Generic_fromJSON,
Generic_toJSON, Generic_toJSON,
Reviver } from "../../utils/JSONReviver"; Reviver } from "../../utils/JSONReviver";
import { Export } from "./Export";
interface IConstructorParams { interface IConstructorParams {
name?: string; name?: string;
@ -43,7 +44,7 @@ export class Material {
imp = 0; imp = 0;
// Exports of this material to another warehouse/industry // Exports of this material to another warehouse/industry
exp: any[] = []; exp: Export[] = [];
// Total amount of this material exported in the last cycle // Total amount of this material exported in the last cycle
totalExp = 0; totalExp = 0;
@ -52,7 +53,7 @@ export class Material {
bCost = 0; bCost = 0;
// Cost / sec to sell this material // Cost / sec to sell this material
sCost = 0; sCost: string | number = 0;
// 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]

@ -14,6 +14,9 @@ import { removeElementById } from "../../utils/uiHelpers/removeElementById";
import { createElement } from "../../utils/uiHelpers/createElement"; import { createElement } from "../../utils/uiHelpers/createElement";
import { numeralWrapper } from "../ui/numeralFormat"; import { numeralWrapper } from "../ui/numeralFormat";
import { Employee } from "./Employee"; import { Employee } from "./Employee";
import { IIndustry } from "./IIndustry";
import { ICorporation } from './ICorporation';
import { IPlayer } from "../PersonObjects/IPlayer";
interface IParams { interface IParams {
loc?: string; loc?: string;
@ -58,7 +61,7 @@ export class OfficeSpace {
return (this.employees.length) >= this.size; return (this.employees.length) >= this.size;
} }
process(marketCycles = 1, parentRefs: any): number { process(marketCycles = 1, parentRefs: {industry: IIndustry; corporation: ICorporation}): number {
const industry = parentRefs.industry; const industry = parentRefs.industry;
// HRBuddy AutoRecruitment and training // HRBuddy AutoRecruitment and training
@ -85,9 +88,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 (industry.funds < 0 && industry.lastCycleRevenue < 0) { if (parentRefs.corporation.funds < 0 && industry.lastCycleRevenue < 0) {
perfMult = Math.pow(0.99, marketCycles); perfMult = Math.pow(0.99, marketCycles);
} else if (industry.funds > 0 && industry.lastCycleRevenue > 0) { } else if (parentRefs.corporation.funds > 0 && industry.lastCycleRevenue > 0) {
perfMult = Math.pow(1.01, marketCycles); perfMult = Math.pow(1.01, marketCycles);
} }
@ -122,7 +125,7 @@ export class OfficeSpace {
return salaryPaid; return salaryPaid;
} }
calculateEmployeeProductivity(parentRefs: any): void { calculateEmployeeProductivity(parentRefs: {corporation: ICorporation; industry: IIndustry}): void {
const company = parentRefs.corporation, industry = parentRefs.industry; const company = parentRefs.corporation, industry = parentRefs.industry;
//Reset //Reset
@ -141,7 +144,7 @@ export class OfficeSpace {
} }
//Takes care of UI as well //Takes care of UI as well
findEmployees(parentRefs: any): void { findEmployees(player: IPlayer, parentRefs: {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;}
@ -197,7 +200,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(employee, parentRefs); office.hireEmployee(player, employee, parentRefs);
removeElementById("cmpy-mgmt-hire-employee-popup"); removeElementById("cmpy-mgmt-hire-employee-popup");
return false; return false;
}, },
@ -224,8 +227,8 @@ export class OfficeSpace {
createPopup("cmpy-mgmt-hire-employee-popup", elems); createPopup("cmpy-mgmt-hire-employee-popup", elems);
} }
hireEmployee(employee: Employee, parentRefs: any): void { hireEmployee(player: IPlayer, employee: Employee, parentRefs: {corporation: ICorporation}): void {
const company = parentRefs.corporation; const corporation = parentRefs.corporation;
const yesBtn = yesNoTxtInpBoxGetYesButton(), const yesBtn = yesNoTxtInpBoxGetYesButton(),
noBtn = yesNoTxtInpBoxGetNoButton(); noBtn = yesNoTxtInpBoxGetNoButton();
yesBtn.innerHTML = "Hire"; yesBtn.innerHTML = "Hire";
@ -240,7 +243,7 @@ export class OfficeSpace {
} }
employee.name = name; employee.name = name;
this.employees.push(employee); this.employees.push(employee);
company.rerender(); corporation.rerender(player);
return yesNoTxtInpBoxClose(); return yesNoTxtInpBoxClose();
}); });
noBtn.addEventListener("click", () => { noBtn.addEventListener("click", () => {
@ -285,7 +288,7 @@ export class OfficeSpace {
} }
//Finds the first unassigned employee and assigns its to the specified job //Finds the first unassigned employee and assigns its to the specified job
assignEmployeeToJob(job: any): boolean { assignEmployeeToJob(job: string): boolean {
for (let i = 0; i < this.employees.length; ++i) { for (let i = 0; i < this.employees.length; ++i) {
if (this.employees[i].pos === EmployeePositions.Unassigned) { if (this.employees[i].pos === EmployeePositions.Unassigned) {
this.employees[i].pos = job; this.employees[i].pos = job;
@ -296,7 +299,7 @@ export class OfficeSpace {
} }
//Finds the first employee with the given job and unassigns it //Finds the first employee with the given job and unassigns it
unassignEmployeeFromJob(job: any): boolean { unassignEmployeeFromJob(job: string): boolean {
for (let i = 0; i < this.employees.length; ++i) { for (let i = 0; i < this.employees.length; ++i) {
if (this.employees[i].pos === job) { if (this.employees[i].pos === job) {
this.employees[i].pos = EmployeePositions.Unassigned; this.employees[i].pos = EmployeePositions.Unassigned;

@ -1,11 +1,13 @@
import React from 'react'; import React from 'react';
import { removePopup } from "../../ui/React/createPopup"; import { removePopup } from "../../ui/React/createPopup";
import { ICorporation } from "../ICorporation"; import { ICorporation } from "../ICorporation";
import { Product } from "../Product";
import { IIndustry } from "../IIndustry";
import { IPlayer } from "../../PersonObjects/IPlayer"; import { IPlayer } from "../../PersonObjects/IPlayer";
interface IProps { interface IProps {
product: any; product: Product;
industry: any; industry: IIndustry;
corp: ICorporation; corp: ICorporation;
popupId: string; popupId: string;
player: IPlayer; player: IPlayer;

@ -2,9 +2,12 @@ import React, { useState } from 'react';
import { dialogBoxCreate } from "../../../utils/DialogBox"; import { dialogBoxCreate } from "../../../utils/DialogBox";
import { removePopup } from "../../ui/React/createPopup"; import { removePopup } from "../../ui/React/createPopup";
import { ICorporation } from "../ICorporation"; import { ICorporation } from "../ICorporation";
import { Material } from "../Material";
import { Export } from "../Export";
import { IIndustry } from "../IIndustry";
interface IProps { interface IProps {
mat: any; mat: Material;
corp: ICorporation; corp: ICorporation;
popupId: string; popupId: string;
} }
@ -64,7 +67,7 @@ export function ExportPopup(props: IProps): React.ReactElement {
removePopup(props.popupId); removePopup(props.popupId);
} }
function removeExport(exp: any): void { function removeExport(exp: Export): void {
for (let i = 0; i < props.mat.exp.length; ++i) { for (let i = 0; i < props.mat.exp.length; ++i) {
if(props.mat.exp[i].ind !== exp.ind || if(props.mat.exp[i].ind !== exp.ind ||
props.mat.exp[i].city !== exp.city || props.mat.exp[i].city !== exp.city ||
@ -75,7 +78,7 @@ export function ExportPopup(props: IProps): React.ReactElement {
rerender(); rerender();
} }
const currentDivision = props.corp.divisions.find((division: any) => division.name === industry); const currentDivision = props.corp.divisions.find((division: IIndustry) => division.name === industry);
return (<> return (<>
<p> <p>
@ -85,12 +88,12 @@ amount to 'MAX' to export all of the materials in this warehouse.
</p> </p>
<select className="dropdown" onChange={onIndustryChange} defaultValue={industry}> <select className="dropdown" onChange={onIndustryChange} defaultValue={industry}>
{ {
props.corp.divisions.map((division: any) => <option key={division.name} value={division.name}>{division.name}</option>) props.corp.divisions.map((division: IIndustry) => <option key={division.name} value={division.name}>{division.name}</option>)
} }
</select> </select>
<select className="dropdown" onChange={onCityChange} defaultValue={city}> <select className="dropdown" onChange={onCityChange} defaultValue={city}>
{ {
currentDivision && Object.keys(currentDivision.warehouses).map((cityName: any) => { currentDivision && Object.keys(currentDivision.warehouses).map((cityName: string) => {
if(currentDivision.warehouses[cityName] === 0) return; if(currentDivision.warehouses[cityName] === 0) return;
return (<option key={cityName} value={cityName}>{cityName}</option>); return (<option key={cityName} value={cityName}>{cityName}</option>);
}) })
@ -103,7 +106,7 @@ Below is a list of all current exports of this material from this warehouse.
Clicking on one of the exports below will REMOVE that export. Clicking on one of the exports below will REMOVE that export.
</p> </p>
{ {
props.mat.exp.map((exp: any, index: number) => <div key={index} className="cmpy-mgmt-existing-export" onClick={() => removeExport(exp)}> props.mat.exp.map((exp: Export, index: number) => <div key={index} className="cmpy-mgmt-existing-export" onClick={() => removeExport(exp)}>
Industry: {exp.ind}<br /> Industry: {exp.ind}<br />
City: {exp.city}<br /> City: {exp.city}<br />
Amount/s: {exp.amt} Amount/s: {exp.amt}

@ -14,9 +14,10 @@ import { UpgradeOfficeSizePopup } from "./UpgradeOfficeSizePopup";
import { ThrowPartyPopup } from "./ThrowPartyPopup"; import { ThrowPartyPopup } from "./ThrowPartyPopup";
import { ICorporation } from "../ICorporation"; import { ICorporation } from "../ICorporation";
import { IPlayer } from "../../PersonObjects/IPlayer"; import { IPlayer } from "../../PersonObjects/IPlayer";
import { CorporationRouting } from "./Routing";
interface IProps { interface IProps {
routing: any; routing: CorporationRouting;
corp: ICorporation; corp: ICorporation;
currentCity: string; currentCity: string;
player: IPlayer; player: IPlayer;
@ -130,6 +131,7 @@ export function IndustryOffice(props: IProps): React.ReactElement {
function renderAutomaticEmployeeManagement(): React.ReactElement { function renderAutomaticEmployeeManagement(): React.ReactElement {
const division = props.routing.currentDivision; // Validated in constructor const division = props.routing.currentDivision; // Validated in constructor
if(division === null) return(<></>);
const office = division.offices[props.currentCity]; // Validated in constructor const office = division.offices[props.currentCity]; // Validated in constructor
const vechain = (props.corp.unlockUpgrades[4] === 1); // Has Vechain upgrade const vechain = (props.corp.unlockUpgrades[4] === 1); // Has Vechain upgrade
@ -432,6 +434,7 @@ export function IndustryOffice(props: IProps): React.ReactElement {
function renderManualEmployeeManagement(): React.ReactElement { function renderManualEmployeeManagement(): React.ReactElement {
const corp = props.corp; const corp = props.corp;
const division = props.routing.currentDivision; // Validated in constructor const division = props.routing.currentDivision; // Validated in constructor
if(division === null) return (<></>);
const office = division.offices[props.currentCity]; // Validated in constructor const office = division.offices[props.currentCity]; // Validated in constructor
function switchModeOnClick(): void { function switchModeOnClick(): void {
@ -542,6 +545,7 @@ export function IndustryOffice(props: IProps): React.ReactElement {
const corp = props.corp; const corp = props.corp;
const division = props.routing.currentDivision; // Validated in constructor const division = props.routing.currentDivision; // Validated in constructor
if(division === null) return (<></>);
const office = division.offices[props.currentCity]; // Validated in constructor const office = division.offices[props.currentCity]; // Validated in constructor
const buttonStyle = { const buttonStyle = {
@ -560,7 +564,7 @@ export function IndustryOffice(props: IProps): React.ReactElement {
} }
function hireEmployeeButtonOnClick(): void { function hireEmployeeButtonOnClick(): void {
office.findEmployees({ corporation: corp, industry: division }); office.findEmployees(props.player, { corporation: corp, industry: division });
} }
// Autohire employee button // Autohire employee button

@ -13,9 +13,10 @@ import { ResearchPopup } from "./ResearchPopup";
import { createPopup } from "../../ui/React/createPopup"; import { createPopup } from "../../ui/React/createPopup";
import { ICorporation } from "../ICorporation"; import { ICorporation } from "../ICorporation";
import { IPlayer } from "../../PersonObjects/IPlayer"; import { IPlayer } from "../../PersonObjects/IPlayer";
import { CorporationRouting } from "./Routing";
interface IProps { interface IProps {
routing: any; routing: CorporationRouting;
corp: ICorporation; corp: ICorporation;
currentCity: string; currentCity: string;
player: IPlayer; player: IPlayer;
@ -24,7 +25,7 @@ interface IProps {
export function IndustryOverview(props: IProps): React.ReactElement { export function IndustryOverview(props: IProps): React.ReactElement {
function renderMakeProductButton(): React.ReactElement { function renderMakeProductButton(): React.ReactElement {
const division = props.routing.currentDivision; // Validated inside render() const division = props.routing.currentDivision; // Validated inside render()
if(division === null) return (<></>);
let createProductButtonText = ""; let createProductButtonText = "";
let createProductPopupText = ""; let createProductPopupText = "";
switch(division.type) { switch(division.type) {
@ -83,6 +84,7 @@ export function IndustryOverview(props: IProps): React.ReactElement {
} }
function openMakeProductPopup(): void { function openMakeProductPopup(): void {
if(division === null) return;
const popupId = "cmpy-mgmt-create-product-popup"; const popupId = "cmpy-mgmt-create-product-popup";
createPopup(popupId, MakeProductPopup, { createPopup(popupId, MakeProductPopup, {
popupText: createProductPopupText, popupText: createProductPopupText,
@ -108,7 +110,7 @@ export function IndustryOverview(props: IProps): React.ReactElement {
function renderText(): React.ReactElement { function renderText(): React.ReactElement {
const corp = props.corp; const corp = props.corp;
const division = props.routing.currentDivision; // Validated inside render() const division = props.routing.currentDivision; // Validated inside render()
if(division === null) return (<></>);
const vechain = (corp.unlockUpgrades[4] === 1); const vechain = (corp.unlockUpgrades[4] === 1);
const profit = division.lastCycleRevenue.minus(division.lastCycleExpenses).toNumber(); const profit = division.lastCycleRevenue.minus(division.lastCycleExpenses).toNumber();
@ -129,6 +131,7 @@ export function IndustryOverview(props: IProps): React.ReactElement {
const profitStr = `Profit: ${numeralWrapper.formatMoney(profit)} / s`; const profitStr = `Profit: ${numeralWrapper.formatMoney(profit)} / s`;
function productionMultHelpTipOnClick(): void { function productionMultHelpTipOnClick(): void {
if(division === null) return;
// Wrapper for createProgressBarText() // Wrapper for createProgressBarText()
// Converts the industry's "effectiveness factors" // Converts the industry's "effectiveness factors"
// into a graphic (string) depicting how high that effectiveness is // into a graphic (string) depicting how high that effectiveness is
@ -158,6 +161,7 @@ export function IndustryOverview(props: IProps): React.ReactElement {
} }
function openResearchPopup(): void { function openResearchPopup(): void {
if(division === null) return;
const popupId = "corporation-research-popup-box"; const popupId = "corporation-research-popup-box";
createPopup(popupId, ResearchPopup, { createPopup(popupId, ResearchPopup, {
industry: division, industry: division,
@ -217,6 +221,7 @@ export function IndustryOverview(props: IProps): React.ReactElement {
function renderUpgrades(): React.ReactElement[] { function renderUpgrades(): React.ReactElement[] {
const corp = props.corp; const corp = props.corp;
const division = props.routing.currentDivision; // Validated inside render() const division = props.routing.currentDivision; // Validated inside render()
if(division === null) return ([<></>]);
const office = division.offices[props.currentCity]; const office = division.offices[props.currentCity];
if (!(office instanceof OfficeSpace)) { if (!(office instanceof OfficeSpace)) {
throw new Error(`Current City (${props.currentCity}) for UI does not have an OfficeSpace object`); throw new Error(`Current City (${props.currentCity}) for UI does not have an OfficeSpace object`);
@ -243,6 +248,7 @@ export function IndustryOverview(props: IProps): React.ReactElement {
} }
function onClick(): void { function onClick(): void {
if(division === null) return;
if (corp.funds.lt(cost)) { if (corp.funds.lt(cost)) {
dialogBoxCreate("Insufficient funds"); dialogBoxCreate("Insufficient funds");
} else { } else {
@ -266,7 +272,13 @@ export function IndustryOverview(props: IProps): React.ReactElement {
return upgrades; return upgrades;
} }
function renderUpgrade(props: any): React.ReactElement { interface IRenderUpgradeProps {
onClick: () => void;
text: string;
tooltip: string;
}
function renderUpgrade(props: IRenderUpgradeProps): React.ReactElement {
return ( return (
<div className={"cmpy-mgmt-upgrade-div tooltip"} onClick={props.onClick} key={props.text}> <div className={"cmpy-mgmt-upgrade-div tooltip"} onClick={props.onClick} key={props.text}>
{props.text} {props.text}

@ -21,14 +21,16 @@ import { dialogBoxCreate } from "../../../utils/DialogBox";
import { createPopup } from "../../ui/React/createPopup"; import { createPopup } from "../../ui/React/createPopup";
import { isString } from "../../../utils/helpers/isString"; import { isString } from "../../../utils/helpers/isString";
import { ICorporation } from "../ICorporation"; import { ICorporation } from "../ICorporation";
import { IPlayer } from "../../PersonObjects/IPlayer"; import { IIndustry } from "../IIndustry";
import { CorporationRouting } from "./Routing";
import { IPlayer } from "../../PersonObjects/IPlayer";
interface IProductProps { interface IProductProps {
corp: ICorporation; corp: ICorporation;
division: any; division: IIndustry;
city: string; city: string;
product: any; product: Product;
player: IPlayer; player: IPlayer;
} }
@ -69,7 +71,7 @@ function ProductComponent(props: IProductProps): React.ReactElement {
if (isString(product.sCost)) { if (isString(product.sCost)) {
sellButtonText += (" @ " + product.sCost); sellButtonText += (" @ " + product.sCost);
} else { } else {
sellButtonText += (" @ " + numeralWrapper.format(product.sCost, "$0.000a")); sellButtonText += (" @ " + numeralWrapper.formatMoney(product.sCost as number));
} }
} }
@ -228,11 +230,11 @@ function ProductComponent(props: IProductProps): React.ReactElement {
} }
interface IMaterialProps { interface IMaterialProps {
corp: any; corp: ICorporation;
division: any; division: IIndustry;
warehouse: any; warehouse: Warehouse;
city: string; city: string;
mat: any; mat: Material;
} }
// Creates the UI for a single Material type // Creates the UI for a single Material type
@ -299,10 +301,10 @@ function MaterialComponent(props: IMaterialProps): React.ReactElement {
sellButtonText += " @ " + numeralWrapper.formatMoney(mat.bCost + markupLimit); sellButtonText += " @ " + numeralWrapper.formatMoney(mat.bCost + markupLimit);
} else if (mat.sCost) { } else if (mat.sCost) {
if (isString(mat.sCost)) { if (isString(mat.sCost)) {
const sCost = mat.sCost.replace(/MP/g, mat.bCost); const sCost = (mat.sCost as string).replace(/MP/g, mat.bCost+'');
sellButtonText += " @ " + numeralWrapper.formatMoney(eval(sCost)); sellButtonText += " @ " + numeralWrapper.formatMoney(eval(sCost));
} else { } else {
sellButtonText += " @ " + numeralWrapper.formatMoney(mat.sCost); sellButtonText += " @ " + numeralWrapper.formatMoney(mat.sCost as number);
} }
} }
} else { } else {
@ -405,8 +407,8 @@ function MaterialComponent(props: IMaterialProps): React.ReactElement {
} }
interface IProps { interface IProps {
corp: any; corp: ICorporation;
routing: any; routing: CorporationRouting;
currentCity: string; currentCity: string;
player: IPlayer; player: IPlayer;
} }
@ -414,7 +416,7 @@ interface IProps {
export function IndustryWarehouse(props: IProps): React.ReactElement { export function IndustryWarehouse(props: IProps): React.ReactElement {
// Returns a boolean indicating whether the given material is relevant for the // Returns a boolean indicating whether the given material is relevant for the
// current industry. // current industry.
function isRelevantMaterial(matName: string, division: any): boolean { function isRelevantMaterial(matName: string, division: IIndustry): boolean {
// Materials that affect Production multiplier // Materials that affect Production multiplier
const prodMultiplierMats = ["Hardware", "Robots", "AICores", "RealEstate"]; const prodMultiplierMats = ["Hardware", "Robots", "AICores", "RealEstate"];
@ -428,6 +430,7 @@ export function IndustryWarehouse(props: IProps): React.ReactElement {
function renderWarehouseUI(): React.ReactElement { function renderWarehouseUI(): React.ReactElement {
const corp = props.corp; const corp = props.corp;
const division = props.routing.currentDivision; // Validated in render() const division = props.routing.currentDivision; // Validated in render()
if(division === null) return (<></>);
const warehouse = division.warehouses[props.currentCity]; // Validated in render() const warehouse = division.warehouses[props.currentCity]; // Validated in render()
// General Storage information at the top // General Storage information at the top
@ -595,7 +598,7 @@ export function IndustryWarehouse(props: IProps): React.ReactElement {
} }
const warehouse = division.warehouses[props.currentCity]; const warehouse = division.warehouses[props.currentCity];
function purchaseWarehouse(division: any, city: string): void { function purchaseWarehouse(division: IIndustry, city: string): void {
if (props.corp.funds.lt(CorporationConstants.WarehouseInitialCost)) { if (props.corp.funds.lt(CorporationConstants.WarehouseInitialCost)) {
dialogBoxCreate("You do not have enough funds to do this!"); dialogBoxCreate("You do not have enough funds to do this!");
} else { } else {

@ -40,7 +40,7 @@ function EffectText(props: IEffectTextProps): React.ReactElement {
} }
interface IProps { interface IProps {
corp: any; corp: ICorporation;
popupId: string; popupId: string;
} }

@ -1,10 +1,11 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { dialogBoxCreate } from "../../../utils/DialogBox"; import { dialogBoxCreate } from "../../../utils/DialogBox";
import { removePopup } from "../../ui/React/createPopup"; import { removePopup } from "../../ui/React/createPopup";
import { Product } from "../Product";
interface IProps { interface IProps {
product: any; product: Product;
city: any; city: string;
popupId: string; popupId: string;
} }

@ -4,10 +4,11 @@ import { removePopup } from "../../ui/React/createPopup";
import { Industries } from "../IndustryData"; import { Industries } from "../IndustryData";
import { Product } from "../Product"; import { Product } from "../Product";
import { ICorporation } from "../ICorporation"; import { ICorporation } from "../ICorporation";
import { IIndustry } from "../IIndustry";
interface IProps { interface IProps {
popupText: string; popupText: string;
division: any; division: IIndustry;
corp: ICorporation; corp: ICorporation;
popupId: string; popupId: string;
} }

@ -1,9 +1,12 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { IIndustry } from "../IIndustry";
import { ICorporation } from "../ICorporation";
import { Material } from "../Material";
interface IMarketTA2Props { interface IMarketTA2Props {
industry: any; industry: IIndustry;
mat: any; mat: Material;
} }
function MarketTA2(props: IMarketTA2Props): React.ReactElement { function MarketTA2(props: IMarketTA2Props): React.ReactElement {
@ -70,9 +73,9 @@ function MarketTA2(props: IMarketTA2Props): React.ReactElement {
} }
interface IProps { interface IProps {
mat: any; mat: Material;
industry: any; industry: IIndustry;
corp: any; corp: ICorporation;
popupId: string; popupId: string;
} }

@ -7,17 +7,19 @@ import {
IndustryDescriptions } from "../IndustryData"; IndustryDescriptions } from "../IndustryData";
import { Industry } from "../Industry"; import { Industry } from "../Industry";
import { ICorporation } from "../ICorporation"; import { ICorporation } from "../ICorporation";
import { IIndustry } from "../IIndustry";
import { CorporationRouting } from "./Routing";
interface IProps { interface IProps {
corp: ICorporation; corp: ICorporation;
popupId: string; popupId: string;
routing: any; routing: CorporationRouting;
} }
// Create a popup that lets the player create a new industry. // Create a popup that lets the player create a new industry.
// This is created when the player clicks the "Expand into new Industry" header tab // This is created when the player clicks the "Expand into new Industry" header tab
export function NewIndustryPopup(props: IProps): React.ReactElement { export function NewIndustryPopup(props: IProps): React.ReactElement {
const allIndustries = Object.keys(Industries).sort(); const allIndustries = Object.keys(Industries).sort();
const possibleIndustries = allIndustries.filter((industryType: string) => props.corp.divisions.find((division: any) => division.type === industryType) === undefined).sort(); const possibleIndustries = allIndustries.filter((industryType: string) => props.corp.divisions.find((division: IIndustry) => division.type === industryType) === undefined).sort();
const [industry, setIndustry] = useState(possibleIndustries.length > 0 ? possibleIndustries[0] : ''); const [industry, setIndustry] = useState(possibleIndustries.length > 0 ? possibleIndustries[0] : '');
const [name, setName] = useState(''); const [name, setName] = useState('');

@ -12,7 +12,9 @@ import { GoPublicPopup } from "./GoPublicPopup";
import { CorporationConstants } from "../data/Constants"; import { CorporationConstants } from "../data/Constants";
import { CorporationUnlockUpgrades } from "../data/CorporationUnlockUpgrades"; import { CorporationUnlockUpgrades } from "../data/CorporationUnlockUpgrades";
import { CorporationUpgrades } from "../data/CorporationUpgrades"; import {
CorporationUpgrade,
CorporationUpgrades } from "../data/CorporationUpgrades";
import { CONSTANTS } from "../../Constants"; import { CONSTANTS } from "../../Constants";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
@ -26,9 +28,21 @@ interface IProps {
player: IPlayer; player: IPlayer;
} }
interface GeneralBtns {
bribeFactions: React.ReactElement;
getStarterGuide: React.ReactElement;
}
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
function createButton(props: any): React.ReactElement { interface ICreateButtonProps {
text: string
class?: string;
display?: string;
tooltip?: string;
onClick?: (event: React.MouseEvent) => void;
}
function createButton(props: ICreateButtonProps): React.ReactElement {
let className = props.class ? props.class : "std-button"; let className = props.class ? props.class : "std-button";
const displayStyle = props.display ? props.display : "block"; const displayStyle = props.display ? props.display : "block";
const hasTooltip = (props.tooltip != null); const hasTooltip = (props.tooltip != null);
@ -117,11 +131,10 @@ export function Overview(props: IProps): React.ReactElement {
function renderButtons(): React.ReactElement { function renderButtons(): React.ReactElement {
// Create a "Getting Started Guide" button that lets player view the // Create a "Getting Started Guide" button that lets player view the
// handbook and adds it to the players home computer // handbook and adds it to the players home computer
const getStarterGuideOnClick = props.corp.getStarterGuide.bind(props.corp);
const getStarterGuideBtn = createButton({ const getStarterGuideBtn = createButton({
class: "a-link-button", class: "a-link-button",
display: "inline-block", display: "inline-block",
onClick: getStarterGuideOnClick, onClick: () => props.corp.getStarterGuide(props.player),
text: "Getting Started Guide", text: "Getting Started Guide",
tooltip: "Get a copy of and read 'The Complete Handbook for Creating a Successful Corporation.' " + tooltip: "Get a copy of and read 'The Complete Handbook for Creating a Successful Corporation.' " +
"This is a .lit file that guides you through the beginning of setting up a Corporation and " + "This is a .lit file that guides you through the beginning of setting up a Corporation and " +
@ -166,10 +179,10 @@ export function Overview(props: IProps): React.ReactElement {
// Render the buttons for when your Corporation is still private // Render the buttons for when your Corporation is still private
function renderPrivateButtons(generalBtns: any): React.ReactElement { function renderPrivateButtons(generalBtns: GeneralBtns): React.ReactElement {
const fundingAvailable = (props.corp.fundingRound < 4); const fundingAvailable = (props.corp.fundingRound < 4);
const findInvestorsClassName = fundingAvailable ? "std-button" : "a-link-button-inactive"; const findInvestorsClassName = fundingAvailable ? "std-button" : "a-link-button-inactive";
const findInvestorsTooltip = fundingAvailable ? "Search for private investors who will give you startup funding in exchangefor equity (stock shares) in your company" : null; const findInvestorsTooltip = fundingAvailable ? "Search for private investors who will give you startup funding in exchangefor equity (stock shares) in your company" : undefined;
function openFindInvestorsPopup(): void { function openFindInvestorsPopup(): void {
const popupId = "cmpy-mgmt-find-investors-popup"; const popupId = "cmpy-mgmt-find-investors-popup";
@ -192,7 +205,6 @@ export function Overview(props: IProps): React.ReactElement {
const findInvestorsBtn = createButton({ const findInvestorsBtn = createButton({
class: findInvestorsClassName, class: findInvestorsClassName,
onClick: openFindInvestorsPopup, onClick: openFindInvestorsPopup,
style: "inline-block",
text: "Find Investors", text: "Find Investors",
tooltip: findInvestorsTooltip, tooltip: findInvestorsTooltip,
display: "inline-block", display: "inline-block",
@ -200,7 +212,6 @@ export function Overview(props: IProps): React.ReactElement {
const goPublicBtn = createButton({ const goPublicBtn = createButton({
class: "std-button", class: "std-button",
onClick: openGoPublicPopup, onClick: openGoPublicPopup,
style: "inline-block",
display: "inline-block", display: "inline-block",
text: "Go Public", text: "Go Public",
tooltip: "Become a publicly traded and owned entity. Going public " + tooltip: "Become a publicly traded and owned entity. Going public " +
@ -221,7 +232,7 @@ export function Overview(props: IProps): React.ReactElement {
} }
// Render the buttons for when your Corporation has gone public // Render the buttons for when your Corporation has gone public
function renderPublicButtons(generalBtns: any): React.ReactElement { function renderPublicButtons(generalBtns: GeneralBtns): React.ReactElement {
const corp = props.corp; const corp = props.corp;
const sellSharesOnCd = (corp.shareSaleCooldown > 0); const sellSharesOnCd = (corp.shareSaleCooldown > 0);
@ -234,7 +245,7 @@ export function Overview(props: IProps): React.ReactElement {
const sellSharesBtn = createButton({ const sellSharesBtn = createButton({
class: sellSharesClass, class: sellSharesClass,
display: "inline-block", display: "inline-block",
onClick: function(event: MouseEvent) { onClick: function(event: React.MouseEvent) {
if(!event.isTrusted) return; if(!event.isTrusted) return;
const popupId = "cmpy-mgmt-sell-shares-popup"; const popupId = "cmpy-mgmt-sell-shares-popup";
createPopup(popupId, SellSharesPopup, { createPopup(popupId, SellSharesPopup, {
@ -333,8 +344,13 @@ export function Overview(props: IProps): React.ReactElement {
} }
}); });
interface UpgradeData {
upgradeData: CorporationUpgrade;
upgradeLevel: number;
}
// Create an array of properties of all unlocks // Create an array of properties of all unlocks
const levelableUpgradeProps = []; const levelableUpgradeProps: UpgradeData[] = [];
for (let i = 0; i < props.corp.upgrades.length; ++i) { for (let i = 0; i < props.corp.upgrades.length; ++i) {
const upgradeData = CorporationUpgrades[i]; const upgradeData = CorporationUpgrades[i];
const level = props.corp.upgrades[i]; const level = props.corp.upgrades[i];
@ -353,7 +369,7 @@ export function Overview(props: IProps): React.ReactElement {
<h1 className={"cmpy-mgmt-upgrade-header"}> Upgrades </h1> <h1 className={"cmpy-mgmt-upgrade-header"}> Upgrades </h1>
{ {
levelableUpgradeProps.map((data: any) => <LevelableUpgrade levelableUpgradeProps.map((data: UpgradeData) => <LevelableUpgrade
player={props.player} player={props.player}
corp={props.corp} corp={props.corp}
upgradeData={data.upgradeData} upgradeData={data.upgradeData}

@ -1,9 +1,11 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { IIndustry } from "../IIndustry";
import { Product } from "../Product";
interface IProps { interface IProps {
product: any; product: Product;
industry: any; industry: IIndustry;
popupId: string; popupId: string;
} }
@ -16,7 +18,7 @@ function MarketTA2(props: IProps): React.ReactElement {
} }
function onChange(event: React.ChangeEvent<HTMLInputElement>): void { function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
setValue(event.target.value); setValue(parseFloat(event.target.value));
} }
@ -25,7 +27,7 @@ function MarketTA2(props: IProps): React.ReactElement {
rerender(); rerender();
} }
const sCost = parseFloat(value); const sCost = value;
let markup = 1; let markup = 1;
if (sCost > props.product.pCost) { if (sCost > props.product.pCost) {
if ((sCost - props.product.pCost) > markupLimit) { if ((sCost - props.product.pCost) > markupLimit) {

@ -2,11 +2,15 @@ import React, { useState } from 'react';
import { dialogBoxCreate } from "../../../utils/DialogBox"; import { dialogBoxCreate } from "../../../utils/DialogBox";
import { removePopup } from "../../ui/React/createPopup"; import { removePopup } from "../../ui/React/createPopup";
import { MaterialSizes } from "../MaterialSizes"; import { MaterialSizes } from "../MaterialSizes";
import { Warehouse } from "../Warehouse";
import { Material } from "../Material";
import { IIndustry } from "../IIndustry";
import { ICorporation } from "../ICorporation";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
interface IBulkPurchaseTextProps { interface IBulkPurchaseTextProps {
warehouse: any; warehouse: Warehouse;
mat: any; mat: Material;
amount: string; amount: string;
} }
@ -28,10 +32,10 @@ function BulkPurchaseText(props: IBulkPurchaseTextProps): React.ReactElement {
} }
interface IProps { interface IProps {
mat: any; mat: Material;
industry: any; industry: IIndustry;
warehouse: any; warehouse: Warehouse;
corp: any; corp: ICorporation;
popupId: string; popupId: string;
} }
@ -89,10 +93,11 @@ export function PurchaseMaterialPopup(props: IProps): React.ReactElement {
const [buyAmt, setBuyAmt] = useState(props.mat.buy ? props.mat.buy : null); const [buyAmt, setBuyAmt] = useState(props.mat.buy ? props.mat.buy : null);
function purchaseMaterial(): void { function purchaseMaterial(): void {
if (isNaN(parseFloat(buyAmt))) { if(buyAmt === null) return;
if (isNaN(buyAmt)) {
dialogBoxCreate("Invalid amount"); dialogBoxCreate("Invalid amount");
} else { } else {
props.mat.buy = parseFloat(buyAmt); props.mat.buy = buyAmt;
if (isNaN(props.mat.buy)) props.mat.buy = 0; if (isNaN(props.mat.buy)) props.mat.buy = 0;
removePopup(props.popupId); removePopup(props.popupId);
} }
@ -108,7 +113,7 @@ export function PurchaseMaterialPopup(props: IProps): React.ReactElement {
} }
function onChange(event: React.ChangeEvent<HTMLInputElement>): void { function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
setBuyAmt(event.target.value); setBuyAmt(parseFloat(event.target.value));
} }
return (<> return (<>

@ -6,9 +6,10 @@ import { IndustryResearchTrees } from "../IndustryData";
import { CorporationConstants } from "../data/Constants"; import { CorporationConstants } from "../data/Constants";
import { ResearchMap } from "../ResearchMap"; import { ResearchMap } from "../ResearchMap";
import { Treant } from 'treant-js'; import { Treant } from 'treant-js';
import { IIndustry } from "../IIndustry";
interface IProps { interface IProps {
industry: any; industry: IIndustry;
popupId: string; popupId: string;
} }

@ -1,33 +1,9 @@
import { IMap } from "../../types"; import { IMap } from "../../types";
import { ICorporation } from "../ICorporation";
import { IIndustry } from "../IIndustry";
export const overviewPage = "Overview"; export const overviewPage = "Overview";
// Interfaces for whatever's required to sanitize routing with Corporation Data
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;
}
interface IDivision {
name: string;
offices: IMap<IOfficeSpace>;
}
interface ICorporation {
divisions: IDivision[];
}
/** /**
* Keeps track of what content is currently being displayed for the Corporation UI * Keeps track of what content is currently being displayed for the Corporation UI
*/ */
@ -39,7 +15,7 @@ export class CorporationRouting {
// Stores a reference to the Division instance that the routing is currently on // Stores a reference to the Division instance that the routing is currently on
// This will be null if routing is on the overview page // This will be null if routing is on the overview page
currentDivision: IDivision | null = null; currentDivision: IIndustry | null = null;
constructor(corp: ICorporation) { constructor(corp: ICorporation) {
this.corp = corp; this.corp = corp;

@ -2,9 +2,10 @@ import React, { useState } from 'react';
import { dialogBoxCreate } from "../../../utils/DialogBox"; import { dialogBoxCreate } from "../../../utils/DialogBox";
import { removePopup } from "../../ui/React/createPopup"; import { removePopup } from "../../ui/React/createPopup";
import { ICorporation } from "../ICorporation"; import { ICorporation } from "../ICorporation";
import { Material } from "../Material";
function initialPrice(mat: any): string { function initialPrice(mat: Material): string {
let val = mat.sCost ? mat.sCost : ''; let val = mat.sCost ? mat.sCost+'' : '';
if (mat.marketTa2) { if (mat.marketTa2) {
val += " (Market-TA.II)"; val += " (Market-TA.II)";
} else if (mat.marketTa1) { } else if (mat.marketTa1) {
@ -14,7 +15,7 @@ function initialPrice(mat: any): string {
} }
interface IProps { interface IProps {
mat: any; mat: Material;
corp: ICorporation; corp: ICorporation;
popupId: string; popupId: string;
} }
@ -31,7 +32,7 @@ export function SellMaterialPopup(props: IProps): React.ReactElement {
if(qty === '') qty = '0'; if(qty === '') qty = '0';
let cost = p.replace(/\s+/g, ''); let cost = p.replace(/\s+/g, '');
cost = cost.replace(/[^-()\d/*+.MP]/g, ''); //Sanitize cost cost = cost.replace(/[^-()\d/*+.MP]/g, ''); //Sanitize cost
let temp = cost.replace(/MP/g, props.mat.bCost); let temp = cost.replace(/MP/g, props.mat.bCost+'');
try { try {
temp = eval(temp); temp = eval(temp);
} catch(e) { } catch(e) {

@ -2,9 +2,10 @@ import React, { useState } from 'react';
import { dialogBoxCreate } from "../../../utils/DialogBox"; import { dialogBoxCreate } from "../../../utils/DialogBox";
import { removePopup } from "../../ui/React/createPopup"; import { removePopup } from "../../ui/React/createPopup";
import { Cities } from "../../Locations/Cities"; import { Cities } from "../../Locations/Cities";
import { Product } from "../Product";
function initialPrice(product: any): string { function initialPrice(product: Product): string {
let val = product.sCost ? product.sCost : ''; let val = product.sCost ? product.sCost+'' : '';
if (product.marketTa2) { if (product.marketTa2) {
val += " (Market-TA.II)"; val += " (Market-TA.II)";
} else if (product.marketTa1) { } else if (product.marketTa1) {
@ -14,7 +15,7 @@ function initialPrice(product: any): string {
} }
interface IProps { interface IProps {
product: any; product: Product;
city: string; city: string;
popupId: string; popupId: string;
} }

@ -22,7 +22,7 @@ export function SellSharesPopup(props: IProps): React.ReactElement {
else setShares(Math.round(parseFloat(event.target.value))); else setShares(Math.round(parseFloat(event.target.value)));
} }
function ProfitIndicator(props: {shares: number | null; corp: any}): React.ReactElement { function ProfitIndicator(props: {shares: number | null; corp: ICorporation}): React.ReactElement {
if(props.shares === null) return (<></>); if(props.shares === null) return (<></>);
if (isNaN(props.shares) || props.shares <= 0) { if (isNaN(props.shares) || props.shares <= 0) {
return (<>ERROR: Invalid value entered for number of shares to sell</>); return (<>ERROR: Invalid value entered for number of shares to sell</>);

@ -57,7 +57,7 @@ export function UpgradeOfficeSizePopup(props: IProps): React.ReactElement {
interface IUpgradeButton { interface IUpgradeButton {
cost: number; cost: number;
size: number; size: number;
corp: any; corp: ICorporation;
} }
function UpgradeSizeButton(props: IUpgradeButton): React.ReactElement { function UpgradeSizeButton(props: IUpgradeButton): React.ReactElement {