convert some corp to mui

This commit is contained in:
Olivier Gagnon 2021-09-29 19:05:25 -04:00
parent 854239ceb1
commit 5cce1c255c
12 changed files with 444 additions and 658 deletions

@ -122,7 +122,6 @@ export class OfficeSpace {
if (document.getElementById("cmpy-mgmt-hire-employee-popup") != null) return; if (document.getElementById("cmpy-mgmt-hire-employee-popup") != null) return;
//Generate three random employees (meh, decent, amazing) //Generate three random employees (meh, decent, amazing)
const mult = getRandomInt(76, 100) / 100;
const int = getRandomInt(50, 100), const int = getRandomInt(50, 100),
cha = getRandomInt(50, 100), cha = getRandomInt(50, 100),
exp = getRandomInt(50, 100), exp = getRandomInt(50, 100),
@ -131,12 +130,12 @@ export class OfficeSpace {
sal = CorporationConstants.EmployeeSalaryMultiplier * (int + cha + exp + cre + eff); sal = CorporationConstants.EmployeeSalaryMultiplier * (int + cha + exp + cre + eff);
const emp = new Employee({ const emp = new Employee({
intelligence: int * mult, intelligence: int,
charisma: cha * mult, charisma: cha,
experience: exp * mult, experience: exp,
creativity: cre * mult, creativity: cre,
efficiency: eff * mult, efficiency: eff,
salary: sal * mult, salary: sal,
}); });
const name = generateRandomString(7); const name = generateRandomString(7);

@ -1,182 +0,0 @@
import React, { useState } from "react";
import { createPopup, removePopup } from "../../ui/React/createPopup";
import { numeralWrapper } from "../../ui/numeralFormat";
import { CorporationConstants } from "../data/Constants";
import { ICorporation } from "../ICorporation";
import { OfficeSpace } from "../OfficeSpace";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { getRandomInt } from "../../utils/helpers/getRandomInt";
import { formatNumber } from "../../utils/StringHelperFunctions";
import { Employee } from "../Employee";
import { dialogBoxCreate } from "../../ui/React/DialogBox";
interface INameEmployeeProps {
office: OfficeSpace;
corp: ICorporation;
popupId: string;
employee: Employee;
player: IPlayer;
rerender: () => void;
}
function NameEmployeePopup(props: INameEmployeeProps): React.ReactElement {
const [name, setName] = useState("");
function nameEmployee(): void {
for (let i = 0; i < props.office.employees.length; ++i) {
if (props.office.employees[i].name === name) {
dialogBoxCreate("You already have an employee with this nickname!");
return;
}
}
props.employee.name = name;
props.office.employees.push(props.employee);
props.rerender();
removePopup(props.popupId);
}
function onKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {
if (event.keyCode === 13) nameEmployee();
}
function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
setName(event.target.value);
}
return (
<>
<p>Give your employee a nickname!</p>
<input
value={name}
className="text-input"
type="text"
placeholder="Employee nickname"
onKeyDown={onKeyDown}
onChange={onChange}
/>
<button className="std-button" onClick={nameEmployee}>
Hire!
</button>
</>
);
}
interface IHireEmployeeProps {
employee: Employee;
office: OfficeSpace;
popupId: string;
player: IPlayer;
corp: ICorporation;
rerender: () => void;
}
function HireEmployeeButton(props: IHireEmployeeProps): React.ReactElement {
function hire(): void {
const popupId = "cmpy-mgmt-name-employee-popup";
createPopup(popupId, NameEmployeePopup, {
rerender: props.rerender,
office: props.office,
corp: props.corp,
popupId: popupId,
player: props.player,
employee: props.employee,
});
removePopup(props.popupId);
}
return (
<div onClick={hire} className="cmpy-mgmt-find-employee-option">
Intelligence: {formatNumber(props.employee.int, 1)}
<br />
Charisma: {formatNumber(props.employee.cha, 1)}
<br />
Experience: {formatNumber(props.employee.exp, 1)}
<br />
Creativity: {formatNumber(props.employee.cre, 1)}
<br />
Efficiency: {formatNumber(props.employee.eff, 1)}
<br />
Salary: {numeralWrapper.formatMoney(props.employee.sal)} \ s<br />
</div>
);
}
interface IProps {
office: OfficeSpace;
corp: ICorporation;
popupId: string;
player: IPlayer;
rerender: () => void;
}
// Create a popup that lets the player manage exports
export function HireEmployeePopup(props: IProps): React.ReactElement {
if (props.office.atCapacity()) return <></>;
//Generate three random employees (meh, decent, amazing)
const mult1 = getRandomInt(25, 50) / 100;
const mult2 = getRandomInt(51, 75) / 100;
const mult3 = getRandomInt(76, 100) / 100;
const int = getRandomInt(50, 100);
const cha = getRandomInt(50, 100);
const exp = getRandomInt(50, 100);
const cre = getRandomInt(50, 100);
const eff = getRandomInt(50, 100);
const sal = CorporationConstants.EmployeeSalaryMultiplier * (int + cha + exp + cre + eff);
const emp1 = new Employee({
intelligence: int * mult1,
charisma: cha * mult1,
experience: exp * mult1,
creativity: cre * mult1,
efficiency: eff * mult1,
salary: sal * mult1,
});
const emp2 = new Employee({
intelligence: int * mult2,
charisma: cha * mult2,
experience: exp * mult2,
creativity: cre * mult2,
efficiency: eff * mult2,
salary: sal * mult2,
});
const emp3 = new Employee({
intelligence: int * mult3,
charisma: cha * mult3,
experience: exp * mult3,
creativity: cre * mult3,
efficiency: eff * mult3,
salary: sal * mult3,
});
return (
<>
<h1>Select one of the following candidates for hire:</h1>
<HireEmployeeButton
rerender={props.rerender}
employee={emp1}
office={props.office}
corp={props.corp}
popupId={props.popupId}
player={props.player}
/>
<HireEmployeeButton
rerender={props.rerender}
employee={emp2}
office={props.office}
corp={props.corp}
popupId={props.popupId}
player={props.player}
/>
<HireEmployeeButton
rerender={props.rerender}
employee={emp3}
office={props.office}
corp={props.corp}
popupId={props.popupId}
player={props.player}
/>
</>
);
}

@ -24,14 +24,7 @@ export function Industry(props: IProps): React.ReactElement {
return ( return (
<div> <div>
<div className={"cmpy-mgmt-industry-left-panel"}> <div className={"cmpy-mgmt-industry-left-panel"}>
<IndustryOverview <IndustryOverview rerender={props.rerender} currentCity={props.city} office={props.office} />
rerender={props.rerender}
player={player}
corp={corp}
division={division}
currentCity={props.city}
office={props.office}
/>
<IndustryOffice rerender={props.rerender} office={props.office} /> <IndustryOffice rerender={props.rerender} office={props.office} />
</div> </div>
<div className={"cmpy-mgmt-industry-right-panel"}> <div className={"cmpy-mgmt-industry-right-panel"}>

@ -8,18 +8,15 @@ import { EmployeePositions } from "../EmployeePositions";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { createPopup } from "../../ui/React/createPopup"; import { UpgradeOfficeSizeModal } from "./UpgradeOfficeSizeModal";
import { UpgradeOfficeSizePopup } from "./UpgradeOfficeSizePopup"; import { ThrowPartyModal } from "./ThrowPartyModal";
import { HireEmployeePopup } from "./HireEmployeePopup";
import { ThrowPartyPopup } from "./ThrowPartyPopup";
import { Money } from "../../ui/React/Money"; import { Money } from "../../ui/React/Money";
import { use } from "../../ui/Context";
import { useCorporation, useDivision } from "./Context"; import { useCorporation, useDivision } from "./Context";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button"; import Button from "@mui/material/Button";
import IconButton from "@mui/material/IconButton"; import IconButton from "@mui/material/IconButton";
import Box from "@mui/material/Box"; import Paper from "@mui/material/Paper";
import ArrowDropUpIcon from "@mui/icons-material/ArrowDropUp"; import ArrowDropUpIcon from "@mui/icons-material/ArrowDropUp";
import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown"; import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
import Tooltip from "@mui/material/Tooltip"; import Tooltip from "@mui/material/Tooltip";
@ -84,12 +81,6 @@ function ManualManagement(props: IProps): React.ReactElement {
props.office.employees.length > 0 ? props.office.employees[0] : null, props.office.employees.length > 0 ? props.office.employees[0] : null,
); );
const employeeInfoDivStyle = {
color: "white",
margin: "4px",
padding: "4px",
};
// Employee Selector // Employee Selector
const employees = []; const employees = [];
for (let i = 0; i < props.office.employees.length; ++i) { for (let i = 0; i < props.office.employees.length; ++i) {
@ -144,12 +135,12 @@ function ManualManagement(props: IProps): React.ReactElement {
const effEff = emp ? emp.eff * corp.getEmployeeEffMultiplier() * division.getEmployeeEffMultiplier() : 0; const effEff = emp ? emp.eff * corp.getEmployeeEffMultiplier() * division.getEmployeeEffMultiplier() : 0;
return ( return (
<div style={employeeInfoDivStyle}> <>
<Select value={employee !== null ? employee.name : ""} onChange={employeeSelectorOnChange}> <Select value={employee !== null ? employee.name : ""} onChange={employeeSelectorOnChange}>
{employees} {employees}
</Select> </Select>
{employee != null && ( {employee != null && (
<p> <Typography>
Morale: {numeralWrapper.format(employee.mor, nf)} Morale: {numeralWrapper.format(employee.mor, nf)}
<br /> <br />
Happiness: {numeralWrapper.format(employee.hap, nf)} Happiness: {numeralWrapper.format(employee.hap, nf)}
@ -167,14 +158,14 @@ function ManualManagement(props: IProps): React.ReactElement {
Efficiency: {numeralWrapper.format(effEff, nf)} Efficiency: {numeralWrapper.format(effEff, nf)}
<br /> <br />
Salary: <Money money={employee.sal} /> Salary: <Money money={employee.sal} />
</p> </Typography>
)} )}
{employee != null && ( {employee != null && (
<Select onChange={employeePositionSelectorOnChange} value={employeePositionSelectorInitialValue}> <Select onChange={employeePositionSelectorOnChange} value={employeePositionSelectorInitialValue}>
{employeePositions} {employeePositions}
</Select> </Select>
)} )}
</div> </>
); );
} }
@ -304,17 +295,22 @@ function AutoManagement(props: IProps): React.ReactElement {
<> <>
<TableRow> <TableRow>
<TableCell> <TableCell>
<p className={"tooltip"} style={{ display: "inline-block" }}> <Tooltip
Material Production: title={
<span className={"tooltiptext"}> <Typography>
The base amount of material this office can produce. Does not include production multipliers from The base amount of material this office can produce. Does not include production multipliers
upgrades and materials. This value is based off the productivity of your Operations, Engineering, from upgrades and materials. This value is based off the productivity of your Operations,
and Management employees Engineering, and Management employees
</span> </Typography>
</p> }
>
<Typography>Material Production:</Typography>
</Tooltip>
</TableCell> </TableCell>
<TableCell> <TableCell>
<p>{numeralWrapper.format(division.getOfficeProductivity(props.office), "0.000")}</p> <Typography>
{numeralWrapper.format(division.getOfficeProductivity(props.office), "0.000")}
</Typography>
</TableCell> </TableCell>
</TableRow> </TableRow>
<TableRow> <TableRow>
@ -415,87 +411,24 @@ function AutoManagement(props: IProps): React.ReactElement {
} }
export function IndustryOffice(props: IProps): React.ReactElement { export function IndustryOffice(props: IProps): React.ReactElement {
const player = use.Player();
const corp = useCorporation(); const corp = useCorporation();
const division = useDivision(); const division = useDivision();
const [upgradeOfficeSizeOpen, setUpgradeOfficeSizeOpen] = useState(false);
const [throwPartyOpen, setThrowPartyOpen] = useState(false);
const [employeeManualAssignMode, setEmployeeManualAssignMode] = useState(false); const [employeeManualAssignMode, setEmployeeManualAssignMode] = useState(false);
const buttonStyle = {
fontSize: "13px",
};
// Hire Employee button
let hireEmployeeButtonClass = "tooltip";
if (props.office.atCapacity()) {
hireEmployeeButtonClass += " a-link-button-inactive";
} else {
hireEmployeeButtonClass += " std-button";
if (props.office.employees.length === 0) {
hireEmployeeButtonClass += " flashing-button";
}
}
function openHireEmployeePopup(): void {
const popupId = "cmpy-mgmt-hire-employee-popup";
createPopup(popupId, HireEmployeePopup, {
rerender: props.rerender,
office: props.office,
corp: corp,
popupId: popupId,
player: player,
});
}
function autohireEmployeeButtonOnClick(): void { function autohireEmployeeButtonOnClick(): void {
if (props.office.atCapacity()) return; if (props.office.atCapacity()) return;
props.office.hireRandomEmployee(); props.office.hireRandomEmployee();
props.rerender(); props.rerender();
} }
function openUpgradeOfficeSizePopup(): void {
const popupId = "cmpy-mgmt-upgrade-office-size-popup";
createPopup(popupId, UpgradeOfficeSizePopup, {
rerender: props.rerender,
office: props.office,
corp: corp,
popupId: popupId,
player: player,
});
}
function openThrowPartyPopup(): void {
const popupId = "cmpy-mgmt-throw-office-party-popup";
createPopup(popupId, ThrowPartyPopup, {
office: props.office,
corp: corp,
popupId: popupId,
});
}
return ( return (
<div className={"cmpy-mgmt-employee-panel"}> <Paper>
<Typography>Office Space</Typography> <Typography>Office Space</Typography>
<Typography> <Typography>
Size: {props.office.employees.length} / {props.office.size} employees Size: {props.office.employees.length} / {props.office.size} employees
</Typography> </Typography>
<Tooltip
title={
props.office.employees.length === 0 ? (
<Typography>
You'll need to hire some employees to get your operations started! It's recommended to have at least one
employee in every position
</Typography>
) : (
""
)
}
>
<span>
<Button disabled={props.office.atCapacity()} onClick={openHireEmployeePopup}>
Hire Employee
</Button>
</span>
</Tooltip>
<Tooltip title={<Typography>Automatically hires an employee and gives him/her a random name</Typography>}> <Tooltip title={<Typography>Automatically hires an employee and gives him/her a random name</Typography>}>
<span> <span>
<Button disabled={props.office.atCapacity()} onClick={autohireEmployeeButtonOnClick}> <Button disabled={props.office.atCapacity()} onClick={autohireEmployeeButtonOnClick}>
@ -506,22 +439,36 @@ export function IndustryOffice(props: IProps): React.ReactElement {
<br /> <br />
<Tooltip title={<Typography>Upgrade the office's size so that it can hold more employees!</Typography>}> <Tooltip title={<Typography>Upgrade the office's size so that it can hold more employees!</Typography>}>
<span> <span>
<Button disabled={corp.funds.lt(0)} onClick={openUpgradeOfficeSizePopup}> <Button disabled={corp.funds.lt(0)} onClick={() => setUpgradeOfficeSizeOpen(true)}>
Upgrade size Upgrade size
</Button> </Button>
</span> </span>
</Tooltip> </Tooltip>
<UpgradeOfficeSizeModal
rerender={props.rerender}
office={props.office}
open={upgradeOfficeSizeOpen}
onClose={() => setUpgradeOfficeSizeOpen(false)}
/>
{!division.hasResearch("AutoPartyManager") && ( {!division.hasResearch("AutoPartyManager") && (
<Tooltip <>
title={<Typography>Throw an office party to increase your employee's morale and happiness</Typography>} <Tooltip
> title={<Typography>Throw an office party to increase your employee's morale and happiness</Typography>}
<span> >
<Button disabled={corp.funds.lt(0)} onClick={openThrowPartyPopup}> <span>
Throw Party <Button disabled={corp.funds.lt(0)} onClick={() => setThrowPartyOpen(true)}>
</Button> Throw Party
</span> </Button>
</Tooltip> </span>
</Tooltip>
<ThrowPartyModal
rerender={props.rerender}
office={props.office}
open={throwPartyOpen}
onClose={() => setThrowPartyOpen(false)}
/>
</>
)} )}
<br /> <br />
@ -532,6 +479,6 @@ export function IndustryOffice(props: IProps): React.ReactElement {
) : ( ) : (
<AutoManagement rerender={props.rerender} office={props.office} /> <AutoManagement rerender={props.rerender} office={props.office} />
)} )}
</div> </Paper>
); );
} }

@ -5,7 +5,6 @@ import React from "react";
import { OfficeSpace } from "../OfficeSpace"; import { OfficeSpace } from "../OfficeSpace";
import { Industries } from "../IndustryData"; import { Industries } from "../IndustryData";
import { IndustryUpgrades } from "../IndustryUpgrades"; import { IndustryUpgrades } from "../IndustryUpgrades";
import { IIndustry } from "../IIndustry";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { dialogBoxCreate } from "../../ui/React/DialogBox"; import { dialogBoxCreate } from "../../ui/React/DialogBox";
import { createProgressBarText } from "../../utils/helpers/createProgressBarText"; import { createProgressBarText } from "../../utils/helpers/createProgressBarText";
@ -13,24 +12,26 @@ import { MakeProductPopup } from "./MakeProductPopup";
import { ResearchPopup } from "./ResearchPopup"; import { ResearchPopup } from "./ResearchPopup";
import { createPopup } from "../../ui/React/createPopup"; import { createPopup } from "../../ui/React/createPopup";
import { Money } from "../../ui/React/Money"; import { Money } from "../../ui/React/Money";
import { ICorporation } from "../ICorporation";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { MoneyCost } from "./MoneyCost"; import { MoneyCost } from "./MoneyCost";
import { useCorporation, useDivision } from "./Context";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import Tooltip from "@mui/material/Tooltip";
import Paper from "@mui/material/Paper";
interface IProps { interface IProps {
corp: ICorporation;
currentCity: string; currentCity: string;
division: IIndustry;
office: OfficeSpace; office: OfficeSpace;
player: IPlayer;
rerender: () => void; rerender: () => void;
} }
export function IndustryOverview(props: IProps): React.ReactElement { export function IndustryOverview(props: IProps): React.ReactElement {
const corp = useCorporation();
const division = useDivision();
function renderMakeProductButton(): React.ReactElement { function renderMakeProductButton(): React.ReactElement {
let createProductButtonText = ""; let createProductButtonText = "";
let createProductPopupText = ""; let createProductPopupText = "";
switch (props.division.type) { switch (division.type) {
case Industries.Food: case Industries.Food:
createProductButtonText = "Build Restaurant"; createProductButtonText = "Build Restaurant";
createProductPopupText = "Build and manage a new restaurant!"; createProductPopupText = "Build and manage a new restaurant!";
@ -78,51 +79,47 @@ export function IndustryOverview(props: IProps): React.ReactElement {
"the product. Investing money in its design will result in a superior product. " + "the product. Investing money in its design will result in a superior product. " +
"Investing money in marketing the product will help the product's sales."; "Investing money in marketing the product will help the product's sales.";
const hasMaxProducts = props.division.hasMaximumNumberProducts(); const hasMaxProducts = division.hasMaximumNumberProducts();
const className = hasMaxProducts ? "a-link-button-inactive tooltip" : "std-button";
const buttonStyle = {
margin: "6px",
display: "inline-block",
};
function openMakeProductPopup(): void { function openMakeProductPopup(): void {
const popupId = "cmpy-mgmt-create-product-popup"; const popupId = "cmpy-mgmt-create-product-popup";
createPopup(popupId, MakeProductPopup, { createPopup(popupId, MakeProductPopup, {
popupText: createProductPopupText, popupText: createProductPopupText,
division: props.division, division: division,
corp: props.corp, corp: corp,
popupId: popupId, popupId: popupId,
}); });
} }
function shouldFlash(): boolean { function shouldFlash(): boolean {
return Object.keys(props.division.products).length === 0; return Object.keys(division.products).length === 0;
} }
return ( return (
<button <Tooltip
className={className + (shouldFlash() ? " flashing-button" : "")} title={
onClick={openMakeProductPopup} hasMaxProducts ? (
style={buttonStyle} <Typography>
disabled={props.corp.funds.lt(0)} ou have reached the maximum number of products: {division.getMaximumNumberProducts()}
</Typography>
) : (
""
)
}
> >
{createProductButtonText} <Button color={shouldFlash() ? "error" : "primary"} onClick={openMakeProductPopup} disabled={corp.funds.lt(0)}>
{hasMaxProducts && ( {createProductButtonText}
<span className={"tooltiptext"}> </Button>
You have reached the maximum number of products: {props.division.getMaximumNumberProducts()} </Tooltip>
</span>
)}
</button>
); );
} }
function renderText(): React.ReactElement { function renderText(): React.ReactElement {
const vechain = props.corp.unlockUpgrades[4] === 1; const vechain = corp.unlockUpgrades[4] === 1;
const profit = props.division.lastCycleRevenue.minus(props.division.lastCycleExpenses).toNumber(); const profit = division.lastCycleRevenue.minus(division.lastCycleExpenses).toNumber();
let advertisingInfo = false; let advertisingInfo = false;
const advertisingFactors = props.division.getAdvertisingFactors(); const advertisingFactors = division.getAdvertisingFactors();
const awarenessFac = advertisingFactors[1]; const awarenessFac = advertisingFactors[1];
const popularityFac = advertisingFactors[2]; const popularityFac = advertisingFactors[2];
const ratioFac = advertisingFactors[3]; const ratioFac = advertisingFactors[3];
@ -155,42 +152,44 @@ export function IndustryOverview(props: IProps): React.ReactElement {
"production multiplier of your entire Division.<br><br>" + "production multiplier of your entire Division.<br><br>" +
"Below are approximations for how effective each material is at boosting " + "Below are approximations for how effective each material is at boosting " +
"this industry's production multiplier (Bigger bars = more effective):<br><br>" + "this industry's production multiplier (Bigger bars = more effective):<br><br>" +
`Hardware:&nbsp;&nbsp;&nbsp; ${convertEffectFacToGraphic(props.division.hwFac)}<br>` + `Hardware:&nbsp;&nbsp;&nbsp; ${convertEffectFacToGraphic(division.hwFac)}<br>` +
`Robots:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ${convertEffectFacToGraphic(props.division.robFac)}<br>` + `Robots:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ${convertEffectFacToGraphic(division.robFac)}<br>` +
`AI Cores:&nbsp;&nbsp;&nbsp; ${convertEffectFacToGraphic(props.division.aiFac)}<br>` + `AI Cores:&nbsp;&nbsp;&nbsp; ${convertEffectFacToGraphic(division.aiFac)}<br>` +
`Real Estate: ${convertEffectFacToGraphic(props.division.reFac)}`, `Real Estate: ${convertEffectFacToGraphic(division.reFac)}`,
); );
} }
function openResearchPopup(): void { function openResearchPopup(): void {
const popupId = "corporation-research-popup-box"; const popupId = "corporation-research-popup-box";
createPopup(popupId, ResearchPopup, { createPopup(popupId, ResearchPopup, {
industry: props.division, industry: division,
popupId: popupId, popupId: popupId,
}); });
} }
return ( return (
<div> <div>
Industry: {props.division.type} (Corp Funds: <Money money={props.corp.funds.toNumber()} />) <Typography>
<br /> <br /> Industry: {division.type} (Corp Funds: <Money money={corp.funds.toNumber()} />)
Awareness: {numeralWrapper.format(props.division.awareness, "0.000")} <br /> <br /> <br />
Popularity: {numeralWrapper.format(props.division.popularity, "0.000")} <br /> Awareness: {numeralWrapper.format(division.awareness, "0.000")} <br />
{advertisingInfo !== false && ( Popularity: {numeralWrapper.format(division.popularity, "0.000")} <br />
<p className={"tooltip"}> {advertisingInfo !== false && (
Advertising Multiplier: x{numeralWrapper.format(totalAdvertisingFac, "0.000")} <p className={"tooltip"}>
<span className={"tooltiptext cmpy-mgmt-advertising-info"}> Advertising Multiplier: x{numeralWrapper.format(totalAdvertisingFac, "0.000")}
Total multiplier for this industrys sales due to its awareness and popularity <span className={"tooltiptext cmpy-mgmt-advertising-info"}>
<br /> Total multiplier for this industrys sales due to its awareness and popularity
Awareness Bonus: x{numeralWrapper.format(Math.pow(awarenessFac, 0.85), "0.000")} <br />
<br /> Awareness Bonus: x{numeralWrapper.format(Math.pow(awarenessFac, 0.85), "0.000")}
Popularity Bonus: x{numeralWrapper.format(Math.pow(popularityFac, 0.85), "0.000")} <br />
<br /> Popularity Bonus: x{numeralWrapper.format(Math.pow(popularityFac, 0.85), "0.000")}
Ratio Multiplier: x{numeralWrapper.format(Math.pow(ratioFac, 0.85), "0.000")} <br />
</span> Ratio Multiplier: x{numeralWrapper.format(Math.pow(ratioFac, 0.85), "0.000")}
</p> </span>
)} </p>
{advertisingInfo} )}
{advertisingInfo}
</Typography>
<br /> <br />
<br /> <br />
<table> <table>
@ -201,7 +200,7 @@ export function IndustryOverview(props: IProps): React.ReactElement {
</td> </td>
<td> <td>
<p> <p>
<Money money={props.division.lastCycleRevenue.toNumber()} /> / s <Money money={division.lastCycleRevenue.toNumber()} /> / s
</p> </p>
</td> </td>
</tr> </tr>
@ -211,7 +210,7 @@ export function IndustryOverview(props: IProps): React.ReactElement {
</td> </td>
<td> <td>
<p> <p>
<Money money={props.division.lastCycleExpenses.toNumber()} /> / s <Money money={division.lastCycleExpenses.toNumber()} /> / s
</p> </p>
</td> </td>
</tr> </tr>
@ -229,7 +228,7 @@ export function IndustryOverview(props: IProps): React.ReactElement {
</table> </table>
<br /> <br />
<p className={"tooltip"}> <p className={"tooltip"}>
Production Multiplier: {numeralWrapper.format(props.division.prodMult, "0.00")} Production Multiplier: {numeralWrapper.format(division.prodMult, "0.00")}
<span className={"tooltiptext"}> <span className={"tooltiptext"}>
Production gain from owning production-boosting materials such as hardware, Robots, AI Cores, and Real Production gain from owning production-boosting materials such as hardware, Robots, AI Cores, and Real
Estate Estate
@ -240,7 +239,7 @@ export function IndustryOverview(props: IProps): React.ReactElement {
</div> </div>
<br /> <br /> <br /> <br />
<p className={"tooltip"}> <p className={"tooltip"}>
Scientific Research: {numeralWrapper.format(props.division.sciResearch.qty, "0.000a")} Scientific Research: {numeralWrapper.format(division.sciResearch.qty, "0.000a")}
<span className={"tooltiptext"}> <span className={"tooltiptext"}>
Scientific Research increases the quality of the materials and products that you produce. Scientific Research increases the quality of the materials and products that you produce.
</span> </span>
@ -258,7 +257,7 @@ export function IndustryOverview(props: IProps): React.ReactElement {
const upgrade = IndustryUpgrades[index]; const upgrade = IndustryUpgrades[index];
// AutoBrew research disables the Coffee upgrade // AutoBrew research disables the Coffee upgrade
if (props.division.hasResearch("AutoBrew") && upgrade[4] === "Coffee") { if (division.hasResearch("AutoBrew") && upgrade[4] === "Coffee") {
continue; continue;
} }
@ -271,15 +270,15 @@ export function IndustryOverview(props: IProps): React.ReactElement {
cost = props.office.employees.length * baseCost; cost = props.office.employees.length * baseCost;
break; break;
default: default:
cost = baseCost * Math.pow(priceMult, props.division.upgrades[i]); cost = baseCost * Math.pow(priceMult, division.upgrades[i]);
break; break;
} }
function onClick(): void { function onClick(): void {
if (props.corp.funds.lt(cost)) return; if (corp.funds.lt(cost)) return;
props.corp.funds = props.corp.funds.minus(cost); corp.funds = corp.funds.minus(cost);
props.division.upgrade(upgrade, { division.upgrade(upgrade, {
corporation: props.corp, corporation: corp,
office: props.office, office: props.office,
}); });
props.rerender(); props.rerender();
@ -291,7 +290,7 @@ export function IndustryOverview(props: IProps): React.ReactElement {
onClick: onClick, onClick: onClick,
text: ( text: (
<> <>
{upgrade[4]} - <MoneyCost money={cost} corp={props.corp} /> {upgrade[4]} - <MoneyCost money={cost} corp={corp} />
</> </>
), ),
tooltip: upgrade[5], tooltip: upgrade[5],
@ -321,13 +320,12 @@ export function IndustryOverview(props: IProps): React.ReactElement {
const makeProductButton = renderMakeProductButton(); const makeProductButton = renderMakeProductButton();
return ( return (
<div className={"cmpy-mgmt-industry-overview-panel"}> <Paper>
{renderText()} {renderText()}
<br /> <br />
<u className={"industry-purchases-and-upgrades-header"}>Purchases & Upgrades</u> <Typography>Purchases & Upgrades</Typography>
<br />
{renderUpgrades()} <br /> {renderUpgrades()} <br />
{props.division.makesProducts && makeProductButton} {division.makesProducts && makeProductButton}
</div> </Paper>
); );
} }

@ -5,8 +5,12 @@ import { dialogBoxCreate } from "../../ui/React/DialogBox";
import { CorporationUpgrade } from "../data/CorporationUpgrades"; import { CorporationUpgrade } from "../data/CorporationUpgrades";
import { LevelUpgrade } from "../Actions"; import { LevelUpgrade } from "../Actions";
import { MoneyCost } from "./MoneyCost"; import { MoneyCost } from "./MoneyCost";
import { use } from "../../ui/Context";
import { useCorporation } from "./Context"; import { useCorporation } from "./Context";
import Typography from "@mui/material/Typography";
import Tooltip from "@mui/material/Tooltip";
import Button from "@mui/material/Button";
import Box from "@mui/material/Box";
import Grid from "@mui/material/Grid";
interface IProps { interface IProps {
upgrade: CorporationUpgrade; upgrade: CorporationUpgrade;
@ -14,7 +18,6 @@ interface IProps {
} }
export function LevelableUpgrade(props: IProps): React.ReactElement { export function LevelableUpgrade(props: IProps): React.ReactElement {
const player = use.Player();
const corp = useCorporation(); const corp = useCorporation();
const data = props.upgrade; const data = props.upgrade;
const level = corp.upgrades[data[0]]; const level = corp.upgrades[data[0]];
@ -23,11 +26,6 @@ export function LevelableUpgrade(props: IProps): React.ReactElement {
const priceMult = data[2]; const priceMult = data[2];
const cost = baseCost * Math.pow(priceMult, level); const cost = baseCost * Math.pow(priceMult, level);
const text = (
<>
{data[4]} - <MoneyCost money={cost} corp={corp} />
</>
);
const tooltip = data[5]; const tooltip = data[5];
function onClick(): void { function onClick(): void {
if (corp.funds.lt(cost)) return; if (corp.funds.lt(cost)) return;
@ -40,9 +38,15 @@ export function LevelableUpgrade(props: IProps): React.ReactElement {
} }
return ( return (
<button className={"cmpy-mgmt-upgrade-div tooltip"} style={{ width: "45%" }} onClick={onClick}> <Grid item xs={4}>
{text} <Box display="flex" alignItems="center" flexDirection="row-reverse">
<span className={"tooltiptext"}>{tooltip}</span> <Button disabled={corp.funds.lt(cost)} sx={{ mx: 1 }} onClick={onClick}>
</button> <MoneyCost money={cost} corp={corp} />
</Button>
<Tooltip title={tooltip}>
<Typography>{data[4]} </Typography>
</Tooltip>
</Box>
</Grid>
); );
} }

@ -19,11 +19,16 @@ import { CONSTANTS } from "../../Constants";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { convertTimeMsToTimeElapsedString } from "../../utils/StringHelperFunctions"; import { convertTimeMsToTimeElapsedString } from "../../utils/StringHelperFunctions";
import { Money } from "../../ui/React/Money"; import { Money } from "../../ui/React/Money";
import { MoneyRate } from "../../ui/React/MoneyRate";
import { StatsTable } from "../../ui/React/StatsTable";
import { use } from "../../ui/Context"; import { use } from "../../ui/Context";
import { useCorporation } from "./Context"; import { useCorporation } from "./Context";
import Typography from "@mui/material/Typography"; import Typography from "@mui/material/Typography";
import Tooltip from "@mui/material/Tooltip"; import Tooltip from "@mui/material/Tooltip";
import Button from "@mui/material/Button"; import Button from "@mui/material/Button";
import Box from "@mui/material/Box";
import Paper from "@mui/material/Paper";
import Grid from "@mui/material/Grid";
interface IProps { interface IProps {
rerender: () => void; rerender: () => void;
@ -33,67 +38,73 @@ export function Overview({ rerender }: IProps): React.ReactElement {
const corp = useCorporation(); const corp = useCorporation();
const profit: number = corp.revenue.minus(corp.expenses).toNumber(); const profit: number = corp.revenue.minus(corp.expenses).toNumber();
const multRows: any[][] = [];
function appendMult(name: string, value: number): void {
if (value === 1) return;
multRows.push([name, numeralWrapper.format(value, "0.000")]);
}
appendMult("Production Multiplier: ", corp.getProductionMultiplier());
appendMult("Storage Multiplier: ", corp.getStorageMultiplier());
appendMult("Advertising Multiplier: ", corp.getAdvertisingMultiplier());
appendMult("Empl. Creativity Multiplier: ", corp.getEmployeeCreMultiplier());
appendMult("Empl. Charisma Multiplier: ", corp.getEmployeeChaMultiplier());
appendMult("Empl. Intelligence Multiplier: ", corp.getEmployeeIntMultiplier());
appendMult("Empl. Efficiency Multiplier: ", corp.getEmployeeEffMultiplier());
appendMult("Sales Multiplier: ", corp.getSalesMultiplier());
appendMult("Scientific Research Multiplier: ", corp.getScientificResearchMultiplier());
return ( return (
<div> <>
<Typography> <StatsTable
Total Funds: <Money money={corp.funds.toNumber()} /> rows={[
<br /> ["Total Funds:", <Money money={corp.funds.toNumber()} />],
Total Revenue: <Money money={corp.revenue.toNumber()} /> / s<br /> ["Total Revenue:", <MoneyRate money={corp.revenue.toNumber()} />],
Total Expenses: <Money money={corp.expenses.toNumber()} /> / s ["Total Expenses:", <MoneyRate money={corp.expenses.toNumber()} />],
<br /> ["Publicly Traded:", corp.public ? "Yes" : "No"],
Total Profits: <Money money={profit} /> / s<br /> ["Owned Stock Shares:", numeralWrapper.format(corp.numShares, "0.000a")],
<DividendsStats profit={profit} /> ["Stock Price:", corp.public ? <Money money={corp.sharePrice} /> : "N/A"],
Publicly Traded: {corp.public ? "Yes" : "No"} ]}
<br /> />
Owned Stock Shares: {numeralWrapper.format(corp.numShares, "0.000a")} <br />
<br /> <Box display="flex">
Stock Price: {corp.public ? <Money money={corp.sharePrice} /> : "N/A"} <Tooltip
<br /> title={
</Typography> <StatsTable
rows={[
["Outstanding Shares:", numeralWrapper.format(corp.issuedShares, "0.000a")],
[
"Private Shares:",
numeralWrapper.format(corp.totalShares - corp.issuedShares - corp.numShares, "0.000a"),
],
]}
/>
}
>
<Typography>Total Stock Shares: {numeralWrapper.format(corp.totalShares, "0.000a")}</Typography>
</Tooltip>
</Box>
<br />
<DividendsStats profit={profit} />
<br />
<StatsTable rows={multRows} />
<br />
<BonusTime />
<Tooltip <Tooltip
title={ title={
<Typography> <Typography>
Outstanding Shares: {numeralWrapper.format(corp.issuedShares, "0.000a")} Get a copy of and read 'The Complete Handbook for Creating a Successful Corporation.' This is a .lit file
<br /> that guides you through the beginning of setting up a Corporation and provides some tips/pointers for
Private Shares: {numeralWrapper.format(corp.totalShares - corp.issuedShares - corp.numShares, "0.000a")} helping you get started with managing it.
</Typography> </Typography>
} }
> >
<Typography className="tooltip"> <Button onClick={() => corp.getStarterGuide(player)}>Getting Started Guide</Button>
Total Stock Shares: {numeralWrapper.format(corp.totalShares, "0.000a")}
</Typography>
</Tooltip> </Tooltip>
<br /> {corp.public ? <PublicButtons rerender={rerender} /> : <PrivateButtons rerender={rerender} />}
<br /> <BribeButton />
<Mult name="Production Multiplier: " mult={corp.getProductionMultiplier()} />
<Mult name="Storage Multiplier: " mult={corp.getStorageMultiplier()} />
<Mult name="Advertising Multiplier: " mult={corp.getAdvertisingMultiplier()} />
<Mult name="Empl. Creativity Multiplier: " mult={corp.getEmployeeCreMultiplier()} />
<Mult name="Empl. Charisma Multiplier: " mult={corp.getEmployeeChaMultiplier()} />
<Mult name="Empl. Intelligence Multiplier: " mult={corp.getEmployeeIntMultiplier()} />
<Mult name="Empl. Efficiency Multiplier: " mult={corp.getEmployeeEffMultiplier()} />
<Mult name="Sales Multiplier: " mult={corp.getSalesMultiplier()} />
<Mult name="Scientific Research Multiplier: " mult={corp.getScientificResearchMultiplier()} />
<br />
<BonusTime />
<div>
<Tooltip
title={
<Typography>
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 provides some tips/pointers for
helping you get started with managing it.
</Typography>
}
>
<Button onClick={() => corp.getStarterGuide(player)}>Getting Started Guide</Button>
</Tooltip>
{corp.public ? <PublicButtons rerender={rerender} /> : <PrivateButtons rerender={rerender} />}
<BribeButton />
</div>
<br /> <br />
<Upgrades rerender={rerender} /> <Upgrades rerender={rerender} />
</div> </>
); );
} }
@ -102,7 +113,6 @@ interface IPrivateButtonsProps {
} }
// Render the buttons for when your Corporation is still private // Render the buttons for when your Corporation is still private
function PrivateButtons({ rerender }: IPrivateButtonsProps): React.ReactElement { function PrivateButtons({ rerender }: IPrivateButtonsProps): React.ReactElement {
const player = use.Player();
const corp = useCorporation(); const corp = useCorporation();
const [findInvestorsopen, setFindInvestorsopen] = useState(false); const [findInvestorsopen, setFindInvestorsopen] = useState(false);
const [goPublicopen, setGoPublicopen] = useState(false); const [goPublicopen, setGoPublicopen] = useState(false);
@ -115,9 +125,11 @@ function PrivateButtons({ rerender }: IPrivateButtonsProps): React.ReactElement
return ( return (
<> <>
<Tooltip title={<Typography>{findInvestorsTooltip}</Typography>}> <Tooltip title={<Typography>{findInvestorsTooltip}</Typography>}>
<Button disabled={!fundingAvailable} onClick={() => setFindInvestorsopen(true)}> <span>
Find Investors <Button disabled={!fundingAvailable} onClick={() => setFindInvestorsopen(true)}>
</Button> Find Investors
</Button>
</span>
</Tooltip> </Tooltip>
<Tooltip <Tooltip
title={ title={
@ -148,21 +160,28 @@ function Upgrades({ rerender }: IUpgradeProps): React.ReactElement {
} }
return ( return (
<div className={"cmpy-mgmt-upgrade-container"}> <>
<h1 className={"cmpy-mgmt-upgrade-header"}> Unlocks </h1> <Paper sx={{ p: 1, my: 1 }}>
{Object.values(CorporationUnlockUpgrades) <Typography variant="h4">Unlocks</Typography>
.filter((upgrade: CorporationUnlockUpgrade) => corp.unlockUpgrades[upgrade[0]] === 0) <Grid container>
.map((upgrade: CorporationUnlockUpgrade) => ( {Object.values(CorporationUnlockUpgrades)
<UnlockUpgrade rerender={rerender} upgradeData={upgrade} key={upgrade[0]} /> .filter((upgrade: CorporationUnlockUpgrade) => corp.unlockUpgrades[upgrade[0]] === 0)
))} .map((upgrade: CorporationUnlockUpgrade) => (
<UnlockUpgrade rerender={rerender} upgradeData={upgrade} key={upgrade[0]} />
<h1 className={"cmpy-mgmt-upgrade-header"}> Upgrades </h1> ))}
{corp.upgrades </Grid>
.map((level: number, i: number) => CorporationUpgrades[i]) </Paper>
.map((upgrade: CorporationUpgrade) => ( <Paper sx={{ p: 1, my: 1 }}>
<LevelableUpgrade rerender={rerender} upgrade={upgrade} key={upgrade[0]} /> <Typography variant="h4">Upgrades</Typography>
))} <Grid container>
</div> {corp.upgrades
.map((level: number, i: number) => CorporationUpgrades[i])
.map((upgrade: CorporationUpgrade) => (
<LevelableUpgrade rerender={rerender} upgrade={upgrade} key={upgrade[0]} />
))}
</Grid>
</Paper>
</>
); );
} }
@ -193,9 +212,11 @@ function PublicButtons({ rerender }: IPublicButtonsProps): React.ReactElement {
return ( return (
<> <>
<Tooltip title={<Typography>{sellSharesTooltip}</Typography>}> <Tooltip title={<Typography>{sellSharesTooltip}</Typography>}>
<Button disabled={sellSharesOnCd} onClick={() => setSellSharesOpen(true)}> <span>
Sell Shares <Button disabled={sellSharesOnCd} onClick={() => setSellSharesOpen(true)}>
</Button> Sell Shares
</Button>
</span>
</Tooltip> </Tooltip>
<SellSharesModal open={sellSharesOpen} onClose={() => setSellSharesOpen(false)} rerender={rerender} /> <SellSharesModal open={sellSharesOpen} onClose={() => setSellSharesOpen(false)} rerender={rerender} />
<Tooltip title={<Typography>Buy back shares you that previously issued or sold at market price.</Typography>}> <Tooltip title={<Typography>Buy back shares you that previously issued or sold at market price.</Typography>}>
@ -204,9 +225,11 @@ function PublicButtons({ rerender }: IPublicButtonsProps): React.ReactElement {
<BuybackSharesModal open={buybackSharesOpen} onClose={() => setBuybackSharesOpen(false)} rerender={rerender} /> <BuybackSharesModal open={buybackSharesOpen} onClose={() => setBuybackSharesOpen(false)} rerender={rerender} />
<br /> <br />
<Tooltip title={<Typography>{issueNewSharesTooltip}</Typography>}> <Tooltip title={<Typography>{issueNewSharesTooltip}</Typography>}>
<Button disabled={issueNewSharesOnCd} onClick={() => setIssueNewSharesOpen(true)}> <span>
Issue New Shares <Button disabled={issueNewSharesOnCd} onClick={() => setIssueNewSharesOpen(true)}>
</Button> Issue New Shares
</Button>
</span>
</Tooltip> </Tooltip>
<IssueNewSharesModal open={issueNewSharesOpen} onClose={() => setIssueNewSharesOpen(false)} /> <IssueNewSharesModal open={issueNewSharesOpen} onClose={() => setIssueNewSharesOpen(false)} />
<Tooltip <Tooltip
@ -264,34 +287,19 @@ function DividendsStats({ profit }: IDividendsStatsProps): React.ReactElement {
const dividendsPerShare = totalDividends / corp.totalShares; const dividendsPerShare = totalDividends / corp.totalShares;
const playerEarnings = corp.numShares * dividendsPerShare; const playerEarnings = corp.numShares * dividendsPerShare;
return ( return (
<> <StatsTable
Retained Profits (after dividends): <Money money={retainedEarnings} /> / s rows={[
<br /> ["Retained Profits (after dividends):", <MoneyRate money={retainedEarnings} />],
<br /> ["Dividend Percentage:", numeralWrapper.format(corp.dividendPercentage / 100, "0%")],
Dividend Percentage: {numeralWrapper.format(corp.dividendPercentage / 100, "0%")} ["Dividends per share:", <MoneyRate money={dividendsPerShare} />],
<br /> ["Your earnings as a shareholder (Pre-Tax):", <MoneyRate money={playerEarnings} />],
Dividends per share: <Money money={dividendsPerShare} /> / s<br /> ["Dividend Tax Rate:", <>{corp.dividendTaxPercentage}%</>],
Your earnings as a shareholder (Pre-Tax): <Money money={playerEarnings} /> / s<br /> [
Dividend Tax Rate: {corp.dividendTaxPercentage}%<br /> "Your earnings as a shareholder (Post-Tax):",
Your earnings as a shareholder (Post-Tax):{" "} <MoneyRate money={playerEarnings * (1 - corp.dividendTaxPercentage / 100)} />,
<Money money={playerEarnings * (1 - corp.dividendTaxPercentage / 100)} /> / s<br /> ],
<br /> ]}
</> />
);
}
interface IMultProps {
name: string;
mult: number;
}
function Mult({ name, mult }: IMultProps): React.ReactElement {
if (mult <= 1) return <></>;
return (
<Typography>
{name}
{numeralWrapper.format(mult, "0.000")}
<br />
</Typography>
); );
} }

@ -0,0 +1,84 @@
import React, { useState } from "react";
import { numeralWrapper } from "../../ui/numeralFormat";
import { dialogBoxCreate } from "../../ui/React/DialogBox";
import { OfficeSpace } from "../OfficeSpace";
import { ThrowParty } from "../Actions";
import { Money } from "../../ui/React/Money";
import { Modal } from "../../ui/React/Modal";
import { useCorporation } from "./Context";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import TextField from "@mui/material/TextField";
import Box from "@mui/material/Box";
interface IProps {
open: boolean;
onClose: () => void;
office: OfficeSpace;
rerender: () => void;
}
export function ThrowPartyModal(props: IProps): React.ReactElement {
const corp = useCorporation();
const [cost, setCost] = useState(0);
const totalCost = cost * props.office.employees.length;
const canParty = corp.funds.gte(totalCost);
function changeCost(event: React.ChangeEvent<HTMLInputElement>): void {
let x = parseFloat(event.target.value);
if (isNaN(x)) x = 0;
setCost(x);
}
function throwParty(): void {
if (cost === null || isNaN(cost) || cost < 0) {
dialogBoxCreate("Invalid value entered");
} else {
if (!canParty) {
dialogBoxCreate("You don't have enough company funds to throw a party!");
} else {
const mult = ThrowParty(corp, props.office, cost);
dialogBoxCreate(
"You threw a party for the office! The morale and happiness " +
"of each employee increased by " +
numeralWrapper.formatPercentage(mult - 1),
);
props.rerender();
props.onClose();
}
}
}
function EffectText(): React.ReactElement {
if (isNaN(cost) || cost < 0) return <p>Invalid value entered!</p>;
return (
<Typography>
Throwing this party will cost a total of <Money money={totalCost} />
</Typography>
);
}
function onKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {
if (event.keyCode === 13) throwParty();
}
return (
<Modal open={props.open} onClose={props.onClose}>
<Typography>Enter the amount of money you would like to spend PER EMPLOYEE on this office party</Typography>
<EffectText />
<Box display="flex" alignItems="center">
<TextField
autoFocus={true}
type="number"
placeholder="$ / employee"
value={cost}
onChange={changeCost}
onKeyDown={onKeyDown}
/>
<Button disabled={!canParty} onClick={throwParty}>
Throw Party
</Button>
</Box>
</Modal>
);
}

@ -1,72 +0,0 @@
import React, { useState } from "react";
import { removePopup } from "../../ui/React/createPopup";
import { numeralWrapper } from "../../ui/numeralFormat";
import { dialogBoxCreate } from "../../ui/React/DialogBox";
import { OfficeSpace } from "../OfficeSpace";
import { ICorporation } from "../ICorporation";
import { ThrowParty } from "../Actions";
interface IProps {
office: OfficeSpace;
corp: ICorporation;
popupId: string;
}
export function ThrowPartyPopup(props: IProps): React.ReactElement {
const [cost, setCost] = useState<number | null>(null);
function changeCost(event: React.ChangeEvent<HTMLInputElement>): void {
setCost(parseFloat(event.target.value));
}
function throwParty(): void {
if (cost === null || isNaN(cost) || cost < 0) {
dialogBoxCreate("Invalid value entered");
} else {
const totalCost = cost * props.office.employees.length;
if (props.corp.funds.lt(totalCost)) {
dialogBoxCreate("You don't have enough company funds to throw a party!");
} else {
const mult = ThrowParty(props.corp, props.office, cost);
dialogBoxCreate(
"You threw a party for the office! The morale and happiness " +
"of each employee increased by " +
numeralWrapper.formatPercentage(mult - 1),
);
removePopup(props.popupId);
}
}
}
function EffectText(props: { cost: number | null; office: OfficeSpace }): React.ReactElement {
let cost = props.cost;
if (cost !== null && (isNaN(cost) || cost < 0)) return <p>Invalid value entered!</p>;
if (cost === null) cost = 0;
return (
<p>Throwing this party will cost a total of {numeralWrapper.formatMoney(cost * props.office.employees.length)}</p>
);
}
function onKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {
if (event.keyCode === 13) throwParty();
}
return (
<>
<p>Enter the amount of money you would like to spend PER EMPLOYEE on this office party</p>
<EffectText cost={cost} office={props.office} />
<input
autoFocus={true}
className="text-input"
type="number"
style={{ margin: "5px" }}
placeholder="$ / employee"
onChange={changeCost}
onKeyDown={onKeyDown}
/>
<button className="std-button" onClick={throwParty}>
Throw Party
</button>
</>
);
}

@ -6,6 +6,11 @@ import { CorporationUnlockUpgrade } from "../data/CorporationUnlockUpgrades";
import { useCorporation } from "./Context"; import { useCorporation } from "./Context";
import { UnlockUpgrade as UU } from "../Actions"; import { UnlockUpgrade as UU } from "../Actions";
import { MoneyCost } from "./MoneyCost"; import { MoneyCost } from "./MoneyCost";
import Typography from "@mui/material/Typography";
import Tooltip from "@mui/material/Tooltip";
import Button from "@mui/material/Button";
import Box from "@mui/material/Box";
import Grid from "@mui/material/Grid";
interface IProps { interface IProps {
upgradeData: CorporationUnlockUpgrade; upgradeData: CorporationUnlockUpgrade;
@ -15,11 +20,6 @@ interface IProps {
export function UnlockUpgrade(props: IProps): React.ReactElement { export function UnlockUpgrade(props: IProps): React.ReactElement {
const corp = useCorporation(); const corp = useCorporation();
const data = props.upgradeData; const data = props.upgradeData;
const text = (
<>
{data[2]} - <MoneyCost money={data[1]} corp={corp} />
</>
);
const tooltip = data[3]; const tooltip = data[3];
function onClick(): void { function onClick(): void {
if (corp.funds.lt(data[1])) return; if (corp.funds.lt(data[1])) return;
@ -32,9 +32,15 @@ export function UnlockUpgrade(props: IProps): React.ReactElement {
} }
return ( return (
<button className={"cmpy-mgmt-upgrade-div tooltip"} style={{ width: "45%" }} onClick={onClick}> <Grid item xs={4}>
{text} <Box display="flex" alignItems="center" flexDirection="row-reverse">
<span className={"tooltiptext"}>{tooltip}</span> <Button disabled={corp.funds.lt(data[1])} sx={{ mx: 1 }} onClick={onClick}>
</button> <MoneyCost money={data[1]} corp={corp} />
</Button>
<Tooltip title={tooltip}>
<Typography>{data[2]}</Typography>
</Tooltip>
</Box>
</Grid>
); );
} }

@ -0,0 +1,92 @@
import React from "react";
import { numeralWrapper } from "../../ui/numeralFormat";
import { CorporationConstants } from "../data/Constants";
import { OfficeSpace } from "../OfficeSpace";
import { ICorporation } from "../ICorporation";
import { UpgradeOfficeSize } from "../Actions";
import { Modal } from "../../ui/React/Modal";
import { useCorporation } from "./Context";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import Tooltip from "@mui/material/Tooltip";
import Box from "@mui/material/Box";
interface IProps {
open: boolean;
onClose: () => void;
office: OfficeSpace;
rerender: () => void;
}
export function UpgradeOfficeSizeModal(props: IProps): React.ReactElement {
const corp = useCorporation();
const initialPriceMult = Math.round(props.office.size / CorporationConstants.OfficeInitialSize);
const costMultiplier = 1.09;
const upgradeCost = CorporationConstants.OfficeInitialCost * Math.pow(costMultiplier, initialPriceMult);
// Calculate cost to upgrade size by 15 employees
let mult = 0;
for (let i = 0; i < 5; ++i) {
mult += Math.pow(costMultiplier, initialPriceMult + i);
}
const upgradeCost15 = CorporationConstants.OfficeInitialCost * mult;
//Calculate max upgrade size and cost
const maxMult = corp.funds.dividedBy(CorporationConstants.OfficeInitialCost).toNumber();
let maxNum = 1;
mult = Math.pow(costMultiplier, initialPriceMult);
while (maxNum < 50) {
//Hard cap of 50x (extra 150 employees)
if (mult >= maxMult) break;
const multIncrease = Math.pow(costMultiplier, initialPriceMult + maxNum);
if (mult + multIncrease > maxMult) {
break;
} else {
mult += multIncrease;
}
++maxNum;
}
const upgradeCostMax = CorporationConstants.OfficeInitialCost * mult;
function upgradeSize(cost: number, size: number): void {
if (corp.funds.lt(cost)) {
return;
}
UpgradeOfficeSize(corp, props.office, size);
props.rerender();
props.rerender();
props.onClose();
}
interface IUpgradeButton {
cost: number;
size: number;
corp: ICorporation;
}
function UpgradeSizeButton(props: IUpgradeButton): React.ReactElement {
return (
<Tooltip title={numeralWrapper.formatMoney(props.cost)}>
<span>
<Button disabled={corp.funds.lt(props.cost)} onClick={() => upgradeSize(props.cost, props.size)}>
+{props.size}
</Button>
</span>
</Tooltip>
);
}
return (
<Modal open={props.open} onClose={props.onClose}>
<Typography>Increase the size of your office space to fit additional employees!</Typography>
<Box display="flex" alignItems="center">
<Typography>Upgrade size: </Typography>
<UpgradeSizeButton corp={corp} cost={upgradeCost} size={CorporationConstants.OfficeInitialSize} />
<UpgradeSizeButton corp={corp} cost={upgradeCost15} size={CorporationConstants.OfficeInitialSize * 5} />
<UpgradeSizeButton corp={corp} cost={upgradeCostMax} size={maxNum * CorporationConstants.OfficeInitialSize} />
</Box>
</Modal>
);
}

@ -1,91 +0,0 @@
import React from "react";
import { removePopup } from "../../ui/React/createPopup";
import { numeralWrapper } from "../../ui/numeralFormat";
import { dialogBoxCreate } from "../../ui/React/DialogBox";
import { CorporationConstants } from "../data/Constants";
import { OfficeSpace } from "../OfficeSpace";
import { ICorporation } from "../ICorporation";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { UpgradeOfficeSize } from "../Actions";
interface IProps {
office: OfficeSpace;
corp: ICorporation;
popupId: string;
player: IPlayer;
rerender: () => void;
}
export function UpgradeOfficeSizePopup(props: IProps): React.ReactElement {
const initialPriceMult = Math.round(props.office.size / CorporationConstants.OfficeInitialSize);
const costMultiplier = 1.09;
const upgradeCost = CorporationConstants.OfficeInitialCost * Math.pow(costMultiplier, initialPriceMult);
// Calculate cost to upgrade size by 15 employees
let mult = 0;
for (let i = 0; i < 5; ++i) {
mult += Math.pow(costMultiplier, initialPriceMult + i);
}
const upgradeCost15 = CorporationConstants.OfficeInitialCost * mult;
//Calculate max upgrade size and cost
const maxMult = props.corp.funds.dividedBy(CorporationConstants.OfficeInitialCost).toNumber();
let maxNum = 1;
mult = Math.pow(costMultiplier, initialPriceMult);
while (maxNum < 50) {
//Hard cap of 50x (extra 150 employees)
if (mult >= maxMult) break;
const multIncrease = Math.pow(costMultiplier, initialPriceMult + maxNum);
if (mult + multIncrease > maxMult) {
break;
} else {
mult += multIncrease;
}
++maxNum;
}
const upgradeCostMax = CorporationConstants.OfficeInitialCost * mult;
function upgradeSize(cost: number, size: number): void {
if (props.corp.funds.lt(cost)) {
dialogBoxCreate("You don't have enough company funds to purchase this upgrade!");
} else {
UpgradeOfficeSize(props.corp, props.office, size);
dialogBoxCreate("Office space increased! It can now hold " + props.office.size + " employees");
props.rerender();
}
removePopup(props.popupId);
}
interface IUpgradeButton {
cost: number;
size: number;
corp: ICorporation;
}
function UpgradeSizeButton(props: IUpgradeButton): React.ReactElement {
return (
<button
className={"tooltip " + (props.corp.funds.lt(props.cost) ? "a-link-button-inactive" : "a-link-button")}
style={{ display: "inline-block", margin: "4px" }}
onClick={() => upgradeSize(props.cost, props.size)}
>
by {props.size}
<span className="tooltiptext">{numeralWrapper.formatMoney(props.cost)}</span>
</button>
);
}
return (
<>
<p>Increase the size of your office space to fit additional employees!</p>
<p>Upgrade size: </p>
<UpgradeSizeButton corp={props.corp} cost={upgradeCost} size={CorporationConstants.OfficeInitialSize} />
<UpgradeSizeButton corp={props.corp} cost={upgradeCost15} size={CorporationConstants.OfficeInitialSize * 5} />
<UpgradeSizeButton
corp={props.corp}
cost={upgradeCostMax}
size={maxNum * CorporationConstants.OfficeInitialSize}
/>
</>
);
}