|
@@ -97,6 +97,8 @@ async function _render(planetName: string, pop: Pop) {
|
|
|
const prices: Map<string, number> = new Map();
|
|
const prices: Map<string, number> = new Map();
|
|
|
for (const price of allPrices)
|
|
for (const price of allPrices)
|
|
|
if (price.exchange_code === 'IC1')
|
|
if (price.exchange_code === 'IC1')
|
|
|
|
|
+ prices.set(price.ticker, price.vwap_30d || price.ask);
|
|
|
|
|
+ else if (price.exchange_code === 'UNIVERSE' && prices.get(price.ticker) === 0) // UNIVERSE always comes after IC1
|
|
|
prices.set(price.ticker, price.vwap_30d);
|
|
prices.set(price.ticker, price.vwap_30d);
|
|
|
|
|
|
|
|
renderTarget.innerHTML = `last POPR: ${lastPOPR.ReportTimestamp} (${lastPOPRts})
|
|
renderTarget.innerHTML = `last POPR: ${lastPOPR.ReportTimestamp} (${lastPOPRts})
|
|
@@ -179,6 +181,7 @@ async function _render(planetName: string, pop: Pop) {
|
|
|
<table class="options">
|
|
<table class="options">
|
|
|
<tr>
|
|
<tr>
|
|
|
<th>config</th>
|
|
<th>config</th>
|
|
|
|
|
+ <th>projected happiness</th>
|
|
|
<th>projected migration</th>
|
|
<th>projected migration</th>
|
|
|
<th>cost/day</th>
|
|
<th>cost/day</th>
|
|
|
<th>unit cost</th>
|
|
<th>unit cost</th>
|
|
@@ -189,6 +192,7 @@ async function _render(planetName: string, pop: Pop) {
|
|
|
unitCost = formatNum(result.cost / result.migration);
|
|
unitCost = formatNum(result.cost / result.migration);
|
|
|
return `<tr>
|
|
return `<tr>
|
|
|
<td>${[...result.config.entries()].map(([building, fill]) => `${building}: ${fill.numMats}`).join(', ')}</td>
|
|
<td>${[...result.config.entries()].map(([building, fill]) => `${building}: ${fill.numMats}`).join(', ')}</td>
|
|
|
|
|
+ <td>${formatPct(result.happiness)}</td>
|
|
|
<td>${formatDelta(result.migration)}</td>
|
|
<td>${formatDelta(result.migration)}</td>
|
|
|
<td>${formatNum(result.cost)}</td>
|
|
<td>${formatNum(result.cost)}</td>
|
|
|
<td>${unitCost}</td>
|
|
<td>${unitCost}</td>
|
|
@@ -248,8 +252,8 @@ function calcPOPIFilled(infra: Infrastructure): number | null {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function paretoFront(pop: Pop, totalNeeds: Record<Need, number>, siteCount: number, currentPOPIFilled: POPIFill,
|
|
function paretoFront(pop: Pop, totalNeeds: Record<Need, number>, siteCount: number, currentPOPIFilled: POPIFill,
|
|
|
- currentPop: number, prices: Map<string, number>): {config: POPIFill, migration: number, cost: number}[] {
|
|
|
|
|
- const results: {config: POPIFill, migration: number, cost: number}[] = [];
|
|
|
|
|
|
|
+ currentPop: number, prices: Map<string, number>): {config: POPIFill, happiness: number, migration: number, cost: number}[] {
|
|
|
|
|
+ const results: {config: POPIFill, happiness: number, migration: number, cost: number}[] = [];
|
|
|
for (const config of popiFillCombinations(currentPOPIFilled)) {
|
|
for (const config of popiFillCombinations(currentPOPIFilled)) {
|
|
|
const happiness = projectedHappiness(pop, totalNeeds, siteCount, config);
|
|
const happiness = projectedHappiness(pop, totalNeeds, siteCount, config);
|
|
|
let migration = 0;
|
|
let migration = 0;
|
|
@@ -269,7 +273,7 @@ function paretoFront(pop: Pop, totalNeeds: Record<Need, number>, siteCount: numb
|
|
|
if ((results[i].migration <= migration && results[i].cost > cost) ||
|
|
if ((results[i].migration <= migration && results[i].cost > cost) ||
|
|
|
(results[i].migration < migration && results[i].cost >= cost))
|
|
(results[i].migration < migration && results[i].cost >= cost))
|
|
|
results.splice(i, 1);
|
|
results.splice(i, 1);
|
|
|
- results.push({config, migration, cost});
|
|
|
|
|
|
|
+ results.push({config, happiness, migration, cost});
|
|
|
}
|
|
}
|
|
|
return results;
|
|
return results;
|
|
|
}
|
|
}
|
|
@@ -332,7 +336,7 @@ function calcCost(config: POPIFill, prices: Map<string, number>): number {
|
|
|
const matPrices: {ticker: string, costPerDay: number}[] = [];
|
|
const matPrices: {ticker: string, costPerDay: number}[] = [];
|
|
|
for (const [mat, amount] of Object.entries(mats)) {
|
|
for (const [mat, amount] of Object.entries(mats)) {
|
|
|
const matCost = prices.get(mat)!;
|
|
const matCost = prices.get(mat)!;
|
|
|
- if (matCost === undefined)
|
|
|
|
|
|
|
+ if (!matCost)
|
|
|
throw new Error('no price for ' + mat);
|
|
throw new Error('no price for ' + mat);
|
|
|
matPrices.push({ticker: mat, costPerDay: matCost * amount});
|
|
matPrices.push({ticker: mat, costPerDay: matCost * amount});
|
|
|
}
|
|
}
|
|
@@ -465,4 +469,5 @@ interface Price {
|
|
|
ticker: string
|
|
ticker: string
|
|
|
exchange_code: string
|
|
exchange_code: string
|
|
|
vwap_30d: number
|
|
vwap_30d: number
|
|
|
|
|
+ ask: number
|
|
|
}
|
|
}
|