Merge branch 'upstream' into dev-submaps

This commit is contained in:
Mészáros Gergely 2022-04-05 01:38:36 +02:00
commit 5db436d627
5 changed files with 110 additions and 31 deletions

View file

@ -2857,6 +2857,7 @@
<button id="culturesEditNamesBase" data-tip="Edit a database used for names generation" class="icon-font"></button>
<button id="culturesAdd" data-tip="Add a new culture. Hold Shift to add multiple" class="icon-plus"></button>
<button id="culturesExport" data-tip="Download cultures-related data" class="icon-download"></button>
<button id="culturesImport" data-tip="Upload cultures-related data" class="icon-upload"></button>
<button id="culturesRecalculate" data-tip="Recalculate cultures based on current values of growth-related attributes" class="icon-retweet"></button>
<span data-tip="Allow culture centers, expansion and type changes to take an immediate effect">
<input id="culturesAutoChange" class="checkbox" type="checkbox">
@ -3756,6 +3757,7 @@
<input type="file" accept=".txt" id="templateToLoad">
<input type="file" accept=".txt" id="namesbaseToLoad">
<input type="file" accept=".json" id="styleToLoad">
<input type="file" accept=".csv" id="culturesCSVToLoad">
</div>
<!-- svg elements not required for map display -->
@ -4650,6 +4652,7 @@
<script defer src="modules/io/cloud.js"></script>
<script defer src="modules/io/export.js"></script>
<script defer src="modules/io/export-json.js"></script>
<script defer src="modules/io/formats.js"></script>
<!-- Web Components -->
<script defer src="components/fill-box.js"></script>

19
modules/io/formats.js Normal file
View file

@ -0,0 +1,19 @@
"use strict"
window.Formats = (function () {
async function csvParser (file, separator=",") {
const txt = await file.text();
const rows = txt.split("\n");
const headers = rows.shift().split(separator).map(x => x.toLowerCase());
const data = rows.filter(a => a.trim()!=="").map(r=>r.split(separator));
return {
headers,
data,
iterator: function* (sortf){
const dataset = sortf? this.data.sort(sortf):this.data;
for (const d of dataset)
yield Object.fromEntries(d.map((a, i) => [this.headers[i], a]));
}};
}
return {csvParser};
})();

View file

@ -794,7 +794,7 @@ window.Markers = (function () {
const {cells, burgs} = pack;
// Portals can only be added to burgs
if (cells.burg[cell]) return;
if (!cells.burg[cell]) return;
const burgName = burgs[cells.burg[cell]].name;
const name = `${burgName} Portal`;

View file

@ -1,5 +1,6 @@
"use strict";
function editCultures() {
const cultureTypes = ["Generic", "River", "Lake", "Naval", "Nomadic", "Hunting", "Highland"];
if (customization) return;
closeDialogs("#culturesEditor, .stable");
if (!layerIsOn("toggleCultures")) toggleCultures();
@ -37,6 +38,9 @@ function editCultures() {
document.getElementById("culturesEditNamesBase").addEventListener("click", editNamesbase);
document.getElementById("culturesAdd").addEventListener("click", enterAddCulturesMode);
document.getElementById("culturesExport").addEventListener("click", downloadCulturesData);
document.getElementById("culturesImport").addEventListener("click", () => document.getElementById("culturesCSVToLoad").click());
document.getElementById("culturesCSVToLoad").addEventListener("change", uploadCulturesData);
function refreshCulturesEditor() {
culturesCollectStatistics();
@ -169,8 +173,7 @@ function editCultures() {
function getTypeOptions(type) {
let options = "";
const types = ["Generic", "River", "Lake", "Naval", "Nomadic", "Hunting", "Highland"];
types.forEach(t => (options += `<option ${type === t ? "selected" : ""} value="${t}">${t}</option>`));
cultureTypes.forEach(t => (options += `<option ${type === t ? "selected" : ""} value="${t}">${t}</option>`));
return options;
}
@ -366,7 +369,7 @@ function editCultures() {
width: "24em",
buttons: {
Apply: function () {
applyPopulationChange();
applyPopulationChange(rural, urban, ruralPop.value, urbanPop.value, culture);
$(this).dialog("close");
},
Cancel: function () {
@ -375,33 +378,34 @@ function editCultures() {
},
position: {my: "center", at: "center", of: "svg"}
});
}
function applyPopulationChange() {
const ruralChange = ruralPop.value / rural;
function applyPopulationChange(oldRural, oldUrban, newRural, newUrban, culture) {
const ruralChange = newRural / oldRural;
if (isFinite(ruralChange) && ruralChange !== 1) {
const cells = pack.cells.i.filter(i => pack.cells.culture[i] === culture);
cells.forEach(i => (pack.cells.pop[i] *= ruralChange));
}
if (!isFinite(ruralChange) && +ruralPop.value > 0) {
const points = ruralPop.value / populationRate;
if (!isFinite(ruralChange) && +newRural > 0) {
const points = newRural / populationRate;
const cells = pack.cells.i.filter(i => pack.cells.culture[i] === culture);
const pop = rn(points / cells.length);
cells.forEach(i => (pack.cells.pop[i] = pop));
}
const urbanChange = urbanPop.value / urban;
const burgs = pack.burgs.filter(b => !b.removed && b.culture === culture);
const urbanChange = newUrban / oldUrban;
if (isFinite(urbanChange) && urbanChange !== 1) {
burgs.forEach(b => (b.population = rn(b.population * urbanChange, 4)));
}
if (!isFinite(urbanChange) && +urbanPop.value > 0) {
const points = urbanPop.value / populationRate / urbanization;
if (!isFinite(urbanChange) && +newUrban > 0) {
const points = newUrban / populationRate / urbanization;
const population = rn(points / burgs.length, 4);
burgs.forEach(b => (b.population = population));
}
refreshCulturesEditor();
}
}
function cultureRegenerateBurgs() {
if (customization === 4) return;
@ -856,7 +860,7 @@ function editCultures() {
function downloadCulturesData() {
const unit = areaUnit.value === "square" ? distanceUnitInput.value + "2" : areaUnit.value;
let data = "Id,Culture,Color,Cells,Expansionism,Type,Area " + unit + ",Population,Namesbase,Emblems Shape\n"; // headers
let data = "Id,Culture,Color,Cells,Expansionism,Type,Area " + unit + ",Population,Namesbase,Emblems Shape,Origin\n"; // headers
body.querySelectorAll(":scope > div").forEach(function (el) {
data += el.dataset.id + ",";
@ -869,7 +873,8 @@ function editCultures() {
data += el.dataset.population + ",";
const base = +el.dataset.base;
data += nameBases[base].name + ",";
data += el.dataset.emblems + "\n";
data += el.dataset.emblems + ",";
data += pack.cultures[+el.dataset.id].origin + "\n";
});
const name = getFileName("Cultures") + ".csv";
@ -881,4 +886,55 @@ function editCultures() {
exitCulturesManualAssignment("close");
exitAddCultureMode();
}
async function uploadCulturesData() {
const csv = await Formats.csvParser(this.files[0]);
this.value = "";
const cultures = pack.cultures;
const shapes = Object.keys(COA.shields.types)
.map(type => Object.keys(COA.shields[type]))
.flat();
const populated = pack.cells.pop.map((c, i) => c? i: null).filter(c => c);
cultures.forEach((item) => {if (item.i) item.removed = true});
for (const c of csv.iterator((a, b) => +a[0] > +b[0])) {
let current;
if (+c.id < cultures.length) {
current = cultures[c.id];
const ratio = current.urban / (current.rural + current.urban);
applyPopulationChange(current.rural, current.urban, c.population*(1 - ratio), c.population*ratio, +c.id);
} else {
current = {
i: cultures.length,
center: ra(populated),
area: 0,
cells: 0,
origin: 0,
rural: 0,
urban: 0,
}
cultures.push(current)
}
current.name = c.culture;
current.code = abbreviate(current.name, cultures.map(c => c.code));
current.color = c.color;
current.expansionism = +c.expansionism;
current.origin = +c.origin;
if (cultureTypes.includes(c.type))
current.type = c.type;
else
current.type = "Generic";
current.removed = false;
const shieldShape = c["emblems shape"].toLowerCase();
if (shapes.includes(shieldShape))
current.shield = shieldShape
else
current.shield = "heater";
const nbi = nameBases.findIndex(n => n.name==c.namesbase);
current.base = nbi==-1? 0: nbi;
}
const validId = cultures.filter(c => !c.removed).map(c => c.i);
cultures.forEach(item => item.origin = validId.includes(item.origin)? item.origin:0);
cultures[0].origin = null;
refreshCulturesEditor();
}
}

View file

@ -105,7 +105,8 @@ function showSupporters() {
Jonathan Williams,ojacid .,Brian Wilson,A Patreon of the Ahts,Shubham Jakhotiya,www15o,Jan Bundesmann,Angelique Badger,Joshua Xiong,Moist mongol,
Frank Fewkes,jason baldrick,Game Master Pro,Andrew Kircher,Preston Mitchell,Chris Kohut,Emarandzeb,Trentin Bergeron,Damon Gallaty,Pleaseworkforonce,
Jordan,William Markus,Sidr Dim,Alexander Whittaker,The Next Level,Patrick Valverde,Markus Peham,Daniel Cooper,the Beagles of Neorbus,Marley Moule,
Maximilian Schielke,Johnathan Xavier Hutchinson,Ele,Rita,Randy Ross,John Wick,RedSpaz,cameron cannon,Ian Grau-Fay,Kyle Barrett,Charlotte Wiland`;
Maximilian Schielke,Johnathan Xavier Hutchinson,Ele,Rita,Randy Ross,John Wick,RedSpaz,cameron cannon,Ian Grau-Fay,Kyle Barrett,Charlotte Wiland,
David Kaul,E. Jason Davis,Cyberate,Atenfox,Sea Wolf,Holly Loveless`;
const array = supporters
.replace(/(?:\r\n|\r|\n)/g, "")