diff --git a/src/Corporation/Corporation.jsx b/src/Corporation/Corporation.jsx
index 02f4c9a76..681960e18 100644
--- a/src/Corporation/Corporation.jsx
+++ b/src/Corporation/Corporation.jsx
@@ -12,6 +12,8 @@ import { MaterialSizes } from "./MaterialSizes";
import { Product } from "./Product";
import { ResearchMap } from "./ResearchMap";
import { Warehouse } from "./Warehouse";
+import { Employee } from "./Employee";
+import { OfficeSpace } from "./OfficeSpace";
import { BitNodeMultipliers } from "../BitNode/BitNodeMultipliers";
import { showLiterature } from "../Literature/LiteratureHelpers";
@@ -1453,167 +1455,6 @@ Industry.fromJSON = function(value) {
Reviver.constructors.Industry = Industry;
-function Employee(params={}) {
- if (!(this instanceof Employee)) {
- return new Employee(params);
- }
- this.name = params.name ? params.name : "Bobby";
-
- //Morale, happiness, and energy are 0-100
- this.mor = params.morale ? params.morale : getRandomInt(50, 100);
- this.hap = params.happiness ? params.happiness : getRandomInt(50, 100);
- this.ene = params.energy ? params.energy : getRandomInt(50, 100);
-
- this.int = params.intelligence ? params.intelligence : getRandomInt(10, 50);
- this.cha = params.charisma ? params.charisma : getRandomInt(10, 50);
- this.exp = params.experience ? params.experience : getRandomInt(10, 50);
- this.cre = params.creativity ? params.creativity : getRandomInt(10, 50);
- this.eff = params.efficiency ? params.efficiency : getRandomInt(10, 50);
- this.sal = params.salary ? params.salary : getRandomInt(0.1, 5);
- this.pro = 0; //Productivity, This is calculated
-
- this.cyclesUntilRaise = CyclesPerEmployeeRaise;
-
- this.loc = params.loc ? params.loc : "";
- this.pos = EmployeePositions.Unassigned;
-}
-
-//Returns the amount the employee needs to be paid
-Employee.prototype.process = function(marketCycles=1, office) {
- var gain = 0.003 * marketCycles,
- det = gain * Math.random();
- this.exp += gain;
-
- // Employee salaries slowly go up over time
- this.cyclesUntilRaise -= marketCycles;
- if (this.cyclesUntilRaise <= 0) {
- this.salary += EmployeeRaiseAmount;
- this.cyclesUntilRaise += CyclesPerEmployeeRaise;
- }
-
- //Training
- var trainingEff = gain * Math.random();
- if (this.pos === EmployeePositions.Training) {
- //To increase creativity and intelligence special upgrades are needed
- this.cha += trainingEff;
- this.exp += trainingEff;
- this.eff += trainingEff;
- }
-
- this.ene -= det;
- this.hap -= det;
-
- if (this.ene < office.minEne) {this.ene = office.minEne;}
- if (this.hap < office.minHap) {this.hap = office.minHap;}
- var salary = this.sal * marketCycles * SecsPerMarketCycle;
- return salary;
-}
-
-Employee.prototype.calculateProductivity = function(corporation, industry) {
- var effCre = this.cre * corporation.getEmployeeCreMultiplier() * industry.getEmployeeCreMultiplier(),
- effCha = this.cha * corporation.getEmployeeChaMultiplier() * industry.getEmployeeChaMultiplier(),
- effInt = this.int * corporation.getEmployeeIntMultiplier() * industry.getEmployeeIntMultiplier(),
- effEff = this.eff * corporation.getEmployeeEffMultiplier() * industry.getEmployeeEffMultiplier();
- const prodBase = this.mor * this.hap * this.ene * 1e-6;
- let prodMult;
- switch(this.pos) {
- //Calculate productivity based on position. This is multipled by prodBase
- //to get final value
- case EmployeePositions.Operations:
- prodMult = (0.6 * effInt) + (0.1 * effCha) + (this.exp) +
- (0.5 * effCre) + (effEff);
- break;
- case EmployeePositions.Engineer:
- prodMult = (effInt) + (0.1 * effCha) + (1.5 * this.exp) +
- (effEff);
- break;
- case EmployeePositions.Business:
- prodMult = (0.4 * effInt) + (effCha) + (0.5 * this.exp);
- break;
- case EmployeePositions.Management:
- prodMult = (2 * effCha) + (this.exp) + (0.2 * effCre) +
- (0.7 * effEff);
- break;
- case EmployeePositions.RandD:
- prodMult = (1.5 * effInt) + (0.8 * this.exp) + (effCre) +
- (0.5 * effEff);
- break;
- case EmployeePositions.Unassigned:
- case EmployeePositions.Training:
- prodMult = 0;
- break;
- default:
- console.error(`Invalid employee position: ${this.pos}`);
- break;
- }
- return prodBase * prodMult;
-}
-
-//Process benefits from having an office party thrown
-Employee.prototype.throwParty = function(money) {
- var mult = 1 + (money / 10e6);
- this.mor *= mult;
- this.mor = Math.min(100, this.mor);
- this.hap *= mult;
- this.hap = Math.min(100, this.hap);
- return mult;
-}
-
-//'panel' is the DOM element on which to create the UI
-Employee.prototype.createUI = function(panel, corporation, industry) {
- var effCre = this.cre * corporation.getEmployeeCreMultiplier() * industry.getEmployeeCreMultiplier(),
- effCha = this.cha * corporation.getEmployeeChaMultiplier() * industry.getEmployeeChaMultiplier(),
- effInt = this.int * corporation.getEmployeeIntMultiplier() * industry.getEmployeeIntMultiplier(),
- effEff = this.eff * corporation.getEmployeeEffMultiplier() * industry.getEmployeeEffMultiplier();
- panel.style.color = "white";
- panel.appendChild(createElement("p", {
- id:"cmpy-mgmt-employee-" + this.name + "-panel-text",
- innerHTML:"Morale: " + formatNumber(this.mor, 3) + "
+ Would you like to expand into a new city by opening an office?
+ This would cost {numeralWrapper.format(CorporationConstants.OfficeInitialCost, '$0.000a')}
+
" +
- "Happiness: " + formatNumber(this.hap, 3) + "
" +
- "Energy: " + formatNumber(this.ene, 3) + "
" +
- "Intelligence: " + formatNumber(effInt, 3) + "
" +
- "Charisma: " + formatNumber(effCha, 3) + "
" +
- "Experience: " + formatNumber(this.exp, 3) + "
" +
- "Creativity: " + formatNumber(effCre, 3) + "
" +
- "Efficiency: " + formatNumber(effEff, 3) + "
" +
- "Salary: " + numeralWrapper.format(this.sal, "$0.000a") + "/ s
",
- }));
-
- //Selector for employee position
- var selector = createElement("select", {});
- for (var key in EmployeePositions) {
- if (EmployeePositions.hasOwnProperty(key)) {
- selector.add(createElement("option", {
- text: EmployeePositions[key],
- value: EmployeePositions[key],
- }));
- }
- }
-
- selector.addEventListener("change", () => {
- this.pos = selector.options[selector.selectedIndex].value;
- });
-
- //Set initial value of selector
- for (var i = 0; i < selector.length; ++i) {
- if (selector.options[i].value === this.pos) {
- selector.selectedIndex = i;
- break;
- }
- }
- panel.appendChild(selector);
-}
-
-Employee.prototype.toJSON = function() {
- return Generic_toJSON("Employee", this);
-}
-
-Employee.fromJSON = function(value) {
- return Generic_fromJSON(Employee, value.data);
-}
-
-Reviver.constructors.Employee = Employee;
-
var OfficeSpaceTiers = {
Basic: "Basic",
Enhanced: "Enhanced",
@@ -1621,298 +1462,6 @@ var OfficeSpaceTiers = {
Extravagant: "Extravagant",
}
-function OfficeSpace(params={}) {
- this.loc = params.loc ? params.loc : "";
- this.cost = params.cost ? params.cost : 1;
- this.size = params.size ? params.size : 1;
- this.comf = params.comfort ? params.comfort : 1;
- this.beau = params.beauty ? params.beauty : 1;
- this.tier = OfficeSpaceTiers.Basic;
-
- // Min/max energy of employees
- this.minEne = 0;
- this.maxEne = 100;
-
- // Min/max Happiness of office
- this.minHap = 0;
- this.maxHap = 100;
-
- // Maximum Morale of office
- this.maxMor = 100;
-
- this.employees = [];
- this.employeeProd = {
- [EmployeePositions.Operations]: 0,
- [EmployeePositions.Engineer]: 0,
- [EmployeePositions.Business]: 0,
- [EmployeePositions.Management]: 0,
- [EmployeePositions.RandD]: 0,
- total: 0,
- };
-}
-
-OfficeSpace.prototype.atCapacity = function() {
- return (this.employees.length) >= this.size;
-}
-
-OfficeSpace.prototype.process = function(marketCycles=1, parentRefs) {
- var industry = parentRefs.industry;
-
- // HRBuddy AutoRecruitment and training
- if (industry.hasResearch("HRBuddy-Recruitment") && !this.atCapacity()) {
- const emp = this.hireRandomEmployee();
- if (industry.hasResearch("HRBuddy-Training")) {
- emp.pos = EmployeePositions.Training;
- }
- }
-
- // Process Office properties
- this.maxEne = 100;
- this.maxHap = 100;
- this.maxMor = 100;
- if (industry.hasResearch("Go-Juice")) {
- this.maxEne += 10;
- }
- if (industry.hasResearch("JoyWire")) {
- this.maxHap += 10;
- }
- if (industry.hasResearch("Sti.mu")) {
- this.maxMor += 10;
- }
-
- // Calculate changes in Morale/Happiness/Energy for Employees
- var perfMult=1; //Multiplier for employee morale/happiness/energy based on company performance
- if (industry.funds < 0 && industry.lastCycleRevenue < 0) {
- perfMult = Math.pow(0.99, marketCycles);
- } else if (industry.funds > 0 && industry.lastCycleRevenue > 0) {
- perfMult = Math.pow(1.01, marketCycles);
- }
-
- const hasAutobrew = industry.hasResearch("AutoBrew");
- const hasAutoparty = industry.hasResearch("AutoPartyManager");
-
- var salaryPaid = 0;
- for (let i = 0; i < this.employees.length; ++i) {
- const emp = this.employees[i];
- if (hasAutoparty) {
- emp.mor = this.maxMor;
- emp.hap = this.maxHap;
- } else {
- emp.mor *= perfMult;
- emp.hap *= perfMult;
- emp.mor = Math.min(emp.mor, this.maxMor);
- emp.hap = Math.min(emp.hap, this.maxHap);
- }
-
- if (hasAutobrew) {
- emp.ene = this.maxEne;
- } else {
- emp.ene *= perfMult;
- emp.ene = Math.min(emp.ene, this.maxEne);
- }
-
- const salary = emp.process(marketCycles, this);
- salaryPaid += salary;
- }
-
- this.calculateEmployeeProductivity(parentRefs);
- return salaryPaid;
-}
-
-OfficeSpace.prototype.calculateEmployeeProductivity = function(parentRefs) {
- var company = parentRefs.corporation, industry = parentRefs.industry;
-
- //Reset
- for (const name in this.employeeProd) {
- this.employeeProd[name] = 0;
- }
-
- var total = 0;
- for (let i = 0; i < this.employees.length; ++i) {
- const employee = this.employees[i];
- const prod = employee.calculateProductivity(company, industry);
- this.employeeProd[employee.pos] += prod;
- total += prod;
- }
- this.employeeProd["total"] = total;
-}
-
-//Takes care of UI as well
-OfficeSpace.prototype.findEmployees = function(parentRefs) {
- if (this.atCapacity()) { return; }
- if (document.getElementById("cmpy-mgmt-hire-employee-popup") != null) {return;}
-
- //Generate three random employees (meh, decent, amazing)
- var mult1 = getRandomInt(25, 50)/100,
- mult2 = getRandomInt(51, 75)/100,
- mult3 = getRandomInt(76, 100)/100;
- var int = getRandomInt(50, 100),
- cha = getRandomInt(50, 100),
- exp = getRandomInt(50, 100),
- cre = getRandomInt(50, 100),
- eff = getRandomInt(50, 100),
- sal = EmployeeSalaryMultiplier * (int + cha + exp + cre + eff);
-
- var emp1 = new Employee({
- intelligence: int * mult1,
- charisma: cha * mult1,
- experience: exp * mult1,
- creativity: cre * mult1,
- efficiency: eff * mult1,
- salary: sal * mult1,
- });
-
- var emp2 = new Employee({
- intelligence: int * mult2,
- charisma: cha * mult2,
- experience: exp * mult2,
- creativity: cre * mult2,
- efficiency: eff * mult2,
- salary: sal * mult2,
- });
-
- var emp3 = new Employee({
- intelligence: int * mult3,
- charisma: cha * mult3,
- experience: exp * mult3,
- creativity: cre * mult3,
- efficiency: eff * mult3,
- salary: sal * mult3,
- });
-
- var text = createElement("h1", {
- innerHTML: "Select one of the following candidates for hire:",
- });
-
- var createEmpDiv = function(employee, office) {
- var div = createElement("div", {
- class:"cmpy-mgmt-find-employee-option",
- innerHTML: "Intelligence: " + formatNumber(employee.int, 1) + "
" +
- "Charisma: " + formatNumber(employee.cha, 1) + "
" +
- "Experience: " + formatNumber(employee.exp, 1) + "
" +
- "Creativity: " + formatNumber(employee.cre, 1) + "
" +
- "Efficiency: " + formatNumber(employee.eff, 1) + "
" +
- "Salary: " + numeralWrapper.format(employee.sal, '$0.000a') + " \ s
",
- clickListener:() => {
- office.hireEmployee(employee, parentRefs);
- removeElementById("cmpy-mgmt-hire-employee-popup");
- return false;
- },
- });
- return div;
- };
-
- var cancelBtn = createElement("a", {
- class:"a-link-button",
- innerText:"Cancel",
- float:"right",
- clickListener:() => {
- removeElementById("cmpy-mgmt-hire-employee-popup");
- return false;
- },
- });
-
- var elems = [text,
- createEmpDiv(emp1, this),
- createEmpDiv(emp2, this),
- createEmpDiv(emp3, this),
- cancelBtn];
-
- createPopup("cmpy-mgmt-hire-employee-popup", elems);
-}
-
-OfficeSpace.prototype.hireEmployee = function(employee, parentRefs) {
- var company = parentRefs.corporation;
- var yesBtn = yesNoTxtInpBoxGetYesButton(),
- noBtn = yesNoTxtInpBoxGetNoButton();
- yesBtn.innerHTML = "Hire";
- noBtn.innerHTML = "Cancel";
- yesBtn.addEventListener("click", () => {
- var name = yesNoTxtInpBoxGetInput();
- for (var i = 0; i < this.employees.length; ++i) {
- if (this.employees[i].name === name) {
- dialogBoxCreate("You already have an employee with this nickname! Please give every employee a unique nickname.");
- return false;
- }
- }
- employee.name = name;
- this.employees.push(employee);
- company.rerender();
- return yesNoTxtInpBoxClose();
- });
- noBtn.addEventListener("click", () => {
- return yesNoTxtInpBoxClose();
- });
- yesNoTxtInpBoxCreate("Give your employee a nickname!");
-}
-
-OfficeSpace.prototype.hireRandomEmployee = function() {
- if (this.atCapacity()) { return; }
- if (document.getElementById("cmpy-mgmt-hire-employee-popup") != null) {return;}
-
- //Generate three random employees (meh, decent, amazing)
- var mult = getRandomInt(76, 100)/100;
- var int = getRandomInt(50, 100),
- cha = getRandomInt(50, 100),
- exp = getRandomInt(50, 100),
- cre = getRandomInt(50, 100),
- eff = getRandomInt(50, 100),
- sal = EmployeeSalaryMultiplier * (int + cha + exp + cre + eff);
-
- var emp = new Employee({
- intelligence: int * mult,
- charisma: cha * mult,
- experience: exp * mult,
- creativity: cre * mult,
- efficiency: eff * mult,
- salary: sal * mult,
- });
-
- var name = generateRandomString(7);
-
- for (let i = 0; i < this.employees.length; ++i) {
- if (this.employees[i].name === name) {
- return this.hireRandomEmployee();
- }
- }
- emp.name = name;
- this.employees.push(emp);
-
- return emp;
-}
-
-//Finds the first unassigned employee and assigns its to the specified job
-OfficeSpace.prototype.assignEmployeeToJob = function(job) {
- for (var i = 0; i < this.employees.length; ++i) {
- if (this.employees[i].pos === EmployeePositions.Unassigned) {
- this.employees[i].pos = job;
- return true;
- }
- }
- return false;
-}
-
-//Finds the first employee with the given job and unassigns it
-OfficeSpace.prototype.unassignEmployeeFromJob = function(job) {
- for (var i = 0; i < this.employees.length; ++i) {
- if (this.employees[i].pos === job) {
- this.employees[i].pos = EmployeePositions.Unassigned;
- return true;
- }
- }
- return false;
-}
-
-OfficeSpace.prototype.toJSON = function() {
- return Generic_toJSON("OfficeSpace", this);
-}
-
-OfficeSpace.fromJSON = function(value) {
- return Generic_fromJSON(OfficeSpace, value.data);
-}
-
-Reviver.constructors.OfficeSpace = OfficeSpace;
-
function Corporation(params={}) {
this.name = params.name ? params.name : "The Corporation";
@@ -2398,4 +1947,4 @@ Corporation.fromJSON = function(value) {
Reviver.constructors.Corporation = Corporation;
-export {Corporation, Industry, OfficeSpace, Warehouse};
+export {Corporation, Industry, Warehouse};
diff --git a/src/Corporation/Employee.ts b/src/Corporation/Employee.ts
new file mode 100644
index 000000000..c42d2cf58
--- /dev/null
+++ b/src/Corporation/Employee.ts
@@ -0,0 +1,194 @@
+import { CorporationConstants } from "./data/Constants";
+import { getRandomInt } from "../../utils/helpers/getRandomInt";
+import { Generic_fromJSON, Generic_toJSON, Reviver } from "../../utils/JSONReviver";
+import { createElement } from "../../utils/uiHelpers/createElement";
+import { EmployeePositions } from "./EmployeePositions";
+import { numeralWrapper } from "../ui/numeralFormat";
+import { formatNumber } from "../../utils/StringHelperFunctions";
+
+interface IParams {
+ name?: string;
+ morale?: number;
+ happiness?: number;
+ energy?: number;
+ intelligence?: number;
+ charisma?: number;
+ experience?: number;
+ creativity?: number;
+ efficiency?: number;
+ salary?: number;
+ loc?: string;
+}
+
+export class Employee {
+ name: string;
+ mor: number;
+ hap: number;
+ ene: number;
+ int: number;
+ cha: number;
+ exp: number;
+ cre: number;
+ eff: number;
+ sal: number;
+ pro = 0;
+ cyclesUntilRaise = CorporationConstants.CyclesPerEmployeeRaise;
+ loc: string;
+ pos: string;
+
+ constructor(params: IParams = {}) {
+ this.name = params.name ? params.name : "Bobby";
+
+ //Morale, happiness, and energy are 0-100
+ this.mor = params.morale ? params.morale : getRandomInt(50, 100);
+ this.hap = params.happiness ? params.happiness : getRandomInt(50, 100);
+ this.ene = params.energy ? params.energy : getRandomInt(50, 100);
+
+ this.int = params.intelligence ? params.intelligence : getRandomInt(10, 50);
+ this.cha = params.charisma ? params.charisma : getRandomInt(10, 50);
+ this.exp = params.experience ? params.experience : getRandomInt(10, 50);
+ this.cre = params.creativity ? params.creativity : getRandomInt(10, 50);
+ this.eff = params.efficiency ? params.efficiency : getRandomInt(10, 50);
+ this.sal = params.salary ? params.salary : getRandomInt(0.1, 5);
+
+ this.loc = params.loc ? params.loc : "";
+ this.pos = EmployeePositions.Unassigned;
+ }
+
+ //Returns the amount the employee needs to be paid
+ process(marketCycles = 1, office: any) {
+ const gain = 0.003 * marketCycles,
+ det = gain * Math.random();
+ this.exp += gain;
+
+ // Employee salaries slowly go up over time
+ this.cyclesUntilRaise -= marketCycles;
+ if (this.cyclesUntilRaise <= 0) {
+ this.sal += CorporationConstants.EmployeeRaiseAmount;
+ this.cyclesUntilRaise += CorporationConstants.CyclesPerEmployeeRaise;
+ }
+
+ //Training
+ const trainingEff = gain * Math.random();
+ if (this.pos === EmployeePositions.Training) {
+ //To increase creativity and intelligence special upgrades are needed
+ this.cha += trainingEff;
+ this.exp += trainingEff;
+ this.eff += trainingEff;
+ }
+
+ this.ene -= det;
+ this.hap -= det;
+
+ if (this.ene < office.minEne) {this.ene = office.minEne;}
+ if (this.hap < office.minHap) {this.hap = office.minHap;}
+ const salary = this.sal * marketCycles * CorporationConstants.SecsPerMarketCycle;
+ return salary;
+ }
+
+ calculateProductivity(corporation: any, industry: any): number {
+ const effCre = this.cre * corporation.getEmployeeCreMultiplier() * industry.getEmployeeCreMultiplier(),
+ effCha = this.cha * corporation.getEmployeeChaMultiplier() * industry.getEmployeeChaMultiplier(),
+ effInt = this.int * corporation.getEmployeeIntMultiplier() * industry.getEmployeeIntMultiplier(),
+ effEff = this.eff * corporation.getEmployeeEffMultiplier() * industry.getEmployeeEffMultiplier();
+ const prodBase = this.mor * this.hap * this.ene * 1e-6;
+ let prodMult = 0;
+ switch(this.pos) {
+ //Calculate productivity based on position. This is multipled by prodBase
+ //to get final value
+ case EmployeePositions.Operations:
+ prodMult = (0.6 * effInt) + (0.1 * effCha) + (this.exp) +
+ (0.5 * effCre) + (effEff);
+ break;
+ case EmployeePositions.Engineer:
+ prodMult = (effInt) + (0.1 * effCha) + (1.5 * this.exp) +
+ (effEff);
+ break;
+ case EmployeePositions.Business:
+ prodMult = (0.4 * effInt) + (effCha) + (0.5 * this.exp);
+ break;
+ case EmployeePositions.Management:
+ prodMult = (2 * effCha) + (this.exp) + (0.2 * effCre) +
+ (0.7 * effEff);
+ break;
+ case EmployeePositions.RandD:
+ prodMult = (1.5 * effInt) + (0.8 * this.exp) + (effCre) +
+ (0.5 * effEff);
+ break;
+ case EmployeePositions.Unassigned:
+ case EmployeePositions.Training:
+ prodMult = 0;
+ break;
+ default:
+ console.error(`Invalid employee position: ${this.pos}`);
+ break;
+ }
+ return prodBase * prodMult;
+ }
+
+ //Process benefits from having an office party thrown
+ throwParty(money: number) {
+ const mult = 1 + (money / 10e6);
+ this.mor *= mult;
+ this.mor = Math.min(100, this.mor);
+ this.hap *= mult;
+ this.hap = Math.min(100, this.hap);
+ return mult;
+ }
+
+ //'panel' is the DOM element on which to create the UI
+ createUI(panel: any, corporation: any, industry: any) {
+ const effCre = this.cre * corporation.getEmployeeCreMultiplier() * industry.getEmployeeCreMultiplier(),
+ effCha = this.cha * corporation.getEmployeeChaMultiplier() * industry.getEmployeeChaMultiplier(),
+ effInt = this.int * corporation.getEmployeeIntMultiplier() * industry.getEmployeeIntMultiplier(),
+ effEff = this.eff * corporation.getEmployeeEffMultiplier() * industry.getEmployeeEffMultiplier();
+ panel.style.color = "white";
+ panel.appendChild(createElement("p", {
+ id:"cmpy-mgmt-employee-" + this.name + "-panel-text",
+ innerHTML:"Morale: " + formatNumber(this.mor, 3) + "
" +
+ "Happiness: " + formatNumber(this.hap, 3) + "
" +
+ "Energy: " + formatNumber(this.ene, 3) + "
" +
+ "Intelligence: " + formatNumber(effInt, 3) + "
" +
+ "Charisma: " + formatNumber(effCha, 3) + "
" +
+ "Experience: " + formatNumber(this.exp, 3) + "
" +
+ "Creativity: " + formatNumber(effCre, 3) + "
" +
+ "Efficiency: " + formatNumber(effEff, 3) + "
" +
+ "Salary: " + numeralWrapper.format(this.sal, "$0.000a") + "/ s
",
+ }));
+
+ //Selector for employee position
+ const selector = createElement("select", {}) as HTMLSelectElement;
+ for (const key in EmployeePositions) {
+ if (EmployeePositions.hasOwnProperty(key)) {
+ selector.add(createElement("option", {
+ text: EmployeePositions[key],
+ value: EmployeePositions[key],
+ }) as HTMLOptionElement);
+ }
+ }
+
+ selector.addEventListener("change", () => {
+ this.pos = selector.options[selector.selectedIndex].value;
+ });
+
+ //Set initial value of selector
+ for (let i = 0; i < selector.length; ++i) {
+ if (selector.options[i].value === this.pos) {
+ selector.selectedIndex = i;
+ break;
+ }
+ }
+ panel.appendChild(selector);
+ }
+
+ toJSON(): any {
+ return Generic_toJSON("Employee", this);
+ }
+
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+ static fromJSON(value: any): Employee {
+ return Generic_fromJSON(Employee, value.data);
+ }
+}
+
+Reviver.constructors.Employee = Employee;
\ No newline at end of file
diff --git a/src/Corporation/IDivision.ts b/src/Corporation/IDivision.ts
index 1ed13a8e8..53b63e1cf 100644
--- a/src/Corporation/IDivision.ts
+++ b/src/Corporation/IDivision.ts
@@ -3,5 +3,5 @@ import { IMap } from "../types";
export interface IDivision {
name: string;
- offices: IMap
" +
+ "Charisma: " + formatNumber(employee.cha, 1) + "
" +
+ "Experience: " + formatNumber(employee.exp, 1) + "
" +
+ "Creativity: " + formatNumber(employee.cre, 1) + "
" +
+ "Efficiency: " + formatNumber(employee.eff, 1) + "
" +
+ "Salary: " + numeralWrapper.format(employee.sal, '$0.000a') + " \ s
",
+ clickListener: () => {
+ office.hireEmployee(employee, parentRefs);
+ removeElementById("cmpy-mgmt-hire-employee-popup");
+ return false;
+ },
+ });
+ return div;
+ };
+
+ const cancelBtn = createElement("a", {
+ class:"a-link-button",
+ innerText:"Cancel",
+ float:"right",
+ clickListener:() => {
+ removeElementById("cmpy-mgmt-hire-employee-popup");
+ return false;
+ },
+ });
+
+ const elems = [text,
+ createEmpDiv(emp1, this),
+ createEmpDiv(emp2, this),
+ createEmpDiv(emp3, this),
+ cancelBtn];
+
+ createPopup("cmpy-mgmt-hire-employee-popup", elems);
+ }
+
+ hireEmployee(employee: Employee, parentRefs: any) {
+ const company = parentRefs.corporation;
+ const yesBtn = yesNoTxtInpBoxGetYesButton(),
+ noBtn = yesNoTxtInpBoxGetNoButton();
+ yesBtn.innerHTML = "Hire";
+ noBtn.innerHTML = "Cancel";
+ yesBtn.addEventListener("click", () => {
+ const name = yesNoTxtInpBoxGetInput();
+ for (let i = 0; i < this.employees.length; ++i) {
+ if (this.employees[i].name === name) {
+ dialogBoxCreate("You already have an employee with this nickname! Please give every employee a unique nickname.");
+ return false;
+ }
+ }
+ employee.name = name;
+ this.employees.push(employee);
+ company.rerender();
+ return yesNoTxtInpBoxClose();
+ });
+ noBtn.addEventListener("click", () => {
+ return yesNoTxtInpBoxClose();
+ });
+ yesNoTxtInpBoxCreate("Give your employee a nickname!");
+ }
+
+ hireRandomEmployee(): Employee | undefined {
+ if (this.atCapacity()) return;
+ if (document.getElementById("cmpy-mgmt-hire-employee-popup") != null) return;
+
+ //Generate three random employees (meh, decent, amazing)
+ const mult = getRandomInt(76, 100)/100;
+ const int = getRandomInt(50, 100),
+ cha = getRandomInt(50, 100),
+ exp = getRandomInt(50, 100),
+ cre = getRandomInt(50, 100),
+ eff = getRandomInt(50, 100),
+ sal = CorporationConstants.EmployeeSalaryMultiplier * (int + cha + exp + cre + eff);
+
+ const emp = new Employee({
+ intelligence: int * mult,
+ charisma: cha * mult,
+ experience: exp * mult,
+ creativity: cre * mult,
+ efficiency: eff * mult,
+ salary: sal * mult,
+ });
+
+ const name = generateRandomString(7);
+
+ for (let i = 0; i < this.employees.length; ++i) {
+ if (this.employees[i].name === name) {
+ return this.hireRandomEmployee();
+ }
+ }
+ emp.name = name;
+ this.employees.push(emp);
+
+ return emp;
+ }
+
+ //Finds the first unassigned employee and assigns its to the specified job
+ assignEmployeeToJob(job: any): boolean {
+ for (let i = 0; i < this.employees.length; ++i) {
+ if (this.employees[i].pos === EmployeePositions.Unassigned) {
+ this.employees[i].pos = job;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ //Finds the first employee with the given job and unassigns it
+ unassignEmployeeFromJob(job: any): boolean {
+ for (let i = 0; i < this.employees.length; ++i) {
+ if (this.employees[i].pos === job) {
+ this.employees[i].pos = EmployeePositions.Unassigned;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ toJSON(): any {
+ return Generic_toJSON("OfficeSpace", this);
+ }
+
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+ static fromJSON(value: any): OfficeSpace {
+ return Generic_fromJSON(OfficeSpace, value.data);
+ }
+}
+
+Reviver.constructors.OfficeSpace = OfficeSpace;
\ No newline at end of file
diff --git a/src/Corporation/data/Constants.ts b/src/Corporation/data/Constants.ts
new file mode 100644
index 000000000..3dce0b1a9
--- /dev/null
+++ b/src/Corporation/data/Constants.ts
@@ -0,0 +1,60 @@
+const CyclesPerMarketCycle = 50;
+const AllCorporationStates = ["START", "PURCHASE", "PRODUCTION", "SALE", "EXPORT"];
+export const CorporationConstants: {
+ INITIALSHARES: number;
+ SHARESPERPRICEUPDATE: number;
+ IssueNewSharesCooldown: number;
+ SellSharesCooldown: number;
+ CyclesPerMarketCycle: number;
+ CyclesPerIndustryStateCycle: number;
+ SecsPerMarketCycle: number;
+ Cities: string[];
+ WarehouseInitialCost: number;
+ WarehouseInitialSize: number;
+ WarehouseUpgradeBaseCost: number;
+ OfficeInitialCost: number;
+ OfficeInitialSize: number;
+ OfficeUpgradeBaseCost: number;
+ BribeThreshold: number;
+ BribeToRepRatio: number;
+ ProductProductionCostRatio: number;
+ DividendMaxPercentage: number;
+ EmployeeSalaryMultiplier: number;
+ CyclesPerEmployeeRaise: number;
+ EmployeeRaiseAmount: number;
+ BaseMaxProducts: number;
+ AllCorporationStates: string[];
+} = {
+ INITIALSHARES: 1e9, //Total number of shares you have at your company
+ SHARESPERPRICEUPDATE: 1e6, //When selling large number of shares, price is dynamically updated for every batch of this amount
+ IssueNewSharesCooldown: 216e3, // 12 Hour in terms of game cycles
+ SellSharesCooldown: 18e3, // 1 Hour in terms of game cycles
+
+ CyclesPerMarketCycle: CyclesPerMarketCycle,
+ CyclesPerIndustryStateCycle: CyclesPerMarketCycle / AllCorporationStates.length,
+ SecsPerMarketCycle: CyclesPerMarketCycle / 5,
+
+ Cities: ["Aevum", "Chongqing", "Sector-12", "New Tokyo", "Ishima", "Volhaven"],
+
+ WarehouseInitialCost: 5e9, //Initial purchase cost of warehouse
+ WarehouseInitialSize: 100,
+ WarehouseUpgradeBaseCost: 1e9,
+
+ OfficeInitialCost: 4e9,
+ OfficeInitialSize: 3,
+ OfficeUpgradeBaseCost: 1e9,
+
+ BribeThreshold: 100e12, //Money needed to be able to bribe for faction rep
+ BribeToRepRatio: 1e9, //Bribe Value divided by this = rep gain
+
+ ProductProductionCostRatio: 5, //Ratio of material cost of a product to its production cost
+
+ DividendMaxPercentage: 50,
+
+ EmployeeSalaryMultiplier: 3, // Employee stats multiplied by this to determine initial salary
+ CyclesPerEmployeeRaise: 400, // All employees get a raise every X market cycles
+ EmployeeRaiseAmount: 50, // Employee salary increases by this (additive)
+
+ BaseMaxProducts: 3, // Initial value for maximum number of products allowed
+ AllCorporationStates: AllCorporationStates,
+};
\ No newline at end of file
diff --git a/src/Corporation/ui/CityTabs.tsx b/src/Corporation/ui/CityTabs.tsx
index e0f222a49..c774adc1b 100644
--- a/src/Corporation/ui/CityTabs.tsx
+++ b/src/Corporation/ui/CityTabs.tsx
@@ -2,35 +2,42 @@
// These allow player to navigate between different cities for each industry
import React from "react";
import { CityTab } from "./CityTab";
+import { ExpandNewCityPopup } from "./ExpandNewCityPopup";
+import { createPopup } from "../../ui/React/createPopup";
+import { IDivision } from "../IDivision";
interface IProps {
eventHandler: any;
routing: any;
onClicks: {[key: string]: () => void};
city: string; // currentCity
- cityStateSetter: any;
+ cityStateSetter: (city: string) => void;
+ corp: any;
}
export function CityTabs(props: IProps): React.ReactElement {
const division = props.routing.currentDivision;
- const tabs = [];
-
- // Tabs for each city
- for (const cityName in props.onClicks) {
- tabs.push(
-
- Est. Production Cost: {numeralWrapper.formatMoney(product.pCost / ProductProductionCostRatio)}
+ Est. Production Cost: {numeralWrapper.formatMoney(product.pCost / CorporationConstants.ProductProductionCostRatio)}
An estimate of the material cost it takes to create this Product.
@@ -181,8 +186,17 @@ function ProductComponent(props) {
)
}
+interface IMaterialProps {
+ corp: any;
+ division: any;
+ warehouse: any;
+ city: string;
+ mat: any;
+ eventHandler: any;
+}
+
// Creates the UI for a single Material type
-function MaterialComponent(props) {
+function MaterialComponent(props: any) {
const corp = props.corp;
const division = props.division;
const warehouse = props.warehouse;
@@ -230,7 +244,7 @@ function MaterialComponent(props) {
sellButtonText += " @ " + numeralWrapper.formatMoney(mat.bCost + markupLimit);
} else if (mat.sCost) {
if (isString(mat.sCost)) {
- var sCost = mat.sCost.replace(/MP/g, mat.bCost);
+ const sCost = mat.sCost.replace(/MP/g, mat.bCost);
sellButtonText += " @ " + numeralWrapper.formatMoney(eval(sCost));
} else {
sellButtonText += " @ " + numeralWrapper.formatMoney(mat.sCost);
@@ -320,10 +334,17 @@ function MaterialComponent(props) {
)
}
-export class IndustryWarehouse extends BaseReactComponent {
+interface IProps {
+ corp: any;
+ routing: any;
+ currentCity: string;
+ eventHandler: any;
+}
+
+export function IndustryWarehouse(props: IProps) {
// Returns a boolean indicating whether the given material is relevant for the
// current industry.
- isRelevantMaterial(matName, division) {
+ function isRelevantMaterial(matName: string, division: any): boolean {
// Materials that affect Production multiplier
const prodMultiplierMats = ["Hardware", "Robots", "AICores", "RealEstate"];
@@ -334,10 +355,10 @@ export class IndustryWarehouse extends BaseReactComponent {
return false;
}
- renderWarehouseUI() {
- const corp = this.corp();
- const division = this.routing().currentDivision; // Validated in render()
- const warehouse = division.warehouses[this.props.currentCity]; // Validated in render()
+ function renderWarehouseUI() {
+ const corp = props.corp;
+ const division = props.routing.currentDivision; // Validated in render()
+ const warehouse = division.warehouses[props.currentCity]; // Validated in render()
// General Storage information at the top
const sizeUsageStyle = {
@@ -346,7 +367,7 @@ export class IndustryWarehouse extends BaseReactComponent {
}
// Upgrade Warehouse size button
- const sizeUpgradeCost = WarehouseUpgradeBaseCost * Math.pow(1.07, warehouse.level + 1);
+ const sizeUpgradeCost = CorporationConstants.WarehouseUpgradeBaseCost * Math.pow(1.07, warehouse.level + 1);
const canAffordUpgrade = (corp.funds.gt(sizeUpgradeCost));
const upgradeWarehouseClass = canAffordUpgrade ? "std-button" : "a-link-button-inactive";
const upgradeWarehouseOnClick = () => {
@@ -416,7 +437,7 @@ export class IndustryWarehouse extends BaseReactComponent {
// Smart Supply Checkbox
const smartSupplyCheckboxId = "cmpy-mgmt-smart-supply-checkbox";
- const smartSupplyOnChange = (e) => {
+ const smartSupplyOnChange = (e: React.ChangeEvent Total Stock Shares: " + numeralWrapper.format(this.corp().totalShares, "0.000a") +
+ "Publicly Traded: " + (props.corp.public ? "Yes" : "No") + " Total Stock Shares: " + numeralWrapper.format(props.corp.totalShares, "0.000a") +
"" +
- `Outstanding Shares: ${numeralWrapper.format(this.corp().issuedShares, "0.000a")}
` +
- `Dividend Percentage: ${numeralWrapper.format(this.corp().dividendPercentage / 100, "0%")}
` +
+ `Dividend Percentage: ${numeralWrapper.format(props.corp.dividendPercentage / 100, "0%")}
` +
`Dividends per share: ${numeralWrapper.format(dividendsPerShare, "$0.000a")} / s
` +
`Your earnings as a shareholder (Pre-Tax): ${numeralWrapper.format(playerEarnings, "$0.000a")} / s
` +
- `Dividend Tax Rate: ${this.corp().dividendTaxPercentage}%
` +
- `Your earnings as a shareholder (Post-Tax): ${numeralWrapper.format(playerEarnings * (1 - (this.corp().dividendTaxPercentage / 100)), "$0.000a")} / s
`;
+ `Dividend Tax Rate: ${props.corp.dividendTaxPercentage}%
` +
+ `Your earnings as a shareholder (Post-Tax): ${numeralWrapper.format(playerEarnings * (1 - (props.corp.dividendTaxPercentage / 100)), "$0.000a")} / s
`;
}
- let txt = "Total Funds: " + numeralWrapper.format(this.corp().funds.toNumber(), '$0.000a') + "
" +
- "Total Revenue: " + numeralWrapper.format(this.corp().revenue.toNumber(), "$0.000a") + " / s
" +
- "Total Expenses: " + numeralWrapper.format(this.corp().expenses.toNumber(), "$0.000a") + " / s
" +
+ let txt = "Total Funds: " + numeralWrapper.format(props.corp.funds.toNumber(), '$0.000a') + "
" +
+ "Total Revenue: " + numeralWrapper.format(props.corp.revenue.toNumber(), "$0.000a") + " / s
" +
+ "Total Expenses: " + numeralWrapper.format(props.corp.expenses.toNumber(), "$0.000a") + " / s
" +
"Total Profits: " + profitStr + " / s
" +
dividendStr +
- "Publicly Traded: " + (this.corp().public ? "Yes" : "No") + "
" +
- "Owned Stock Shares: " + numeralWrapper.format(this.corp().numShares, '0.000a') + "
" +
- "Stock Price: " + (this.corp().public ? numeralWrapper.formatMoney(this.corp().sharePrice) : "N/A") + "
" +
- "
" +
+ "Owned Stock Shares: " + numeralWrapper.format(props.corp.numShares, '0.000a') + "
" +
+ "Stock Price: " + (props.corp.public ? numeralWrapper.formatMoney(props.corp.sharePrice) : "N/A") + "
" +
+ "
` +
- `Private Shares: ${numeralWrapper.format(this.corp().totalShares - this.corp().issuedShares - this.corp().numShares, "0.000a")}` +
+ `Outstanding Shares: ${numeralWrapper.format(props.corp.issuedShares, "0.000a")}
` +
+ `Private Shares: ${numeralWrapper.format(props.corp.totalShares - props.corp.issuedShares - props.corp.numShares, "0.000a")}` +
"
";
- const storedTime = this.corp().storedCycles * CONSTANTS.MilliPerCycle;
+ const storedTime = props.corp.storedCycles * CONSTANTS.MilliPerCycle;
if (storedTime > 15000) {
txt += `Bonus time: ${convertTimeMsToTimeElapsedString(storedTime)}
`;
}
- let prodMult = this.corp().getProductionMultiplier(),
- storageMult = this.corp().getStorageMultiplier(),
- advMult = this.corp().getAdvertisingMultiplier(),
- empCreMult = this.corp().getEmployeeCreMultiplier(),
- empChaMult = this.corp().getEmployeeChaMultiplier(),
- empIntMult = this.corp().getEmployeeIntMultiplier(),
- empEffMult = this.corp().getEmployeeEffMultiplier(),
- salesMult = this.corp().getSalesMultiplier(),
- sciResMult = this.corp().getScientificResearchMultiplier();
+ const prodMult = props.corp.getProductionMultiplier(),
+ storageMult = props.corp.getStorageMultiplier(),
+ advMult = props.corp.getAdvertisingMultiplier(),
+ empCreMult = props.corp.getEmployeeCreMultiplier(),
+ empChaMult = props.corp.getEmployeeChaMultiplier(),
+ empIntMult = props.corp.getEmployeeIntMultiplier(),
+ empEffMult = props.corp.getEmployeeEffMultiplier(),
+ salesMult = props.corp.getSalesMultiplier(),
+ sciResMult = props.corp.getScientificResearchMultiplier();
if (prodMult > 1) {txt += "Production Multiplier: " + numeralWrapper.format(prodMult, "0.000") + "
";}
if (storageMult > 1) {txt += "Storage Multiplier: " + numeralWrapper.format(storageMult, "0.000") + "
";}
if (advMult > 1) {txt += "Advertising Multiplier: " + numeralWrapper.format(advMult, "0.000") + "
";}
@@ -101,11 +104,11 @@ export class Overview extends BaseReactComponent {
// Render the buttons that lie below the overview text.
// These are mainly for things such as managing finances/stock
- renderButtons() {
+ function renderButtons() {
// Create a "Getting Started Guide" button that lets player view the
// handbook and adds it to the players home computer
- const getStarterGuideOnClick = this.corp().getStarterGuide.bind(this.corp());
- const getStarterGuideBtn = this.createButton({
+ const getStarterGuideOnClick = props.corp.getStarterGuide.bind(props.corp);
+ const getStarterGuideBtn = createButton({
class: "a-link-button",
display: "inline-block",
onClick: getStarterGuideOnClick,
@@ -117,13 +120,12 @@ export class Overview extends BaseReactComponent {
// Create a "Bribe Factions" button if your Corporation is powerful enough.
// This occurs regardless of whether you're public or private
- const canBribe = (this.corp().determineValuation() >= BribeThreshold);
- const bribeFactionsOnClick = this.eventHandler().createBribeFactionsPopup.bind(this.eventHandler());
+ const canBribe = (props.corp.determineValuation() >= CorporationConstants.BribeThreshold);
const bribeFactionsClass = (canBribe ? "a-link-button" : "a-link-button-inactive");
- const bribeFactionsBtn = this.createButton({
+ const bribeFactionsBtn = createButton({
class: bribeFactionsClass,
display: "inline-block",
- onClick: bribeFactionsOnClick,
+ onClick: props.eventHandler.createBribeFactionsPopup,
text: "Bribe Factions",
tooltip: (canBribe
? "Use your Corporations power and influence to bribe Faction leaders in exchange for reputation"
@@ -136,34 +138,36 @@ export class Overview extends BaseReactComponent {
getStarterGuide: getStarterGuideBtn,
};
- if (this.corp().public) {
- return this.renderPublicButtons(generalBtns);
+ if (props.corp.public) {
+ return renderPublicButtons(generalBtns);
} else {
- return this.renderPrivateButtons(generalBtns);
+ return renderPrivateButtons(generalBtns);
}
}
// Render the buttons for when your Corporation is still private
- renderPrivateButtons(generalBtns) {
- const fundingAvailable = (this.corp().fundingRound < 4);
+ function renderPrivateButtons(generalBtns: any) {
+ const fundingAvailable = (props.corp.fundingRound < 4);
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 findInvestorsOnClick = this.corp().getInvestment.bind(this.corp());
- const goPublicOnClick = this.corp().goPublic.bind(this.corp());
+ const findInvestorsOnClick = props.corp.getInvestment.bind(props.corp);
+ const goPublicOnClick = props.corp.goPublic.bind(props.corp);
- const findInvestorsBtn = this.createButton({
+ const findInvestorsBtn = createButton({
class: findInvestorsClassName,
onClick: findInvestorsOnClick,
style: "inline-block",
text: "Find Investors",
tooltip: findInvestorsTooltip,
+ display: "inline-block",
});
- const goPublicBtn = this.createButton({
+ const goPublicBtn = createButton({
class: "std-button",
onClick: goPublicOnClick,
style: "inline-block",
+ display: "inline-block",
text: "Go Public",
tooltip: "Become a publicly traded and owned entity. Going public " +
"involves issuing shares for an IPO. Once you are a public " +
@@ -183,10 +187,9 @@ export class Overview extends BaseReactComponent {
}
// Render the buttons for when your Corporation has gone public
- renderPublicButtons(generalBtns) {
- const corp = this.corp();
+ function renderPublicButtons(generalBtns: any) {
+ const corp = props.corp;
- const sellSharesOnClick = this.eventHandler().createSellSharesPopup.bind(this.eventHandler());
const sellSharesOnCd = (corp.shareSaleCooldown > 0);
const sellSharesClass = sellSharesOnCd ? "a-link-button-inactive" : "std-button";
const sellSharesTooltip = sellSharesOnCd
@@ -194,45 +197,42 @@ export class Overview extends BaseReactComponent {
: "Sell your shares in the company. The money earned from selling your " +
"shares goes into your personal account, not the Corporation's. " +
"This is one of the only ways to profit from your business venture."
- const sellSharesBtn = this.createButton({
+ const sellSharesBtn = createButton({
class: sellSharesClass,
display: "inline-block",
- onClick: function(event) {
+ onClick: function(event: MouseEvent) {
if(!event.isTrusted) return;
- sellSharesOnClick(event);
+ props.eventHandler.createSellSharesPopup(event);
},
text: "Sell Shares",
tooltip: sellSharesTooltip,
});
- const buybackSharesOnClick = this.eventHandler().createBuybackSharesPopup.bind(this.eventHandler());
- const buybackSharesBtn = this.createButton({
+ const buybackSharesBtn = createButton({
class: "std-button",
display: "inline-block",
- onClick: buybackSharesOnClick,
+ onClick: props.eventHandler.createBuybackSharesPopup,
text: "Buyback shares",
tooltip: "Buy back shares you that previously issued or sold at market price.",
});
- const issueNewSharesOnClick = this.eventHandler().createIssueNewSharesPopup.bind(this.eventHandler());
const issueNewSharesOnCd = (corp.issueNewSharesCooldown > 0);
const issueNewSharesClass = issueNewSharesOnCd ? "a-link-button-inactive" : "std-button";
const issueNewSharesTooltip = issueNewSharesOnCd
? "Cannot issue new shares for " + corp.convertCooldownToString(corp.issueNewSharesCooldown)
: "Issue new equity shares to raise capital.";
- const issueNewSharesBtn = this.createButton({
+ const issueNewSharesBtn = createButton({
class: issueNewSharesClass,
display: "inline-block",
- onClick: issueNewSharesOnClick,
+ onClick: props.eventHandler.createIssueNewSharesPopup,
text: "Issue New Shares",
tooltip: issueNewSharesTooltip,
});
- const issueDividendsOnClick = this.eventHandler().createIssueDividendsPopup.bind(this.eventHandler());
- const issueDividendsBtn = this.createButton({
+ const issueDividendsBtn = createButton({
class: "std-button",
display: "inline-block",
- onClick: issueDividendsOnClick,
+ onClick: props.eventHandler.createIssueDividendsPopup,
text: "Issue Dividends",
tooltip: "Manage the dividends that are paid out to shareholders (including yourself)",
});
@@ -252,23 +252,27 @@ export class Overview extends BaseReactComponent {
}
// Render the UI for Corporation upgrades
- renderUpgrades() {
+ function renderUpgrades() {
// Don't show upgrades
- if (this.corp().divisions.length <= 0) { return; }
+ if (props.corp.divisions.length <= 0) { return; }
// Create an array of all Unlocks
- const unlockUpgrades = [];
+ const unlockUpgrades: React.ReactElement[] = [];
Object.values(CorporationUnlockUpgrades).forEach((unlockData) => {
- if (this.corp().unlockUpgrades[unlockData[0]] === 0) {
- unlockUpgrades.push(this.renderUnlockUpgrade(unlockData));
+ if (props.corp.unlockUpgrades[unlockData[0]] === 0) {
+ unlockUpgrades.push( Upgrades
{
- levelableUpgradeProps.map((data) => {
- return this.renderLevelableUpgrade(data);
- })
+ levelableUpgradeProps.map((data: any) =>
- {this.renderUpgrades()}
-
+ {renderUpgrades()}
+