From 73b39d217d6c30b9d2c681144c2fcc50d0e5ef05 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Mon, 4 Mar 2024 21:04:25 +0100 Subject: [PATCH] fix: #1048 --- index.html | 4 +- modules/dynamic/editors/states-editor.js | 47 +++++++------ modules/io/load.js | 90 ++++++++++++++++++------ modules/ui/editors.js | 35 +++++---- versioning.js | 2 +- 5 files changed, 114 insertions(+), 64 deletions(-) diff --git a/index.html b/index.html index cf33e512..89c77396 100644 --- a/index.html +++ b/index.html @@ -8063,7 +8063,7 @@ - + @@ -8101,7 +8101,7 @@ - + diff --git a/modules/dynamic/editors/states-editor.js b/modules/dynamic/editors/states-editor.js index 2adcbbc8..70a45017 100644 --- a/modules/dynamic/editors/states-editor.js +++ b/modules/dynamic/editors/states-editor.js @@ -624,28 +624,36 @@ function stateRemovePrompt(state) { }); } -function stateRemove(state) { - statesBody.select("#state" + state).remove(); - statesBody.select("#state-gap" + state).remove(); - statesHalo.select("#state-border" + state).remove(); - labels.select("#stateLabel" + state).remove(); - defs.select("#textPath_stateLabel" + state).remove(); +function stateRemove(stateId) { + statesBody.select("#state" + stateId).remove(); + statesBody.select("#state-gap" + stateId).remove(); + statesHalo.select("#state-border" + stateId).remove(); + labels.select("#stateLabel" + stateId).remove(); + defs.select("#textPath_stateLabel" + stateId).remove(); - unfog("focusState" + state); - pack.burgs.forEach(b => { - if (b.state === state) b.state = 0; + unfog("focusState" + stateId); + + pack.burgs.forEach(burg => { + if (burg.state === stateId) { + burg.state = 0; + if (burg.capital) { + burg.capital = 0; + moveBurgToGroup(burg.i, "towns"); + } + } }); + pack.cells.state.forEach((s, i) => { - if (s === state) pack.cells.state[i] = 0; + if (s === stateId) pack.cells.state[i] = 0; }); // remove emblem - const coaId = "stateCOA" + state; + const coaId = "stateCOA" + stateId; byId(coaId).remove(); - emblems.select(`#stateEmblems > use[data-i='${state}']`).remove(); + emblems.select(`#stateEmblems > use[data-i='${stateId}']`).remove(); // remove provinces - pack.states[state].provinces.forEach(p => { + pack.states[stateId].provinces.forEach(p => { pack.provinces[p] = {i: p, removed: true}; pack.cells.province.forEach((pr, i) => { if (pr === p) pack.cells.province[i] = 0; @@ -660,19 +668,14 @@ function stateRemove(state) { }); // remove military - pack.states[state].military.forEach(m => { - const id = `regiment${state}-${m.i}`; + pack.states[stateId].military.forEach(m => { + const id = `regiment${stateId}-${m.i}`; const index = notes.findIndex(n => n.id === id); if (index != -1) notes.splice(index, 1); }); - armies.select("g#army" + state).remove(); + armies.select("g#army" + stateId).remove(); - const capital = pack.states[state].capital; - pack.burgs[capital].capital = 0; - pack.burgs[capital].state = 0; - moveBurgToGroup(capital, "towns"); - - pack.states[state] = {i: state, removed: true}; + pack.states[stateId] = {i: stateId, removed: true}; debug.selectAll(".highlight").remove(); if (!layerIsOn("toggleStates")) toggleStates(); diff --git a/modules/io/load.js b/modules/io/load.js index 034d977a..3f6abf40 100644 --- a/modules/io/load.js +++ b/modules/io/load.js @@ -478,7 +478,7 @@ async function parseLoadedData(data, mapVersion) { const cells = pack.cells; if (pack.cells.i.length !== pack.cells.state.length) { - const message = "Data Integrity Check. Striping issue detected. To fix edit the heightmap in erase mode"; + const message = "Data integrity check. Striping issue detected. To fix edit the heightmap in ERASE mode"; ERROR && console.error(message); } @@ -486,7 +486,7 @@ async function parseLoadedData(data, mapVersion) { invalidStates.forEach(s => { const invalidCells = cells.i.filter(i => cells.state[i] === s); invalidCells.forEach(i => (cells.state[i] = 0)); - ERROR && console.error("Data Integrity Check. Invalid state", s, "is assigned to cells", invalidCells); + ERROR && console.error("Data integrity check. Invalid state", s, "is assigned to cells", invalidCells); }); const invalidProvinces = [...new Set(cells.province)].filter( @@ -495,14 +495,14 @@ async function parseLoadedData(data, mapVersion) { invalidProvinces.forEach(p => { const invalidCells = cells.i.filter(i => cells.province[i] === p); invalidCells.forEach(i => (cells.province[i] = 0)); - ERROR && console.error("Data Integrity Check. Invalid province", p, "is assigned to cells", invalidCells); + ERROR && console.error("Data integrity check. Invalid province", p, "is assigned to cells", invalidCells); }); const invalidCultures = [...new Set(cells.culture)].filter(c => !pack.cultures[c] || pack.cultures[c].removed); invalidCultures.forEach(c => { const invalidCells = cells.i.filter(i => cells.culture[i] === c); invalidCells.forEach(i => (cells.province[i] = 0)); - ERROR && console.error("Data Integrity Check. Invalid culture", c, "is assigned to cells", invalidCells); + ERROR && console.error("Data integrity check. Invalid culture", c, "is assigned to cells", invalidCells); }); const invalidReligions = [...new Set(cells.religion)].filter( @@ -511,14 +511,14 @@ async function parseLoadedData(data, mapVersion) { invalidReligions.forEach(r => { const invalidCells = cells.i.filter(i => cells.religion[i] === r); invalidCells.forEach(i => (cells.religion[i] = 0)); - ERROR && console.error("Data Integrity Check. Invalid religion", r, "is assigned to cells", invalidCells); + ERROR && console.error("Data integrity check. Invalid religion", r, "is assigned to cells", invalidCells); }); const invalidFeatures = [...new Set(cells.f)].filter(f => f && !pack.features[f]); invalidFeatures.forEach(f => { const invalidCells = cells.i.filter(i => cells.f[i] === f); // No fix as for now - ERROR && console.error("Data Integrity Check. Invalid feature", f, "is assigned to cells", invalidCells); + ERROR && console.error("Data integrity check. Invalid feature", f, "is assigned to cells", invalidCells); }); const invalidBurgs = [...new Set(cells.burg)].filter( @@ -527,7 +527,7 @@ async function parseLoadedData(data, mapVersion) { invalidBurgs.forEach(burgId => { const invalidCells = cells.i.filter(i => cells.burg[i] === burgId); invalidCells.forEach(i => (cells.burg[i] = 0)); - ERROR && console.error("Data Integrity Check. Invalid burg", burgId, "is assigned to cells", invalidCells); + ERROR && console.error("Data integrity check. Invalid burg", burgId, "is assigned to cells", invalidCells); }); const invalidRivers = [...new Set(cells.r)].filter(r => r && !pack.rivers.find(river => river.i === r)); @@ -535,60 +535,110 @@ async function parseLoadedData(data, mapVersion) { const invalidCells = cells.i.filter(i => cells.r[i] === r); invalidCells.forEach(i => (cells.r[i] = 0)); rivers.select("river" + r).remove(); - ERROR && console.error("Data Integrity Check. Invalid river", r, "is assigned to cells", invalidCells); + ERROR && console.error("Data integrity check. Invalid river", r, "is assigned to cells", invalidCells); }); pack.burgs.forEach(burg => { - if ((!burg.i || burg.removed) && burg.lock) { + if (!burg.i && burg.lock) { + ERROR && console.error(`Data integrity check. Burg 0 is marked as locked, removing the status`); + delete burg.lock; + return; + } + + if (burg.removed && burg.lock) { ERROR && - console.error( - `Data Integrity Check. Burg ${burg.i || "0"} is removed or invalid but still locked. Unlocking the burg` - ); + console.error(`Data integrity check. Removed burg ${burg.i} is marked as locked. Unlocking the burg`); delete burg.lock; return; } if (!burg.i || burg.removed) return; + if (burg.cell === undefined || burg.x === undefined || burg.y === undefined) { ERROR && console.error( - `Data Integrity Check. Burg ${burg.i} is missing cell info or coordinates. Removing the burg` + `Data integrity check. Burg ${burg.i} is missing cell info or coordinates. Removing the burg` ); burg.removed = true; } if (burg.port < 0) { - ERROR && console.error("Data Integrity Check. Burg", burg.i, "has invalid port value", burg.port); + ERROR && console.error("Data integrity check. Burg", burg.i, "has invalid port value", burg.port); burg.port = 0; } if (burg.cell >= cells.i.length) { - ERROR && console.error("Data Integrity Check. Burg", burg.i, "is linked to invalid cell", burg.cell); + ERROR && console.error("Data integrity check. Burg", burg.i, "is linked to invalid cell", burg.cell); burg.cell = findCell(burg.x, burg.y); cells.i.filter(i => cells.burg[i] === burg.i).forEach(i => (cells.burg[i] = 0)); cells.burg[burg.cell] = burg.i; } if (burg.state && !pack.states[burg.state]) { - ERROR && console.error("Data Integrity Check. Burg", burg.i, "is linked to invalid state", burg.state); + ERROR && console.error("Data integrity check. Burg", burg.i, "is linked to invalid state", burg.state); burg.state = 0; } if (burg.state && pack.states[burg.state].removed) { - ERROR && console.error("Data Integrity Check. Burg", burg.i, "is linked to removed state", burg.state); + ERROR && console.error("Data integrity check. Burg", burg.i, "is linked to removed state", burg.state); burg.state = 0; } if (burg.state === undefined) { - ERROR && console.error("Data Integrity Check. Burg", burg.i, "has no state data"); + ERROR && console.error("Data integrity check. Burg", burg.i, "has no state data"); burg.state = 0; } }); + pack.states.forEach(state => { + if (state.removed) return; + + const stateBurgs = pack.burgs.filter(b => b.state === state.i && !b.removed); + const capitalBurgs = stateBurgs.filter(b => b.capital); + + if (!state.i && capitalBurgs.length) { + ERROR && + console.error( + `Data integrity check. Neutral burgs (${capitalBurgs + .map(b => b.i) + .join(", ")}) marked as capitals. Moving them to towns` + ); + + capitalBurgs.forEach(burg => { + burg.capital = 0; + moveBurgToGroup(burg.i, "towns"); + }); + + return; + } + + if (capitalBurgs.length > 1) { + const message = `Data integrity check. State ${state.i} has multiple capitals (${capitalBurgs + .map(b => b.i) + .join(", ")}) assigned. Keeping the first as capital and moving others to towns`; + ERROR && console.error(message); + + capitalBurgs.forEach((burg, i) => { + if (!i) return; + burg.capital = 0; + moveBurgToGroup(burg.i, "towns"); + }); + + return; + } + + if (stateBurgs.length && !capitalBurgs.length) { + ERROR && + console.error(`Data integrity check. State ${state.i} has no capital. Assigning the first burg as capital`); + stateBurgs[0].capital = 1; + moveBurgToGroup(stateBurgs[0].i, "cities"); + } + }); + pack.provinces.forEach(p => { if (!p.i || p.removed) return; if (pack.states[p.state] && !pack.states[p.state].removed) return; - ERROR && console.error("Data Integrity Check. Province", p.i, "is linked to removed state", p.state); + ERROR && console.error("Data integrity check. Province", p.i, "is linked to removed state", p.state); p.removed = true; // remove incorrect province }); @@ -598,7 +648,7 @@ async function parseLoadedData(data, mapVersion) { pack.markers.forEach(marker => { if (markerIds[marker.i]) { - ERROR && console.error("Data Integrity Check. Marker", marker.i, "has non-unique id. Changing to", nextId); + ERROR && console.error("Data integrity check. Marker", marker.i, "has non-unique id. Changing to", nextId); const domElements = document.querySelectorAll("#marker" + marker.i); if (domElements[1]) domElements[1].id = "marker" + nextId; // rename 2nd dom element diff --git a/modules/ui/editors.js b/modules/ui/editors.js index a7c0c9cb..890fb58f 100644 --- a/modules/ui/editors.js +++ b/modules/ui/editors.js @@ -243,25 +243,22 @@ function removeBurg(id) { } } -function toggleCapital(burg) { - const state = pack.burgs[burg].state; - if (!state) { - tip("Neutral lands cannot have a capital", false, "error"); - return; - } - if (pack.burgs[burg].capital) { - tip("To change capital please assign a capital status to another burg of this state", false, "error"); - return; - } - const old = pack.states[state].capital; +function toggleCapital(burgId) { + const {burgs, states} = pack; + if (burgs[burgId].capital) + return tip("To change capital please assign a capital status to another burg of this state", false, "error"); - // change statuses - pack.states[state].capital = burg; - pack.states[state].center = pack.burgs[burg].cell; - pack.burgs[burg].capital = 1; - pack.burgs[old].capital = 0; - moveBurgToGroup(burg, "cities"); - moveBurgToGroup(old, "towns"); + const stateId = burgs[burgId].state; + if (!stateId) return tip("Neutral lands cannot have a capital", false, "error"); + + const prevCapitalId = states[stateId].capital; + states[stateId].capital = burgId; + states[stateId].center = burgs[burgId].cell; + burgs[burgId].capital = 1; + burgs[prevCapitalId].capital = 0; + + moveBurgToGroup(burgId, "cities"); + moveBurgToGroup(prevCapitalId, "towns"); } function togglePort(burg) { @@ -1176,7 +1173,7 @@ function refreshAllEditors() { // dynamically loaded editors async function editStates() { if (customization) return; - const Editor = await import("../dynamic/editors/states-editor.js?v=1.96.00"); + const Editor = await import("../dynamic/editors/states-editor.js?v=1.96.06"); Editor.open(); } diff --git a/versioning.js b/versioning.js index 393373ca..67182953 100644 --- a/versioning.js +++ b/versioning.js @@ -1,7 +1,7 @@ "use strict"; // version and caching control -const version = "1.96.05"; // generator version, update each time +const version = "1.96.06"; // generator version, update each time { document.title += " v" + version;