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;