goods export system

This commit is contained in:
Azgaar 2021-08-08 20:47:00 +03:00
parent 2312d99760
commit 1f6f693be7
7 changed files with 118 additions and 35 deletions

View file

@ -229,12 +229,12 @@ window.BurgsAndStates = (function () {
const {cells, burgs} = pack;
for (const burg of burgs) {
if (!burg.i || burg.removed) continue;
if (newburg && newburg.i !== burg.i) continue;
const {cell, state, pop, capital} = burg;
const {i, removed, cell, state, pop, capital, tradeCenter} = burg;
if (!i || removed) continue;
if (newburg && newburg.i !== i) continue;
burg.citadel = capital || (pop > 50 && P(0.75)) || P(0.5) ? 1 : 0;
burg.plaza = pop > 50 || (pop > 30 && P(0.75)) || (pop > 10 && P(0.5)) || P(0.25) ? 1 : 0;
burg.plaza = tradeCenter === i;
burg.walls = capital || pop > 30 || (pop > 20 && P(0.75)) || (pop > 10 && P(0.5)) || P(0.2) ? 1 : 0;
burg.shanty = pop > 30 || (pop > 20 && P(0.75)) || (burg.walls && P(0.75)) ? 1 : 0;
const religion = cells.religion[cell];

View file

@ -102,11 +102,11 @@ window.Production = (function () {
queue.queue({...occupation, basePriority: newBasePriority, priority: newPriority});
}
burg.produced = {};
for (const resourceId in productionPull) {
const production = Math.ceil(productionPull[resourceId]);
productionPull[resourceId] = production;
const production = productionPull[resourceId];
burg.produced[resourceId] = Math.ceil(production);
}
burg.production = productionPull;
}
};

View file

@ -2,23 +2,95 @@
window.Trade = (function () {
const defineCenters = () => {
const {cells} = pack;
TIME && console.time('defineCenters');
pack.trade = {centers: [], deals: []};
const {burgs, trade} = pack;
// min distance between trade centers
let minSpacing = (((graphWidth + graphHeight) * 2) / burgs.length ** 0.7) | 0;
const tradeScore = burgs.map(({i, removed, capital, port, population, produced}) => {
if (!i || removed) return {i: 0, score: 0};
const totalProduction = d3.sum(Object.values(produced));
let score = Math.round(totalProduction - population);
if (capital) score *= 2;
if (port) score *= 3;
return {i, score};
});
const candidatesSorted = tradeScore.sort((a, b) => b.score - a.score);
const centersTree = d3.quadtree();
for (const {i} of candidatesSorted) {
if (!i) continue;
const {x, y} = burgs[i];
const tradeCenter = centersTree.find(x, y, minSpacing);
if (tradeCenter) {
const centerBurg = tradeCenter[2];
burgs[i].tradeCenter = centerBurg;
const {x: x2, y: y2} = burgs[centerBurg];
debug.append('line').attr('x1', x).attr('y1', y).attr('x2', x2).attr('y2', y2).attr('stroke', 'black').attr('stroke-width', 0.2);
} else {
trade.centers.push({i: trade.centers.length, burg: i, x, y});
centersTree.add([x, y, i]);
burgs[i].tradeCenter = i;
}
minSpacing += 1;
}
for (const {i, score} of candidatesSorted) {
if (!i) continue;
const {x, y} = burgs[i];
debug.append('text').attr('x', x).attr('y', y).style('font-size', 4).text(score);
}
TIME && console.timeEnd('defineCenters');
};
const exportGoods = () => {
for (const burg of pack.burgs) {
if (!burg.i || burg.removed) continue;
const {population, production: resourcePool} = burg;
const localUsage = Math.ceil(population);
const {burgs, states, trade} = pack;
const DEFAULT_TRANSPORT_DIST = (graphWidth + graphHeight) / 20;
const surplus = {};
for (const resourceId in resourcePool) {
const production = resourcePool[resourceId];
const extraProduction = production - localUsage;
if (extraProduction > 0) surplus[resourceId] = extraProduction;
for (const tradeCenter of trade.centers) {
const {i: centerId, burg: centerBurg, x: x0, y: y0} = tradeCenter;
const goods = {};
for (const burg of burgs) {
const {i, removed, tradeCenter, produced, population, state, x, y} = burg;
if (!i || removed || tradeCenter !== centerBurg) continue;
const consumption = Math.ceil(population);
const distance = Math.hypot(x - x0, y - y0);
const transportFee = (distance / DEFAULT_TRANSPORT_DIST) ** 0.8 || 0.02;
const salesTax = states[state].salesTax || 0.1;
for (const resourceId in produced) {
const production = produced[resourceId];
const quantity = production - consumption;
if (quantity < 1) continue;
const {value} = Resources.get(+resourceId);
const basePrice = value * quantity;
const transportCost = rn((value * quantity) ** 0.5 * transportFee, 2);
const netPrice = basePrice - transportCost;
const stateIncome = rn(netPrice * salesTax, 2);
const burgIncome = rn(netPrice - stateIncome, 2);
if (burgIncome < 1 || burgIncome < basePrice / 4) continue;
trade.deals.push({resourceId: +resourceId, quantity, exporter: i, tradeCenter: centerId, basePrice, transportCost, stateIncome, burgIncome});
if (!goods[resourceId]) goods[resourceId] = quantity;
else goods[resourceId] += quantity;
}
}
burg.export = surplus;
tradeCenter.goods = goods;
}
};

View file

@ -98,8 +98,10 @@ function editBurg(id) {
else document.getElementById('burgShanty').classList.add('inactive');
// economics block
document.getElementById('burgProduction').innerHTML = getProduction(b.production);
document.getElementById('burgExport').innerHTML = getProduction(b.export);
document.getElementById('burgProduction').innerHTML = getProduction(b.produced);
const deals = pack.trade.deals;
document.getElementById('burgExport').innerHTML = getExport(deals.filter((deal) => deal.exporter === b.i));
document.getElementById('burgImport').innerHTML = '';
//toggle lock
updateBurgLockIcon();
@ -119,12 +121,12 @@ function editBurg(id) {
document.getElementById('burgEmblem').setAttribute('href', '#' + coaID);
}
function getProduction(resources) {
function getProduction(pool) {
let html = '';
for (const resourceId in resources) {
for (const resourceId in pool) {
const {name, unit, icon} = Resources.get(+resourceId);
const production = resources[resourceId];
const production = pool[resourceId];
const unitName = production > 1 ? unit + 's' : unit;
html += `<span data-tip="${name}: ${production} ${unitName}">
@ -136,6 +138,24 @@ function editBurg(id) {
return html;
}
function getExport(dealsArray) {
if (!dealsArray.length) return 'no';
const totalIncome = d3.sum(dealsArray.map((deal) => deal.burgIncome));
const exported = dealsArray.map((deal) => {
const {resourceId, quantity, burgIncome} = deal;
const {name, unit, icon} = Resources.get(resourceId);
const unitName = quantity > 1 ? unit + 's' : unit;
return `<span data-tip="${name}: ${quantity} ${unitName}. Income: ${burgIncome}">
<svg class="resIcon"><use href="#${icon}"></svg>
<span style="margin: 0 0.2em 0 -0.2em">${quantity}</span>
</span>`;
});
return `${totalIncome}: ${exported.join('')}`;
}
// [-1; 31] °C, source: https://en.wikipedia.org/wiki/List_of_cities_by_average_temperature
function getTemperatureLikeness(temperature) {
if (temperature < -15) return 'nowhere in the real-world';