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="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="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="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> <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"> <span data-tip="Allow culture centers, expansion and type changes to take an immediate effect">
<input id="culturesAutoChange" class="checkbox" type="checkbox"> <input id="culturesAutoChange" class="checkbox" type="checkbox">
@ -3756,6 +3757,7 @@
<input type="file" accept=".txt" id="templateToLoad"> <input type="file" accept=".txt" id="templateToLoad">
<input type="file" accept=".txt" id="namesbaseToLoad"> <input type="file" accept=".txt" id="namesbaseToLoad">
<input type="file" accept=".json" id="styleToLoad"> <input type="file" accept=".json" id="styleToLoad">
<input type="file" accept=".csv" id="culturesCSVToLoad">
</div> </div>
<!-- svg elements not required for map display --> <!-- svg elements not required for map display -->
@ -4650,6 +4652,7 @@
<script defer src="modules/io/cloud.js"></script> <script defer src="modules/io/cloud.js"></script>
<script defer src="modules/io/export.js"></script> <script defer src="modules/io/export.js"></script>
<script defer src="modules/io/export-json.js"></script> <script defer src="modules/io/export-json.js"></script>
<script defer src="modules/io/formats.js"></script>
<!-- Web Components --> <!-- Web Components -->
<script defer src="components/fill-box.js"></script> <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; const {cells, burgs} = pack;
// Portals can only be added to burgs // 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 burgName = burgs[cells.burg[cell]].name;
const name = `${burgName} Portal`; const name = `${burgName} Portal`;

View file

@ -1,5 +1,6 @@
"use strict"; "use strict";
function editCultures() { function editCultures() {
const cultureTypes = ["Generic", "River", "Lake", "Naval", "Nomadic", "Hunting", "Highland"];
if (customization) return; if (customization) return;
closeDialogs("#culturesEditor, .stable"); closeDialogs("#culturesEditor, .stable");
if (!layerIsOn("toggleCultures")) toggleCultures(); if (!layerIsOn("toggleCultures")) toggleCultures();
@ -37,6 +38,9 @@ function editCultures() {
document.getElementById("culturesEditNamesBase").addEventListener("click", editNamesbase); document.getElementById("culturesEditNamesBase").addEventListener("click", editNamesbase);
document.getElementById("culturesAdd").addEventListener("click", enterAddCulturesMode); document.getElementById("culturesAdd").addEventListener("click", enterAddCulturesMode);
document.getElementById("culturesExport").addEventListener("click", downloadCulturesData); document.getElementById("culturesExport").addEventListener("click", downloadCulturesData);
document.getElementById("culturesImport").addEventListener("click", () => document.getElementById("culturesCSVToLoad").click());
document.getElementById("culturesCSVToLoad").addEventListener("change", uploadCulturesData);
function refreshCulturesEditor() { function refreshCulturesEditor() {
culturesCollectStatistics(); culturesCollectStatistics();
@ -169,8 +173,7 @@ function editCultures() {
function getTypeOptions(type) { function getTypeOptions(type) {
let options = ""; let options = "";
const types = ["Generic", "River", "Lake", "Naval", "Nomadic", "Hunting", "Highland"]; cultureTypes.forEach(t => (options += `<option ${type === t ? "selected" : ""} value="${t}">${t}</option>`));
types.forEach(t => (options += `<option ${type === t ? "selected" : ""} value="${t}">${t}</option>`));
return options; return options;
} }
@ -366,7 +369,7 @@ function editCultures() {
width: "24em", width: "24em",
buttons: { buttons: {
Apply: function () { Apply: function () {
applyPopulationChange(); applyPopulationChange(rural, urban, ruralPop.value, urbanPop.value, culture);
$(this).dialog("close"); $(this).dialog("close");
}, },
Cancel: function () { Cancel: function () {
@ -375,32 +378,33 @@ function editCultures() {
}, },
position: {my: "center", at: "center", of: "svg"} position: {my: "center", at: "center", of: "svg"}
}); });
}
function applyPopulationChange() { function applyPopulationChange(oldRural, oldUrban, newRural, newUrban, culture) {
const ruralChange = ruralPop.value / rural; const ruralChange = newRural / oldRural;
if (isFinite(ruralChange) && ruralChange !== 1) { if (isFinite(ruralChange) && ruralChange !== 1) {
const cells = pack.cells.i.filter(i => pack.cells.culture[i] === culture); const cells = pack.cells.i.filter(i => pack.cells.culture[i] === culture);
cells.forEach(i => (pack.cells.pop[i] *= ruralChange)); cells.forEach(i => (pack.cells.pop[i] *= ruralChange));
}
if (!isFinite(ruralChange) && +ruralPop.value > 0) {
const points = ruralPop.value / 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;
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;
const population = rn(points / burgs.length, 4);
burgs.forEach(b => (b.population = population));
}
refreshCulturesEditor();
} }
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 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) && +newUrban > 0) {
const points = newUrban / populationRate / urbanization;
const population = rn(points / burgs.length, 4);
burgs.forEach(b => (b.population = population));
}
refreshCulturesEditor();
} }
function cultureRegenerateBurgs() { function cultureRegenerateBurgs() {
@ -856,7 +860,7 @@ function editCultures() {
function downloadCulturesData() { function downloadCulturesData() {
const unit = areaUnit.value === "square" ? distanceUnitInput.value + "2" : areaUnit.value; 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) { body.querySelectorAll(":scope > div").forEach(function (el) {
data += el.dataset.id + ","; data += el.dataset.id + ",";
@ -869,7 +873,8 @@ function editCultures() {
data += el.dataset.population + ","; data += el.dataset.population + ",";
const base = +el.dataset.base; const base = +el.dataset.base;
data += nameBases[base].name + ","; 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"; const name = getFileName("Cultures") + ".csv";
@ -881,4 +886,55 @@ function editCultures() {
exitCulturesManualAssignment("close"); exitCulturesManualAssignment("close");
exitAddCultureMode(); 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, 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, 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, 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 const array = supporters
.replace(/(?:\r\n|\r|\n)/g, "") .replace(/(?:\r\n|\r|\n)/g, "")