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;
//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),
@ -131,12 +130,12 @@ export class OfficeSpace {
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,
intelligence: int,
charisma: cha,
experience: exp,
creativity: cre,
efficiency: eff,
salary: sal,
});
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 (
<div>
<div className={"cmpy-mgmt-industry-left-panel"}>
<IndustryOverview
rerender={props.rerender}
player={player}
corp={corp}
division={division}
currentCity={props.city}
office={props.office}
/>
<IndustryOverview rerender={props.rerender} currentCity={props.city} office={props.office} />
<IndustryOffice rerender={props.rerender} office={props.office} />
</div>
<div className={"cmpy-mgmt-industry-right-panel"}>

@ -8,18 +8,15 @@ import { EmployeePositions } from "../EmployeePositions";
import { numeralWrapper } from "../../ui/numeralFormat";
import { createPopup } from "../../ui/React/createPopup";
import { UpgradeOfficeSizePopup } from "./UpgradeOfficeSizePopup";
import { HireEmployeePopup } from "./HireEmployeePopup";
import { ThrowPartyPopup } from "./ThrowPartyPopup";
import { UpgradeOfficeSizeModal } from "./UpgradeOfficeSizeModal";
import { ThrowPartyModal } from "./ThrowPartyModal";
import { Money } from "../../ui/React/Money";
import { use } from "../../ui/Context";
import { useCorporation, useDivision } from "./Context";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
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 ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
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,
);
const employeeInfoDivStyle = {
color: "white",
margin: "4px",
padding: "4px",
};
// Employee Selector
const employees = [];
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;
return (
<div style={employeeInfoDivStyle}>
<>
<Select value={employee !== null ? employee.name : ""} onChange={employeeSelectorOnChange}>
{employees}
</Select>
{employee != null && (
<p>
<Typography>
Morale: {numeralWrapper.format(employee.mor, nf)}
<br />
Happiness: {numeralWrapper.format(employee.hap, nf)}
@ -167,14 +158,14 @@ function ManualManagement(props: IProps): React.ReactElement {
Efficiency: {numeralWrapper.format(effEff, nf)}
<br />
Salary: <Money money={employee.sal} />
</p>
</Typography>
)}
{employee != null && (
<Select onChange={employeePositionSelectorOnChange} value={employeePositionSelectorInitialValue}>
{employeePositions}
</Select>
)}
</div>
</>
);
}
@ -304,17 +295,22 @@ function AutoManagement(props: IProps): React.ReactElement {
<>
<TableRow>
<TableCell>
<p className={"tooltip"} style={{ display: "inline-block" }}>
Material Production:
<span className={"tooltiptext"}>
The base amount of material this office can produce. Does not include production multipliers from
upgrades and materials. This value is based off the productivity of your Operations, Engineering,
and Management employees
</span>
</p>
<Tooltip
title={
<Typography>
The base amount of material this office can produce. Does not include production multipliers
from upgrades and materials. This value is based off the productivity of your Operations,
Engineering, and Management employees
</Typography>
}
>
<Typography>Material Production:</Typography>
</Tooltip>
</TableCell>
<TableCell>
<p>{numeralWrapper.format(division.getOfficeProductivity(props.office), "0.000")}</p>
<Typography>
{numeralWrapper.format(division.getOfficeProductivity(props.office), "0.000")}
</Typography>
</TableCell>
</TableRow>
<TableRow>
@ -415,87 +411,24 @@ function AutoManagement(props: IProps): React.ReactElement {
}
export function IndustryOffice(props: IProps): React.ReactElement {
const player = use.Player();
const corp = useCorporation();
const division = useDivision();
const [upgradeOfficeSizeOpen, setUpgradeOfficeSizeOpen] = useState(false);
const [throwPartyOpen, setThrowPartyOpen] = 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 {
if (props.office.atCapacity()) return;
props.office.hireRandomEmployee();
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 (
<div className={"cmpy-mgmt-employee-panel"}>
<Paper>
<Typography>Office Space</Typography>
<Typography>
Size: {props.office.employees.length} / {props.office.size} employees
</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>}>
<span>
<Button disabled={props.office.atCapacity()} onClick={autohireEmployeeButtonOnClick}>
@ -506,22 +439,36 @@ export function IndustryOffice(props: IProps): React.ReactElement {
<br />
<Tooltip title={<Typography>Upgrade the office's size so that it can hold more employees!</Typography>}>
<span>
<Button disabled={corp.funds.lt(0)} onClick={openUpgradeOfficeSizePopup}>
<Button disabled={corp.funds.lt(0)} onClick={() => setUpgradeOfficeSizeOpen(true)}>
Upgrade size
</Button>
</span>
</Tooltip>
<UpgradeOfficeSizeModal
rerender={props.rerender}
office={props.office}
open={upgradeOfficeSizeOpen}
onClose={() => setUpgradeOfficeSizeOpen(false)}
/>
{!division.hasResearch("AutoPartyManager") && (
<>
<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}>
<Button disabled={corp.funds.lt(0)} onClick={() => setThrowPartyOpen(true)}>
Throw Party
</Button>
</span>
</Tooltip>
<ThrowPartyModal
rerender={props.rerender}
office={props.office}
open={throwPartyOpen}
onClose={() => setThrowPartyOpen(false)}
/>
</>
)}
<br />
@ -532,6 +479,6 @@ export function IndustryOffice(props: IProps): React.ReactElement {
) : (
<AutoManagement rerender={props.rerender} office={props.office} />
)}
</div>
</Paper>
);
}

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

@ -5,8 +5,12 @@ import { dialogBoxCreate } from "../../ui/React/DialogBox";
import { CorporationUpgrade } from "../data/CorporationUpgrades";
import { LevelUpgrade } from "../Actions";
import { MoneyCost } from "./MoneyCost";
import { use } from "../../ui/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 {
upgrade: CorporationUpgrade;
@ -14,7 +18,6 @@ interface IProps {
}
export function LevelableUpgrade(props: IProps): React.ReactElement {
const player = use.Player();
const corp = useCorporation();
const data = props.upgrade;
const level = corp.upgrades[data[0]];
@ -23,11 +26,6 @@ export function LevelableUpgrade(props: IProps): React.ReactElement {
const priceMult = data[2];
const cost = baseCost * Math.pow(priceMult, level);
const text = (
<>
{data[4]} - <MoneyCost money={cost} corp={corp} />
</>
);
const tooltip = data[5];
function onClick(): void {
if (corp.funds.lt(cost)) return;
@ -40,9 +38,15 @@ export function LevelableUpgrade(props: IProps): React.ReactElement {
}
return (
<button className={"cmpy-mgmt-upgrade-div tooltip"} style={{ width: "45%" }} onClick={onClick}>
{text}
<span className={"tooltiptext"}>{tooltip}</span>
</button>
<Grid item xs={4}>
<Box display="flex" alignItems="center" flexDirection="row-reverse">
<Button disabled={corp.funds.lt(cost)} sx={{ mx: 1 }} onClick={onClick}>
<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 { convertTimeMsToTimeElapsedString } from "../../utils/StringHelperFunctions";
import { Money } from "../../ui/React/Money";
import { MoneyRate } from "../../ui/React/MoneyRate";
import { StatsTable } from "../../ui/React/StatsTable";
import { use } from "../../ui/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 Paper from "@mui/material/Paper";
import Grid from "@mui/material/Grid";
interface IProps {
rerender: () => void;
@ -33,50 +38,57 @@ export function Overview({ rerender }: IProps): React.ReactElement {
const corp = useCorporation();
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 (
<div>
<Typography>
Total Funds: <Money money={corp.funds.toNumber()} />
<>
<StatsTable
rows={[
["Total Funds:", <Money money={corp.funds.toNumber()} />],
["Total Revenue:", <MoneyRate money={corp.revenue.toNumber()} />],
["Total Expenses:", <MoneyRate money={corp.expenses.toNumber()} />],
["Publicly Traded:", corp.public ? "Yes" : "No"],
["Owned Stock Shares:", numeralWrapper.format(corp.numShares, "0.000a")],
["Stock Price:", corp.public ? <Money money={corp.sharePrice} /> : "N/A"],
]}
/>
<br />
Total Revenue: <Money money={corp.revenue.toNumber()} /> / s<br />
Total Expenses: <Money money={corp.expenses.toNumber()} /> / s
<br />
Total Profits: <Money money={profit} /> / s<br />
<DividendsStats profit={profit} />
Publicly Traded: {corp.public ? "Yes" : "No"}
<br />
Owned Stock Shares: {numeralWrapper.format(corp.numShares, "0.000a")}
<br />
Stock Price: {corp.public ? <Money money={corp.sharePrice} /> : "N/A"}
<br />
</Typography>
<Box display="flex">
<Tooltip
title={
<Typography>
Outstanding Shares: {numeralWrapper.format(corp.issuedShares, "0.000a")}
<br />
Private Shares: {numeralWrapper.format(corp.totalShares - corp.issuedShares - corp.numShares, "0.000a")}
</Typography>
<StatsTable
rows={[
["Outstanding Shares:", numeralWrapper.format(corp.issuedShares, "0.000a")],
[
"Private Shares:",
numeralWrapper.format(corp.totalShares - corp.issuedShares - corp.numShares, "0.000a"),
],
]}
/>
}
>
<Typography className="tooltip">
Total Stock Shares: {numeralWrapper.format(corp.totalShares, "0.000a")}
</Typography>
<Typography>Total Stock Shares: {numeralWrapper.format(corp.totalShares, "0.000a")}</Typography>
</Tooltip>
</Box>
<br />
<DividendsStats profit={profit} />
<br />
<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()} />
<StatsTable rows={multRows} />
<br />
<BonusTime />
<div>
<Tooltip
title={
<Typography>
@ -90,10 +102,9 @@ export function Overview({ rerender }: IProps): React.ReactElement {
</Tooltip>
{corp.public ? <PublicButtons rerender={rerender} /> : <PrivateButtons rerender={rerender} />}
<BribeButton />
</div>
<br />
<Upgrades rerender={rerender} />
</div>
</>
);
}
@ -102,7 +113,6 @@ interface IPrivateButtonsProps {
}
// Render the buttons for when your Corporation is still private
function PrivateButtons({ rerender }: IPrivateButtonsProps): React.ReactElement {
const player = use.Player();
const corp = useCorporation();
const [findInvestorsopen, setFindInvestorsopen] = useState(false);
const [goPublicopen, setGoPublicopen] = useState(false);
@ -115,9 +125,11 @@ function PrivateButtons({ rerender }: IPrivateButtonsProps): React.ReactElement
return (
<>
<Tooltip title={<Typography>{findInvestorsTooltip}</Typography>}>
<span>
<Button disabled={!fundingAvailable} onClick={() => setFindInvestorsopen(true)}>
Find Investors
</Button>
</span>
</Tooltip>
<Tooltip
title={
@ -148,21 +160,28 @@ function Upgrades({ rerender }: IUpgradeProps): React.ReactElement {
}
return (
<div className={"cmpy-mgmt-upgrade-container"}>
<h1 className={"cmpy-mgmt-upgrade-header"}> Unlocks </h1>
<>
<Paper sx={{ p: 1, my: 1 }}>
<Typography variant="h4">Unlocks</Typography>
<Grid container>
{Object.values(CorporationUnlockUpgrades)
.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>
</Grid>
</Paper>
<Paper sx={{ p: 1, my: 1 }}>
<Typography variant="h4">Upgrades</Typography>
<Grid container>
{corp.upgrades
.map((level: number, i: number) => CorporationUpgrades[i])
.map((upgrade: CorporationUpgrade) => (
<LevelableUpgrade rerender={rerender} upgrade={upgrade} key={upgrade[0]} />
))}
</div>
</Grid>
</Paper>
</>
);
}
@ -193,9 +212,11 @@ function PublicButtons({ rerender }: IPublicButtonsProps): React.ReactElement {
return (
<>
<Tooltip title={<Typography>{sellSharesTooltip}</Typography>}>
<span>
<Button disabled={sellSharesOnCd} onClick={() => setSellSharesOpen(true)}>
Sell Shares
</Button>
</span>
</Tooltip>
<SellSharesModal open={sellSharesOpen} onClose={() => setSellSharesOpen(false)} rerender={rerender} />
<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} />
<br />
<Tooltip title={<Typography>{issueNewSharesTooltip}</Typography>}>
<span>
<Button disabled={issueNewSharesOnCd} onClick={() => setIssueNewSharesOpen(true)}>
Issue New Shares
</Button>
</span>
</Tooltip>
<IssueNewSharesModal open={issueNewSharesOpen} onClose={() => setIssueNewSharesOpen(false)} />
<Tooltip
@ -264,34 +287,19 @@ function DividendsStats({ profit }: IDividendsStatsProps): React.ReactElement {
const dividendsPerShare = totalDividends / corp.totalShares;
const playerEarnings = corp.numShares * dividendsPerShare;
return (
<>
Retained Profits (after dividends): <Money money={retainedEarnings} /> / s
<br />
<br />
Dividend Percentage: {numeralWrapper.format(corp.dividendPercentage / 100, "0%")}
<br />
Dividends per share: <Money money={dividendsPerShare} /> / s<br />
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):{" "}
<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>
<StatsTable
rows={[
["Retained Profits (after dividends):", <MoneyRate money={retainedEarnings} />],
["Dividend Percentage:", numeralWrapper.format(corp.dividendPercentage / 100, "0%")],
["Dividends per share:", <MoneyRate money={dividendsPerShare} />],
["Your earnings as a shareholder (Pre-Tax):", <MoneyRate money={playerEarnings} />],
["Dividend Tax Rate:", <>{corp.dividendTaxPercentage}%</>],
[
"Your earnings as a shareholder (Post-Tax):",
<MoneyRate money={playerEarnings * (1 - corp.dividendTaxPercentage / 100)} />,
],
]}
/>
);
}

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