From 1c5f9f7ab60c468b9b3e2924dcd2e8541efdbc2f Mon Sep 17 00:00:00 2001 From: Azgaar Date: Sat, 28 Sep 2019 20:25:53 +0300 Subject: [PATCH] v1.1.03 --- modules/ui/cultures-editor.js | 63 ++++++++++++++++++++++++++++++++- modules/ui/provinces-editor.js | 59 +++++++++++++++++++++++++++++++ modules/ui/religions-editor.js | 64 +++++++++++++++++++++++++++++++++- modules/ui/states-editor.js | 9 ++--- modules/ui/zones-editor.js | 62 +++++++++++++++++++++++++++++++- 5 files changed, 250 insertions(+), 7 deletions(-) diff --git a/modules/ui/cultures-editor.js b/modules/ui/cultures-editor.js index c1562171..7c27a9fc 100644 --- a/modules/ui/cultures-editor.js +++ b/modules/ui/cultures-editor.js @@ -63,7 +63,7 @@ function editCultures() { const rural = c.rural * populationRate.value; const urban = c.urban * populationRate.value * urbanization.value; const population = rn(rural + urban); - const populationTip = `Total population: ${si(population)}; Rural population: ${si(rural)}; Urban population: ${si(urban)}`; + const populationTip = `Total population: ${si(population)}; Rural population: ${si(rural)}; Urban population: ${si(urban)}. Click to edit`; totalArea += area; totalPopulation += population; @@ -125,6 +125,7 @@ function editCultures() { body.querySelectorAll("div > input.statePower").forEach(el => el.addEventListener("input", cultureChangeExpansionism)); body.querySelectorAll("div > select.cultureType").forEach(el => el.addEventListener("change", cultureChangeType)); body.querySelectorAll("div > select.cultureBase").forEach(el => el.addEventListener("change", cultureChangeBase)); + body.querySelectorAll("div > div.culturePopulation").forEach(el => el.addEventListener("click", changePopulation)); body.querySelectorAll("div > span.icon-arrows-cw").forEach(el => el.addEventListener("click", cultureRegenerateBurgs)); body.querySelectorAll("div > span.icon-trash-empty").forEach(el => el.addEventListener("click", cultureRemove)); @@ -203,6 +204,66 @@ function editCultures() { this.parentNode.dataset.base = pack.cultures[culture].base = v; } + function changePopulation() { + const culture = +this.parentNode.dataset.id; + const c = pack.cultures[culture]; + if (!c.cells) {tip("Culture does not have any cells, cannot change population", false, "error"); return;} + const rural = rn(c.rural * populationRate.value); + const urban = rn(c.urban * populationRate.value * urbanization.value); + const total = rural + urban; + const l = n => Number(n).toLocaleString(); + const burgs = pack.burgs.filter(b => !b.removed && b.culture === culture); + + alertMessage.innerHTML = ` + Rural: + Urban: +

Total population: ${l(total)} ⇒ ${l(total)} (100%)

`; + + const update = function() { + const totalNew = ruralPop.valueAsNumber + urbanPop.valueAsNumber; + if (isNaN(totalNew)) return; + totalPop.innerHTML = l(totalNew); + totalPopPerc.innerHTML = rn(totalNew / total * 100); + } + + ruralPop.oninput = () => update(); + urbanPop.oninput = () => update(); + + $("#alert").dialog({ + resizable: false, title: "Change culture population", width: "24em", buttons: { + Apply: function() {applyPopulationChange(); $(this).dialog("close");}, + Cancel: function() {$(this).dialog("close");} + }, position: {my: "center", at: "center", of: "svg"} + }); + + function applyPopulationChange() { + const ruralChange = rn(ruralPop.value / rural, 4); + 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.value; + 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 = rn(urbanPop.value / urban, 4); + if (isFinite(urbanChange) && urbanChange !== 1) { + burgs.forEach(b => b.population *= urbanChange); + } + if (!isFinite(urbanChange) && +urbanPop.value > 0) { + const points = urbanPop.value / populationRate.value / urbanization.value; + const population = rn(points / burgs.length); + burgs.forEach(b => b.population = population); + } + + refreshCulturesEditor(); + } + + } + function cultureRegenerateBurgs() { if (customization === 4) return; const culture = +this.parentNode.dataset.id; diff --git a/modules/ui/provinces-editor.js b/modules/ui/provinces-editor.js index 5407a075..2c16a4b2 100644 --- a/modules/ui/provinces-editor.js +++ b/modules/ui/provinces-editor.js @@ -39,6 +39,7 @@ function editProvinces() { if (cl.contains("icon-fleur")) provinceOpenCOA(p); else if (cl.contains("icon-star-empty")) capitalZoomIn(p); else if (cl.contains("icon-flag-empty")) declareProvinceIndependence(p); else + if (cl.contains("culturePopulation")) changePopulation(p); else if (cl.contains("icon-pin")) focusOn(p, cl); else if (cl.contains("icon-trash-empty")) removeProvince(p); if (cl.contains("hoverButton") && cl.contains("stateName")) regenerateName(p, line); else @@ -266,6 +267,64 @@ function editProvinces() { editStates(); } + function changePopulation(province) { + const p = pack.provinces[province]; + if (!p.cells) {tip("Province does not have any cells, cannot change population", false, "error"); return;} + const rural = rn(p.rural * populationRate.value); + const urban = rn(p.urban * populationRate.value * urbanization.value); + const total = rural + urban; + const l = n => Number(n).toLocaleString(); + + alertMessage.innerHTML = ` + Rural: + Urban: +

Total population: ${l(total)} ⇒ ${l(total)} (100%)

`; + + const update = function() { + const totalNew = ruralPop.valueAsNumber + urbanPop.valueAsNumber; + if (isNaN(totalNew)) return; + totalPop.innerHTML = l(totalNew); + totalPopPerc.innerHTML = rn(totalNew / total * 100); + } + + ruralPop.oninput = () => update(); + urbanPop.oninput = () => update(); + + $("#alert").dialog({ + resizable: false, title: "Change province population", width: "24em", buttons: { + Apply: function() {applyPopulationChange(); $(this).dialog("close");}, + Cancel: function() {$(this).dialog("close");} + }, position: {my: "center", at: "center", of: "svg"} + }); + + function applyPopulationChange() { + const ruralChange = rn(ruralPop.value / rural, 4); + if (isFinite(ruralChange) && ruralChange !== 1) { + const cells = pack.cells.i.filter(i => pack.cells.province[i] === province); + cells.forEach(i => pack.cells.pop[i] *= ruralChange); + } + if (!isFinite(ruralChange) && +ruralPop.value > 0) { + const points = ruralPop.value / populationRate.value; + const cells = pack.cells.i.filter(i => pack.cells.province[i] === province); + const pop = rn(points / cells.length); + cells.forEach(i => pack.cells.pop[i] = pop); + } + + const urbanChange = rn(urbanPop.value / urban, 4); + if (isFinite(urbanChange) && urbanChange !== 1) { + p.burgs.forEach(b => pack.burgs[b].population *= urbanChange); + } + if (!isFinite(urbanChange) && +urbanPop.value > 0) { + const points = urbanPop.value / populationRate.value / urbanization.value; + const population = rn(points / burgs.length); + p.burgs.forEach(b => pack.burgs[b].population = population); + } + + refreshProvincesEditor(); + } + + } + function focusOn(p, cl) { const inactive = cl.contains("inactive"); cl.toggle("inactive"); diff --git a/modules/ui/religions-editor.js b/modules/ui/religions-editor.js index ab5a5950..7a24b978 100644 --- a/modules/ui/religions-editor.js +++ b/modules/ui/religions-editor.js @@ -66,7 +66,7 @@ function editReligions() { const urban = r.urban * populationRate.value * urbanization.value; const population = rn(rural + urban); if (r.i && !r.cells && body.dataset.extinct !== "show") continue; // hide extinct religions - const populationTip = `Believers: ${si(population)}; Rural areas: ${si(rural)}; Urban areas: ${si(urban)}`; + const populationTip = `Believers: ${si(population)}; Rural areas: ${si(rural)}; Urban areas: ${si(urban)}. Click to change`; totalArea += area; totalPopulation += population; @@ -124,6 +124,7 @@ function editReligions() { body.querySelectorAll("div > input.religionForm").forEach(el => el.addEventListener("input", religionChangeForm)); body.querySelectorAll("div > input.religionDeity").forEach(el => el.addEventListener("input", religionChangeDeity)); body.querySelectorAll("div > span.icon-arrows-cw").forEach(el => el.addEventListener("click", regenerateDeity)); + body.querySelectorAll("div > div.culturePopulation").forEach(el => el.addEventListener("click", changePopulation)); body.querySelectorAll("div > span.icon-trash-empty").forEach(el => el.addEventListener("click", religionRemove)); if (body.dataset.type === "percentage") {body.dataset.type = "absolute"; togglePercentageMode();} @@ -228,6 +229,67 @@ function editReligions() { this.nextElementSibling.value = deity; } + function changePopulation() { + const religion = +this.parentNode.dataset.id; + const r = pack.religions[religion]; + if (!r.cells) {tip("Religion does not have any cells, cannot change population", false, "error"); return;} + const rural = rn(r.rural * populationRate.value); + const urban = rn(r.urban * populationRate.value * urbanization.value); + const total = rural + urban; + const l = n => Number(n).toLocaleString(); + const burgs = pack.burgs.filter(b => !b.removed && pack.cells.religion[b.cell] === religion); + + alertMessage.innerHTML = `

Please note all population of religion territory is considered + believers of this religion. It means believers number change will directly change population

+ Rural: + Urban: +

Total believers: ${l(total)} ⇒ ${l(total)} (100%)

`; + + const update = function() { + const totalNew = ruralPop.valueAsNumber + urbanPop.valueAsNumber; + if (isNaN(totalNew)) return; + totalPop.innerHTML = l(totalNew); + totalPopPerc.innerHTML = rn(totalNew / total * 100); + } + + ruralPop.oninput = () => update(); + urbanPop.oninput = () => update(); + + $("#alert").dialog({ + resizable: false, title: "Change believers number", width: "24em", buttons: { + Apply: function() {applyPopulationChange(); $(this).dialog("close");}, + Cancel: function() {$(this).dialog("close");} + }, position: {my: "center", at: "center", of: "svg"} + }); + + function applyPopulationChange() { + const ruralChange = rn(ruralPop.value / rural, 4); + if (isFinite(ruralChange) && ruralChange !== 1) { + const cells = pack.cells.i.filter(i => pack.cells.religion[i] === religion); + cells.forEach(i => pack.cells.pop[i] *= ruralChange); + } + if (!isFinite(ruralChange) && +ruralPop.value > 0) { + const points = ruralPop.value / populationRate.value; + const cells = pack.cells.i.filter(i => pack.cells.religion[i] === religion); + const pop = rn(points / cells.length); + cells.forEach(i => pack.cells.pop[i] = pop); + } + + const urbanChange = rn(urbanPop.value / urban, 4); + if (isFinite(urbanChange) && urbanChange !== 1) { + burgs.forEach(b => b.population *= urbanChange); + } + if (!isFinite(urbanChange) && +urbanPop.value > 0) { + const points = urbanPop.value / populationRate.value / urbanization.value; + const population = rn(points / burgs.length); + burgs.forEach(b => b.population = population); + } + + refreshReligionsEditor(); + } + + } + function religionRemove() { if (customization) return; const religion = +this.parentNode.dataset.id; diff --git a/modules/ui/states-editor.js b/modules/ui/states-editor.js index d8288f11..3a647071 100644 --- a/modules/ui/states-editor.js +++ b/modules/ui/states-editor.js @@ -297,16 +297,17 @@ function editStates() { const rural = rn(s.rural * populationRate.value); const urban = rn(s.urban * populationRate.value * urbanization.value); const total = rural + urban; + const l = n => Number(n).toLocaleString(); alertMessage.innerHTML = ` - Rural: + Rural: Urban: -

Total population: ${total} ⇒ ${total} (100%)

`; +

Total population: ${l(total)} ⇒ ${l(total)} (100%)

`; const update = function() { const totalNew = ruralPop.valueAsNumber + urbanPop.valueAsNumber; if (isNaN(totalNew)) return; - totalPop.innerHTML = totalNew; + totalPop.innerHTML = l(totalNew); totalPopPerc.innerHTML = rn(totalNew / total * 100); } @@ -314,7 +315,7 @@ function editStates() { urbanPop.oninput = () => update(); $("#alert").dialog({ - resizable: false, title: "Change state population", width: "23em", buttons: { + resizable: false, title: "Change state population", width: "24em", buttons: { Apply: function() {applyPopulationChange(); $(this).dialog("close");}, Cancel: function() {$(this).dialog("close");} }, position: {my: "center", at: "center", of: "svg"} diff --git a/modules/ui/zones-editor.js b/modules/ui/zones-editor.js index ef75f2cf..f8811960 100644 --- a/modules/ui/zones-editor.js +++ b/modules/ui/zones-editor.js @@ -27,6 +27,7 @@ function editZones() { body.addEventListener("click", function(ev) { const el = ev.target, cl = el.classList, zone = el.parentNode.dataset.id; + if (cl.contains("culturePopulation")) {changePopulation(zone); return;} if (cl.contains("icon-trash-empty")) {zoneRemove(zone); return;} if (cl.contains("icon-eye")) {toggleVisibility(el); return;} if (cl.contains("icon-pin")) {focusOnZone(zone, cl); return;} @@ -52,7 +53,7 @@ function editZones() { const rural = d3.sum(c.map(i => pack.cells.pop[i])) * populationRate.value; const urban = d3.sum(c.map(i => pack.cells.burg[i]).map(b => pack.burgs[b].population)) * populationRate.value * urbanization.value; const population = rural + urban; - const populationTip = `Total population: ${si(population)}; Rural population: ${si(rural)}; Urban population: ${si(urban)}`; + const populationTip = `Total population: ${si(population)}; Rural population: ${si(rural)}; Urban population: ${si(urban)}. Click to change`; const inactive = this.style.display === "none"; const focused = defs.select("#fog #focus"+this.id).size(); @@ -357,6 +358,65 @@ function editZones() { this.classList.toggle("pressed"); } + function changePopulation(zone) { + const dataCells = zones.select("#"+zone).attr("data-cells"); + const cells = dataCells ? dataCells.split(",").map(i => +i) : []; + if (!cells.length) {tip("Zone does not have any cells, cannot change population", false, "error"); return;} + const burgs = pack.burgs.filter(b => !b.removed && cells.includes(b.cell)); + + const rural = rn(d3.sum(cells.map(i => pack.cells.pop[i])) * populationRate.value); + const urban = rn(d3.sum(cells.map(i => pack.cells.burg[i]).map(b => pack.burgs[b].population)) * populationRate.value * urbanization.value); + const total = rural + urban; + const l = n => Number(n).toLocaleString(); + + alertMessage.innerHTML = ` + Rural: + Urban: +

Total population: ${l(total)} ⇒ ${l(total)} (100%)

`; + + const update = function() { + const totalNew = ruralPop.valueAsNumber + urbanPop.valueAsNumber; + if (isNaN(totalNew)) return; + totalPop.innerHTML = l(totalNew); + totalPopPerc.innerHTML = rn(totalNew / total * 100); + } + + ruralPop.oninput = () => update(); + urbanPop.oninput = () => update(); + + $("#alert").dialog({ + resizable: false, title: "Change zone population", width: "24em", buttons: { + Apply: function() {applyPopulationChange(); $(this).dialog("close");}, + Cancel: function() {$(this).dialog("close");} + }, position: {my: "center", at: "center", of: "svg"} + }); + + function applyPopulationChange() { + const ruralChange = rn(ruralPop.value / rural, 4); + if (isFinite(ruralChange) && ruralChange !== 1) { + cells.forEach(i => pack.cells.pop[i] *= ruralChange); + } + if (!isFinite(ruralChange) && +ruralPop.value > 0) { + const points = ruralPop.value / populationRate.value; + const pop = rn(points / cells.length); + cells.forEach(i => pack.cells.pop[i] = pop); + } + + const urbanChange = rn(urbanPop.value / urban, 4); + if (isFinite(urbanChange) && urbanChange !== 1) { + burgs.forEach(b => b.population *= urbanChange); + } + if (!isFinite(urbanChange) && +urbanPop.value > 0) { + const points = urbanPop.value / populationRate.value / urbanization.value; + const population = rn(points / burgs.length); + burgs.forEach(b => b.population = population); + } + + zonesEditorAddLines(); + } + + } + function zoneRemove(zone) { zones.select("#"+zone).remove(); unfocus(zone);