|
|
@@ -1,4 +1,5 @@
|
|
|
import {cachedFetchJSON} from './cache';
|
|
|
+import {setupPopover} from './popover';
|
|
|
|
|
|
const BUY = new Set([
|
|
|
// definitely buy
|
|
|
@@ -38,6 +39,7 @@ const shipbuilders = [
|
|
|
|
|
|
const main = document.querySelector('main.shipbuilding')!;
|
|
|
(async () => {
|
|
|
+ setupPopover();
|
|
|
main.innerHTML = 'loading...';
|
|
|
try {
|
|
|
await render();
|
|
|
@@ -268,6 +270,24 @@ function renderProduction(expertiseGroups: Record<string, string[]>, production:
|
|
|
const section = element('section');
|
|
|
section.append(element('h2', {textContent: 'production'}));
|
|
|
|
|
|
+ // mat → list of {outputMat, expertise, amount} that consume it as an input
|
|
|
+ const matConsumers: Record<string, {downstreamMat: string, expertise: string, amount: number}[]> = {};
|
|
|
+ for (const [expertise, productionBuildings] of Object.entries(expertiseGroups)) {
|
|
|
+ for (const building of productionBuildings) {
|
|
|
+ for (const [mat, totalAmount] of Object.entries(production[building])) {
|
|
|
+ const recipe = recipes[mat];
|
|
|
+ const outputPerRun = recipe.outputs.find((o) => o.material_ticker === mat)!.material_amount;
|
|
|
+ for (const input of recipe.inputs) {
|
|
|
+ const ticker = input.material_ticker;
|
|
|
+ if (!matConsumers[ticker])
|
|
|
+ matConsumers[ticker] = [];
|
|
|
+ const amount = input.material_amount * totalAmount / outputPerRun;
|
|
|
+ matConsumers[ticker].push({downstreamMat: mat, expertise, amount});
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
let totalConsumablesCost = 0;
|
|
|
for (const [expertise, productionBuildings] of Object.entries(expertiseGroups)) {
|
|
|
section.append(element('h3', {textContent: expertise.toLocaleLowerCase()}));
|
|
|
@@ -277,10 +297,13 @@ function renderProduction(expertiseGroups: Record<string, string[]>, production:
|
|
|
let buildingMins = 0;
|
|
|
for (const [index, [mat, amount]] of mats.entries()) {
|
|
|
const traded = prices[mat]?.AverageTraded30D ?? 0;
|
|
|
- const span = element('span', {
|
|
|
- textContent: `${formatAmount(amount)}x${mat}`,
|
|
|
- });
|
|
|
+ const span = element('span', {textContent: `${formatAmount(amount)}x${mat}`});
|
|
|
span.style.color = traded > amount * 2 ? '#0cc' : '#c70';
|
|
|
+ const consumers = matConsumers[mat];
|
|
|
+ if (consumers)
|
|
|
+ span.dataset.tooltip = consumers
|
|
|
+ .map((c) => `${formatAmount(c.amount)}x${mat} → ${c.downstreamMat} (${c.expertise.toLocaleLowerCase()})`)
|
|
|
+ .join('\n');
|
|
|
buildingMats.append(span);
|
|
|
if (index < mats.length - 1)
|
|
|
buildingMats.append(document.createTextNode(' '));
|