mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-26 17:43:48 +01:00
convert some corp to mui
This commit is contained in:
parent
5cce1c255c
commit
510fcedf90
@ -385,9 +385,6 @@ export class Industry implements IIndustry {
|
||||
const prod = this.products[prodName];
|
||||
if (prod === undefined) continue;
|
||||
warehouse.sizeUsed += prod.data[warehouse.loc][0] * prod.siz;
|
||||
if (prod.data[warehouse.loc][0] > 0) {
|
||||
warehouse.breakdown += prodName + ": " + formatNumber(prod.data[warehouse.loc][0] * prod.siz, 0) + "<br>";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,10 +15,6 @@ interface IConstructorParams {
|
||||
}
|
||||
|
||||
export class Warehouse {
|
||||
// Text that describes how the space in this Warehouse is being used
|
||||
// Used to create a tooltip in the UI
|
||||
breakdown = "";
|
||||
|
||||
// Warehouse's level, which affects its maximum size
|
||||
level = 1;
|
||||
|
||||
@ -90,14 +86,10 @@ export class Warehouse {
|
||||
// Re-calculate how much space is being used by this Warehouse
|
||||
updateMaterialSizeUsed(): void {
|
||||
this.sizeUsed = 0;
|
||||
this.breakdown = "";
|
||||
for (const matName in this.materials) {
|
||||
const mat = this.materials[matName];
|
||||
if (MaterialSizes.hasOwnProperty(matName)) {
|
||||
this.sizeUsed += mat.qty * MaterialSizes[matName];
|
||||
if (mat.qty > 0) {
|
||||
this.breakdown += matName + ": " + numeralWrapper.format(mat.qty * MaterialSizes[matName], "0,0.0") + "<br>";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.sizeUsed > this.size) {
|
||||
|
@ -9,6 +9,7 @@ import { Warehouse } from "../Warehouse";
|
||||
import { OfficeSpace } from "../OfficeSpace";
|
||||
import { use } from "../../ui/Context";
|
||||
import { useCorporation, useDivision } from "./Context";
|
||||
import Box from "@mui/material/Box";
|
||||
|
||||
interface IProps {
|
||||
city: string;
|
||||
@ -22,12 +23,12 @@ export function Industry(props: IProps): React.ReactElement {
|
||||
const corp = useCorporation();
|
||||
const division = useDivision();
|
||||
return (
|
||||
<div>
|
||||
<div className={"cmpy-mgmt-industry-left-panel"}>
|
||||
<Box display="flex">
|
||||
<Box sx={{ width: "50%" }}>
|
||||
<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"}>
|
||||
</Box>
|
||||
<Box sx={{ width: "50%" }}>
|
||||
<IndustryWarehouse
|
||||
rerender={props.rerender}
|
||||
player={player}
|
||||
@ -36,7 +37,7 @@ export function Industry(props: IProps): React.ReactElement {
|
||||
division={division}
|
||||
warehouse={props.warehouse}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
@ -432,7 +432,7 @@ export function IndustryOffice(props: IProps): React.ReactElement {
|
||||
<Tooltip title={<Typography>Automatically hires an employee and gives him/her a random name</Typography>}>
|
||||
<span>
|
||||
<Button disabled={props.office.atCapacity()} onClick={autohireEmployeeButtonOnClick}>
|
||||
Autohire Employee
|
||||
Hire Employee
|
||||
</Button>
|
||||
</span>
|
||||
</Tooltip>
|
||||
|
@ -1,101 +1,74 @@
|
||||
// React Component for displaying an Industry's overview information
|
||||
// (top-left panel in the Industry UI)
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { OfficeSpace } from "../OfficeSpace";
|
||||
import { Industries } from "../IndustryData";
|
||||
import { IndustryUpgrades } from "../IndustryUpgrades";
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { dialogBoxCreate } from "../../ui/React/DialogBox";
|
||||
import { createProgressBarText } from "../../utils/helpers/createProgressBarText";
|
||||
import { MakeProductPopup } from "./MakeProductPopup";
|
||||
import { MakeProductModal } from "./MakeProductModal";
|
||||
import { ResearchPopup } from "./ResearchPopup";
|
||||
import { createPopup } from "../../ui/React/createPopup";
|
||||
import { Money } from "../../ui/React/Money";
|
||||
import { MoneyRate } from "../../ui/React/MoneyRate";
|
||||
import { StatsTable } from "../../ui/React/StatsTable";
|
||||
import { StaticModal } from "../../ui/React/StaticModal";
|
||||
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";
|
||||
import IconButton from "@mui/material/IconButton";
|
||||
import HelpIcon from "@mui/icons-material/Help";
|
||||
import Box from "@mui/material/Box";
|
||||
|
||||
interface IProps {
|
||||
currentCity: string;
|
||||
office: OfficeSpace;
|
||||
rerender: () => void;
|
||||
}
|
||||
|
||||
export function IndustryOverview(props: IProps): React.ReactElement {
|
||||
function MakeProductButton(): React.ReactElement {
|
||||
const corp = useCorporation();
|
||||
const division = useDivision();
|
||||
function renderMakeProductButton(): React.ReactElement {
|
||||
let createProductButtonText = "";
|
||||
let createProductPopupText = "";
|
||||
switch (division.type) {
|
||||
case Industries.Food:
|
||||
createProductButtonText = "Build Restaurant";
|
||||
createProductPopupText = "Build and manage a new restaurant!";
|
||||
break;
|
||||
case Industries.Tobacco:
|
||||
createProductButtonText = "Create Product";
|
||||
createProductPopupText = "Create a new tobacco product!";
|
||||
break;
|
||||
case Industries.Pharmaceutical:
|
||||
createProductButtonText = "Create Drug";
|
||||
createProductPopupText = "Design and develop a new pharmaceutical drug!";
|
||||
break;
|
||||
case Industries.Computer:
|
||||
case "Computer":
|
||||
createProductButtonText = "Create Product";
|
||||
createProductPopupText = "Design and manufacture a new computer hardware product!";
|
||||
break;
|
||||
case Industries.Robotics:
|
||||
createProductButtonText = "Design Robot";
|
||||
createProductPopupText = "Design and create a new robot or robotic system!";
|
||||
break;
|
||||
case Industries.Software:
|
||||
createProductButtonText = "Develop Software";
|
||||
createProductPopupText = "Develop a new piece of software!";
|
||||
break;
|
||||
case Industries.Healthcare:
|
||||
createProductButtonText = "Build Hospital";
|
||||
createProductPopupText = "Build and manage a new hospital!";
|
||||
break;
|
||||
case Industries.RealEstate:
|
||||
createProductButtonText = "Develop Property";
|
||||
createProductPopupText = "Develop a new piece of real estate property!";
|
||||
break;
|
||||
default:
|
||||
createProductButtonText = "Create Product";
|
||||
createProductPopupText = "Create a new product!";
|
||||
return <></>;
|
||||
}
|
||||
createProductPopupText +=
|
||||
"<br><br>To begin developing a product, " +
|
||||
"first choose the city in which it will be designed. The stats of your employees " +
|
||||
"in the selected city affect the properties of the finished product, such as its " +
|
||||
"quality, performance, and durability.<br><br>" +
|
||||
"You can also choose to invest money in the design and marketing of " +
|
||||
"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 [makeOpen, setMakeOpen] = useState(false);
|
||||
|
||||
const hasMaxProducts = division.hasMaximumNumberProducts();
|
||||
const hasMaxProducts = division.hasMaximumNumberProducts();
|
||||
|
||||
function openMakeProductPopup(): void {
|
||||
const popupId = "cmpy-mgmt-create-product-popup";
|
||||
createPopup(popupId, MakeProductPopup, {
|
||||
popupText: createProductPopupText,
|
||||
division: division,
|
||||
corp: corp,
|
||||
popupId: popupId,
|
||||
});
|
||||
}
|
||||
function shouldFlash(): boolean {
|
||||
return Object.keys(division.products).length === 0;
|
||||
}
|
||||
|
||||
function shouldFlash(): boolean {
|
||||
return Object.keys(division.products).length === 0;
|
||||
}
|
||||
let createProductButtonText = "";
|
||||
switch (division.type) {
|
||||
case Industries.Food:
|
||||
createProductButtonText = "Build Restaurant";
|
||||
break;
|
||||
case Industries.Tobacco:
|
||||
createProductButtonText = "Create Product";
|
||||
break;
|
||||
case Industries.Pharmaceutical:
|
||||
createProductButtonText = "Create Drug";
|
||||
break;
|
||||
case Industries.Computer:
|
||||
case "Computer":
|
||||
createProductButtonText = "Create Product";
|
||||
break;
|
||||
case Industries.Robotics:
|
||||
createProductButtonText = "Design Robot";
|
||||
break;
|
||||
case Industries.Software:
|
||||
createProductButtonText = "Develop Software";
|
||||
break;
|
||||
case Industries.Healthcare:
|
||||
createProductButtonText = "Build Hospital";
|
||||
break;
|
||||
case Industries.RealEstate:
|
||||
createProductButtonText = "Develop Property";
|
||||
break;
|
||||
default:
|
||||
createProductButtonText = "Create Product";
|
||||
return <></>;
|
||||
}
|
||||
|
||||
return (
|
||||
return (
|
||||
<>
|
||||
<Tooltip
|
||||
title={
|
||||
hasMaxProducts ? (
|
||||
@ -107,225 +80,212 @@ export function IndustryOverview(props: IProps): React.ReactElement {
|
||||
)
|
||||
}
|
||||
>
|
||||
<Button color={shouldFlash() ? "error" : "primary"} onClick={openMakeProductPopup} disabled={corp.funds.lt(0)}>
|
||||
<Button
|
||||
color={shouldFlash() ? "error" : "primary"}
|
||||
onClick={() => setMakeOpen(true)}
|
||||
disabled={corp.funds.lt(0)}
|
||||
>
|
||||
{createProductButtonText}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
);
|
||||
<MakeProductModal open={makeOpen} onClose={() => setMakeOpen(false)} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
function Text(): React.ReactElement {
|
||||
const corp = useCorporation();
|
||||
const division = useDivision();
|
||||
const [helpOpen, setHelpOpen] = useState(false);
|
||||
const vechain = corp.unlockUpgrades[4] === 1;
|
||||
const profit = division.lastCycleRevenue.minus(division.lastCycleExpenses).toNumber();
|
||||
|
||||
let advertisingInfo = false;
|
||||
const advertisingFactors = division.getAdvertisingFactors();
|
||||
const awarenessFac = advertisingFactors[1];
|
||||
const popularityFac = advertisingFactors[2];
|
||||
const ratioFac = advertisingFactors[3];
|
||||
const totalAdvertisingFac = advertisingFactors[0];
|
||||
if (vechain) {
|
||||
advertisingInfo = true;
|
||||
}
|
||||
|
||||
function renderText(): React.ReactElement {
|
||||
const vechain = corp.unlockUpgrades[4] === 1;
|
||||
const profit = division.lastCycleRevenue.minus(division.lastCycleExpenses).toNumber();
|
||||
|
||||
let advertisingInfo = false;
|
||||
const advertisingFactors = division.getAdvertisingFactors();
|
||||
const awarenessFac = advertisingFactors[1];
|
||||
const popularityFac = advertisingFactors[2];
|
||||
const ratioFac = advertisingFactors[3];
|
||||
const totalAdvertisingFac = advertisingFactors[0];
|
||||
if (vechain) {
|
||||
advertisingInfo = true;
|
||||
}
|
||||
|
||||
function productionMultHelpTipOnClick(): void {
|
||||
// Wrapper for createProgressBarText()
|
||||
// Converts the industry's "effectiveness factors"
|
||||
// into a graphic (string) depicting how high that effectiveness is
|
||||
function convertEffectFacToGraphic(fac: number): string {
|
||||
return createProgressBarText({
|
||||
progress: fac,
|
||||
totalTicks: 20,
|
||||
});
|
||||
}
|
||||
|
||||
dialogBoxCreate(
|
||||
"Owning Hardware, Robots, AI Cores, and Real Estate " +
|
||||
"can boost your Industry's production. The effect these " +
|
||||
"materials have on your production varies between Industries. " +
|
||||
"For example, Real Estate may be very effective for some Industries, " +
|
||||
"but ineffective for others.<br><br>" +
|
||||
"This division's production multiplier is calculated by summing " +
|
||||
"the individual production multiplier of each of its office locations. " +
|
||||
"This production multiplier is applied to each office. Therefore, it is " +
|
||||
"beneficial to expand into new cities as this can greatly increase the " +
|
||||
"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: ${convertEffectFacToGraphic(division.hwFac)}<br>` +
|
||||
`Robots: ${convertEffectFacToGraphic(division.robFac)}<br>` +
|
||||
`AI Cores: ${convertEffectFacToGraphic(division.aiFac)}<br>` +
|
||||
`Real Estate: ${convertEffectFacToGraphic(division.reFac)}`,
|
||||
);
|
||||
}
|
||||
|
||||
function openResearchPopup(): void {
|
||||
const popupId = "corporation-research-popup-box";
|
||||
createPopup(popupId, ResearchPopup, {
|
||||
industry: division,
|
||||
popupId: popupId,
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Typography>
|
||||
Industry: {division.type} (Corp Funds: <Money money={corp.funds.toNumber()} />)
|
||||
<br /> <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")}
|
||||
<span className={"tooltiptext cmpy-mgmt-advertising-info"}>
|
||||
Total multiplier for this industrys sales due to its awareness and popularity
|
||||
<br />
|
||||
Awareness Bonus: x{numeralWrapper.format(Math.pow(awarenessFac, 0.85), "0.000")}
|
||||
<br />
|
||||
Popularity Bonus: x{numeralWrapper.format(Math.pow(popularityFac, 0.85), "0.000")}
|
||||
<br />
|
||||
Ratio Multiplier: x{numeralWrapper.format(Math.pow(ratioFac, 0.85), "0.000")}
|
||||
</span>
|
||||
</p>
|
||||
)}
|
||||
{advertisingInfo}
|
||||
</Typography>
|
||||
<br />
|
||||
<br />
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<p>Revenue: </p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
<Money money={division.lastCycleRevenue.toNumber()} /> / s
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>Expenses: </p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
<Money money={division.lastCycleExpenses.toNumber()} /> / s
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<p>Profit: </p>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
<Money money={profit} /> / s
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br />
|
||||
<p className={"tooltip"}>
|
||||
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
|
||||
</span>
|
||||
</p>
|
||||
<div className={"help-tip"} onClick={productionMultHelpTipOnClick}>
|
||||
?
|
||||
</div>
|
||||
<br /> <br />
|
||||
<p className={"tooltip"}>
|
||||
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>
|
||||
</p>
|
||||
<button className={"help-tip"} onClick={openResearchPopup}>
|
||||
Research
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
function convertEffectFacToGraphic(fac: number): string {
|
||||
return createProgressBarText({
|
||||
progress: fac,
|
||||
totalTicks: 20,
|
||||
});
|
||||
}
|
||||
|
||||
function renderUpgrades(): React.ReactElement[] {
|
||||
const upgrades = [];
|
||||
for (const index in IndustryUpgrades) {
|
||||
const upgrade = IndustryUpgrades[index];
|
||||
function openResearchPopup(): void {
|
||||
const popupId = "corporation-research-popup-box";
|
||||
createPopup(popupId, ResearchPopup, {
|
||||
industry: division,
|
||||
popupId: popupId,
|
||||
});
|
||||
}
|
||||
|
||||
// AutoBrew research disables the Coffee upgrade
|
||||
if (division.hasResearch("AutoBrew") && upgrade[4] === "Coffee") {
|
||||
continue;
|
||||
}
|
||||
|
||||
const i = upgrade[0];
|
||||
const baseCost = upgrade[1];
|
||||
const priceMult = upgrade[2];
|
||||
let cost = 0;
|
||||
switch (i) {
|
||||
case 0: //Coffee, cost is static per employee
|
||||
cost = props.office.employees.length * baseCost;
|
||||
break;
|
||||
default:
|
||||
cost = baseCost * Math.pow(priceMult, division.upgrades[i]);
|
||||
break;
|
||||
}
|
||||
|
||||
function onClick(): void {
|
||||
if (corp.funds.lt(cost)) return;
|
||||
corp.funds = corp.funds.minus(cost);
|
||||
division.upgrade(upgrade, {
|
||||
corporation: corp,
|
||||
office: props.office,
|
||||
});
|
||||
props.rerender();
|
||||
}
|
||||
|
||||
upgrades.push(
|
||||
renderUpgrade({
|
||||
key: index,
|
||||
onClick: onClick,
|
||||
text: (
|
||||
return (
|
||||
<div>
|
||||
<Typography>
|
||||
Industry: {division.type} (Corp Funds: <Money money={corp.funds.toNumber()} />)
|
||||
</Typography>
|
||||
<br />
|
||||
<StatsTable
|
||||
rows={[
|
||||
["Awareness:", numeralWrapper.format(division.awareness, "0.000")],
|
||||
["Popularity:", numeralWrapper.format(division.popularity, "0.000")],
|
||||
]}
|
||||
/>
|
||||
{advertisingInfo !== false && (
|
||||
<Tooltip
|
||||
title={
|
||||
<>
|
||||
{upgrade[4]} - <MoneyCost money={cost} corp={corp} />
|
||||
<Typography>Total multiplier for this industrys sales due to its awareness and popularity</Typography>
|
||||
<StatsTable
|
||||
rows={[
|
||||
["Awareness Bonus:", "x" + numeralWrapper.format(Math.pow(awarenessFac, 0.85), "0.000")],
|
||||
["Popularity Bonus:", "x" + numeralWrapper.format(Math.pow(popularityFac, 0.85), "0.000")],
|
||||
["Ratio Multiplier:", "x" + numeralWrapper.format(Math.pow(ratioFac, 0.85), "0.000")],
|
||||
]}
|
||||
/>
|
||||
</>
|
||||
),
|
||||
tooltip: upgrade[5],
|
||||
}),
|
||||
);
|
||||
}
|
||||
>
|
||||
<Typography>Advertising Multiplier: x{numeralWrapper.format(totalAdvertisingFac, "0.000")}</Typography>
|
||||
</Tooltip>
|
||||
)}
|
||||
<br />
|
||||
<StatsTable
|
||||
rows={[
|
||||
["Revenue:", <MoneyRate money={division.lastCycleRevenue.toNumber()} />],
|
||||
["Expenses:", <MoneyRate money={division.lastCycleExpenses.toNumber()} />],
|
||||
["Profit:", <MoneyRate money={profit} />],
|
||||
]}
|
||||
/>
|
||||
<br />
|
||||
<Box display="flex" alignItems="center">
|
||||
<Tooltip
|
||||
title={
|
||||
<Typography>
|
||||
Production gain from owning production-boosting materials such as hardware, Robots, AI Cores, and Real
|
||||
Estate.
|
||||
</Typography>
|
||||
}
|
||||
>
|
||||
<Typography>Production Multiplier: {numeralWrapper.format(division.prodMult, "0.00")}</Typography>
|
||||
</Tooltip>
|
||||
<IconButton onClick={() => setHelpOpen(true)}>
|
||||
<HelpIcon />
|
||||
</IconButton>
|
||||
<StaticModal open={helpOpen} onClose={() => setHelpOpen(false)}>
|
||||
<Typography>
|
||||
Owning Hardware, Robots, AI Cores, and Real Estate can boost your Industry's production. The effect these
|
||||
materials have on your production varies between Industries. For example, Real Estate may be very effective
|
||||
for some Industries, but ineffective for others.
|
||||
<br />
|
||||
<br />
|
||||
This division's production multiplier is calculated by summing the individual production multiplier of each
|
||||
of its office locations. This production multiplier is applied to each office. Therefore, it is beneficial
|
||||
to expand into new cities as this can greatly increase the 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: {convertEffectFacToGraphic(division.hwFac)}
|
||||
<br />
|
||||
Robots: {convertEffectFacToGraphic(division.robFac)}
|
||||
<br />
|
||||
AI Cores: {convertEffectFacToGraphic(division.aiFac)}
|
||||
<br />
|
||||
Real Estate: {convertEffectFacToGraphic(division.reFac)}
|
||||
</Typography>
|
||||
</StaticModal>
|
||||
</Box>
|
||||
|
||||
<Box display="flex" alignItems="center">
|
||||
<Tooltip
|
||||
title={
|
||||
<Typography>
|
||||
Scientific Research increases the quality of the materials and products that you produce.
|
||||
</Typography>
|
||||
}
|
||||
>
|
||||
<Typography>Scientific Research: {numeralWrapper.format(division.sciResearch.qty, "0.000a")}</Typography>
|
||||
</Tooltip>
|
||||
<Button sx={{ mx: 1 }} onClick={openResearchPopup}>
|
||||
Research
|
||||
</Button>
|
||||
</Box>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Upgrades(props: { office: OfficeSpace; rerender: () => void }): React.ReactElement {
|
||||
const corp = useCorporation();
|
||||
const division = useDivision();
|
||||
const upgrades = [];
|
||||
for (const index in IndustryUpgrades) {
|
||||
const upgrade = IndustryUpgrades[index];
|
||||
|
||||
// AutoBrew research disables the Coffee upgrade
|
||||
if (division.hasResearch("AutoBrew") && upgrade[4] === "Coffee") {
|
||||
continue;
|
||||
}
|
||||
|
||||
return upgrades;
|
||||
}
|
||||
const i = upgrade[0];
|
||||
const baseCost = upgrade[1];
|
||||
const priceMult = upgrade[2];
|
||||
let cost = 0;
|
||||
switch (i) {
|
||||
case 0: //Coffee, cost is static per employee
|
||||
cost = props.office.employees.length * baseCost;
|
||||
break;
|
||||
default:
|
||||
cost = baseCost * Math.pow(priceMult, division.upgrades[i]);
|
||||
break;
|
||||
}
|
||||
|
||||
interface IRenderUpgradeProps {
|
||||
key: string;
|
||||
onClick: () => void;
|
||||
text: JSX.Element;
|
||||
tooltip: string;
|
||||
}
|
||||
function onClick(): void {
|
||||
if (corp.funds.lt(cost)) return;
|
||||
corp.funds = corp.funds.minus(cost);
|
||||
division.upgrade(upgrade, {
|
||||
corporation: corp,
|
||||
office: props.office,
|
||||
});
|
||||
props.rerender();
|
||||
}
|
||||
|
||||
function renderUpgrade(props: IRenderUpgradeProps): React.ReactElement {
|
||||
return (
|
||||
<div className={"cmpy-mgmt-upgrade-div tooltip"} onClick={props.onClick} key={props.key}>
|
||||
{props.text}
|
||||
{props.tooltip != null && <span className={"tooltiptext"}>{props.tooltip}</span>}
|
||||
</div>
|
||||
upgrades.push(
|
||||
<Tooltip key={index} title={upgrade[5]}>
|
||||
<Button onClick={onClick}>
|
||||
{upgrade[4]} -
|
||||
<MoneyCost money={cost} corp={corp} />
|
||||
</Button>
|
||||
</Tooltip>,
|
||||
);
|
||||
}
|
||||
|
||||
const makeProductButton = renderMakeProductButton();
|
||||
return <>{upgrades}</>;
|
||||
}
|
||||
|
||||
interface IProps {
|
||||
currentCity: string;
|
||||
office: OfficeSpace;
|
||||
rerender: () => void;
|
||||
}
|
||||
|
||||
export function IndustryOverview(props: IProps): React.ReactElement {
|
||||
const division = useDivision();
|
||||
|
||||
return (
|
||||
<Paper>
|
||||
{renderText()}
|
||||
<Text />
|
||||
<br />
|
||||
<Typography>Purchases & Upgrades</Typography>
|
||||
{renderUpgrades()} <br />
|
||||
{division.makesProducts && makeProductButton}
|
||||
<Upgrades office={props.office} rerender={props.rerender} /> <br />
|
||||
{division.makesProducts && <MakeProductButton />}
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
// React Component for displaying an Industry's warehouse information
|
||||
// (right-side panel in the Industry UI)
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { CorporationConstants } from "../data/Constants";
|
||||
import { OfficeSpace } from "../OfficeSpace";
|
||||
@ -15,7 +15,8 @@ import { SellMaterialPopup } from "./SellMaterialPopup";
|
||||
import { SellProductPopup } from "./SellProductPopup";
|
||||
import { PurchaseMaterialPopup } from "./PurchaseMaterialPopup";
|
||||
import { ProductMarketTaPopup } from "./ProductMarketTaPopup";
|
||||
import { SmartSupplyPopup } from "./SmartSupplyPopup";
|
||||
import { SmartSupplyModal } from "./SmartSupplyModal";
|
||||
import { MaterialSizes } from "../MaterialSizes";
|
||||
|
||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||
import { createPopup } from "../../ui/React/createPopup";
|
||||
@ -29,6 +30,13 @@ import { MoneyCost } from "./MoneyCost";
|
||||
import { isRelevantMaterial } from "./Helpers";
|
||||
import { IndustryProductEquation } from "./IndustryProductEquation";
|
||||
import { PurchaseWarehouse } from "../Actions";
|
||||
import { useCorporation, useDivision } from "./Context";
|
||||
|
||||
import Typography from "@mui/material/Typography";
|
||||
import Tooltip from "@mui/material/Tooltip";
|
||||
import Paper from "@mui/material/Paper";
|
||||
import Button from "@mui/material/Button";
|
||||
import Box from "@mui/material/Box";
|
||||
|
||||
interface IProductProps {
|
||||
corp: ICorporation;
|
||||
@ -41,8 +49,8 @@ interface IProductProps {
|
||||
|
||||
// Creates the UI for a single Product type
|
||||
function ProductComponent(props: IProductProps): React.ReactElement {
|
||||
const corp = props.corp;
|
||||
const division = props.division;
|
||||
const corp = useCorporation();
|
||||
const division = useDivision();
|
||||
const city = props.city;
|
||||
const product = props.product;
|
||||
|
||||
@ -136,7 +144,7 @@ function ProductComponent(props: IProductProps): React.ReactElement {
|
||||
rerender: props.rerender,
|
||||
product: product,
|
||||
industry: division,
|
||||
corp: props.corp,
|
||||
corp: corp,
|
||||
popupId: popupId,
|
||||
player: props.player,
|
||||
});
|
||||
@ -164,21 +172,11 @@ function ProductComponent(props: IProductProps): React.ReactElement {
|
||||
|
||||
{hasUpgradeDashboard && (
|
||||
<div>
|
||||
<button className={"std-button"} onClick={openSellProductPopup}>
|
||||
{sellButtonText}
|
||||
</button>
|
||||
<Button onClick={openSellProductPopup}>{sellButtonText}</Button>
|
||||
<br />
|
||||
<button className={"std-button"} onClick={openLimitProductProdutionPopup}>
|
||||
{limitProductionButtonText}
|
||||
</button>
|
||||
<button className={"std-button"} onClick={openDiscontinueProductPopup}>
|
||||
Discontinue
|
||||
</button>
|
||||
{division.hasResearch("Market-TA.I") && (
|
||||
<button className={"std-button"} onClick={openProductMarketTaPopup}>
|
||||
Market-TA
|
||||
</button>
|
||||
)}
|
||||
<Button onClick={openLimitProductProdutionPopup}>{limitProductionButtonText}</Button>
|
||||
<Button onClick={openDiscontinueProductPopup}>Discontinue</Button>
|
||||
{division.hasResearch("Market-TA.I") && <Button onClick={openProductMarketTaPopup}>Market-TA</Button>}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
@ -227,29 +225,17 @@ function ProductComponent(props: IProductProps): React.ReactElement {
|
||||
</p>
|
||||
|
||||
<div>
|
||||
<button className={"std-button"} onClick={openSellProductPopup}>
|
||||
{sellButtonText}
|
||||
</button>
|
||||
<Button onClick={openSellProductPopup}>{sellButtonText}</Button>
|
||||
<br />
|
||||
<button className={"std-button"} onClick={openLimitProductProdutionPopup}>
|
||||
{limitProductionButtonText}
|
||||
</button>
|
||||
<button className={"std-button"} onClick={openDiscontinueProductPopup}>
|
||||
Discontinue
|
||||
</button>
|
||||
{division.hasResearch("Market-TA.I") && (
|
||||
<button className={"std-button"} onClick={openProductMarketTaPopup}>
|
||||
Market-TA
|
||||
</button>
|
||||
)}
|
||||
<Button onClick={openLimitProductProdutionPopup}>{limitProductionButtonText}</Button>
|
||||
<Button onClick={openDiscontinueProductPopup}>Discontinue</Button>
|
||||
{division.hasResearch("Market-TA.I") && <Button onClick={openProductMarketTaPopup}>Market-TA</Button>}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface IMaterialProps {
|
||||
corp: ICorporation;
|
||||
division: IIndustry;
|
||||
warehouse: Warehouse;
|
||||
city: string;
|
||||
mat: Material;
|
||||
@ -258,8 +244,8 @@ interface IMaterialProps {
|
||||
|
||||
// Creates the UI for a single Material type
|
||||
function MaterialComponent(props: IMaterialProps): React.ReactElement {
|
||||
const corp = props.corp;
|
||||
const division = props.division;
|
||||
const corp = useCorporation();
|
||||
const division = useDivision();
|
||||
const warehouse = props.warehouse;
|
||||
const city = props.city;
|
||||
const mat = props.mat;
|
||||
@ -291,7 +277,7 @@ function MaterialComponent(props: IMaterialProps): React.ReactElement {
|
||||
mat: mat,
|
||||
industry: division,
|
||||
warehouse: warehouse,
|
||||
corp: props.corp,
|
||||
corp: corp,
|
||||
popupId: popupId,
|
||||
});
|
||||
}
|
||||
@ -300,7 +286,7 @@ function MaterialComponent(props: IMaterialProps): React.ReactElement {
|
||||
const popupId = "cmpy-mgmt-export-popup";
|
||||
createPopup(popupId, ExportPopup, {
|
||||
mat: mat,
|
||||
corp: props.corp,
|
||||
corp: corp,
|
||||
popupId: popupId,
|
||||
});
|
||||
}
|
||||
@ -358,7 +344,7 @@ function MaterialComponent(props: IMaterialProps): React.ReactElement {
|
||||
const popupId = "cmpy-mgmt-material-sell-popup";
|
||||
createPopup(popupId, SellMaterialPopup, {
|
||||
mat: mat,
|
||||
corp: props.corp,
|
||||
corp: corp,
|
||||
popupId: popupId,
|
||||
});
|
||||
}
|
||||
@ -368,13 +354,13 @@ function MaterialComponent(props: IMaterialProps): React.ReactElement {
|
||||
createPopup(popupId, MaterialMarketTaPopup, {
|
||||
mat: mat,
|
||||
industry: division,
|
||||
corp: props.corp,
|
||||
corp: corp,
|
||||
popupId: popupId,
|
||||
});
|
||||
}
|
||||
|
||||
function shouldFlash(): boolean {
|
||||
return props.division.prodMats.includes(props.mat.name) && !mat.sllman[0];
|
||||
return division.prodMats.includes(props.mat.name) && !mat.sllman[0];
|
||||
}
|
||||
|
||||
return (
|
||||
@ -409,33 +395,25 @@ function MaterialComponent(props: IMaterialProps): React.ReactElement {
|
||||
</div>
|
||||
|
||||
<div style={{ display: "inline-block" }}>
|
||||
<button
|
||||
<Button
|
||||
className={purchaseButtonClass}
|
||||
onClick={openPurchaseMaterialPopup}
|
||||
disabled={props.warehouse.smartSupplyEnabled && Object.keys(props.division.reqMats).includes(props.mat.name)}
|
||||
disabled={props.warehouse.smartSupplyEnabled && Object.keys(division.reqMats).includes(props.mat.name)}
|
||||
>
|
||||
{purchaseButtonText}
|
||||
{tutorial && (
|
||||
<span className={"tooltiptext"}>Purchase your required materials to get production started!</span>
|
||||
)}
|
||||
</button>
|
||||
</Button>
|
||||
|
||||
{corp.unlockUpgrades[0] === 1 && (
|
||||
<button className={"std-button"} onClick={openExportPopup}>
|
||||
Export
|
||||
</button>
|
||||
)}
|
||||
{corp.unlockUpgrades[0] === 1 && <Button onClick={openExportPopup}>Export</Button>}
|
||||
<br />
|
||||
|
||||
<button className={`std-button${shouldFlash() ? " flashing-button" : ""}`} onClick={openSellMaterialPopup}>
|
||||
<Button className={`std-button${shouldFlash() ? " flashing-button" : ""}`} onClick={openSellMaterialPopup}>
|
||||
{sellButtonText}
|
||||
</button>
|
||||
</Button>
|
||||
|
||||
{division.hasResearch("Market-TA.I") && (
|
||||
<button className={"std-button"} onClick={openMaterialMarketTaPopup}>
|
||||
Market-TA
|
||||
</button>
|
||||
)}
|
||||
{division.hasResearch("Market-TA.I") && <Button onClick={openMaterialMarketTaPopup}>Market-TA</Button>}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@ -450,177 +428,188 @@ interface IProps {
|
||||
rerender: () => void;
|
||||
}
|
||||
|
||||
export function IndustryWarehouse(props: IProps): React.ReactElement {
|
||||
function renderWarehouseUI(): React.ReactElement {
|
||||
if (props.warehouse === 0) return <></>;
|
||||
// General Storage information at the top
|
||||
const sizeUsageStyle = {
|
||||
color: props.warehouse.sizeUsed >= props.warehouse.size ? "red" : "white",
|
||||
margin: "5px",
|
||||
};
|
||||
function WarehouseRoot(props: IProps): React.ReactElement {
|
||||
const corp = useCorporation();
|
||||
const division = useDivision();
|
||||
const [smartSupplyOpen, setSmartSupplyOpen] = useState(false);
|
||||
if (props.warehouse === 0) return <></>;
|
||||
|
||||
// Upgrade Warehouse size button
|
||||
const sizeUpgradeCost = CorporationConstants.WarehouseUpgradeBaseCost * Math.pow(1.07, props.warehouse.level + 1);
|
||||
const canAffordUpgrade = props.corp.funds.gt(sizeUpgradeCost);
|
||||
const upgradeWarehouseClass = canAffordUpgrade ? "std-button" : "a-link-button-inactive";
|
||||
function upgradeWarehouseOnClick(): void {
|
||||
if (props.division === null) return;
|
||||
if (props.warehouse === 0) return;
|
||||
++props.warehouse.level;
|
||||
props.warehouse.updateSize(props.corp, props.division);
|
||||
props.corp.funds = props.corp.funds.minus(sizeUpgradeCost);
|
||||
props.rerender();
|
||||
}
|
||||
|
||||
function openSmartSupplyPopup(): void {
|
||||
if (props.warehouse === 0) return;
|
||||
const popupId = "cmpy-mgmt-smart-supply-popup";
|
||||
createPopup(popupId, SmartSupplyPopup, {
|
||||
division: props.division,
|
||||
warehouse: props.warehouse,
|
||||
corp: props.corp,
|
||||
player: props.player,
|
||||
popupId: popupId,
|
||||
});
|
||||
}
|
||||
|
||||
const ratioLines = [];
|
||||
for (const matName in props.division.reqMats) {
|
||||
if (props.division.reqMats.hasOwnProperty(matName)) {
|
||||
const text = [" *", props.division.reqMats[matName], matName].join(" ");
|
||||
ratioLines.push(
|
||||
<div key={matName}>
|
||||
<p>{text}</p>
|
||||
</div>,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Current State:
|
||||
let stateText;
|
||||
switch (props.division.state) {
|
||||
case "START":
|
||||
stateText = "Current state: Preparing...";
|
||||
break;
|
||||
case "PURCHASE":
|
||||
stateText = "Current state: Purchasing materials...";
|
||||
break;
|
||||
case "PRODUCTION":
|
||||
stateText = "Current state: Producing materials and/or products...";
|
||||
break;
|
||||
case "SALE":
|
||||
stateText = "Current state: Selling materials and/or products...";
|
||||
break;
|
||||
case "EXPORT":
|
||||
stateText = "Current state: Exporting materials and/or products...";
|
||||
break;
|
||||
default:
|
||||
console.error(`Invalid state: ${props.division.state}`);
|
||||
break;
|
||||
}
|
||||
|
||||
// Create React components for materials
|
||||
const mats = [];
|
||||
for (const matName in props.warehouse.materials) {
|
||||
if (props.warehouse.materials[matName] instanceof Material) {
|
||||
// Only create UI for materials that are relevant for the industry
|
||||
if (isRelevantMaterial(matName, props.division)) {
|
||||
mats.push(
|
||||
<MaterialComponent
|
||||
rerender={props.rerender}
|
||||
city={props.currentCity}
|
||||
corp={props.corp}
|
||||
division={props.division}
|
||||
key={matName}
|
||||
mat={props.warehouse.materials[matName]}
|
||||
warehouse={props.warehouse}
|
||||
/>,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create React components for products
|
||||
const products = [];
|
||||
if (props.division.makesProducts && Object.keys(props.division.products).length > 0) {
|
||||
for (const productName in props.division.products) {
|
||||
const product = props.division.products[productName];
|
||||
if (product instanceof Product) {
|
||||
products.push(
|
||||
<ProductComponent
|
||||
rerender={props.rerender}
|
||||
player={props.player}
|
||||
city={props.currentCity}
|
||||
corp={props.corp}
|
||||
division={props.division}
|
||||
key={productName}
|
||||
product={product}
|
||||
/>,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={"cmpy-mgmt-warehouse-panel"}>
|
||||
<p className={"tooltip"} style={sizeUsageStyle}>
|
||||
Storage: {numeralWrapper.formatBigNumber(props.warehouse.sizeUsed)} /{" "}
|
||||
{numeralWrapper.formatBigNumber(props.warehouse.size)}
|
||||
<span className={"tooltiptext"} dangerouslySetInnerHTML={{ __html: props.warehouse.breakdown }}></span>
|
||||
</p>
|
||||
|
||||
<button className={upgradeWarehouseClass} onClick={upgradeWarehouseOnClick}>
|
||||
Upgrade Warehouse Size - <MoneyCost money={sizeUpgradeCost} corp={props.corp} />
|
||||
</button>
|
||||
|
||||
<p>This industry uses the following equation for it's production: </p>
|
||||
<br />
|
||||
<br />
|
||||
<IndustryProductEquation division={props.division} />
|
||||
<br />
|
||||
<br />
|
||||
<p>
|
||||
To get started with production, purchase your required materials or import them from another of your company's
|
||||
divisions.
|
||||
</p>
|
||||
<br />
|
||||
|
||||
<p>{stateText}</p>
|
||||
|
||||
{props.corp.unlockUpgrades[1] && (
|
||||
<>
|
||||
<button className="std-button" onClick={openSmartSupplyPopup}>
|
||||
Configure Smart Supply
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
|
||||
{mats}
|
||||
|
||||
{products}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function purchaseWarehouse(division: IIndustry, city: string): void {
|
||||
PurchaseWarehouse(props.corp, division, city);
|
||||
// Upgrade Warehouse size button
|
||||
const sizeUpgradeCost = CorporationConstants.WarehouseUpgradeBaseCost * Math.pow(1.07, props.warehouse.level + 1);
|
||||
const canAffordUpgrade = corp.funds.gt(sizeUpgradeCost);
|
||||
function upgradeWarehouseOnClick(): void {
|
||||
if (division === null) return;
|
||||
if (props.warehouse === 0) return;
|
||||
if (!canAffordUpgrade) return;
|
||||
++props.warehouse.level;
|
||||
props.warehouse.updateSize(corp, division);
|
||||
corp.funds = corp.funds.minus(sizeUpgradeCost);
|
||||
props.rerender();
|
||||
}
|
||||
|
||||
if (props.warehouse instanceof Warehouse) {
|
||||
return renderWarehouseUI();
|
||||
} else {
|
||||
return (
|
||||
<div className={"cmpy-mgmt-warehouse-panel"}>
|
||||
<button
|
||||
className={"std-button"}
|
||||
onClick={() => purchaseWarehouse(props.division, props.currentCity)}
|
||||
disabled={props.corp.funds.lt(CorporationConstants.WarehouseInitialCost)}
|
||||
>
|
||||
Purchase Warehouse (
|
||||
<MoneyCost money={CorporationConstants.WarehouseInitialCost} corp={props.corp} />)
|
||||
</button>
|
||||
</div>
|
||||
const ratioLines = [];
|
||||
for (const matName in division.reqMats) {
|
||||
if (division.reqMats.hasOwnProperty(matName)) {
|
||||
const text = [" *", division.reqMats[matName], matName].join(" ");
|
||||
ratioLines.push(
|
||||
<div key={matName}>
|
||||
<p>{text}</p>
|
||||
</div>,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Current State:
|
||||
let stateText;
|
||||
switch (division.state) {
|
||||
case "START":
|
||||
stateText = "Current state: Preparing...";
|
||||
break;
|
||||
case "PURCHASE":
|
||||
stateText = "Current state: Purchasing materials...";
|
||||
break;
|
||||
case "PRODUCTION":
|
||||
stateText = "Current state: Producing materials and/or products...";
|
||||
break;
|
||||
case "SALE":
|
||||
stateText = "Current state: Selling materials and/or products...";
|
||||
break;
|
||||
case "EXPORT":
|
||||
stateText = "Current state: Exporting materials and/or products...";
|
||||
break;
|
||||
default:
|
||||
console.error(`Invalid state: ${division.state}`);
|
||||
break;
|
||||
}
|
||||
|
||||
// Create React components for materials
|
||||
const mats = [];
|
||||
for (const matName in props.warehouse.materials) {
|
||||
if (!(props.warehouse.materials[matName] instanceof Material)) continue;
|
||||
// Only create UI for materials that are relevant for the industry
|
||||
if (!isRelevantMaterial(matName, division)) continue;
|
||||
mats.push(
|
||||
<MaterialComponent
|
||||
rerender={props.rerender}
|
||||
city={props.currentCity}
|
||||
key={matName}
|
||||
mat={props.warehouse.materials[matName]}
|
||||
warehouse={props.warehouse}
|
||||
/>,
|
||||
);
|
||||
}
|
||||
|
||||
// Create React components for products
|
||||
const products = [];
|
||||
if (division.makesProducts && Object.keys(division.products).length > 0) {
|
||||
for (const productName in division.products) {
|
||||
const product = division.products[productName];
|
||||
if (!(product instanceof Product)) continue;
|
||||
products.push(
|
||||
<ProductComponent
|
||||
rerender={props.rerender}
|
||||
player={props.player}
|
||||
city={props.currentCity}
|
||||
corp={corp}
|
||||
division={division}
|
||||
key={productName}
|
||||
product={product}
|
||||
/>,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
let breakdown = <></>;
|
||||
for (const matName in props.warehouse.materials) {
|
||||
if (matName === "RealEstate") continue;
|
||||
const mat = props.warehouse.materials[matName];
|
||||
if (!MaterialSizes.hasOwnProperty(matName)) continue;
|
||||
if (mat.qty === 0) continue;
|
||||
breakdown = (
|
||||
<>
|
||||
{breakdown}
|
||||
{matName}: {numeralWrapper.format(mat.qty * MaterialSizes[matName], "0,0.0")}
|
||||
<br />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={"cmpy-mgmt-warehouse-panel"}>
|
||||
<Box display="flex" alignItems="center">
|
||||
<Tooltip title={props.warehouse.sizeUsed !== 0 ? breakdown : ""}>
|
||||
<Typography color={props.warehouse.sizeUsed >= props.warehouse.size ? "error" : "primary"}>
|
||||
Storage: {numeralWrapper.formatBigNumber(props.warehouse.sizeUsed)} /{" "}
|
||||
{numeralWrapper.formatBigNumber(props.warehouse.size)}
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
|
||||
<Button disabled={!canAffordUpgrade} onClick={upgradeWarehouseOnClick}>
|
||||
Upgrade Warehouse Size -
|
||||
<MoneyCost money={sizeUpgradeCost} corp={corp} />
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
<Typography>This industry uses the following equation for it's production: </Typography>
|
||||
<br />
|
||||
<Typography>
|
||||
<IndustryProductEquation division={division} />
|
||||
</Typography>
|
||||
<br />
|
||||
<Typography>
|
||||
To get started with production, purchase your required materials or import them from another of your company's
|
||||
divisions.
|
||||
</Typography>
|
||||
<br />
|
||||
|
||||
<Typography>{stateText}</Typography>
|
||||
|
||||
{corp.unlockUpgrades[1] && (
|
||||
<>
|
||||
<Button onClick={() => setSmartSupplyOpen(true)}>Configure Smart Supply</Button>
|
||||
<SmartSupplyModal
|
||||
open={smartSupplyOpen}
|
||||
onClose={() => setSmartSupplyOpen(false)}
|
||||
warehouse={props.warehouse}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
||||
{mats}
|
||||
|
||||
{products}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function IndustryWarehouse(props: IProps): React.ReactElement {
|
||||
if (props.warehouse instanceof Warehouse) {
|
||||
return <WarehouseRoot {...props} />;
|
||||
} else {
|
||||
return <EmptyWarehouse rerender={props.rerender} city={props.currentCity} />;
|
||||
}
|
||||
}
|
||||
|
||||
interface IEmptyProps {
|
||||
city: string;
|
||||
rerender: () => void;
|
||||
}
|
||||
|
||||
function EmptyWarehouse(props: IEmptyProps): React.ReactElement {
|
||||
const corp = useCorporation();
|
||||
const division = useDivision();
|
||||
const disabled = corp.funds.lt(CorporationConstants.WarehouseInitialCost);
|
||||
function purchaseWarehouse(): void {
|
||||
if (disabled) return;
|
||||
PurchaseWarehouse(corp, division, props.city);
|
||||
props.rerender();
|
||||
}
|
||||
return (
|
||||
<Paper>
|
||||
<Button onClick={purchaseWarehouse} disabled={disabled}>
|
||||
Purchase Warehouse (
|
||||
<MoneyCost money={CorporationConstants.WarehouseInitialCost} corp={corp} />)
|
||||
</Button>
|
||||
</Paper>
|
||||
);
|
||||
}
|
||||
|
@ -25,9 +25,7 @@ export function MainPanel(props: IProps): React.ReactElement {
|
||||
if (division === undefined) throw new Error("Cannot find division");
|
||||
return (
|
||||
<Context.Division.Provider value={division}>
|
||||
<div id="cmpy-mgmt-panel">
|
||||
<CityTabs rerender={props.rerender} city={CityName.Sector12} />
|
||||
</div>
|
||||
<CityTabs rerender={props.rerender} city={CityName.Sector12} />
|
||||
</Context.Division.Provider>
|
||||
);
|
||||
}
|
||||
|
193
src/Corporation/ui/MakeProductModal.tsx
Normal file
193
src/Corporation/ui/MakeProductModal.tsx
Normal file
@ -0,0 +1,193 @@
|
||||
import React, { useState } from "react";
|
||||
import { dialogBoxCreate } from "../../ui/React/DialogBox";
|
||||
import { Modal } from "../../ui/React/Modal";
|
||||
import { Industries } from "../IndustryData";
|
||||
import { MakeProduct } from "../Actions";
|
||||
import { useCorporation, useDivision } from "./Context";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import Button from "@mui/material/Button";
|
||||
import MenuItem from "@mui/material/MenuItem";
|
||||
import Select, { SelectChangeEvent } from "@mui/material/Select";
|
||||
|
||||
interface IProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
function productPlaceholder(tpe: string): string {
|
||||
if (tpe === Industries.Food) {
|
||||
return "Restaurant Name";
|
||||
} else if (tpe === Industries.Healthcare) {
|
||||
return "Hospital Name";
|
||||
} else if (tpe === Industries.RealEstate) {
|
||||
return "Property Name";
|
||||
}
|
||||
return "Product Name";
|
||||
}
|
||||
|
||||
// Create a popup that lets the player create a product for their current industry
|
||||
export function MakeProductModal(props: IProps): React.ReactElement {
|
||||
const corp = useCorporation();
|
||||
const division = useDivision();
|
||||
const allCities = Object.keys(division.offices).filter((cityName: string) => division.offices[cityName] !== 0);
|
||||
const [city, setCity] = useState(allCities.length > 0 ? allCities[0] : "");
|
||||
const [name, setName] = useState("");
|
||||
const [design, setDesign] = useState<number | null>(null);
|
||||
const [marketing, setMarketing] = useState<number | null>(null);
|
||||
if (division.hasMaximumNumberProducts()) return <></>;
|
||||
|
||||
let createProductPopupText = <></>;
|
||||
switch (division.type) {
|
||||
case Industries.Food:
|
||||
createProductPopupText = (
|
||||
<>
|
||||
{createProductPopupText}
|
||||
<br />
|
||||
Build and manage a new restaurant!
|
||||
</>
|
||||
);
|
||||
break;
|
||||
case Industries.Tobacco:
|
||||
createProductPopupText = (
|
||||
<>
|
||||
{createProductPopupText}
|
||||
<br />
|
||||
Create a new tobacco product!
|
||||
</>
|
||||
);
|
||||
break;
|
||||
case Industries.Pharmaceutical:
|
||||
createProductPopupText = (
|
||||
<>
|
||||
{createProductPopupText}
|
||||
<br />
|
||||
Design and develop a new pharmaceutical drug!
|
||||
</>
|
||||
);
|
||||
break;
|
||||
case Industries.Computer:
|
||||
case "Computer":
|
||||
createProductPopupText = (
|
||||
<>
|
||||
{createProductPopupText}
|
||||
<br />
|
||||
Design and manufacture a new computer hardware product!
|
||||
</>
|
||||
);
|
||||
break;
|
||||
case Industries.Robotics:
|
||||
createProductPopupText = (
|
||||
<>
|
||||
{createProductPopupText}
|
||||
<br />
|
||||
Design and create a new robot or robotic system!
|
||||
</>
|
||||
);
|
||||
break;
|
||||
case Industries.Software:
|
||||
createProductPopupText = (
|
||||
<>
|
||||
{createProductPopupText}
|
||||
<br />
|
||||
Develop a new piece of software!
|
||||
</>
|
||||
);
|
||||
break;
|
||||
case Industries.Healthcare:
|
||||
createProductPopupText = (
|
||||
<>
|
||||
{createProductPopupText}
|
||||
<br />
|
||||
Build and manage a new hospital!
|
||||
</>
|
||||
);
|
||||
break;
|
||||
case Industries.RealEstate:
|
||||
createProductPopupText = (
|
||||
<>
|
||||
{createProductPopupText}
|
||||
<br />
|
||||
Develop a new piece of real estate property!
|
||||
</>
|
||||
);
|
||||
break;
|
||||
default:
|
||||
createProductPopupText = (
|
||||
<>
|
||||
{createProductPopupText}
|
||||
<br />
|
||||
Create a new product!
|
||||
</>
|
||||
);
|
||||
return <></>;
|
||||
}
|
||||
createProductPopupText = (
|
||||
<>
|
||||
{createProductPopupText}
|
||||
<br />
|
||||
<br />
|
||||
To begin developing a product, first choose the city in which it will be designed. The stats of your employees in
|
||||
the selected city affect the properties of the finished product, such as its quality, performance, and durability.
|
||||
<br />
|
||||
<br />
|
||||
You can also choose to invest money in the design and marketing of 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.
|
||||
</>
|
||||
);
|
||||
|
||||
function makeProduct(): void {
|
||||
if (design === null || marketing === null) return;
|
||||
try {
|
||||
MakeProduct(corp, division, city, name, design, marketing);
|
||||
} catch (err) {
|
||||
dialogBoxCreate(err + "");
|
||||
}
|
||||
props.onClose();
|
||||
}
|
||||
|
||||
function onCityChange(event: SelectChangeEvent<string>): void {
|
||||
setCity(event.target.value);
|
||||
}
|
||||
|
||||
function onProductNameChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||
setName(event.target.value);
|
||||
}
|
||||
|
||||
function onDesignChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||
if (event.target.value === "") setDesign(null);
|
||||
else setDesign(parseFloat(event.target.value));
|
||||
}
|
||||
|
||||
function onMarketingChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||
if (event.target.value === "") setMarketing(null);
|
||||
else setMarketing(parseFloat(event.target.value));
|
||||
}
|
||||
|
||||
function onKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {
|
||||
if (event.keyCode === 13) makeProduct();
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal open={props.open} onClose={props.onClose}>
|
||||
<Typography>{createProductPopupText}</Typography>
|
||||
<Select style={{ margin: "5px" }} onChange={onCityChange} defaultValue={city}>
|
||||
{allCities.map((cityName: string) => (
|
||||
<MenuItem key={cityName} value={cityName}>
|
||||
{cityName}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
<TextField onChange={onProductNameChange} placeholder={productPlaceholder(division.type)} />
|
||||
<br />
|
||||
<TextField onChange={onDesignChange} autoFocus={true} type="number" placeholder={"Design investment"} />
|
||||
<TextField
|
||||
onChange={onMarketingChange}
|
||||
onKeyDown={onKeyDown}
|
||||
type="number"
|
||||
placeholder={"Marketing investment"}
|
||||
/>
|
||||
<Button onClick={makeProduct}>Develop Product</Button>
|
||||
</Modal>
|
||||
);
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
import React, { useState } from "react";
|
||||
import { dialogBoxCreate } from "../../ui/React/DialogBox";
|
||||
import { removePopup } from "../../ui/React/createPopup";
|
||||
import { Industries } from "../IndustryData";
|
||||
import { ICorporation } from "../ICorporation";
|
||||
import { IIndustry } from "../IIndustry";
|
||||
import { MakeProduct } from "../Actions";
|
||||
|
||||
interface IProps {
|
||||
popupText: string;
|
||||
division: IIndustry;
|
||||
corp: ICorporation;
|
||||
popupId: string;
|
||||
}
|
||||
|
||||
function productPlaceholder(tpe: string): string {
|
||||
if (tpe === Industries.Food) {
|
||||
return "Restaurant Name";
|
||||
} else if (tpe === Industries.Healthcare) {
|
||||
return "Hospital Name";
|
||||
} else if (tpe === Industries.RealEstate) {
|
||||
return "Property Name";
|
||||
}
|
||||
return "Product Name";
|
||||
}
|
||||
|
||||
// Create a popup that lets the player create a product for their current industry
|
||||
export function MakeProductPopup(props: IProps): React.ReactElement {
|
||||
const allCities = Object.keys(props.division.offices).filter(
|
||||
(cityName: string) => props.division.offices[cityName] !== 0,
|
||||
);
|
||||
const [city, setCity] = useState(allCities.length > 0 ? allCities[0] : "");
|
||||
const [name, setName] = useState("");
|
||||
const [design, setDesign] = useState<number | null>(null);
|
||||
const [marketing, setMarketing] = useState<number | null>(null);
|
||||
if (props.division.hasMaximumNumberProducts()) return <></>;
|
||||
|
||||
function makeProduct(): void {
|
||||
if (design === null || marketing === null) return;
|
||||
try {
|
||||
MakeProduct(props.corp, props.division, city, name, design, marketing);
|
||||
} catch (err) {
|
||||
dialogBoxCreate(err + "");
|
||||
}
|
||||
removePopup(props.popupId);
|
||||
}
|
||||
|
||||
function onCityChange(event: React.ChangeEvent<HTMLSelectElement>): void {
|
||||
setCity(event.target.value);
|
||||
}
|
||||
|
||||
function onProductNameChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||
setName(event.target.value);
|
||||
}
|
||||
|
||||
function onDesignChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||
if (event.target.value === "") setDesign(null);
|
||||
else setDesign(parseFloat(event.target.value));
|
||||
}
|
||||
|
||||
function onMarketingChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||
if (event.target.value === "") setMarketing(null);
|
||||
else setMarketing(parseFloat(event.target.value));
|
||||
}
|
||||
|
||||
function onKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {
|
||||
if (event.keyCode === 13) makeProduct();
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<p dangerouslySetInnerHTML={{ __html: props.popupText }} />
|
||||
<select className="dropdown" style={{ margin: "5px" }} onChange={onCityChange} defaultValue={city}>
|
||||
{allCities.map((cityName: string) => (
|
||||
<option key={cityName} value={cityName}>
|
||||
{cityName}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<input
|
||||
onChange={onProductNameChange}
|
||||
className="text-input"
|
||||
style={{ margin: "5px" }}
|
||||
placeholder={productPlaceholder(props.division.type)}
|
||||
/>
|
||||
<br />
|
||||
<input
|
||||
onChange={onDesignChange}
|
||||
autoFocus={true}
|
||||
type="number"
|
||||
className="text-input"
|
||||
style={{ margin: "5px" }}
|
||||
placeholder={"Design investment"}
|
||||
/>
|
||||
<input
|
||||
onChange={onMarketingChange}
|
||||
onKeyDown={onKeyDown}
|
||||
type="number"
|
||||
className="text-input"
|
||||
style={{ margin: "5px" }}
|
||||
placeholder={"Marketing investment"}
|
||||
/>
|
||||
<button className="std-button" onClick={makeProduct}>
|
||||
Develop Product
|
||||
</button>
|
||||
</>
|
||||
);
|
||||
}
|
@ -6,6 +6,7 @@ import { CorporationConstants } from "../data/Constants";
|
||||
import { Treant } from "treant-js";
|
||||
import { IIndustry } from "../IIndustry";
|
||||
import { Research } from "../Actions";
|
||||
import Typography from "@mui/material/Typography";
|
||||
|
||||
interface IProps {
|
||||
industry: IIndustry;
|
||||
|
@ -1,12 +1,14 @@
|
||||
import React, { useState } from "react";
|
||||
|
||||
import { Warehouse } from "../Warehouse";
|
||||
import { ICorporation } from "../ICorporation";
|
||||
import { IIndustry } from "../IIndustry";
|
||||
import { SetSmartSupply, SetSmartSupplyUseLeftovers } from "../Actions";
|
||||
import { IPlayer } from "../../PersonObjects/IPlayer";
|
||||
import { Material } from "../Material";
|
||||
import { dialogBoxCreate } from "../../ui/React/DialogBox";
|
||||
import { Modal } from "../../ui/React/Modal";
|
||||
import { useDivision } from "./Context";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import FormControlLabel from "@mui/material/FormControlLabel";
|
||||
import Switch from "@mui/material/Switch";
|
||||
|
||||
interface ILeftoverProps {
|
||||
matName: string;
|
||||
@ -26,33 +28,31 @@ function Leftover(props: ILeftoverProps): React.ReactElement {
|
||||
setChecked(event.target.checked);
|
||||
}
|
||||
|
||||
const matNameId = `${props.matName}-use-leftovers`;
|
||||
return (
|
||||
<div key={props.matName}>
|
||||
<label style={{ color: "white" }} htmlFor={matNameId}>
|
||||
{props.warehouse.materials[props.matName].name}
|
||||
</label>
|
||||
<input type={"checkbox"} id={matNameId} onChange={onChange} style={{ margin: "3px" }} checked={checked} />
|
||||
<>
|
||||
<FormControlLabel
|
||||
control={<Switch checked={checked} onChange={onChange} />}
|
||||
label={<Typography>{props.warehouse.materials[props.matName].name}</Typography>}
|
||||
/>
|
||||
<br />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
interface IProps {
|
||||
division: IIndustry;
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
warehouse: Warehouse;
|
||||
corp: ICorporation;
|
||||
player: IPlayer;
|
||||
popupId: string;
|
||||
}
|
||||
|
||||
export function SmartSupplyPopup(props: IProps): React.ReactElement {
|
||||
export function SmartSupplyModal(props: IProps): React.ReactElement {
|
||||
const division = useDivision();
|
||||
const setRerender = useState(false)[1];
|
||||
function rerender(): void {
|
||||
setRerender((old) => !old);
|
||||
}
|
||||
|
||||
// Smart Supply Checkbox
|
||||
const smartSupplyCheckboxId = "cmpy-mgmt-smart-supply-checkbox";
|
||||
function smartSupplyOnChange(e: React.ChangeEvent<HTMLInputElement>): void {
|
||||
SetSmartSupply(props.warehouse, e.target.checked);
|
||||
rerender();
|
||||
@ -62,25 +62,21 @@ export function SmartSupplyPopup(props: IProps): React.ReactElement {
|
||||
const mats = [];
|
||||
for (const matName in props.warehouse.materials) {
|
||||
if (!(props.warehouse.materials[matName] instanceof Material)) continue;
|
||||
if (!Object.keys(props.division.reqMats).includes(matName)) continue;
|
||||
if (!Object.keys(division.reqMats).includes(matName)) continue;
|
||||
mats.push(<Leftover key={matName} warehouse={props.warehouse} matName={matName} />);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<label style={{ color: "white" }} htmlFor={smartSupplyCheckboxId}>
|
||||
Enable Smart Supply
|
||||
</label>
|
||||
<input
|
||||
type={"checkbox"}
|
||||
id={smartSupplyCheckboxId}
|
||||
onChange={smartSupplyOnChange}
|
||||
style={{ margin: "3px" }}
|
||||
checked={props.warehouse.smartSupplyEnabled}
|
||||
/>
|
||||
<br />
|
||||
<p>Use materials already in the warehouse instead of buying new ones, if available:</p>
|
||||
{mats}
|
||||
</>
|
||||
<Modal open={props.open} onClose={props.onClose}>
|
||||
<>
|
||||
<FormControlLabel
|
||||
control={<Switch checked={props.warehouse.smartSupplyEnabled} onChange={smartSupplyOnChange} />}
|
||||
label={<Typography>Enable Smart Supply</Typography>}
|
||||
/>
|
||||
<br />
|
||||
<Typography>Use materials already in the warehouse instead of buying new ones, if available:</Typography>
|
||||
{mats}
|
||||
</>
|
||||
</Modal>
|
||||
);
|
||||
}
|
16
src/ui/React/StaticModal.tsx
Normal file
16
src/ui/React/StaticModal.tsx
Normal file
@ -0,0 +1,16 @@
|
||||
import React from "react";
|
||||
import { Modal } from "./Modal";
|
||||
|
||||
interface IProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
children: JSX.Element[] | JSX.Element | React.ReactElement[] | React.ReactElement;
|
||||
}
|
||||
|
||||
export function StaticModal(props: IProps): React.ReactElement {
|
||||
return (
|
||||
<Modal open={props.open} onClose={props.onClose}>
|
||||
{props.children}
|
||||
</Modal>
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue
Block a user