CORPORATION: Rework material production limit (#2683)

This commit is contained in:
catloversg
2026-04-29 05:50:40 +07:00
committed by GitHub
parent 8ad5ec075e
commit 01c63ea0c0
8 changed files with 396 additions and 220 deletions
+21 -20
View File
@@ -585,20 +585,16 @@ export class Division {
/* Process production of materials */
if (this.producedMaterials.length > 0) {
const mat = warehouse.materials[this.producedMaterials[0]];
//Calculate the maximum production of this material based
//on the office's productivity
const maxProd =
this.getOfficeProductivity(office) *
this.productionMult * // Multiplier from materials
this.productionMult * // Multiplier from boost materials
corporation.getProductionMultiplier() *
this.getProductionMultiplier(); // Multiplier from Research
let prod;
// If there is a limit set on production, apply the limit
prod = mat.productionLimit === null ? maxProd : Math.min(maxProd, mat.productionLimit);
prod *= corpConstants.secondsPerMarketCycle * marketCycles; //Convert production from per second to per market cycle
// Convert production from per second to per market cycle
let prod = maxProd * corpConstants.secondsPerMarketCycle * marketCycles;
// Calculate net change in warehouse storage making the produced materials will cost
let totalMatSize = 0;
@@ -670,6 +666,14 @@ export class Division {
}
avgQlt = Math.max(avgQlt, 1);
for (let j = 0; j < this.producedMaterials.length; ++j) {
let outputAmount = prod * producableFrac;
const productionLimit = warehouse.materials[this.producedMaterials[j]].productionLimit;
if (productionLimit !== null) {
// productionLimit is per second, so we need to convert it to per market cycle.
const effectiveLimitValue = productionLimit * corpConstants.secondsPerMarketCycle * marketCycles;
outputAmount = Math.min(outputAmount, effectiveLimitValue);
}
let tempQlt =
office.employeeProductionByJob[CorpEmployeeJob.Engineer] / 90 +
Math.pow(this.researchPoints, this.researchFactor) +
@@ -680,27 +684,24 @@ export class Division {
1,
(warehouse.materials[this.producedMaterials[j]].quality *
warehouse.materials[this.producedMaterials[j]].stored +
tempQlt * prod * producableFrac) /
(warehouse.materials[this.producedMaterials[j]].stored + prod * producableFrac),
tempQlt * outputAmount) /
(warehouse.materials[this.producedMaterials[j]].stored + outputAmount),
);
warehouse.materials[this.producedMaterials[j]].averagePrice =
(warehouse.materials[this.producedMaterials[j]].averagePrice *
warehouse.materials[this.producedMaterials[j]].stored +
warehouse.materials[this.producedMaterials[j]].marketPrice * prod * producableFrac) /
(warehouse.materials[this.producedMaterials[j]].stored + prod * producableFrac);
warehouse.materials[this.producedMaterials[j]].stored += prod * producableFrac;
warehouse.materials[this.producedMaterials[j]].marketPrice * outputAmount) /
(warehouse.materials[this.producedMaterials[j]].stored + outputAmount);
warehouse.materials[this.producedMaterials[j]].stored += outputAmount;
warehouse.materials[this.producedMaterials[j]].productionAmount =
outputAmount / (corpConstants.secondsPerMarketCycle * marketCycles);
}
} else {
for (const reqMatName of getRecordKeys(this.requiredMaterials)) {
warehouse.materials[reqMatName].productionAmount = 0;
}
}
//Per second
const materialProduction = (prod * producableFrac) / (corpConstants.secondsPerMarketCycle * marketCycles);
for (const prodMatName of this.producedMaterials) {
warehouse.materials[prodMatName].productionAmount = materialProduction;
}
} else {
//If this doesn't produce any materials, then it only creates
//Products. Creating products will consume materials. The
@@ -853,12 +854,12 @@ export class Division {
if (!warehouse) continue;
switch (state) {
case "PRODUCTION": {
//Calculate the maximum production of this material based
//Calculate the maximum production of this product based
//on the office's productivity
const maxProd =
this.getOfficeProductivity(office, { forProduct: true }) *
corporation.getProductionMultiplier() *
this.productionMult * // Multiplier from materials
this.productionMult * // Multiplier from boost materials
this.getProductionMultiplier() * // Multiplier from research
this.getProductProductionMultiplier(); // Multiplier from research
let prod;
+2
View File
@@ -73,6 +73,7 @@ function WarehouseRoot(props: WarehouseProps): React.ReactElement {
const isInStock = props.warehouse.materials[matName].stored > 0;
const isRelevant = isRelevantMaterial(matName, division);
if (!isInStock && !isRelevant) continue;
const isOutputMaterial = division.producedMaterials.includes(matName);
mats.push(
<MaterialElem
rerender={props.rerender}
@@ -80,6 +81,7 @@ function WarehouseRoot(props: WarehouseProps): React.ReactElement {
key={matName}
mat={props.warehouse.materials[matName]}
warehouse={props.warehouse}
isOutputMaterial={isOutputMaterial}
/>,
);
}
+14 -9
View File
@@ -19,6 +19,7 @@ interface IMaterialProps {
city: CityName;
mat: Material;
rerender: () => void;
isOutputMaterial: boolean;
}
// Creates the UI for a single Material type
@@ -74,7 +75,7 @@ export function MaterialElem(props: IMaterialProps): React.ReactElement {
}
// Limit Production button
let limitMaterialButtonText = "Limit Material";
let limitMaterialButtonText = "Limit Material Production";
if (mat.productionLimit !== null) {
limitMaterialButtonText += " (" + formatCorpStat(mat.productionLimit) + ")";
}
@@ -158,14 +159,18 @@ export function MaterialElem(props: IMaterialProps): React.ReactElement {
open={sellMaterialOpen}
onClose={() => setSellMaterialOpen(false)}
/>
<Button color={tutorial ? "error" : "primary"} onClick={() => setLimitProductionOpen(true)}>
{limitMaterialButtonText}
</Button>
<LimitMaterialProductionModal
material={mat}
open={limitProductionOpen}
onClose={() => setLimitProductionOpen(false)}
/>
{props.isOutputMaterial && (
<>
<Button color={tutorial ? "error" : "primary"} onClick={() => setLimitProductionOpen(true)}>
{limitMaterialButtonText}
</Button>
<LimitMaterialProductionModal
material={mat}
open={limitProductionOpen}
onClose={() => setLimitProductionOpen(false)}
/>
</>
)}
</Box>
</Box>
</Paper>
@@ -45,7 +45,16 @@ export function LimitMaterialProductionModal(props: IProps): React.ReactElement
<Typography>
Enter a limit to the amount of this material you would like to produce per second. Leave the box empty to set no
limit.
<br />
<br />
This limit applies only to output; it does not affect input consumption.
<br />
<br />
For example, in Agriculture, assume the division's raw production is 1000. You need to consume 500 Water and 200
Chemicals to produce 1000 Plants and 1000 Food. If you set the limits for Plants and Food to 200 and 100
respectively, you will still consume 500 Water and 200 Chemicals, but only produce 200 Plants and 100 Food.
</Typography>
<br />
<TextField autoFocus={true} placeholder="Limit" type="number" onChange={onChange} onKeyDown={onKeyDown} />
<Button onClick={limitMaterialProduction}>Limit production</Button>
</Modal>
+13
View File
@@ -10117,6 +10117,19 @@ export interface WarehouseAPI {
* @remarks
* RAM cost: 20 GB
*
* This limit applies only to output; it does not affect input consumption.
*
* For example, in Agriculture, assume the division's raw production is 1000. You need to consume 500 Water and 200
* Chemicals to produce 1000 Plants and 1000 Food. If you set the limits for Plants and Food to 200 and 100
* respectively, you will still consume 500 Water and 200 Chemicals, but only produce 200 Plants and 100 Food.
*
* With industries that produce both materials and products, the material production limits do not affect product
* production.
*
* You can set a limit on any material, but only limits on output materials are enforced. Limits on other materials
* are stored but ignored during production calculations. For example, in Agriculture, only limits on Plants and Food
* are enforced.
*
* @param divisionName - Name of the division.
* @param city - Name of the city.
* @param materialName - Name of the material.