Show total raw input requirements with operating velocity on cards and two-line layout for Direct Inputs in inspector
This commit is contained in:
parent
ff8983273e
commit
1212224c19
4 changed files with 48 additions and 13 deletions
|
|
@ -169,6 +169,25 @@
|
||||||
background: var(--primary-blue-light);
|
background: var(--primary-blue-light);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.chain-item-row.chain-item-two-lines {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: stretch;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chain-item-header-line {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chain-item-sub-line {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
.chain-item-left {
|
.chain-item-left {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
|
||||||
|
|
@ -117,12 +117,16 @@ export function mountInspector(container, state, onAction) {
|
||||||
const parent = getProduct(inp.id);
|
const parent = getProduct(inp.id);
|
||||||
const parentStock = state.products[inp.id]?.stock || 0;
|
const parentStock = state.products[inp.id]?.stock || 0;
|
||||||
return `
|
return `
|
||||||
<div class="chain-item-row" data-product="${parent.id}">
|
<div class="chain-item-row chain-item-two-lines" data-product="${parent.id}">
|
||||||
<div class="chain-item-left">
|
<div class="chain-item-header-line">
|
||||||
<iconify-icon icon="${parent.icon}" style="color: ${parent.color};"></iconify-icon>
|
<div class="chain-item-left">
|
||||||
<span>${parent.name}</span>
|
<iconify-icon icon="${parent.icon}" style="color: ${parent.color};"></iconify-icon>
|
||||||
|
<span class="chain-item-name">${parent.name}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="chain-item-sub-line">
|
||||||
|
<span class="chain-item-ratio font-mono">${inp.amount} per unit (<strong id="insp-inp-val-${inp.id}">${fmtNum(parentStock, 0)}</strong> on hand)</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="chain-item-ratio font-mono">${inp.amount} per unit (<strong id="insp-inp-val-${inp.id}">${fmtNum(parentStock, 0)}</strong> on hand)</span>
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}).join('')}
|
}).join('')}
|
||||||
|
|
|
||||||
|
|
@ -48,17 +48,19 @@ export function renderFacilityCardHtml(p, pState, state, buyMode) {
|
||||||
if (!isRaw) {
|
if (!isRaw) {
|
||||||
inputsHtml = `
|
inputsHtml = `
|
||||||
<div class="inputs-strip">
|
<div class="inputs-strip">
|
||||||
<span class="inputs-label">Inputs per line:</span>
|
<span class="inputs-label">Total Input Requirements (Operating Velocity):</span>
|
||||||
<div class="inputs-chips">
|
<div class="inputs-chips">
|
||||||
${p.inputs.map(inp => {
|
${p.inputs.map(inp => {
|
||||||
const inpProduct = getProduct(inp.id);
|
const inpProduct = getProduct(inp.id);
|
||||||
const currentStock = state.products[inp.id]?.stock || 0;
|
const currentStock = state.products[inp.id]?.stock || 0;
|
||||||
const neededPerLine = inp.amount * pState.lines;
|
const neededPerBatch = inp.amount * pState.lines;
|
||||||
const isLow = currentStock < neededPerLine;
|
const reqRatePerSec = inp.amount * pState.lines * (rates.cyclesPerSec || 0);
|
||||||
|
const isLow = currentStock < neededPerBatch;
|
||||||
return `
|
return `
|
||||||
<span class="input-chip ${isLow ? 'low-stock' : ''}" id="chip-${p.id}-${inp.id}" title="${inpProduct?.name}">
|
<span class="input-chip ${isLow ? 'low-stock' : ''}" id="chip-${p.id}-${inp.id}" title="${inpProduct?.name} requirement: ${inp.amount * pState.lines} per batch, running at ${fmtNum(reqRatePerSec, 1)} units/sec consumption">
|
||||||
<iconify-icon icon="${inpProduct?.icon || 'lucide:box'}"></iconify-icon>
|
<iconify-icon icon="${inpProduct?.icon || 'lucide:box'}"></iconify-icon>
|
||||||
${inpProduct?.name}: <strong id="chip-val-${p.id}-${inp.id}">${fmtNum(currentStock, 0)}</strong> / ${fmtNum(neededPerLine, 0)}
|
<span>${inpProduct?.name}: <strong id="chip-val-${p.id}-${inp.id}">${fmtNum(currentStock, 0)}</strong> / ${fmtNum(neededPerBatch, 0)}</span>
|
||||||
|
<span class="input-chip-rate font-mono" id="chip-rate-${p.id}-${inp.id}">(${fmtNum(reqRatePerSec, 1)}/s)</span>
|
||||||
</span>
|
</span>
|
||||||
`;
|
`;
|
||||||
}).join('')}
|
}).join('')}
|
||||||
|
|
@ -309,8 +311,9 @@ export function updateFacilityCardDom(p, pState, state, buyMode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Input Chips Stock
|
// Input Chips Stock & Real-time Rate
|
||||||
if (p.inputs && p.inputs.length > 0) {
|
if (p.inputs && p.inputs.length > 0) {
|
||||||
|
const cyclesPerSec = rates.cyclesPerSec || 0;
|
||||||
for (const inp of p.inputs) {
|
for (const inp of p.inputs) {
|
||||||
const currentStock = state.products[inp.id]?.stock || 0;
|
const currentStock = state.products[inp.id]?.stock || 0;
|
||||||
const elChipVal = document.getElementById(`chip-val-${p.id}-${inp.id}`);
|
const elChipVal = document.getElementById(`chip-val-${p.id}-${inp.id}`);
|
||||||
|
|
@ -320,6 +323,14 @@ export function updateFacilityCardDom(p, pState, state, buyMode) {
|
||||||
elChipVal.textContent = textVal;
|
elChipVal.textContent = textVal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const elChipRate = document.getElementById(`chip-rate-${p.id}-${inp.id}`);
|
||||||
|
if (elChipRate) {
|
||||||
|
const reqRatePerSec = inp.amount * pState.lines * cyclesPerSec;
|
||||||
|
const textRate = `(${fmtNum(reqRatePerSec, 1)}/s)`;
|
||||||
|
if (elChipRate.textContent !== textRate) {
|
||||||
|
elChipRate.textContent = textRate;
|
||||||
|
}
|
||||||
|
}
|
||||||
const elChip = document.getElementById(`chip-${p.id}-${inp.id}`);
|
const elChip = document.getElementById(`chip-${p.id}-${inp.id}`);
|
||||||
if (elChip) {
|
if (elChip) {
|
||||||
const needed = inp.amount * pState.lines;
|
const needed = inp.amount * pState.lines;
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,8 @@ export function getProductOutputRates(p, pState, state) {
|
||||||
const isBottlenecked = !!pState.isBottlenecked;
|
const isBottlenecked = !!pState.isBottlenecked;
|
||||||
|
|
||||||
// Output velocity: units per second
|
// Output velocity: units per second
|
||||||
const prodRate = isBottlenecked ? 0 : (1 / baseCycleTime) * p.outputAmount * pState.lines;
|
const cyclesPerSec = (1 / baseCycleTime);
|
||||||
|
const prodRate = isBottlenecked ? 0 : cyclesPerSec * p.outputAmount * pState.lines;
|
||||||
|
|
||||||
// Logistics revenue rate: items sold passively per second * price
|
// Logistics revenue rate: items sold passively per second * price
|
||||||
const logisticsUnits = pState.logistics || 0;
|
const logisticsUnits = pState.logistics || 0;
|
||||||
|
|
@ -51,7 +52,7 @@ export function getProductOutputRates(p, pState, state) {
|
||||||
revRate = effectiveSellRate * salePrice;
|
revRate = effectiveSellRate * salePrice;
|
||||||
}
|
}
|
||||||
|
|
||||||
return { prodRate, revRate, isBottlenecked, milestoneMult };
|
return { prodRate, revRate, isBottlenecked, milestoneMult, baseCycleTime, cyclesPerSec };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue