mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-29 19:13:49 +01:00
Finished converting all the popups.
This commit is contained in:
parent
3ba04220e1
commit
cf72d72bb0
@ -47,7 +47,6 @@ import { yesNoBoxCreate,
|
|||||||
// UI Related Imports
|
// UI Related Imports
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
import { CorporationEventHandler } from "./ui/CorporationUIEventHandler";
|
|
||||||
import { CorporationRoot } from "./ui/Root";
|
import { CorporationRoot } from "./ui/Root";
|
||||||
import { CorporationRouting } from "./ui/Routing";
|
import { CorporationRouting } from "./ui/Routing";
|
||||||
|
|
||||||
@ -1884,7 +1883,6 @@ Corporation.prototype.getStarterGuide = function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let corpRouting;
|
let corpRouting;
|
||||||
let eventHandler;
|
|
||||||
let companyManagementDiv;
|
let companyManagementDiv;
|
||||||
Corporation.prototype.createUI = function() {
|
Corporation.prototype.createUI = function() {
|
||||||
companyManagementDiv = createElement("div", {
|
companyManagementDiv = createElement("div", {
|
||||||
@ -1895,13 +1893,12 @@ Corporation.prototype.createUI = function() {
|
|||||||
document.getElementById("entire-game-container").appendChild(companyManagementDiv);
|
document.getElementById("entire-game-container").appendChild(companyManagementDiv);
|
||||||
|
|
||||||
corpRouting = new CorporationRouting(this);
|
corpRouting = new CorporationRouting(this);
|
||||||
eventHandler = new CorporationEventHandler(this, corpRouting);
|
|
||||||
|
|
||||||
this.rerender();
|
this.rerender();
|
||||||
}
|
}
|
||||||
|
|
||||||
Corporation.prototype.rerender = function() {
|
Corporation.prototype.rerender = function() {
|
||||||
if (companyManagementDiv == null || corpRouting == null || eventHandler == null) {
|
if (companyManagementDiv == null || corpRouting == null) {
|
||||||
console.warn(`Corporation.rerender() called when companyManagementDiv, corpRouting, or eventHandler is null`);
|
console.warn(`Corporation.rerender() called when companyManagementDiv, corpRouting, or eventHandler is null`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1910,7 +1907,6 @@ Corporation.prototype.rerender = function() {
|
|||||||
ReactDOM.render(<CorporationRoot
|
ReactDOM.render(<CorporationRoot
|
||||||
corp={this}
|
corp={this}
|
||||||
routing={corpRouting}
|
routing={corpRouting}
|
||||||
eventHandler={eventHandler}
|
|
||||||
player={Player}
|
player={Player}
|
||||||
/>, companyManagementDiv);
|
/>, companyManagementDiv);
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ import { createPopup } from "../../ui/React/createPopup";
|
|||||||
import { IDivision } from "../IDivision";
|
import { IDivision } from "../IDivision";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
eventHandler: any;
|
|
||||||
routing: any;
|
routing: any;
|
||||||
onClicks: {[key: string]: () => void};
|
onClicks: {[key: string]: () => void};
|
||||||
city: string; // currentCity
|
city: string; // currentCity
|
||||||
|
@ -1,578 +0,0 @@
|
|||||||
// Creates a class for handling UI events, such as clicks and keyboard events
|
|
||||||
import { CorporationRouting } from "./Routing";
|
|
||||||
import { Corporation,
|
|
||||||
Industry,
|
|
||||||
Warehouse,
|
|
||||||
DividendMaxPercentage,
|
|
||||||
IssueNewSharesCooldown } from "../Corporation";
|
|
||||||
import { OfficeSpace } from "../OfficeSpace";
|
|
||||||
|
|
||||||
import { Industries,
|
|
||||||
IndustryStartingCosts,
|
|
||||||
IndustryDescriptions,
|
|
||||||
} from "../IndustryData";
|
|
||||||
|
|
||||||
import { MaterialSizes } from "../MaterialSizes";
|
|
||||||
|
|
||||||
import { Product } from "../Product";
|
|
||||||
|
|
||||||
import { Cities } from "../../Locations/Cities";
|
|
||||||
|
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
|
||||||
|
|
||||||
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
|
||||||
|
|
||||||
import { getRandomInt } from "../../../utils/helpers/getRandomInt";
|
|
||||||
import { KEY } from "../../../utils/helpers/keyCodes";
|
|
||||||
|
|
||||||
import { clearSelector } from "../../../utils/uiHelpers/clearSelector";
|
|
||||||
import { createElement } from "../../../utils/uiHelpers/createElement";
|
|
||||||
import { createOptionElement } from "../../../utils/uiHelpers/createOptionElement";
|
|
||||||
import { createPopup } from "../../../utils/uiHelpers/createPopup";
|
|
||||||
import { createPopupCloseButton } from "../../../utils/uiHelpers/createPopupCloseButton";
|
|
||||||
import { getSelectText,
|
|
||||||
getSelectValue } from "../../../utils/uiHelpers/getSelectData";
|
|
||||||
import { removeElementById } from "../../../utils/uiHelpers/removeElementById";
|
|
||||||
|
|
||||||
export class CorporationEventHandler {
|
|
||||||
constructor(corp, routing) {
|
|
||||||
if (!(corp instanceof Corporation)) {
|
|
||||||
throw new Error(`CorporationEventHandler constructed without proper Corporation instance`);
|
|
||||||
}
|
|
||||||
if (!(routing instanceof CorporationRouting)) {
|
|
||||||
throw new Error(`CorporationEventHandler constructed without proper CorporationRouting instance`);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.corp = corp;
|
|
||||||
this.routing = routing;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a popup that lets the player use the Market TA research for Products
|
|
||||||
createProductMarketTaPopup(product, industry) {
|
|
||||||
const popupId = "cmpy-mgmt-marketta-popup";
|
|
||||||
const markupLimit = product.rat / product.mku;
|
|
||||||
const ta1 = createElement("p", {
|
|
||||||
innerHTML: "<u><strong>Market-TA.I</strong></u><br>" +
|
|
||||||
"The maximum sale price you can mark this up to is " +
|
|
||||||
numeralWrapper.formatMoney(product.pCost + markupLimit) +
|
|
||||||
". This means that if you set the sale price higher than this, " +
|
|
||||||
"you will begin to experience a loss in number of sales",
|
|
||||||
});
|
|
||||||
|
|
||||||
// Enable using Market-TA1 for automatically setting sale price
|
|
||||||
const useTa1AutoSaleId = "cmpy-mgmt-marketa1-checkbox";
|
|
||||||
const useTa1AutoSaleDiv = createElement("div", { display: "block" });
|
|
||||||
const useTa1AutoSaleLabel = createElement("label", {
|
|
||||||
color: "white",
|
|
||||||
for: useTa1AutoSaleId,
|
|
||||||
innerText: "Use Market-TA.I for Auto-Sale Price",
|
|
||||||
tooltip: "If this is enabled, then this Product will automatically " +
|
|
||||||
"be sold at the price identified by Market-TA.I (i.e. the price shown above)",
|
|
||||||
})
|
|
||||||
const useTa1AutoSaleCheckbox = createElement("input", {
|
|
||||||
checked: product.marketTa1,
|
|
||||||
id: useTa1AutoSaleId,
|
|
||||||
margin: "3px",
|
|
||||||
type: "checkbox",
|
|
||||||
changeListener: (e) => {
|
|
||||||
product.marketTa1 = e.target.checked;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
useTa1AutoSaleDiv.appendChild(useTa1AutoSaleLabel);
|
|
||||||
useTa1AutoSaleDiv.appendChild(useTa1AutoSaleCheckbox);
|
|
||||||
|
|
||||||
const closeBtn = createPopupCloseButton(popupId, {
|
|
||||||
class: "std-button",
|
|
||||||
display: "block",
|
|
||||||
innerText: "Close",
|
|
||||||
});
|
|
||||||
|
|
||||||
if (industry.hasResearch("Market-TA.II")) {
|
|
||||||
let updateTa2Text;
|
|
||||||
const ta2Text = createElement("p");
|
|
||||||
const ta2Input = createElement("input", {
|
|
||||||
marginTop: "4px",
|
|
||||||
onkeyup: (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
updateTa2Text();
|
|
||||||
},
|
|
||||||
type: "number",
|
|
||||||
value: product.pCost,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Function that updates the text in ta2Text element
|
|
||||||
updateTa2Text = function() {
|
|
||||||
const sCost = parseFloat(ta2Input.value);
|
|
||||||
let markup = 1;
|
|
||||||
if (sCost > product.pCost) {
|
|
||||||
if ((sCost - product.pCost) > markupLimit) {
|
|
||||||
markup = markupLimit / (sCost - product.pCost);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ta2Text.innerHTML = `<br><u><strong>Market-TA.II</strong></u><br>` +
|
|
||||||
`If you sell at ${numeralWrapper.formatMoney(sCost)}, ` +
|
|
||||||
`then you will sell ${numeralWrapper.format(markup, "0.00000")}x as much compared ` +
|
|
||||||
`to if you sold at market price.`;
|
|
||||||
}
|
|
||||||
updateTa2Text();
|
|
||||||
|
|
||||||
// Enable using Market-TA2 for automatically setting sale price
|
|
||||||
const useTa2AutoSaleId = "cmpy-mgmt-marketa2-checkbox";
|
|
||||||
const useTa2AutoSaleDiv = createElement("div", { display: "block" });
|
|
||||||
const useTa2AutoSaleLabel = createElement("label", {
|
|
||||||
color: "white",
|
|
||||||
for: useTa2AutoSaleId,
|
|
||||||
innerText: "Use Market-TA.II for Auto-Sale Price",
|
|
||||||
tooltip: "If this is enabled, then this Product will automatically " +
|
|
||||||
"be sold at the optimal price such that the amount sold matches the " +
|
|
||||||
"amount produced. (i.e. the highest possible price, while still ensuring " +
|
|
||||||
" that all produced materials will be sold)",
|
|
||||||
})
|
|
||||||
const useTa2AutoSaleCheckbox = createElement("input", {
|
|
||||||
checked: product.marketTa2,
|
|
||||||
id: useTa2AutoSaleId,
|
|
||||||
margin: "3px",
|
|
||||||
type: "checkbox",
|
|
||||||
changeListener: (e) => {
|
|
||||||
product.marketTa2 = e.target.checked;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
useTa2AutoSaleDiv.appendChild(useTa2AutoSaleLabel);
|
|
||||||
useTa2AutoSaleDiv.appendChild(useTa2AutoSaleCheckbox);
|
|
||||||
|
|
||||||
const ta2OverridesTa1 = createElement("p", {
|
|
||||||
innerText: "Note that Market-TA.II overrides Market-TA.I. This means that if " +
|
|
||||||
"both are enabled, then Market-TA.II will take effect, not Market-TA.I",
|
|
||||||
});
|
|
||||||
|
|
||||||
createPopup(popupId, [ta1, useTa1AutoSaleDiv, ta2Text, ta2Input, useTa2AutoSaleDiv, ta2OverridesTa1, closeBtn]);
|
|
||||||
} else {
|
|
||||||
// Market-TA.I only
|
|
||||||
createPopup(popupId, [ta1, useTa1AutoSaleDiv, closeBtn]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a popup that lets the player purchase a Material
|
|
||||||
createPurchaseMaterialPopup(mat, industry, warehouse) {
|
|
||||||
const corp = this.corp;
|
|
||||||
|
|
||||||
const purchasePopupId = "cmpy-mgmt-material-purchase-popup";
|
|
||||||
const txt = createElement("p", {
|
|
||||||
innerHTML: "Enter the amount of " + mat.name + " you would like " +
|
|
||||||
"to purchase per second. This material's cost changes constantly",
|
|
||||||
});
|
|
||||||
let confirmBtn;
|
|
||||||
let input = createElement("input", {
|
|
||||||
margin: "5px",
|
|
||||||
placeholder: "Purchase amount",
|
|
||||||
type: "number",
|
|
||||||
value: mat.buy ? mat.buy : null,
|
|
||||||
onkeyup: (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
if (e.keyCode === KEY.ENTER) {confirmBtn.click();}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
confirmBtn = createElement("button", {
|
|
||||||
innerText: "Confirm", class: "std-button",
|
|
||||||
clickListener: () => {
|
|
||||||
if (isNaN(input.value)) {
|
|
||||||
dialogBoxCreate("Invalid amount");
|
|
||||||
} else {
|
|
||||||
mat.buy = parseFloat(input.value);
|
|
||||||
if (isNaN(mat.buy)) {mat.buy = 0;}
|
|
||||||
removeElementById(purchasePopupId);
|
|
||||||
this.rerender();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const clearButton = createElement("button", {
|
|
||||||
innerText: "Clear Purchase", class: "std-button",
|
|
||||||
clickListener: () => {
|
|
||||||
mat.buy = 0;
|
|
||||||
removeElementById(purchasePopupId);
|
|
||||||
this.rerender();
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const cancelBtn = createPopupCloseButton(purchasePopupId, {
|
|
||||||
class: "std-button",
|
|
||||||
innerText: "Cancel",
|
|
||||||
});
|
|
||||||
|
|
||||||
const elems = [txt, input, confirmBtn, clearButton, cancelBtn];
|
|
||||||
|
|
||||||
if (industry.hasResearch("Bulk Purchasing")) {
|
|
||||||
const bulkPurchaseInfo = createElement("p", {
|
|
||||||
innerText: "Enter the amount of " + mat.name + " you would like " +
|
|
||||||
"to bulk purchase. This purchases the specified amount instantly " +
|
|
||||||
"(all at once).",
|
|
||||||
});
|
|
||||||
|
|
||||||
let bulkPurchaseCostTxt = createElement("p");
|
|
||||||
function updateBulkPurchaseText(amount) {
|
|
||||||
const parsedAmt = parseFloat(amount);
|
|
||||||
const cost = parsedAmt * mat.bCost;
|
|
||||||
|
|
||||||
const matSize = MaterialSizes[mat.name];
|
|
||||||
const maxAmount = ((warehouse.size - warehouse.sizeUsed) / matSize);
|
|
||||||
|
|
||||||
if (parsedAmt * matSize > maxAmount) {
|
|
||||||
bulkPurchaseCostTxt.innerText = "Not enough warehouse space to purchase this amount";
|
|
||||||
} else if (isNaN(cost)) {
|
|
||||||
bulkPurchaseCostTxt.innerText = "Invalid put for Bulk Purchase amount";
|
|
||||||
} else {
|
|
||||||
bulkPurchaseCostTxt.innerText = `Purchasing ${numeralWrapper.format(parsedAmt, "0,0.00")} of ` +
|
|
||||||
`${mat.name} will cost ${numeralWrapper.formatMoney(cost)}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let bulkPurchaseConfirmBtn;
|
|
||||||
const bulkPurchaseInput = createElement("input", {
|
|
||||||
margin: "5px",
|
|
||||||
placeholder: "Bulk Purchase amount",
|
|
||||||
type: "number",
|
|
||||||
onkeyup: (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
updateBulkPurchaseText(e.target.value);
|
|
||||||
if (e.keyCode === KEY.ENTER) {bulkPurchaseConfirmBtn.click();}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
bulkPurchaseConfirmBtn = createElement("button", {
|
|
||||||
class: "std-button",
|
|
||||||
innerText: "Confirm Bulk Purchase",
|
|
||||||
clickListener: () => {
|
|
||||||
const amount = parseFloat(bulkPurchaseInput.value);
|
|
||||||
|
|
||||||
const matSize = MaterialSizes[mat.name];
|
|
||||||
const maxAmount = ((warehouse.size - warehouse.sizeUsed) / matSize);
|
|
||||||
if (amount * matSize > maxAmount) {
|
|
||||||
dialogBoxCreate(`You do not have enough warehouse size to fit this purchase`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isNaN(amount)) {
|
|
||||||
dialogBoxCreate("Invalid input amount");
|
|
||||||
} else {
|
|
||||||
const cost = amount * mat.bCost;
|
|
||||||
if (corp.funds.gt(cost)) {
|
|
||||||
corp.funds = corp.funds.minus(cost);
|
|
||||||
mat.qty += amount;
|
|
||||||
} else {
|
|
||||||
dialogBoxCreate(`You cannot afford this purchase.`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
removeElementById(purchasePopupId);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
elems.push(bulkPurchaseInfo);
|
|
||||||
elems.push(bulkPurchaseCostTxt);
|
|
||||||
elems.push(bulkPurchaseInput);
|
|
||||||
elems.push(bulkPurchaseConfirmBtn);
|
|
||||||
}
|
|
||||||
|
|
||||||
createPopup(purchasePopupId, elems);
|
|
||||||
input.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a popup that let the player manage sales of a material
|
|
||||||
createSellMaterialPopup(mat) {
|
|
||||||
const sellPopupId = "cmpy-mgmt-material-sell-popup";
|
|
||||||
const txt = createElement("p", {
|
|
||||||
innerHTML: "Enter the maximum amount of " + mat.name + " you would like " +
|
|
||||||
"to sell per second, as well as the price at which you would " +
|
|
||||||
"like to sell at.<br><br>" +
|
|
||||||
"If the sell amount is set to 0, then the material will not be sold. If the sell price " +
|
|
||||||
"if set to 0, then the material will be discarded<br><br>" +
|
|
||||||
"Setting the sell amount to 'MAX' will result in you always selling the " +
|
|
||||||
"maximum possible amount of the material.<br><br>" +
|
|
||||||
"When setting the sell amount, you can use the 'PROD' variable to designate a dynamically " +
|
|
||||||
"changing amount that depends on your production. For example, if you set the sell amount " +
|
|
||||||
"to 'PROD-5' then you will always sell 5 less of the material than you produce.<br><br>" +
|
|
||||||
"When setting the sell price, you can use the 'MP' variable to designate a dynamically " +
|
|
||||||
"changing price that depends on the market price. For example, if you set the sell price " +
|
|
||||||
"to 'MP+10' then it will always be sold at $10 above the market price.",
|
|
||||||
});
|
|
||||||
const br = createElement("br");
|
|
||||||
let confirmBtn;
|
|
||||||
const inputQty = createElement("input", {
|
|
||||||
type: "text", marginTop: "4px",
|
|
||||||
value: mat.sllman[1] ? mat.sllman[1] : null,
|
|
||||||
placeholder: "Sell amount",
|
|
||||||
onkeyup: (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
if (e.keyCode === KEY.ENTER) {confirmBtn.click();}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
let inputButtonInitValue = mat.sCost ? mat.sCost : null;
|
|
||||||
if (mat.marketTa2) {
|
|
||||||
inputButtonInitValue += " (Market-TA.II)";
|
|
||||||
} else if (mat.marketTa1) {
|
|
||||||
inputButtonInitValue += " (Market-TA.I)";
|
|
||||||
}
|
|
||||||
|
|
||||||
const inputPx = createElement("input", {
|
|
||||||
type: "text", marginTop: "4px",
|
|
||||||
value: inputButtonInitValue,
|
|
||||||
placeholder: "Sell price",
|
|
||||||
onkeyup: (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
if (e.keyCode === KEY.ENTER) {confirmBtn.click();}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
confirmBtn = createElement("button", {
|
|
||||||
class: "std-button",
|
|
||||||
innerText: "Confirm",
|
|
||||||
clickListener: () => {
|
|
||||||
//Parse price
|
|
||||||
let cost = inputPx.value.replace(/\s+/g, '');
|
|
||||||
cost = cost.replace(/[^-()\d/*+.MP]/g, ''); //Sanitize cost
|
|
||||||
let temp = cost.replace(/MP/g, mat.bCost);
|
|
||||||
try {
|
|
||||||
temp = eval(temp);
|
|
||||||
} catch(e) {
|
|
||||||
dialogBoxCreate("Invalid value or expression for sell price field: " + e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (temp == null || isNaN(temp)) {
|
|
||||||
dialogBoxCreate("Invalid value or expression for sell price field");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cost.includes("MP")) {
|
|
||||||
mat.sCost = cost; //Dynamically evaluated
|
|
||||||
} else {
|
|
||||||
mat.sCost = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Parse quantity
|
|
||||||
if (inputQty.value.includes("MAX") || inputQty.value.includes("PROD")) {
|
|
||||||
let qty = inputQty.value.replace(/\s+/g, '');
|
|
||||||
qty = qty.replace(/[^-()\d/*+.MAXPROD]/g, '');
|
|
||||||
let tempQty = qty.replace(/MAX/g, 1);
|
|
||||||
tempQty = tempQty.replace(/PROD/g, 1);
|
|
||||||
try {
|
|
||||||
tempQty = eval(tempQty);
|
|
||||||
} catch(e) {
|
|
||||||
dialogBoxCreate("Invalid value or expression for sell price field: " + e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tempQty == null || isNaN(tempQty)) {
|
|
||||||
dialogBoxCreate("Invalid value or expression for sell price field");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
mat.sllman[0] = true;
|
|
||||||
mat.sllman[1] = qty; //Use sanitized input
|
|
||||||
} else if (isNaN(inputQty.value)) {
|
|
||||||
dialogBoxCreate("Invalid value for sell quantity field! Must be numeric or 'MAX'");
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
var qty = parseFloat(inputQty.value);
|
|
||||||
if (isNaN(qty)) {qty = 0;}
|
|
||||||
if (qty === 0) {
|
|
||||||
mat.sllman[0] = false;
|
|
||||||
mat.sllman[1] = 0;
|
|
||||||
} else {
|
|
||||||
mat.sllman[0] = true;
|
|
||||||
mat.sllman[1] = qty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
removeElementById(sellPopupId);
|
|
||||||
this.rerender();
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const cancelBtn = createPopupCloseButton(sellPopupId, {
|
|
||||||
class: "std-button",
|
|
||||||
innerText: "Cancel",
|
|
||||||
});
|
|
||||||
|
|
||||||
createPopup(sellPopupId, [txt, br, inputQty, inputPx, confirmBtn, cancelBtn]);
|
|
||||||
inputQty.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a popup that lets the player manage sales of the product
|
|
||||||
createSellProductPopup(product, city) {
|
|
||||||
const popupId = "cmpy-mgmt-sell-product-popup";
|
|
||||||
const txt = createElement("p", {
|
|
||||||
innerHTML:"Enter the maximum amount of " + product.name + " you would like " +
|
|
||||||
"to sell per second, as well as the price at which you would like to " +
|
|
||||||
"sell it at.<br><br>" +
|
|
||||||
"If the sell amount is set to 0, then the product will not be sold. If the " +
|
|
||||||
"sell price is set to 0, then the product will be discarded.<br><br>" +
|
|
||||||
"Setting the sell amount to 'MAX' will result in you always selling the " +
|
|
||||||
"maximum possible amount of the material.<br><br>" +
|
|
||||||
"When setting the sell amount, you can use the 'PROD' variable to designate a " +
|
|
||||||
"dynamically changing amount that depends on your production. For example, " +
|
|
||||||
"if you set the sell amount to 'PROD-1' then you will always sell 1 less of " +
|
|
||||||
"the material than you produce.<br><br>" +
|
|
||||||
"When setting the sell price, you can use the 'MP' variable to set a " +
|
|
||||||
"dynamically changing price that depends on the Product's estimated " +
|
|
||||||
"market price. For example, if you set it to 'MP*5' then it " +
|
|
||||||
"will always be sold at five times the estimated market price.",
|
|
||||||
});
|
|
||||||
let confirmBtn;
|
|
||||||
const inputQty = createElement("input", {
|
|
||||||
margin: "5px 0px 5px 0px",
|
|
||||||
placeholder: "Sell amount",
|
|
||||||
type: "text",
|
|
||||||
value: product.sllman[city][1] ? product.sllman[city][1] : null,
|
|
||||||
onkeyup: (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
if (e.keyCode === KEY.ENTER) {confirmBtn.click();}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
let inputButtonInitValue = product.sCost ? product.sCost : null;
|
|
||||||
if (product.marketTa2) {
|
|
||||||
inputButtonInitValue += " (Market-TA.II)";
|
|
||||||
} else if (product.marketTa1) {
|
|
||||||
inputButtonInitValue += " (Market-TA.I)";
|
|
||||||
}
|
|
||||||
|
|
||||||
const inputPx = createElement("input", {
|
|
||||||
margin: "5px 0px 5px 0px",
|
|
||||||
placeholder: "Sell price",
|
|
||||||
type: "text",
|
|
||||||
value: inputButtonInitValue,
|
|
||||||
onkeyup: (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
if (e.keyCode === KEY.ENTER) {confirmBtn.click();}
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const checkboxDiv = createElement("div", {
|
|
||||||
border: "1px solid white",
|
|
||||||
display: "inline-block",
|
|
||||||
})
|
|
||||||
const checkboxLabel = createElement("label", {
|
|
||||||
for: popupId + "-checkbox",
|
|
||||||
innerText: "Use same 'Sell Amount' for all cities",
|
|
||||||
});
|
|
||||||
const checkbox = createElement("input", {
|
|
||||||
checked: true,
|
|
||||||
id: popupId + "-checkbox",
|
|
||||||
margin: "2px",
|
|
||||||
type: "checkbox",
|
|
||||||
});
|
|
||||||
checkboxDiv.appendChild(checkboxLabel);
|
|
||||||
checkboxDiv.appendChild(checkbox);
|
|
||||||
|
|
||||||
confirmBtn = createElement("button", {
|
|
||||||
class: "std-button",
|
|
||||||
innerText: "Confirm",
|
|
||||||
clickListener: () => {
|
|
||||||
//Parse price
|
|
||||||
if (inputPx.value.includes("MP")) {
|
|
||||||
//Dynamically evaluated quantity. First test to make sure its valid
|
|
||||||
//Sanitize input, then replace dynamic variables with arbitrary numbers
|
|
||||||
var price = inputPx.value.replace(/\s+/g, '');
|
|
||||||
price = price.replace(/[^-()\d/*+.MP]/g, '');
|
|
||||||
var temp = price.replace(/MP/g, 1);
|
|
||||||
try {
|
|
||||||
temp = eval(temp);
|
|
||||||
} catch(e) {
|
|
||||||
dialogBoxCreate("Invalid value or expression for sell quantity field: " + e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (temp == null || isNaN(temp)) {
|
|
||||||
dialogBoxCreate("Invalid value or expression for sell quantity field.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
product.sCost = price; //Use sanitized price
|
|
||||||
} else {
|
|
||||||
var cost = parseFloat(inputPx.value);
|
|
||||||
if (isNaN(cost)) {
|
|
||||||
dialogBoxCreate("Invalid value for sell price field");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
product.sCost = cost;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Array of all cities. Used later
|
|
||||||
const cities = Object.keys(Cities);
|
|
||||||
|
|
||||||
// Parse quantity
|
|
||||||
if (inputQty.value.includes("MAX") || inputQty.value.includes("PROD")) {
|
|
||||||
//Dynamically evaluated quantity. First test to make sure its valid
|
|
||||||
var qty = inputQty.value.replace(/\s+/g, '');
|
|
||||||
qty = qty.replace(/[^-()\d/*+.MAXPROD]/g, '');
|
|
||||||
var temp = qty.replace(/MAX/g, 1);
|
|
||||||
temp = temp.replace(/PROD/g, 1);
|
|
||||||
try {
|
|
||||||
temp = eval(temp);
|
|
||||||
} catch(e) {
|
|
||||||
dialogBoxCreate("Invalid value or expression for sell price field: " + e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (temp == null || isNaN(temp)) {
|
|
||||||
dialogBoxCreate("Invalid value or expression for sell price field");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (checkbox.checked) {
|
|
||||||
for (let i = 0; i < cities.length; ++i) {
|
|
||||||
const tempCity = cities[i];
|
|
||||||
product.sllman[tempCity][0] = true;
|
|
||||||
product.sllman[tempCity][1] = qty; //Use sanitized input
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
product.sllman[city][0] = true;
|
|
||||||
product.sllman[city][1] = qty; //Use sanitized input
|
|
||||||
}
|
|
||||||
} else if (isNaN(inputQty.value)) {
|
|
||||||
dialogBoxCreate("Invalid value for sell quantity field! Must be numeric");
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
var qty = parseFloat(inputQty.value);
|
|
||||||
if (isNaN(qty)) {qty = 0;}
|
|
||||||
if (qty === 0) {
|
|
||||||
if (checkbox.checked) {
|
|
||||||
for (let i = 0; i < cities.length; ++i) {
|
|
||||||
const tempCity = cities[i];
|
|
||||||
product.sllman[tempCity][0] = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
product.sllman[city][0] = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (checkbox.checked) {
|
|
||||||
for (let i = 0; i < cities.length; ++i) {
|
|
||||||
const tempCity = cities[i];
|
|
||||||
product.sllman[tempCity][0] = true;
|
|
||||||
product.sllman[tempCity][1] = qty;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
product.sllman[city][0] = true;
|
|
||||||
product.sllman[city][1] = qty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
removeElementById(popupId);
|
|
||||||
this.rerender();
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const cancelBtn = createPopupCloseButton(popupId, { class: "std-button" });
|
|
||||||
|
|
||||||
const linebreak1 = createElement("br");
|
|
||||||
|
|
||||||
createPopup(popupId, [txt, inputQty, inputPx, confirmBtn, cancelBtn, linebreak1,
|
|
||||||
checkboxDiv]);
|
|
||||||
inputQty.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
rerender() {
|
|
||||||
this.corp.rerender();
|
|
||||||
}
|
|
||||||
}
|
|
@ -9,7 +9,6 @@ import { createPopup } from "../../ui/React/createPopup";
|
|||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
corp: any;
|
corp: any;
|
||||||
eventHandler: any;
|
|
||||||
routing: any;
|
routing: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ import { IndustryWarehouse } from "./IndustryWarehouse";
|
|||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
routing: any;
|
routing: any;
|
||||||
eventHandler: any;
|
|
||||||
corp: any;
|
corp: any;
|
||||||
currentCity: string;
|
currentCity: string;
|
||||||
}
|
}
|
||||||
@ -19,12 +18,10 @@ export function Industry(props: IProps): React.ReactElement {
|
|||||||
<div className={"cmpy-mgmt-industry-left-panel"}>
|
<div className={"cmpy-mgmt-industry-left-panel"}>
|
||||||
<IndustryOverview
|
<IndustryOverview
|
||||||
routing={props.routing}
|
routing={props.routing}
|
||||||
eventHandler={props.eventHandler}
|
|
||||||
corp={props.corp}
|
corp={props.corp}
|
||||||
currentCity={props.currentCity} />
|
currentCity={props.currentCity} />
|
||||||
<IndustryOffice
|
<IndustryOffice
|
||||||
routing={props.routing}
|
routing={props.routing}
|
||||||
eventHandler={props.eventHandler}
|
|
||||||
corp={props.corp}
|
corp={props.corp}
|
||||||
currentCity={props.currentCity} />
|
currentCity={props.currentCity} />
|
||||||
</div>
|
</div>
|
||||||
@ -32,8 +29,7 @@ export function Industry(props: IProps): React.ReactElement {
|
|||||||
<IndustryWarehouse
|
<IndustryWarehouse
|
||||||
corp={props.corp}
|
corp={props.corp}
|
||||||
routing={props.routing}
|
routing={props.routing}
|
||||||
currentCity={props.currentCity}
|
currentCity={props.currentCity} />
|
||||||
eventHandler={props.eventHandler} />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -15,7 +15,6 @@ import { ThrowPartyPopup } from "./ThrowPartyPopup";
|
|||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
routing: any;
|
routing: any;
|
||||||
eventHandler: any;
|
|
||||||
corp: any;
|
corp: any;
|
||||||
currentCity: string;
|
currentCity: string;
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,6 @@ import { createPopup } from "../../ui/React/createPopup";
|
|||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
routing: any;
|
routing: any;
|
||||||
eventHandler: any;
|
|
||||||
corp: any;
|
corp: any;
|
||||||
currentCity: string;
|
currentCity: string;
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,10 @@ import { DiscontinueProductPopup } from "./DiscontinueProductPopup";
|
|||||||
import { ExportPopup } from "./ExportPopup";
|
import { ExportPopup } from "./ExportPopup";
|
||||||
import { LimitProductProductionPopup } from "./LimitProductProductionPopup";
|
import { LimitProductProductionPopup } from "./LimitProductProductionPopup";
|
||||||
import { MaterialMarketTaPopup } from "./MaterialMarketTaPopup";
|
import { MaterialMarketTaPopup } from "./MaterialMarketTaPopup";
|
||||||
|
import { SellMaterialPopup } from "./SellMaterialPopup";
|
||||||
|
import { SellProductPopup } from "./SellProductPopup";
|
||||||
|
import { PurchaseMaterialPopup } from "./PurchaseMaterialPopup";
|
||||||
|
import { ProductMarketTaPopup } from "./ProductMarketTaPopup";
|
||||||
|
|
||||||
import { numeralWrapper } from "../../ui/numeralFormat";
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||||
@ -23,7 +27,6 @@ interface IProductProps {
|
|||||||
division: any;
|
division: any;
|
||||||
city: string;
|
city: string;
|
||||||
product: any;
|
product: any;
|
||||||
eventHandler: any;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates the UI for a single Product type
|
// Creates the UI for a single Product type
|
||||||
@ -32,7 +35,6 @@ function ProductComponent(props: IProductProps): React.ReactElement {
|
|||||||
const division = props.division;
|
const division = props.division;
|
||||||
const city = props.city;
|
const city = props.city;
|
||||||
const product = props.product;
|
const product = props.product;
|
||||||
const eventHandler = props.eventHandler;
|
|
||||||
|
|
||||||
// Numeraljs formatters
|
// Numeraljs formatters
|
||||||
const nf = "0.000";
|
const nf = "0.000";
|
||||||
@ -67,7 +69,15 @@ function ProductComponent(props: IProductProps): React.ReactElement {
|
|||||||
sellButtonText += (" @ " + numeralWrapper.format(product.sCost, "$0.000a"));
|
sellButtonText += (" @ " + numeralWrapper.format(product.sCost, "$0.000a"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const sellButtonOnClick = eventHandler.createSellProductPopup.bind(eventHandler, product, city);
|
|
||||||
|
function openSellProductPopup(): void {
|
||||||
|
const popupId = "cmpy-mgmt-limit-product-production-popup";
|
||||||
|
createPopup(popupId, SellProductPopup, {
|
||||||
|
product: product,
|
||||||
|
city: city,
|
||||||
|
popupId: popupId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Limit Production button
|
// Limit Production button
|
||||||
let limitProductionButtonText = "Limit Production";
|
let limitProductionButtonText = "Limit Production";
|
||||||
@ -94,8 +104,14 @@ function ProductComponent(props: IProductProps): React.ReactElement {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Market TA button
|
function openProductMarketTaPopup(): void {
|
||||||
const marketTaButtonOnClick = eventHandler.createProductMarketTaPopup.bind(eventHandler, product, division);
|
const popupId = "cmpy-mgmt-marketta-popup";
|
||||||
|
createPopup(popupId, ProductMarketTaPopup, {
|
||||||
|
product: product,
|
||||||
|
industry: division,
|
||||||
|
popupId: popupId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Unfinished Product
|
// Unfinished Product
|
||||||
if (!product.fin) {
|
if (!product.fin) {
|
||||||
@ -107,7 +123,7 @@ function ProductComponent(props: IProductProps): React.ReactElement {
|
|||||||
<br />
|
<br />
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button className={"std-button"} onClick={sellButtonOnClick}>
|
<button className={"std-button"} onClick={openSellProductPopup}>
|
||||||
{sellButtonText}
|
{sellButtonText}
|
||||||
</button><br />
|
</button><br />
|
||||||
<button className={"std-button"} onClick={openLimitProductProdutionPopup}>
|
<button className={"std-button"} onClick={openLimitProductProdutionPopup}>
|
||||||
@ -118,7 +134,7 @@ function ProductComponent(props: IProductProps): React.ReactElement {
|
|||||||
</button>
|
</button>
|
||||||
{
|
{
|
||||||
division.hasResearch("Market-TA.I") &&
|
division.hasResearch("Market-TA.I") &&
|
||||||
<button className={"std-button"} onClick={marketTaButtonOnClick}>
|
<button className={"std-button"} onClick={openProductMarketTaPopup}>
|
||||||
Market-TA
|
Market-TA
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
@ -187,7 +203,7 @@ function ProductComponent(props: IProductProps): React.ReactElement {
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<button className={"std-button"} onClick={sellButtonOnClick}>
|
<button className={"std-button"} onClick={openSellProductPopup}>
|
||||||
{sellButtonText}
|
{sellButtonText}
|
||||||
</button><br />
|
</button><br />
|
||||||
<button className={"std-button"} onClick={openLimitProductProdutionPopup}>
|
<button className={"std-button"} onClick={openLimitProductProdutionPopup}>
|
||||||
@ -198,7 +214,7 @@ function ProductComponent(props: IProductProps): React.ReactElement {
|
|||||||
</button>
|
</button>
|
||||||
{
|
{
|
||||||
division.hasResearch("Market-TA.I") &&
|
division.hasResearch("Market-TA.I") &&
|
||||||
<button className={"std-button"} onClick={marketTaButtonOnClick}>
|
<button className={"std-button"} onClick={openProductMarketTaPopup}>
|
||||||
Market-TA
|
Market-TA
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
@ -213,7 +229,6 @@ interface IMaterialProps {
|
|||||||
warehouse: any;
|
warehouse: any;
|
||||||
city: string;
|
city: string;
|
||||||
mat: any;
|
mat: any;
|
||||||
eventHandler: any;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates the UI for a single Material type
|
// Creates the UI for a single Material type
|
||||||
@ -223,7 +238,6 @@ function MaterialComponent(props: IMaterialProps): React.ReactElement {
|
|||||||
const warehouse = props.warehouse;
|
const warehouse = props.warehouse;
|
||||||
const city = props.city;
|
const city = props.city;
|
||||||
const mat = props.mat;
|
const mat = props.mat;
|
||||||
const eventHandler = props.eventHandler;
|
|
||||||
const markupLimit = mat.getMarkupLimit();
|
const markupLimit = mat.getMarkupLimit();
|
||||||
const office = division.offices[city];
|
const office = division.offices[city];
|
||||||
if (!(office instanceof OfficeSpace)) {
|
if (!(office instanceof OfficeSpace)) {
|
||||||
@ -245,7 +259,17 @@ function MaterialComponent(props: IMaterialProps): React.ReactElement {
|
|||||||
// Purchase material button
|
// Purchase material button
|
||||||
const purchaseButtonText = `Buy (${numeralWrapper.format(mat.buy, nfB)})`;
|
const purchaseButtonText = `Buy (${numeralWrapper.format(mat.buy, nfB)})`;
|
||||||
const purchaseButtonClass = tutorial ? "std-button flashing-button tooltip" : "std-button";
|
const purchaseButtonClass = tutorial ? "std-button flashing-button tooltip" : "std-button";
|
||||||
const purchaseButtonOnClick = eventHandler.createPurchaseMaterialPopup.bind(eventHandler, mat, division, warehouse);
|
|
||||||
|
function openPurchaseMaterialPopup() {
|
||||||
|
const popupId = "cmpy-mgmt-material-purchase-popup";
|
||||||
|
createPopup(popupId, PurchaseMaterialPopup, {
|
||||||
|
mat: mat,
|
||||||
|
industry: division,
|
||||||
|
warehouse: warehouse,
|
||||||
|
corp: props.corp,
|
||||||
|
popupId: popupId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function openExportPopup() {
|
function openExportPopup() {
|
||||||
const popupId = "cmpy-mgmt-export-popup";
|
const popupId = "cmpy-mgmt-export-popup";
|
||||||
@ -280,7 +304,15 @@ function MaterialComponent(props: IMaterialProps): React.ReactElement {
|
|||||||
} else {
|
} else {
|
||||||
sellButtonText = "Sell (0.000/0.000)";
|
sellButtonText = "Sell (0.000/0.000)";
|
||||||
}
|
}
|
||||||
const sellButtonOnClick = eventHandler.createSellMaterialPopup.bind(eventHandler, mat);
|
|
||||||
|
function openSellMaterialPopup(): void {
|
||||||
|
const popupId = "cmpy-mgmt-material-sell-popup";
|
||||||
|
createPopup(popupId, SellMaterialPopup, {
|
||||||
|
mat: mat,
|
||||||
|
corp: props.corp,
|
||||||
|
popupId: popupId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function openMaterialMarketTaPopup(): void {
|
function openMaterialMarketTaPopup(): void {
|
||||||
const popupId = "cmpy-mgmt-export-popup";
|
const popupId = "cmpy-mgmt-export-popup";
|
||||||
@ -334,7 +366,7 @@ function MaterialComponent(props: IMaterialProps): React.ReactElement {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style={{display: "inline-block"}}>
|
<div style={{display: "inline-block"}}>
|
||||||
<button className={purchaseButtonClass} onClick={purchaseButtonOnClick}>
|
<button className={purchaseButtonClass} onClick={openPurchaseMaterialPopup}>
|
||||||
{purchaseButtonText}
|
{purchaseButtonText}
|
||||||
{
|
{
|
||||||
tutorial &&
|
tutorial &&
|
||||||
@ -352,7 +384,7 @@ function MaterialComponent(props: IMaterialProps): React.ReactElement {
|
|||||||
}
|
}
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<button className={"std-button"} onClick={sellButtonOnClick}>
|
<button className={"std-button"} onClick={openSellMaterialPopup}>
|
||||||
{sellButtonText}
|
{sellButtonText}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@ -372,7 +404,6 @@ interface IProps {
|
|||||||
corp: any;
|
corp: any;
|
||||||
routing: any;
|
routing: any;
|
||||||
currentCity: string;
|
currentCity: string;
|
||||||
eventHandler: any;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function IndustryWarehouse(props: IProps): React.ReactElement {
|
export function IndustryWarehouse(props: IProps): React.ReactElement {
|
||||||
@ -485,7 +516,6 @@ export function IndustryWarehouse(props: IProps): React.ReactElement {
|
|||||||
city={props.currentCity}
|
city={props.currentCity}
|
||||||
corp={corp}
|
corp={corp}
|
||||||
division={division}
|
division={division}
|
||||||
eventHandler={props.eventHandler}
|
|
||||||
key={matName}
|
key={matName}
|
||||||
mat={warehouse.materials[matName]}
|
mat={warehouse.materials[matName]}
|
||||||
warehouse={warehouse} />);
|
warehouse={warehouse} />);
|
||||||
@ -502,7 +532,6 @@ export function IndustryWarehouse(props: IProps): React.ReactElement {
|
|||||||
city={props.currentCity}
|
city={props.currentCity}
|
||||||
corp={corp}
|
corp={corp}
|
||||||
division={division}
|
division={division}
|
||||||
eventHandler={props.eventHandler}
|
|
||||||
key={productName}
|
key={productName}
|
||||||
product={division.products[productName]}
|
product={division.products[productName]}
|
||||||
/>);
|
/>);
|
||||||
|
@ -14,7 +14,6 @@ import { IPlayer } from "../../PersonObjects/IPlayer";
|
|||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
corp: any;
|
corp: any;
|
||||||
eventHandler: any;
|
|
||||||
routing: any;
|
routing: any;
|
||||||
player: IPlayer;
|
player: IPlayer;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ import { IPlayer } from "../../PersonObjects/IPlayer";
|
|||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
corp: any;
|
corp: any;
|
||||||
eventHandler: any;
|
|
||||||
player: IPlayer;
|
player: IPlayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
105
src/Corporation/ui/ProductMarketTaPopup.tsx
Normal file
105
src/Corporation/ui/ProductMarketTaPopup.tsx
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Warehouse } from "../Warehouse";
|
||||||
|
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||||
|
import { createElement } from "../../../utils/uiHelpers/createElement";
|
||||||
|
import { removePopup } from "../../ui/React/createPopup";
|
||||||
|
import { createOptionElement } from "../../../utils/uiHelpers/createOptionElement";
|
||||||
|
import { clearSelector } from "../../../utils/uiHelpers/clearSelector";
|
||||||
|
import { getSelectText,
|
||||||
|
getSelectValue } from "../../../utils/uiHelpers/getSelectData";
|
||||||
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
product: any;
|
||||||
|
industry: any;
|
||||||
|
popupId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function MarketTA2(props: IProps): React.ReactElement {
|
||||||
|
const markupLimit = props.product.rat / props.product.mku;
|
||||||
|
const [value, setValue] = useState(props.product.pCost);
|
||||||
|
const setRerender = useState(false)[1];
|
||||||
|
function rerender(): void {
|
||||||
|
setRerender(old => !old);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||||
|
setValue(event.target.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function onCheckedChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||||
|
props.product.marketTa2 = event.target.checked;
|
||||||
|
rerender();
|
||||||
|
}
|
||||||
|
|
||||||
|
const sCost = parseFloat(value);
|
||||||
|
let markup = 1;
|
||||||
|
if (sCost > props.product.pCost) {
|
||||||
|
if ((sCost - props.product.pCost) > markupLimit) {
|
||||||
|
markup = markupLimit / (sCost - props.product.pCost);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (<>
|
||||||
|
<p>
|
||||||
|
<br /><u><strong>Market-TA.II</strong></u><br />
|
||||||
|
If you sell at {numeralWrapper.formatMoney(sCost)},
|
||||||
|
then you will sell {numeralWrapper.format(markup, "0.00000")}x as much compared
|
||||||
|
to if you sold at market price.
|
||||||
|
</p>
|
||||||
|
<input className="text-input" onChange={onChange} value={value} type="number" style={{marginTop: "4px"}} />
|
||||||
|
<div style={{display: 'block'}}>
|
||||||
|
<label className="tooltip" htmlFor="cmpy-mgmt-marketa2-checkbox" style={{color: "white"}}>
|
||||||
|
Use Market-TA.II for Auto-Sale Price
|
||||||
|
<span className="tooltiptext">
|
||||||
|
If this is enabled, then this Product will automatically
|
||||||
|
be sold at the optimal price such that the amount sold matches the
|
||||||
|
amount produced. (i.e. the highest possible price, while still ensuring
|
||||||
|
that all produced materials will be sold).
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<input className="text-input" onChange={onCheckedChange} id="cmpy-mgmt-marketa2-checkbox" style={{margin: "3px"}} type="checkbox" checked={props.product.marketTa2} />
|
||||||
|
</div>
|
||||||
|
<p>
|
||||||
|
Note that Market-TA.II overrides Market-TA.I. This means that if
|
||||||
|
both are enabled, then Market-TA.II will take effect, not Market-TA.I
|
||||||
|
</p>
|
||||||
|
</>);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a popup that lets the player use the Market TA research for Products
|
||||||
|
export function ProductMarketTaPopup(props: IProps): React.ReactElement {
|
||||||
|
const markupLimit = props.product.rat / props.product.mku;
|
||||||
|
const setRerender = useState(false)[1];
|
||||||
|
function rerender(): void {
|
||||||
|
setRerender(old => !old);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||||
|
props.product.marketTa1 = event.target.checked;
|
||||||
|
rerender();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (<>
|
||||||
|
<p>
|
||||||
|
<u><strong>Market-TA.I</strong></u><br />
|
||||||
|
The maximum sale price you can mark this up to
|
||||||
|
is {numeralWrapper.formatMoney(props.product.pCost + markupLimit)}.
|
||||||
|
This means that if you set the sale price higher than this,
|
||||||
|
you will begin to experience a loss in number of sales.
|
||||||
|
</p>
|
||||||
|
<div style={{display: 'block'}}>
|
||||||
|
<label className="tooltip" htmlFor="cmpy-mgmt-marketa1-checkbox" style={{color: "white"}}>
|
||||||
|
Use Market-TA.I for Auto-Sale Price
|
||||||
|
<span className="tooltiptext">
|
||||||
|
If this is enabled, then this Product will automatically
|
||||||
|
be sold at the price identified by Market-TA.I
|
||||||
|
(i.e. the price shown above).
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
<input onChange={onChange} className="text-input" id="cmpy-mgmt-marketa1-checkbox" style={{margin: "3px"}} type="checkbox" checked={props.product.marketTa1} />
|
||||||
|
</div>
|
||||||
|
{props.industry.hasResearch("Market-TA.II") && <MarketTA2 product={props.product} industry={props.industry} popupId={props.popupId} />}
|
||||||
|
</>);
|
||||||
|
}
|
130
src/Corporation/ui/PurchaseMaterialPopup.tsx
Normal file
130
src/Corporation/ui/PurchaseMaterialPopup.tsx
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Warehouse } from "../Warehouse";
|
||||||
|
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||||
|
import { createElement } from "../../../utils/uiHelpers/createElement";
|
||||||
|
import { removePopup } from "../../ui/React/createPopup";
|
||||||
|
import { createOptionElement } from "../../../utils/uiHelpers/createOptionElement";
|
||||||
|
import { clearSelector } from "../../../utils/uiHelpers/clearSelector";
|
||||||
|
import { getSelectText,
|
||||||
|
getSelectValue } from "../../../utils/uiHelpers/getSelectData";
|
||||||
|
import { MaterialSizes } from "../MaterialSizes";
|
||||||
|
import { numeralWrapper } from "../../ui/numeralFormat";
|
||||||
|
|
||||||
|
interface IBulkPurchaseTextProps {
|
||||||
|
warehouse: any;
|
||||||
|
mat: any;
|
||||||
|
amount: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function BulkPurchaseText(props: IBulkPurchaseTextProps): React.ReactElement {
|
||||||
|
const parsedAmt = parseFloat(props.amount);
|
||||||
|
const cost = parsedAmt * props.mat.bCost;
|
||||||
|
|
||||||
|
const matSize = MaterialSizes[props.mat.name];
|
||||||
|
const maxAmount = ((props.warehouse.size - props.warehouse.sizeUsed) / matSize);
|
||||||
|
|
||||||
|
if (parsedAmt * matSize > maxAmount) {
|
||||||
|
return (<>Not enough warehouse space to purchase this amount</>);
|
||||||
|
} else if (isNaN(cost)) {
|
||||||
|
return (<>Invalid put for Bulk Purchase amount</>);
|
||||||
|
} else {
|
||||||
|
return (<>Purchasing {numeralWrapper.format(parsedAmt, "0,0.00")} of
|
||||||
|
{props.mat.name} will cost {numeralWrapper.formatMoney(cost)}</>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
mat: any;
|
||||||
|
industry: any;
|
||||||
|
warehouse: any;
|
||||||
|
corp: any;
|
||||||
|
popupId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function BulkPurchase(props: IProps): React.ReactElement {
|
||||||
|
const [buyAmt, setBuyAmt] = useState('');
|
||||||
|
|
||||||
|
function bulkPurchase(): void {
|
||||||
|
const amount = parseFloat(buyAmt);
|
||||||
|
|
||||||
|
const matSize = MaterialSizes[props.mat.name];
|
||||||
|
const maxAmount = ((props.warehouse.size - props.warehouse.sizeUsed) / matSize);
|
||||||
|
if (amount * matSize > maxAmount) {
|
||||||
|
dialogBoxCreate(`You do not have enough warehouse size to fit this purchase`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isNaN(amount)) {
|
||||||
|
dialogBoxCreate("Invalid input amount");
|
||||||
|
} else {
|
||||||
|
const cost = amount * props.mat.bCost;
|
||||||
|
if (props.corp.funds.gt(cost)) {
|
||||||
|
props.corp.funds = props.corp.funds.minus(cost);
|
||||||
|
props.mat.qty += amount;
|
||||||
|
} else {
|
||||||
|
dialogBoxCreate(`You cannot afford this purchase.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
removePopup(props.popupId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {
|
||||||
|
if (event.keyCode === 13) bulkPurchase();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||||
|
setBuyAmt(event.target.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (<>
|
||||||
|
<p>
|
||||||
|
Enter the amount of {props.mat.name} you would like
|
||||||
|
to bulk purchase. This purchases the specified amount instantly
|
||||||
|
(all at once).
|
||||||
|
</p>
|
||||||
|
<BulkPurchaseText warehouse={props.warehouse} mat={props.mat} amount={buyAmt} />
|
||||||
|
<input onChange={onChange} type="number" placeholder="Bulk Purchase amount" style={{margin: "5px"}} />
|
||||||
|
<button className="std-button">Confirm Bulk Purchase</button>
|
||||||
|
</>);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a popup that lets the player purchase a Material
|
||||||
|
export function PurchaseMaterialPopup(props: IProps): React.ReactElement {
|
||||||
|
const [buyAmt, setBuyAmt] = useState(props.mat.buy ? props.mat.buy : null);
|
||||||
|
|
||||||
|
function purchaseMaterial(): void {
|
||||||
|
if (isNaN(parseFloat(buyAmt))) {
|
||||||
|
dialogBoxCreate("Invalid amount");
|
||||||
|
} else {
|
||||||
|
props.mat.buy = parseFloat(buyAmt);
|
||||||
|
if (isNaN(props.mat.buy)) props.mat.buy = 0;
|
||||||
|
removePopup(props.popupId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearPurchase(): void {
|
||||||
|
props.mat.buy = 0;
|
||||||
|
removePopup(props.popupId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {
|
||||||
|
if (event.keyCode === 13) purchaseMaterial();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||||
|
setBuyAmt(event.target.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (<>
|
||||||
|
<p>
|
||||||
|
Enter the amount of {props.mat.name} you would like
|
||||||
|
to purchase per second. This material's cost changes constantly.
|
||||||
|
</p>
|
||||||
|
<input onChange={onChange} className="text-input" autoFocus={true} placeholder="Purchase amount" type="number" style={{margin: "5px"}} onKeyDown={onKeyDown} />
|
||||||
|
<button onClick={purchaseMaterial} className="std-button">Confirm</button>
|
||||||
|
<button onClick={clearPurchase} className="std-button">Clear Purchase</button>
|
||||||
|
{props.industry.hasResearch("Bulk Purchasing") && <BulkPurchase corp={props.corp} mat={props.mat} industry={props.industry} warehouse={props.warehouse} popupId={props.popupId} />}
|
||||||
|
</>);
|
||||||
|
}
|
@ -7,7 +7,6 @@ import { IPlayer } from "../../PersonObjects/IPlayer";
|
|||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
corp: any;
|
corp: any;
|
||||||
eventHandler: any;
|
|
||||||
routing: any;
|
routing: any;
|
||||||
player: IPlayer;
|
player: IPlayer;
|
||||||
}
|
}
|
||||||
@ -15,8 +14,8 @@ interface IProps {
|
|||||||
export function CorporationRoot(props: IProps): React.ReactElement {
|
export function CorporationRoot(props: IProps): React.ReactElement {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<HeaderTabs corp={props.corp} eventHandler={props.eventHandler} routing={props.routing} />
|
<HeaderTabs corp={props.corp} routing={props.routing} />
|
||||||
<MainPanel corp={props.corp} eventHandler={props.eventHandler} routing={props.routing} player={props.player} />
|
<MainPanel corp={props.corp} routing={props.routing} player={props.player} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
129
src/Corporation/ui/SellMaterialPopup.tsx
Normal file
129
src/Corporation/ui/SellMaterialPopup.tsx
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Warehouse } from "../Warehouse";
|
||||||
|
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||||
|
import { createElement } from "../../../utils/uiHelpers/createElement";
|
||||||
|
import { removePopup } from "../../ui/React/createPopup";
|
||||||
|
import { createOptionElement } from "../../../utils/uiHelpers/createOptionElement";
|
||||||
|
import { clearSelector } from "../../../utils/uiHelpers/clearSelector";
|
||||||
|
import { getSelectText,
|
||||||
|
getSelectValue } from "../../../utils/uiHelpers/getSelectData";
|
||||||
|
|
||||||
|
function initialPrice(mat: any): string {
|
||||||
|
let val = mat.sCost ? mat.sCost : '';
|
||||||
|
if (mat.marketTa2) {
|
||||||
|
val += " (Market-TA.II)";
|
||||||
|
} else if (mat.marketTa1) {
|
||||||
|
val += " (Market-TA.I)";
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
mat: any;
|
||||||
|
corp: any;
|
||||||
|
popupId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a popup that let the player manage sales of a material
|
||||||
|
export function SellMaterialPopup(props: IProps): React.ReactElement {
|
||||||
|
const [amt, setAmt] = useState<string>(props.mat.sllman[1] ? props.mat.sllman[1] : '');
|
||||||
|
const [price, setPrice] = useState<string>(initialPrice(props.mat));
|
||||||
|
|
||||||
|
function sellMaterial(): void {
|
||||||
|
let p = price;
|
||||||
|
let qty = amt;
|
||||||
|
if(p === '') p = '0';
|
||||||
|
if(qty === '') qty = '0';
|
||||||
|
let cost = p.replace(/\s+/g, '');
|
||||||
|
cost = cost.replace(/[^-()\d/*+.MP]/g, ''); //Sanitize cost
|
||||||
|
let temp = cost.replace(/MP/g, props.mat.bCost);
|
||||||
|
try {
|
||||||
|
temp = eval(temp);
|
||||||
|
} catch(e) {
|
||||||
|
dialogBoxCreate("Invalid value or expression for sell price field: " + e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (temp == null || isNaN(parseFloat(temp))) {
|
||||||
|
dialogBoxCreate("Invalid value or expression for sell price field");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cost.includes("MP")) {
|
||||||
|
props.mat.sCost = cost; //Dynamically evaluated
|
||||||
|
} else {
|
||||||
|
props.mat.sCost = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Parse quantity
|
||||||
|
if (qty.includes("MAX") || qty.includes("PROD")) {
|
||||||
|
let q = qty.replace(/\s+/g, '');
|
||||||
|
q = q.replace(/[^-()\d/*+.MAXPROD]/g, '');
|
||||||
|
let tempQty = q.replace(/MAX/g, '1');
|
||||||
|
tempQty = tempQty.replace(/PROD/g, '1');
|
||||||
|
try {
|
||||||
|
tempQty = eval(tempQty);
|
||||||
|
} catch(e) {
|
||||||
|
dialogBoxCreate("Invalid value or expression for sell price field: " + e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tempQty == null || isNaN(parseFloat(tempQty))) {
|
||||||
|
dialogBoxCreate("Invalid value or expression for sell price field");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
props.mat.sllman[0] = true;
|
||||||
|
props.mat.sllman[1] = q; //Use sanitized input
|
||||||
|
} else if (isNaN(parseFloat(qty))) {
|
||||||
|
dialogBoxCreate("Invalid value for sell quantity field! Must be numeric or 'MAX'");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
let q = parseFloat(qty);
|
||||||
|
if (isNaN(q)) {q = 0;}
|
||||||
|
if (q === 0) {
|
||||||
|
props.mat.sllman[0] = false;
|
||||||
|
props.mat.sllman[1] = 0;
|
||||||
|
} else {
|
||||||
|
props.mat.sllman[0] = true;
|
||||||
|
props.mat.sllman[1] = q;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
removePopup(props.popupId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onAmtChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||||
|
setAmt(event.target.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onPriceChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||||
|
setPrice(event.target.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {
|
||||||
|
if (event.keyCode === 13) sellMaterial();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (<>
|
||||||
|
<p>
|
||||||
|
Enter the maximum amount of {props.mat.name} you would like
|
||||||
|
to sell per second, as well as the price at which you would
|
||||||
|
like to sell at.<br /><br />
|
||||||
|
If the sell amount is set to 0, then the material will not be sold. If the sell price
|
||||||
|
if set to 0, then the material will be discarded<br /><br />
|
||||||
|
Setting the sell amount to 'MAX' will result in you always selling the
|
||||||
|
maximum possible amount of the material.<br /><br />
|
||||||
|
When setting the sell amount, you can use the 'PROD' variable to designate a dynamically
|
||||||
|
changing amount that depends on your production. For example, if you set the sell amount
|
||||||
|
to 'PROD-5' then you will always sell 5 less of the material than you produce.<br /><br />
|
||||||
|
When setting the sell price, you can use the 'MP' variable to designate a dynamically
|
||||||
|
changing price that depends on the market price. For example, if you set the sell price
|
||||||
|
to 'MP+10' then it will always be sold at $10 above the market price.
|
||||||
|
</p>
|
||||||
|
<br />
|
||||||
|
<input className="text-input" value={amt} autoFocus={true} type="text" placeholder="Sell amount" style={{marginTop: "4px"}} onChange={onAmtChange} onKeyDown={onKeyDown} />
|
||||||
|
<input className="text-input" value={price} type="text" placeholder="Sell price" style={{marginTop: "4px"}} onChange={onPriceChange} onKeyDown={onKeyDown} />
|
||||||
|
<button className="std-button" onClick={sellMaterial}>Confirm</button>
|
||||||
|
</>);
|
||||||
|
}
|
170
src/Corporation/ui/SellProductPopup.tsx
Normal file
170
src/Corporation/ui/SellProductPopup.tsx
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Warehouse } from "../Warehouse";
|
||||||
|
import { dialogBoxCreate } from "../../../utils/DialogBox";
|
||||||
|
import { createElement } from "../../../utils/uiHelpers/createElement";
|
||||||
|
import { removePopup } from "../../ui/React/createPopup";
|
||||||
|
import { createOptionElement } from "../../../utils/uiHelpers/createOptionElement";
|
||||||
|
import { clearSelector } from "../../../utils/uiHelpers/clearSelector";
|
||||||
|
import { getSelectText,
|
||||||
|
getSelectValue } from "../../../utils/uiHelpers/getSelectData";
|
||||||
|
import { Cities } from "../../Locations/Cities";
|
||||||
|
|
||||||
|
function initialPrice(product: any): string {
|
||||||
|
let val = product.sCost ? product.sCost : '';
|
||||||
|
if (product.marketTa2) {
|
||||||
|
val += " (Market-TA.II)";
|
||||||
|
} else if (product.marketTa1) {
|
||||||
|
val += " (Market-TA.I)";
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
product: any;
|
||||||
|
city: string;
|
||||||
|
popupId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a popup that let the player manage sales of a material
|
||||||
|
export function SellProductPopup(props: IProps): React.ReactElement {
|
||||||
|
const [checked, setChecked] = useState(true);
|
||||||
|
const [iQty, setQty] = useState<string>(props.product.sllman[props.city][1] ? props.product.sllman[props.city][1] : '');
|
||||||
|
const [px, setPx] = useState<string>(initialPrice(props.product));
|
||||||
|
|
||||||
|
function onCheckedChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||||
|
setChecked(event.target.checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sellProduct(): void {
|
||||||
|
//Parse price
|
||||||
|
if (px.includes("MP")) {
|
||||||
|
//Dynamically evaluated quantity. First test to make sure its valid
|
||||||
|
//Sanitize input, then replace dynamic variables with arbitrary numbers
|
||||||
|
var price = px.replace(/\s+/g, '');
|
||||||
|
price = price.replace(/[^-()\d/*+.MP]/g, '');
|
||||||
|
var temp = price.replace(/MP/g, '1');
|
||||||
|
try {
|
||||||
|
temp = eval(temp);
|
||||||
|
} catch(e) {
|
||||||
|
dialogBoxCreate("Invalid value or expression for sell quantity field: " + e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (temp == null || isNaN(parseFloat(temp))) {
|
||||||
|
dialogBoxCreate("Invalid value or expression for sell quantity field.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
props.product.sCost = price; //Use sanitized price
|
||||||
|
} else {
|
||||||
|
var cost = parseFloat(px);
|
||||||
|
if (isNaN(cost)) {
|
||||||
|
dialogBoxCreate("Invalid value for sell price field");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
props.product.sCost = cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Array of all cities. Used later
|
||||||
|
const cities = Object.keys(Cities);
|
||||||
|
|
||||||
|
// Parse quantity
|
||||||
|
if (iQty.includes("MAX") || iQty.includes("PROD")) {
|
||||||
|
//Dynamically evaluated quantity. First test to make sure its valid
|
||||||
|
var qty = iQty.replace(/\s+/g, '');
|
||||||
|
qty = qty.replace(/[^-()\d/*+.MAXPROD]/g, '');
|
||||||
|
var temp = qty.replace(/MAX/g, '1');
|
||||||
|
temp = temp.replace(/PROD/g, '1');
|
||||||
|
try {
|
||||||
|
temp = eval(temp);
|
||||||
|
} catch(e) {
|
||||||
|
dialogBoxCreate("Invalid value or expression for sell price field: " + e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (temp == null || isNaN(parseFloat(temp))) {
|
||||||
|
dialogBoxCreate("Invalid value or expression for sell price field");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (checked) {
|
||||||
|
for (let i = 0; i < cities.length; ++i) {
|
||||||
|
const tempCity = cities[i];
|
||||||
|
props.product.sllman[tempCity][0] = true;
|
||||||
|
props.product.sllman[tempCity][1] = qty; //Use sanitized input
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
props.product.sllman[props.city][0] = true;
|
||||||
|
props.product.sllman[props.city][1] = qty; //Use sanitized input
|
||||||
|
}
|
||||||
|
} else if (isNaN(parseFloat(iQty))) {
|
||||||
|
dialogBoxCreate("Invalid value for sell quantity field! Must be numeric");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
let qty = parseFloat(iQty);
|
||||||
|
if (isNaN(qty)) {qty = 0;}
|
||||||
|
if (qty === 0) {
|
||||||
|
if (checked) {
|
||||||
|
for (let i = 0; i < cities.length; ++i) {
|
||||||
|
const tempCity = cities[i];
|
||||||
|
props.product.sllman[tempCity][0] = false;
|
||||||
|
props.product.sllman[tempCity][1] = '';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
props.product.sllman[props.city][0] = false;
|
||||||
|
props.product.sllman[props.city][1] = '';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (checked) {
|
||||||
|
for (let i = 0; i < cities.length; ++i) {
|
||||||
|
const tempCity = cities[i];
|
||||||
|
props.product.sllman[tempCity][0] = true;
|
||||||
|
props.product.sllman[tempCity][1] = qty;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
props.product.sllman[props.city][0] = true;
|
||||||
|
props.product.sllman[props.city][1] = qty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
removePopup(props.popupId);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onAmtChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||||
|
setQty(event.target.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onPriceChange(event: React.ChangeEvent<HTMLInputElement>): void {
|
||||||
|
setPx(event.target.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onKeyDown(event: React.KeyboardEvent<HTMLInputElement>): void {
|
||||||
|
if (event.keyCode === 13) sellProduct();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (<>
|
||||||
|
<p>
|
||||||
|
Enter the maximum amount of {props.product.name} you would like
|
||||||
|
to sell per second, as well as the price at which you would like to
|
||||||
|
sell it at.<br /><br />
|
||||||
|
If the sell amount is set to 0, then the product will not be sold. If the
|
||||||
|
sell price is set to 0, then the product will be discarded.<br /><br />
|
||||||
|
Setting the sell amount to 'MAX' will result in you always selling the
|
||||||
|
maximum possible amount of the material.<br /><br />
|
||||||
|
When setting the sell amount, you can use the 'PROD' variable to designate a
|
||||||
|
dynamically changing amount that depends on your production. For example,
|
||||||
|
if you set the sell amount to 'PROD-1' then you will always sell 1 less of
|
||||||
|
the material than you produce.<br /><br />
|
||||||
|
When setting the sell price, you can use the 'MP' variable to set a
|
||||||
|
dynamically changing price that depends on the Product's estimated
|
||||||
|
market price. For example, if you set it to 'MP*5' then it
|
||||||
|
will always be sold at five times the estimated market price.
|
||||||
|
</p>
|
||||||
|
<br />
|
||||||
|
<input className="text-input" value={iQty} autoFocus={true} type="text" placeholder="Sell amount" style={{marginTop: "4px"}} onChange={onAmtChange} onKeyDown={onKeyDown} />
|
||||||
|
<input className="text-input" value={px} type="text" placeholder="Sell price" style={{marginTop: "4px"}} onChange={onPriceChange} onKeyDown={onKeyDown} />
|
||||||
|
<button className="std-button" onClick={sellProduct}>Confirm</button>
|
||||||
|
<div style={{border: "1px solid white", display: "inline-block"}}>
|
||||||
|
<label htmlFor={props.popupId+'-checkbox'}>Use same 'Sell Amount' for all cities</label>
|
||||||
|
<input checked={checked} onChange={onCheckedChange} id={props.popupId + "-checkbox"} style={{margin:"2px"}} type="checkbox" />
|
||||||
|
</div>
|
||||||
|
</>);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user