mirror of
https://github.com/bitburner-official/bitburner-src.git
synced 2024-11-08 08:43:53 +01:00
Fix for invalid materials in warehouse (#660)
This commit is contained in:
parent
26cdc502bf
commit
312e3eb71f
@ -249,14 +249,26 @@ export function SetSmartSupplyOption(warehouse: Warehouse, material: Material, u
|
||||
warehouse.smartSupplyOptions[material.name] = useOption;
|
||||
}
|
||||
|
||||
export function BuyMaterial(material: Material, amt: number): void {
|
||||
export function BuyMaterial(division: Division, material: Material, amt: number): void {
|
||||
if (!isRelevantMaterial(material.name, division)) {
|
||||
throw new Error(`${material.name} is not a relevant material for industry ${division.type}`);
|
||||
}
|
||||
if (isNaN(amt) || amt < 0) {
|
||||
throw new Error(`Invalid amount '${amt}' to buy material '${material.name}'`);
|
||||
}
|
||||
material.buyAmount = amt;
|
||||
}
|
||||
|
||||
export function BulkPurchase(corp: Corporation, warehouse: Warehouse, material: Material, amt: number): void {
|
||||
export function BulkPurchase(
|
||||
corp: Corporation,
|
||||
division: Division,
|
||||
warehouse: Warehouse,
|
||||
material: Material,
|
||||
amt: number,
|
||||
): void {
|
||||
if (!isRelevantMaterial(material.name, division)) {
|
||||
throw new Error(`${material.name} is not a relevant material for industry ${division.type}`);
|
||||
}
|
||||
const matSize = MaterialInfo[material.name].size;
|
||||
const maxAmount = (warehouse.size - warehouse.sizeUsed) / matSize;
|
||||
if (isNaN(amt) || amt < 0) {
|
||||
|
@ -16,27 +16,30 @@ import MenuItem from "@mui/material/MenuItem";
|
||||
import Select, { SelectChangeEvent } from "@mui/material/Select";
|
||||
import { useRerender } from "../../../ui/React/hooks";
|
||||
import { getRecordKeys } from "../../../Types/Record";
|
||||
import { ButtonWithTooltip } from "../../../ui/Components/ButtonWithTooltip";
|
||||
|
||||
interface IProps {
|
||||
interface ExportModalProps {
|
||||
open: boolean;
|
||||
onClose: () => void;
|
||||
mat: Material;
|
||||
}
|
||||
|
||||
// Create a popup that lets the player manage exports
|
||||
export function ExportModal(props: IProps): React.ReactElement {
|
||||
export function ExportModal(props: ExportModalProps): React.ReactElement {
|
||||
const corp = useCorporation();
|
||||
const [exportAmount, setExportAmount] = useState("");
|
||||
const rerender = useRerender();
|
||||
|
||||
const possibleDivisions = [...corp.divisions.values()].filter((division: Division) => {
|
||||
return isRelevantMaterial(props.mat.name, division);
|
||||
});
|
||||
if (possibleDivisions.length === 0) throw new Error("Export popup created with no divisions.");
|
||||
const defaultDivision = possibleDivisions[0];
|
||||
if (Object.keys(defaultDivision.warehouses).length === 0)
|
||||
throw new Error("Export popup created in a division with no warehouses.");
|
||||
const [targetDivision, setTargetDivision] = useState(defaultDivision);
|
||||
const [targetCity, setTargetCity] = useState(CityName.Sector12);
|
||||
const [exportAmount, setExportAmount] = useState("");
|
||||
const rerender = useRerender();
|
||||
// This weird assignment is used because ts thinks possibleDivisions[0] is always a division
|
||||
const defaultDivision = possibleDivisions.length ? possibleDivisions[0] : null;
|
||||
const [targetDivision, setTargetDivision] = useState<Division | null>(defaultDivision);
|
||||
|
||||
const possibleCities = targetDivision ? getRecordKeys(targetDivision.warehouses) : [];
|
||||
const defaultCity = possibleCities.length ? possibleCities[0] : null;
|
||||
const [targetCity, setTargetCity] = useState(defaultCity);
|
||||
|
||||
function onCityChange(event: SelectChangeEvent<CityName>): void {
|
||||
setTargetCity(event.target.value as CityName);
|
||||
@ -54,6 +57,7 @@ export function ExportModal(props: IProps): React.ReactElement {
|
||||
|
||||
function exportMaterial(): void {
|
||||
try {
|
||||
if (!targetDivision || !targetCity) return;
|
||||
ExportMaterial(targetDivision, targetCity, props.mat, exportAmount);
|
||||
} catch (err) {
|
||||
dialogBoxCreate(err + "");
|
||||
@ -75,9 +79,8 @@ export function ExportModal(props: IProps): React.ReactElement {
|
||||
rerender();
|
||||
}
|
||||
|
||||
const possibleCities = getRecordKeys(targetDivision.warehouses);
|
||||
if (possibleCities.length > 0 && !possibleCities.includes(targetCity)) {
|
||||
setTargetCity(possibleCities[0]);
|
||||
if (targetCity && !possibleCities.includes(targetCity as CityName)) {
|
||||
setTargetCity(possibleCities.length ? possibleCities[0] : null);
|
||||
}
|
||||
|
||||
return (
|
||||
@ -104,16 +107,14 @@ export function ExportModal(props: IProps): React.ReactElement {
|
||||
<br />
|
||||
For example: setting the amount "(EINV-20)/10" would try to export all except 20 of the material.
|
||||
</Typography>
|
||||
<Select onChange={onTargetDivisionChange} value={targetDivision.name}>
|
||||
{[...corp.divisions.values()]
|
||||
.filter((division) => isRelevantMaterial(props.mat.name, division))
|
||||
.map((division) => (
|
||||
<MenuItem key={division.name} value={division.name}>
|
||||
{division.name}
|
||||
</MenuItem>
|
||||
))}
|
||||
<Select onChange={onTargetDivisionChange} value={targetDivision?.name ?? ""}>
|
||||
{possibleDivisions.map((division) => (
|
||||
<MenuItem key={division.name} value={division.name}>
|
||||
{division.name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
<Select onChange={onCityChange} value={targetCity}>
|
||||
<Select onChange={onCityChange} value={targetCity ?? ""}>
|
||||
{possibleCities.map((cityName) => (
|
||||
<MenuItem key={cityName} value={cityName}>
|
||||
{cityName}
|
||||
@ -121,7 +122,12 @@ export function ExportModal(props: IProps): React.ReactElement {
|
||||
))}
|
||||
</Select>
|
||||
<TextField placeholder="Export amount / s" onChange={onAmtChange} value={exportAmount} />
|
||||
<Button onClick={exportMaterial}>Export</Button>
|
||||
<ButtonWithTooltip
|
||||
disabledTooltip={!targetDivision ? "No target division selected" : !targetCity ? "No target city selected" : ""}
|
||||
onClick={exportMaterial}
|
||||
>
|
||||
Export
|
||||
</ButtonWithTooltip>
|
||||
<Typography>
|
||||
Below is a list of all current exports of this material from this warehouse. Clicking on one of the exports
|
||||
below will REMOVE that export.
|
||||
|
@ -6,7 +6,7 @@ import { Material } from "../../Material";
|
||||
import { formatMatPurchaseAmount, formatMoney } from "../../../ui/formatNumber";
|
||||
import { BulkPurchase, BuyMaterial } from "../../Actions";
|
||||
import { Modal } from "../../../ui/React/Modal";
|
||||
import { useCorporation } from "../Context";
|
||||
import { useCorporation, useDivision } from "../Context";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import TextField from "@mui/material/TextField";
|
||||
import Button from "@mui/material/Button";
|
||||
@ -26,6 +26,7 @@ interface IBPProps {
|
||||
|
||||
function BulkPurchaseSection(props: IBPProps): React.ReactElement {
|
||||
const corp = useCorporation();
|
||||
const division = useDivision();
|
||||
const [buyAmt, setBuyAmt] = useState("");
|
||||
const [disabled, setDisabled] = useState(false);
|
||||
|
||||
@ -64,7 +65,7 @@ function BulkPurchaseSection(props: IBPProps): React.ReactElement {
|
||||
|
||||
function bulkPurchase(): void {
|
||||
try {
|
||||
BulkPurchase(corp, props.warehouse, props.mat, parseFloat(buyAmt));
|
||||
BulkPurchase(corp, division, props.warehouse, props.mat, parseFloat(buyAmt));
|
||||
} catch (err) {
|
||||
dialogBoxCreate(err + "");
|
||||
}
|
||||
@ -110,12 +111,13 @@ interface IProps {
|
||||
|
||||
// Create a popup that lets the player purchase a Material
|
||||
export function PurchaseMaterialModal(props: IProps): React.ReactElement {
|
||||
const division = useDivision();
|
||||
const [buyAmt, setBuyAmt] = useState(props.mat.buyAmount ? props.mat.buyAmount : 0);
|
||||
|
||||
function purchaseMaterial(): void {
|
||||
if (buyAmt === null) return;
|
||||
try {
|
||||
BuyMaterial(props.mat, buyAmt);
|
||||
BuyMaterial(division, props.mat, buyAmt);
|
||||
} catch (err) {
|
||||
dialogBoxCreate(err + "");
|
||||
}
|
||||
|
@ -416,24 +416,28 @@ export function NetscriptCorporation(): InternalAPI<NSCorporation> {
|
||||
buyMaterial: (ctx) => (_divisionName, _cityName, _materialName, _amt) => {
|
||||
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
|
||||
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||
const division = getCorporation().divisions.get(divisionName);
|
||||
if (!division) throw helpers.makeRuntimeErrorMsg(ctx, `No division with provided name ${divisionName}`);
|
||||
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
|
||||
const materialName = getEnumHelper("CorpMaterialName").nsGetMember(ctx, _materialName, "materialName");
|
||||
const amt = helpers.number(ctx, "amt", _amt);
|
||||
if (amt < 0 || !Number.isFinite(amt))
|
||||
throw new Error("Invalid value for amount field! Must be numeric and greater than 0");
|
||||
const material = getMaterial(divisionName, cityName, materialName);
|
||||
BuyMaterial(material, amt);
|
||||
BuyMaterial(division, material, amt);
|
||||
},
|
||||
bulkPurchase: (ctx) => (_divisionName, _cityName, _materialName, _amt) => {
|
||||
checkAccess(ctx, CorpUnlockName.WarehouseAPI);
|
||||
const divisionName = helpers.string(ctx, "divisionName", _divisionName);
|
||||
const division = getCorporation().divisions.get(divisionName);
|
||||
if (!division) throw helpers.makeRuntimeErrorMsg(ctx, `No division with provided name ${divisionName}`);
|
||||
const corporation = getCorporation();
|
||||
const cityName = getEnumHelper("CityName").nsGetMember(ctx, _cityName);
|
||||
const materialName = getEnumHelper("CorpMaterialName").nsGetMember(ctx, _materialName, "materialName");
|
||||
const amt = helpers.number(ctx, "amt", _amt);
|
||||
const warehouse = getWarehouse(divisionName, cityName);
|
||||
const material = getMaterial(divisionName, cityName, materialName);
|
||||
BulkPurchase(corporation, warehouse, material, amt);
|
||||
BulkPurchase(corporation, division, warehouse, material, amt);
|
||||
},
|
||||
makeProduct:
|
||||
(ctx) =>
|
||||
|
Loading…
Reference in New Issue
Block a user