Added more complex customization to smart supply

This commit is contained in:
Olivier Gagnon 2021-09-07 16:46:36 -04:00
parent ea99166f7f
commit bc034bb417
10 changed files with 205 additions and 66 deletions

File diff suppressed because one or more lines are too long

@ -1,2 +1,2 @@
!function(n){function t(t){for(var e,i,f=t[0],c=t[1],l=t[2],a=0,s=[];a<f.length;a++)i=f[a],Object.prototype.hasOwnProperty.call(u,i)&&u[i]&&s.push(u[i][0]),u[i]=0;for(e in c)Object.prototype.hasOwnProperty.call(c,e)&&(n[e]=c[e]);for(p&&p(t);s.length;)s.shift()();return r.push.apply(r,l||[]),o()}function o(){for(var n,t=0;t<r.length;t++){for(var o=r[t],e=!0,f=1;f<o.length;f++){var c=o[f];0!==u[c]&&(e=!1)}e&&(r.splice(t--,1),n=i(i.s=o[0]))}return n}var e={},u={2:0},r=[];function i(t){if(e[t])return e[t].exports;var o=e[t]={i:t,l:!1,exports:{}};return n[t].call(o.exports,o,o.exports,i),o.l=!0,o.exports}i.m=n,i.c=e,i.d=function(n,t,o){i.o(n,t)||Object.defineProperty(n,t,{enumerable:!0,get:o})},i.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},i.t=function(n,t){if(1&t&&(n=i(n)),8&t)return n;if(4&t&&"object"==typeof n&&n&&n.__esModule)return n;var o=Object.create(null);if(i.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:n}),2&t&&"string"!=typeof n)for(var e in n)i.d(o,e,function(t){return n[t]}.bind(null,e));return o},i.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return i.d(t,"a",t),t},i.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},i.p="";var f=window.webpackJsonp=window.webpackJsonp||[],c=f.push.bind(f);f.push=t,f=f.slice();for(var l=0;l<f.length;l++)t(f[l]);var p=c;r.push([900,0]),o()}({900:function(n,t,o){"use strict";o.r(t);o(901),o(903),o(905),o(907),o(909),o(911),o(913),o(915),o(917),o(919),o(921),o(923),o(925),o(927),o(929),o(931),o(933),o(935),o(937),o(939),o(941),o(943),o(945),o(947),o(949),o(951),o(953),o(955),o(957),o(959),o(961),o(963)},903:function(n,t,o){},905:function(n,t,o){},907:function(n,t,o){},909:function(n,t,o){},911:function(n,t,o){},913:function(n,t,o){},915:function(n,t,o){},917:function(n,t,o){},919:function(n,t,o){},921:function(n,t,o){},923:function(n,t,o){},925:function(n,t,o){},927:function(n,t,o){},929:function(n,t,o){},931:function(n,t,o){},933:function(n,t,o){},935:function(n,t,o){},937:function(n,t,o){},939:function(n,t,o){},941:function(n,t,o){},943:function(n,t,o){},945:function(n,t,o){},947:function(n,t,o){},949:function(n,t,o){},951:function(n,t,o){},953:function(n,t,o){},955:function(n,t,o){},957:function(n,t,o){},959:function(n,t,o){},961:function(n,t,o){},963:function(n,t,o){}}); !function(n){function t(t){for(var e,i,f=t[0],c=t[1],l=t[2],a=0,s=[];a<f.length;a++)i=f[a],Object.prototype.hasOwnProperty.call(u,i)&&u[i]&&s.push(u[i][0]),u[i]=0;for(e in c)Object.prototype.hasOwnProperty.call(c,e)&&(n[e]=c[e]);for(p&&p(t);s.length;)s.shift()();return r.push.apply(r,l||[]),o()}function o(){for(var n,t=0;t<r.length;t++){for(var o=r[t],e=!0,f=1;f<o.length;f++){var c=o[f];0!==u[c]&&(e=!1)}e&&(r.splice(t--,1),n=i(i.s=o[0]))}return n}var e={},u={2:0},r=[];function i(t){if(e[t])return e[t].exports;var o=e[t]={i:t,l:!1,exports:{}};return n[t].call(o.exports,o,o.exports,i),o.l=!0,o.exports}i.m=n,i.c=e,i.d=function(n,t,o){i.o(n,t)||Object.defineProperty(n,t,{enumerable:!0,get:o})},i.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},i.t=function(n,t){if(1&t&&(n=i(n)),8&t)return n;if(4&t&&"object"==typeof n&&n&&n.__esModule)return n;var o=Object.create(null);if(i.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:n}),2&t&&"string"!=typeof n)for(var e in n)i.d(o,e,function(t){return n[t]}.bind(null,e));return o},i.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return i.d(t,"a",t),t},i.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},i.p="";var f=window.webpackJsonp=window.webpackJsonp||[],c=f.push.bind(f);f.push=t,f=f.slice();for(var l=0;l<f.length;l++)t(f[l]);var p=c;r.push([902,0]),o()}({902:function(n,t,o){"use strict";o.r(t);o(903),o(905),o(907),o(909),o(911),o(913),o(915),o(917),o(919),o(921),o(923),o(925),o(927),o(929),o(931),o(933),o(935),o(937),o(939),o(941),o(943),o(945),o(947),o(949),o(951),o(953),o(955),o(957),o(959),o(961),o(963),o(965)},905:function(n,t,o){},907:function(n,t,o){},909:function(n,t,o){},911:function(n,t,o){},913:function(n,t,o){},915:function(n,t,o){},917:function(n,t,o){},919:function(n,t,o){},921:function(n,t,o){},923:function(n,t,o){},925:function(n,t,o){},927:function(n,t,o){},929:function(n,t,o){},931:function(n,t,o){},933:function(n,t,o){},935:function(n,t,o){},937:function(n,t,o){},939:function(n,t,o){},941:function(n,t,o){},943:function(n,t,o){},945:function(n,t,o){},947:function(n,t,o){},949:function(n,t,o){},951:function(n,t,o){},953:function(n,t,o){},955:function(n,t,o){},957:function(n,t,o){},959:function(n,t,o){},961:function(n,t,o){},963:function(n,t,o){},965:function(n,t,o){}});
//# sourceMappingURL=engineStyle.bundle.js.map //# sourceMappingURL=engineStyle.bundle.js.map

30
dist/vendor.bundle.js vendored

File diff suppressed because one or more lines are too long

@ -685,8 +685,9 @@ export class Industry implements IIndustry {
} }
} }
// Use the materials already in the warehouse. // Use the materials already in the warehouse if the option is on.
for (const matName in smartBuy) { for (const matName in smartBuy) {
if (!warehouse.smartSupplyUseLeftovers[matName]) continue;
const mat = warehouse.materials[matName]; const mat = warehouse.materials[matName];
const buyAmt = smartBuy[matName]; const buyAmt = smartBuy[matName];
if (buyAmt === undefined) if (buyAmt === undefined)

@ -41,6 +41,9 @@ export class Warehouse {
// Whether Smart Supply is enabled for this Industry (the Industry that this Warehouse is for) // Whether Smart Supply is enabled for this Industry (the Industry that this Warehouse is for)
smartSupplyEnabled = false; smartSupplyEnabled = false;
// Decide if smart supply should use the materials already in the warehouse when deciding on the amount to buy.
smartSupplyUseLeftovers: { [key: string]: boolean | undefined } = {};
// Stores the amount of product to be produced. Used for Smart Supply unlock. // Stores the amount of product to be produced. Used for Smart Supply unlock.
// The production tracked by smart supply is always based on the previous cycle, // The production tracked by smart supply is always based on the previous cycle,
// so it will always trail the "true" production by 1 cycle // so it will always trail the "true" production by 1 cycle
@ -64,6 +67,20 @@ export class Warehouse {
RealEstate: new Material({ name: "Real Estate" }), RealEstate: new Material({ name: "Real Estate" }),
}; };
this.smartSupplyUseLeftovers = {
Water: true,
Energy: true,
Food: true,
Plants: true,
Metal: true,
Hardware: true,
Chemicals: true,
Drugs: true,
Robots: true,
AICores: true,
RealEstate: true,
};
if (params.corp && params.industry) { if (params.corp && params.industry) {
this.updateSize(params.corp, params.industry); this.updateSize(params.corp, params.industry);
} }

@ -30,6 +30,7 @@ export const CorporationConstants: {
EmployeeRaiseAmount: number; EmployeeRaiseAmount: number;
BaseMaxProducts: number; BaseMaxProducts: number;
AllCorporationStates: string[]; AllCorporationStates: string[];
AllMaterials: string[];
} = { } = {
INITIALSHARES: 1e9, //Total number of shares you have at your company INITIALSHARES: 1e9, //Total number of shares you have at your company
SHARESPERPRICEUPDATE: 1e6, //When selling large number of shares, price is dynamically updated for every batch of this amount SHARESPERPRICEUPDATE: 1e6, //When selling large number of shares, price is dynamically updated for every batch of this amount
@ -71,4 +72,17 @@ export const CorporationConstants: {
BaseMaxProducts: 3, // Initial value for maximum number of products allowed BaseMaxProducts: 3, // Initial value for maximum number of products allowed
AllCorporationStates: AllCorporationStates, AllCorporationStates: AllCorporationStates,
AllMaterials: [
"Water",
"Energy",
"Food",
"Plants",
"Metal",
"Hardware",
"Chemicals",
"Drugs",
"Robots",
"AI Cores",
"Real Estate",
],
}; };

@ -46,7 +46,6 @@ export function ExportPopup(props: IProps): React.ReactElement {
function exportMaterial(): void { function exportMaterial(): void {
const industryName = industry; const industryName = industry;
const cityName = city; const cityName = city;
console.log(`${industryName}, ${cityName}, ${amt}`);
// Sanitize amt // Sanitize amt
let sanitizedAmt = amt.replace(/\s+/g, ""); let sanitizedAmt = amt.replace(/\s+/g, "");
@ -66,7 +65,6 @@ export function ExportPopup(props: IProps): React.ReactElement {
return; return;
} }
const exportObj = { ind: industryName, city: cityName, amt: sanitizedAmt }; const exportObj = { ind: industryName, city: cityName, amt: sanitizedAmt };
console.log(exportObj);
props.mat.exp.push(exportObj); props.mat.exp.push(exportObj);
removePopup(props.popupId); removePopup(props.popupId);
} }

@ -0,0 +1,23 @@
import { IIndustry } from "../IIndustry";
// Returns a boolean indicating whether the given material is relevant for the
// current industry.
export function isRelevantMaterial(
matName: string,
division: IIndustry,
): boolean {
// Materials that affect Production multiplier
const prodMultiplierMats = ["Hardware", "Robots", "AICores", "RealEstate"];
if (Object.keys(division.reqMats).includes(matName)) {
return true;
}
if (division.prodMats.includes(matName)) {
return true;
}
if (prodMultiplierMats.includes(matName)) {
return true;
}
return false;
}

@ -15,6 +15,7 @@ import { SellMaterialPopup } from "./SellMaterialPopup";
import { SellProductPopup } from "./SellProductPopup"; import { SellProductPopup } from "./SellProductPopup";
import { PurchaseMaterialPopup } from "./PurchaseMaterialPopup"; import { PurchaseMaterialPopup } from "./PurchaseMaterialPopup";
import { ProductMarketTaPopup } from "./ProductMarketTaPopup"; import { ProductMarketTaPopup } from "./ProductMarketTaPopup";
import { SmartSupplyPopup } from "./SmartSupplyPopup";
import { numeralWrapper } from "../../ui/numeralFormat"; import { numeralWrapper } from "../../ui/numeralFormat";
import { dialogBoxCreate } from "../../../utils/DialogBox"; import { dialogBoxCreate } from "../../../utils/DialogBox";
@ -24,9 +25,9 @@ import { isString } from "../../../utils/helpers/isString";
import { ICorporation } from "../ICorporation"; import { ICorporation } from "../ICorporation";
import { IIndustry } from "../IIndustry"; import { IIndustry } from "../IIndustry";
import { IPlayer } from "../../PersonObjects/IPlayer"; import { IPlayer } from "../../PersonObjects/IPlayer";
import { SetSmartSupply } from "../Actions";
import { Money } from "../../ui/React/Money"; import { Money } from "../../ui/React/Money";
import { MoneyCost } from "./MoneyCost"; import { MoneyCost } from "./MoneyCost";
import { isRelevantMaterial } from "./Helpers";
interface IProductProps { interface IProductProps {
corp: ICorporation; corp: ICorporation;
@ -88,11 +89,23 @@ function ProductComponent(props: IProductProps): React.ReactElement {
</> </>
); );
} else if (product.sCost) { } else if (product.sCost) {
sellButtonText = ( if (isString(product.sCost)) {
<> const sCost = (product.sCost as string).replace(
{sellButtonText} @ <Money money={product.sCost} /> /MP/g,
</> product.pCost + "",
); );
sellButtonText = (
<>
{sellButtonText} @ <Money money={eval(sCost)} />
</>
);
} else {
sellButtonText = (
<>
{sellButtonText} @ <Money money={product.sCost} />
</>
);
}
} }
function openSellProductPopup(): void { function openSellProductPopup(): void {
@ -473,25 +486,6 @@ interface IProps {
} }
export function IndustryWarehouse(props: IProps): React.ReactElement { export function IndustryWarehouse(props: IProps): React.ReactElement {
// Returns a boolean indicating whether the given material is relevant for the
// current industry.
function isRelevantMaterial(matName: string, division: IIndustry): boolean {
// Materials that affect Production multiplier
const prodMultiplierMats = ["Hardware", "Robots", "AICores", "RealEstate"];
if (Object.keys(division.reqMats).includes(matName)) {
return true;
}
if (division.prodMats.includes(matName)) {
return true;
}
if (prodMultiplierMats.includes(matName)) {
return true;
}
return false;
}
function renderWarehouseUI(): React.ReactElement { function renderWarehouseUI(): React.ReactElement {
if (props.warehouse === 0) return <></>; if (props.warehouse === 0) return <></>;
// General Storage information at the top // General Storage information at the top
@ -517,6 +511,18 @@ export function IndustryWarehouse(props: IProps): React.ReactElement {
props.corp.rerender(props.player); props.corp.rerender(props.player);
} }
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,
});
}
// Industry material Requirements // Industry material Requirements
let generalReqsText = let generalReqsText =
"This Industry uses [" + "This Industry uses [" +
@ -580,14 +586,6 @@ export function IndustryWarehouse(props: IProps): React.ReactElement {
break; break;
} }
// Smart Supply Checkbox
const smartSupplyCheckboxId = "cmpy-mgmt-smart-supply-checkbox";
function smartSupplyOnChange(e: React.ChangeEvent<HTMLInputElement>): void {
if (props.warehouse === 0) return;
SetSmartSupply(props.warehouse, e.target.checked);
props.corp.rerender(props.player);
}
// Create React components for materials // Create React components for materials
const mats = []; const mats = [];
for (const matName in props.warehouse.materials) { for (const matName in props.warehouse.materials) {
@ -664,18 +662,11 @@ export function IndustryWarehouse(props: IProps): React.ReactElement {
<p>{stateText}</p> <p>{stateText}</p>
{props.corp.unlockUpgrades[1] && ( {props.corp.unlockUpgrades[1] && (
<div> <>
<label style={{ color: "white" }} htmlFor={smartSupplyCheckboxId}> <button className="std-button" onClick={openSmartSupplyPopup}>
Enable Smart Supply Configure Smart Supply
</label> </button>
<input </>
type={"checkbox"}
id={smartSupplyCheckboxId}
onChange={smartSupplyOnChange}
style={{ margin: "3px" }}
checked={props.warehouse.smartSupplyEnabled}
/>
</div>
)} )}
{mats} {mats}

@ -0,0 +1,95 @@
import React, { useState } from "react";
import { Warehouse } from "../Warehouse";
import { ICorporation } from "../ICorporation";
import { IIndustry } from "../IIndustry";
import { SetSmartSupply } from "../Actions";
import { IPlayer } from "../../PersonObjects/IPlayer";
import { isRelevantMaterial } from "./Helpers";
import { Material } from "../Material";
interface ILeftoverProps {
matName: string;
warehouse: Warehouse;
}
function Leftover(props: ILeftoverProps): React.ReactElement {
const [checked, setChecked] = useState(
!!props.warehouse.smartSupplyUseLeftovers[props.matName],
);
function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
props.warehouse.smartSupplyUseLeftovers[props.matName] =
event.target.checked;
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}
/>
<br />
</div>
);
}
interface IProps {
division: IIndustry;
warehouse: Warehouse;
corp: ICorporation;
player: IPlayer;
popupId: string;
}
export function SmartSupplyPopup(props: IProps): React.ReactElement {
const setRerender = useState(false)[1];
function rerender() {
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();
}
// Create React components for materials
const mats = [];
for (const matName in props.warehouse.materials) {
if (!(props.warehouse.materials[matName] instanceof Material)) continue;
if (!isRelevantMaterial(matName, props.division)) 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}
</>
);
}