|
@@ -223,18 +223,24 @@ function renderProduction(expertiseGroups: Record<string, string[]>, production:
|
|
|
const section = element('section');
|
|
const section = element('section');
|
|
|
section.append(element('h2', {textContent: 'production'}));
|
|
section.append(element('h2', {textContent: 'production'}));
|
|
|
|
|
|
|
|
|
|
+ const matInputs: Record<string, {upstreamMat: string, amount: number}[]> = {};
|
|
|
// mat → list of {outputMat, expertise, amount} that consume it as an input
|
|
// mat → list of {outputMat, expertise, amount} that consume it as an input
|
|
|
const matConsumers: Record<string, {downstreamMat: string, expertise: string, amount: number}[]> = {};
|
|
const matConsumers: Record<string, {downstreamMat: string, expertise: string, amount: number}[]> = {};
|
|
|
for (const [expertise, productionBuildings] of Object.entries(expertiseGroups)) {
|
|
for (const [expertise, productionBuildings] of Object.entries(expertiseGroups)) {
|
|
|
for (const building of productionBuildings) {
|
|
for (const building of productionBuildings) {
|
|
|
for (const [mat, totalAmount] of Object.entries(production[building])) {
|
|
for (const [mat, totalAmount] of Object.entries(production[building])) {
|
|
|
const recipe = recipes[mat];
|
|
const recipe = recipes[mat];
|
|
|
|
|
+ if (!matInputs[mat])
|
|
|
|
|
+ matInputs[mat] = [];
|
|
|
|
|
+
|
|
|
const outputPerRun = recipe.outputs.find((o) => o.material_ticker === mat)!.material_amount;
|
|
const outputPerRun = recipe.outputs.find((o) => o.material_ticker === mat)!.material_amount;
|
|
|
for (const input of recipe.inputs) {
|
|
for (const input of recipe.inputs) {
|
|
|
const ticker = input.material_ticker;
|
|
const ticker = input.material_ticker;
|
|
|
|
|
+ const amount = input.material_amount * totalAmount / outputPerRun;
|
|
|
|
|
+ matInputs[mat].push({upstreamMat: ticker, amount});
|
|
|
|
|
+
|
|
|
if (!matConsumers[ticker])
|
|
if (!matConsumers[ticker])
|
|
|
matConsumers[ticker] = [];
|
|
matConsumers[ticker] = [];
|
|
|
- const amount = input.material_amount * totalAmount / outputPerRun;
|
|
|
|
|
matConsumers[ticker].push({downstreamMat: mat, expertise, amount});
|
|
matConsumers[ticker].push({downstreamMat: mat, expertise, amount});
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -251,7 +257,8 @@ function renderProduction(expertiseGroups: Record<string, string[]>, production:
|
|
|
let buildingMins = 0;
|
|
let buildingMins = 0;
|
|
|
for (const [mat, amount] of mats) {
|
|
for (const [mat, amount] of mats) {
|
|
|
buildingMats.append(document.createTextNode(' '));
|
|
buildingMats.append(document.createTextNode(' '));
|
|
|
- buildingMats.append(renderProductionBuildingMat(expertise, mat, amount, storage[mat] ?? 0, matConsumers, shipTo));
|
|
|
|
|
|
|
+ buildingMats.append(renderProductionBuildingMat(expertise, mat, amount, storage,
|
|
|
|
|
+ matInputs, matConsumers, shipTo));
|
|
|
|
|
|
|
|
const recipe = recipes[mat];
|
|
const recipe = recipes[mat];
|
|
|
const outputPerRun = recipe.outputs.find((o) => o.material_ticker === mat)!.material_amount;
|
|
const outputPerRun = recipe.outputs.find((o) => o.material_ticker === mat)!.material_amount;
|
|
@@ -281,15 +288,23 @@ function renderProduction(expertiseGroups: Record<string, string[]>, production:
|
|
|
return section;
|
|
return section;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-function renderProductionBuildingMat(expertise: string, mat: string, amount: number, inStorage: number,
|
|
|
|
|
- matConsumers: Record<string, {downstreamMat: string, expertise: string, amount: number}[]>,
|
|
|
|
|
- shipTo: Record<string, Record<string, number>>): HTMLElement {
|
|
|
|
|
|
|
+function renderProductionBuildingMat(expertise: string, mat: string, amount: number, storage: Record<string, number>,
|
|
|
|
|
+ matInputs: Record<string, {upstreamMat: string, amount: number}[]>,
|
|
|
|
|
+ matConsumers: Record<string, {downstreamMat: string, expertise: string, amount: number}[]>,
|
|
|
|
|
+ shipTo: Record<string, Record<string, number>>): HTMLElement {
|
|
|
|
|
+ const inStorage = storage[mat] ?? 0;
|
|
|
const span = element('span', {textContent: `${formatAmount(amount)}x${mat} (${inStorage})`});
|
|
const span = element('span', {textContent: `${formatAmount(amount)}x${mat} (${inStorage})`});
|
|
|
const percent = Math.min(inStorage / (amount * 2), 1);
|
|
const percent = Math.min(inStorage / (amount * 2), 1);
|
|
|
span.style.color = `color-mix(in xyz, #0aa ${percent * 100}%, #f80 )`;
|
|
span.style.color = `color-mix(in xyz, #0aa ${percent * 100}%, #f80 )`;
|
|
|
|
|
+
|
|
|
|
|
+ let tooltip = '';
|
|
|
|
|
+ const inputs = matInputs[mat];
|
|
|
|
|
+ if (inputs)
|
|
|
|
|
+ tooltip += inputs.map((i) => `${formatAmount(i.amount)}x${i.upstreamMat} (${storage[i.upstreamMat] ?? 0}) → ` +
|
|
|
|
|
+ `${formatAmount(amount)}x${mat}`).join('\n') + '\n';
|
|
|
const consumers = matConsumers[mat];
|
|
const consumers = matConsumers[mat];
|
|
|
if (consumers) {
|
|
if (consumers) {
|
|
|
- span.dataset.tooltip = consumers
|
|
|
|
|
|
|
+ tooltip += consumers
|
|
|
.map((c) => `${formatAmount(c.amount)}x${mat} → ${c.downstreamMat} (${c.expertise.toLocaleLowerCase()})`)
|
|
.map((c) => `${formatAmount(c.amount)}x${mat} → ${c.downstreamMat} (${c.expertise.toLocaleLowerCase()})`)
|
|
|
.join('\n');
|
|
.join('\n');
|
|
|
for (const consumer of consumers) {
|
|
for (const consumer of consumers) {
|
|
@@ -300,6 +315,7 @@ function renderProductionBuildingMat(expertise: string, mat: string, amount: num
|
|
|
shipTo[consumer.expertise][mat] = (shipTo[consumer.expertise][mat] ?? 0) + consumer.amount;
|
|
shipTo[consumer.expertise][mat] = (shipTo[consumer.expertise][mat] ?? 0) + consumer.amount;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ span.dataset.tooltip = tooltip;
|
|
|
return span;
|
|
return span;
|
|
|
}
|
|
}
|
|
|
|
|
|