refactor(burgs): centralize burg management logic in Burgs module

Moved burg-related functions like `removeBurg`, `changeGroup`, and `toggleCapital` into the Burgs module to improve code organization and maintainability. Updated all references to these functions across the codebase. This change reduces duplication and ensures consistent behavior for burg management operations.
This commit is contained in:
Azgaar 2025-04-17 01:03:14 +02:00
parent a5939be6e2
commit fd9e010153
12 changed files with 213 additions and 215 deletions

View file

@ -314,11 +314,18 @@ window.Burgs = (() => {
function defineGroup(burg, populations) {
if (burg.lock) {
// locked bugrgs: don't change group if it still exists
// locked burgs: don't change group if it still exists
const group = options.burgs.groups.find(g => g.name === burg.group);
if (group) return;
}
const defaultGroup = options.burgs.groups.find(g => g.isDefault);
if (!defaultGroup) {
ERROR & console.error("No default group defined");
return;
}
burg.group = defaultGroup.name;
for (const group of options.burgs.groups) {
if (!group.active) continue;
@ -348,8 +355,7 @@ window.Burgs = (() => {
if (!isFit) continue;
}
// apply fitting or default group
burg.group = group.name;
burg.group = group.name; // apply fitting group
return;
}
}
@ -404,7 +410,7 @@ window.Burgs = (() => {
const temple = +burg.temple;
const shantytown = +burg.shanty;
const style = "bw";
const style = "natural";
const url = new URL("https://watabou.github.io/city-generator/");
url.search = new URLSearchParams({
@ -476,7 +482,7 @@ window.Burgs = (() => {
const style = (() => {
if ([1, 2].includes(biome)) return "sand";
if (temp <= 5 || [9, 10, 11].includes(biome)) return "snow";
return "minimal";
return "default";
})();
const url = new URL("https://watabou.github.io/village-generator/");
@ -556,5 +562,38 @@ window.Burgs = (() => {
return burgId;
}
return {generate, getDefaultGroups, specify, defineGroup, getPreview, getType, add};
function changeGroup(burg, group) {
if (group) {
burg.group = group;
} else {
const validBurgs = pack.burgs.filter(b => b.i && !b.removed);
const populations = validBurgs.map(b => b.population).sort((a, b) => a - b);
defineGroup(burg, populations);
}
drawBurgIcon(burg);
drawBurgLabel(burg);
}
function remove(burgId) {
const burg = pack.burgs[burgId];
if (!burg) return tip(`Burg ${burgId} not found`, false, "error");
pack.cells.burg[burg.cell] = 0;
burg.removed = true;
const noteId = notes.findIndex(note => note.id === `burg${burgId}`);
if (noteId !== -1) notes.splice(noteId, 1);
if (burg.coa) {
byId("burgCOA" + burgId)?.remove();
emblems.select(`#burgEmblems > use[data-i='${burgId}']`).remove();
delete burg.coa;
}
removeBurgIcon(burg.i);
removeBurgLabel(burg.i);
}
return {generate, getDefaultGroups, specify, defineGroup, getPreview, getType, add, changeGroup, remove};
})();

View file

@ -603,7 +603,7 @@ function stateRemove(stateId) {
burg.state = 0;
if (burg.capital) {
burg.capital = 0;
moveBurgToGroup(burg.i, "town");
Burgs.changeGroup(burg);
}
}
});
@ -1181,30 +1181,30 @@ function addState() {
if (cells.h[center] < 20)
return tip("You cannot place state into the water. Please click on a land cell", false, "error");
let burg = cells.burg[center];
if (burg && burgs[burg].capital)
let burgId = cells.burg[center];
if (burgId && burgs[burgId].capital)
return tip("Existing capital cannot be selected as a new state capital! Select other cell", false, "error");
if (!burg) burg = Burgs.add(point);
if (!burgId) burgId = Burgs.add(point);
const oldState = cells.state[center];
const newState = states.length;
// turn burg into a capital
burgs[burg].capital = 1;
burgs[burg].state = newState;
moveBurgToGroup(burg, "city");
burgs[burgId].capital = 1;
burgs[burgId].state = newState;
Burgs.changeGroup(burgs[burgId]);
if (d3.event.shiftKey === false) exitAddStateMode();
const culture = cells.culture[center];
const basename = center % 5 === 0 ? burgs[burg].name : Names.getCulture(culture);
const basename = center % 5 === 0 ? burgs[burgId].name : Names.getCulture(culture);
const name = Names.getState(basename, culture);
const color = getRandomColor();
// generate emblem
const cultureType = pack.cultures[culture].type;
const coa = COA.generate(burgs[burg].coa, 0.4, null, cultureType);
const coa = COA.generate(burgs[burgId].coa, 0.4, null, cultureType);
coa.shield = COA.getShield(culture, null);
// update diplomacy and reverse relations
@ -1244,7 +1244,7 @@ function addState() {
provinces: [],
color,
expansionism: 0.5,
capital: burg,
capital: burgId,
type: "Generic",
center,
culture,
@ -1380,19 +1380,19 @@ function openStateMergeDialog() {
});
// reassing burgs
pack.burgs.forEach(b => {
if (statesToMerge.includes(b.state)) {
if (b.capital) {
moveBurgToGroup(b.i, "town");
b.capital = 0;
pack.burgs.forEach(burg => {
if (statesToMerge.includes(burg.state)) {
if (burg.capital) {
burg.capital = 0;
Burgs.changeGroup(burg);
}
b.state = rulingStateId;
burg.state = rulingStateId;
}
});
// reassign provinces
pack.provinces.forEach((p, i) => {
if (statesToMerge.includes(p.state)) p.state = rulingStateId;
pack.provinces.forEach(province => {
if (statesToMerge.includes(province.state)) province.state = rulingStateId;
});
// reassing cells

View file

@ -618,14 +618,12 @@ async function parseLoadedData(data, mapVersion) {
if (!state.i && capitalBurgs.length) {
ERROR &&
console.error(
`[Data integrity] Neutral burgs (${capitalBurgs
.map(b => b.i)
.join(", ")}) marked as capitals. Moving them to town`
`[Data integrity] Neutral burgs (${capitalBurgs.map(b => b.i).join(", ")}) marked as capitals`
);
capitalBurgs.forEach(burg => {
burg.capital = 0;
moveBurgToGroup(burg.i, "town");
Burgs.changeGroup(burg);
});
return;
@ -634,23 +632,23 @@ async function parseLoadedData(data, mapVersion) {
if (capitalBurgs.length > 1) {
const message = `[Data integrity] State ${state.i} has multiple capitals (${capitalBurgs
.map(b => b.i)
.join(", ")}) assigned. Keeping the first as capital and moving others to town`;
.join(", ")}) assigned. Keeping the first as capital and moving others`;
ERROR && console.error(message);
capitalBurgs.forEach((burg, i) => {
if (!i) return;
burg.capital = 0;
moveBurgToGroup(burg.i, "town");
Burgs.changeGroup(burg);
});
return;
}
if (state.i && stateBurgs.length && !capitalBurgs.length) {
ERROR &&
console.error(`[Data integrity] State ${state.i} has no capital. Assigning the first burg as capital`);
stateBurgs[0].capital = 1;
moveBurgToGroup(stateBurgs[0].i, "city");
ERROR && console.error(`[Data integrity] State ${state.i} has no capital. Making the first burg capital`);
const capital = stateBurgs[0];
capital.capital = 1;
Burgs.changeGroup(capital);
}
});

View file

@ -8,11 +8,11 @@ function drawBurgIcons() {
const burgsInGroup = pack.burgs.filter(b => b.group === name && !b.removed);
if (!burgsInGroup.length) continue;
const burgGroup = document.querySelector("#burgIcons > g#" + name);
if (!burgGroup) continue;
const iconsGroup = document.querySelector("#burgIcons > g#" + name);
if (!iconsGroup) continue;
const icon = burgGroup.dataset.icon || "#icon-circle";
burgGroup.innerHTML = burgsInGroup
const icon = iconsGroup.dataset.icon || "#icon-circle";
iconsGroup.innerHTML = burgsInGroup
.map(b => `<use id="burg${b.i}" data-id="${b.i}" href="${icon}" x="${b.x}" y="${b.y}"></use>`)
.join("");
@ -31,10 +31,16 @@ function drawBurgIcons() {
}
function drawBurgIcon(burg) {
removeBurgIcon(burg.i);
const iconGroup = burgIcons.select("#" + burg.group);
if (iconGroup.empty()) return;
const icon = iconGroup.attr("data-icon") || "#icon-circle";
burgIcons
.select("#" + burg.group)
.append("use")
.attr("href", "#icon-circle")
.attr("href", icon)
.attr("id", "burg" + burg.i)
.attr("data-id", burg.i)
.attr("x", burg.x)
@ -52,41 +58,49 @@ function drawBurgIcon(burg) {
}
}
function removeBurgIcon(burgId) {
const existingIcon = document.getElementById("burg" + burgId);
if (existingIcon) existingIcon.remove();
const existingAnchor = document.getElementById("anchor" + burgId);
if (existingAnchor) existingAnchor.remove();
}
function createIconGroups() {
// save existing styles and remove all groups
const defaultIconStyle = style.burgIcons.town || Object.values(style.burgIcons)[0];
document.querySelectorAll("g#burgIcons > g").forEach(group => {
const groupStyle = Object.keys(defaultIconStyle).reduce((acc, key) => {
acc[key] = group.getAttribute(key);
style.burgIcons[group.id] = Array.from(group.attributes).reduce((acc, attribute) => {
acc[attribute.name] = attribute.value;
return acc;
}, {});
style.burgIcons[group.id] = groupStyle;
group.remove();
});
const defaultAnchorStyle = style.anchors.town || Object.values(style.anchors)[0];
document.querySelectorAll("g#anchors > g").forEach(group => {
const groupStyle = Object.keys(defaultAnchorStyle).reduce((acc, key) => {
acc[key] = group.getAttribute(key);
style.anchors[group.id] = Array.from(group.attributes).reduce((acc, attribute) => {
acc[attribute.name] = attribute.value;
return acc;
}, {});
style.anchors[group.id] = groupStyle;
group.remove();
});
// create groups for each burg group and apply stored or default style
const defaultIconStyle = style.burgIcons.town || Object.values(style.burgIcons)[0];
const defaultAnchorStyle = style.anchors.town || Object.values(style.anchors)[0];
const sortedGroups = [...options.burgs.groups].sort((a, b) => a.order - b.order);
for (const {name} of sortedGroups) {
const burgGroup = burgIcons.append("g").attr("id", name);
const burgGroup = burgIcons.append("g");
const iconStyles = style.burgIcons[name] || defaultIconStyle;
Object.entries(iconStyles).forEach(([key, value]) => {
burgGroup.attr(key, value);
});
burgGroup.attr("id", name);
const anchorGroup = anchors.append("g").attr("id", name);
const anchorGroup = anchors.append("g");
const anchorStyles = style.anchors[name] || defaultAnchorStyle;
Object.entries(anchorStyles).forEach(([key, value]) => {
anchorGroup.attr(key, value);
});
anchorGroup.attr("id", name);
}
}

View file

@ -33,11 +33,14 @@ function drawBurgLabels() {
}
function drawBurgLabel(burg) {
const group = burgLabels.select("#" + burg.group);
removeBurgLabel(burg.i);
const labelGroup = burgLabels.select("#" + burg.group);
if (labelGroup.empty()) return;
const dx = labelGroup.attr("data-dx") || 0;
const dy = labelGroup.attr("data-dy") || 0;
group
labelGroup
.append("text")
.attr("text-rendering", "optimizeSpeed")
.attr("id", "burgLabel" + burg.i)
@ -49,26 +52,30 @@ function drawBurgLabel(burg) {
.text(burg.name);
}
function createLabelGroups() {
const defaultStyle = style.burgLabels.town || Object.values(style.burgLabels)[0];
function removeBurgLabel(burgId) {
const existingLabel = document.getElementById("burgLabel" + burgId);
if (existingLabel) existingLabel.remove();
}
function createLabelGroups() {
// save existing styles and remove all groups
document.querySelectorAll("g#burgLabels > g").forEach(group => {
const groupStyle = Object.keys(defaultStyle).reduce((acc, key) => {
acc[key] = group.getAttribute(key);
style.burgLabels[group.id] = Array.from(group.attributes).reduce((acc, attribute) => {
acc[attribute.name] = attribute.value;
return acc;
}, {});
style.burgLabels[group.id] = groupStyle;
group.remove();
});
// create groups for each burg group and apply stored or default style
const defaultStyle = style.burgLabels.town || Object.values(style.burgLabels)[0];
const sortedGroups = [...options.burgs.groups].sort((a, b) => a.order - b.order);
for (const {name} of sortedGroups) {
const group = burgLabels.append("g").attr("id", name);
const group = burgLabels.append("g");
const styles = style.burgLabels[name] || defaultStyle;
Object.entries(styles).forEach(([key, value]) => {
group.attr(key, value);
});
group.attr("id", name);
}
}

View file

@ -83,20 +83,13 @@ function editBurg(id) {
byId("burgElevation").innerHTML = getHeight(pack.cells.h[b.cell]);
// toggle features
if (b.capital) byId("burgCapital").classList.remove("inactive");
else byId("burgCapital").classList.add("inactive");
if (b.port) byId("burgPort").classList.remove("inactive");
else byId("burgPort").classList.add("inactive");
if (b.citadel) byId("burgCitadel").classList.remove("inactive");
else byId("burgCitadel").classList.add("inactive");
if (b.walls) byId("burgWalls").classList.remove("inactive");
else byId("burgWalls").classList.add("inactive");
if (b.plaza) byId("burgPlaza").classList.remove("inactive");
else byId("burgPlaza").classList.add("inactive");
if (b.temple) byId("burgTemple").classList.remove("inactive");
else byId("burgTemple").classList.add("inactive");
if (b.shanty) byId("burgShanty").classList.remove("inactive");
else byId("burgShanty").classList.add("inactive");
byId("burgCapital").classList.toggle("inactive", !b.capital);
byId("burgPort").classList.toggle("inactive", !b.port);
byId("burgCitadel").classList.toggle("inactive", !b.citadel);
byId("burgWalls").classList.toggle("inactive", !b.walls);
byId("burgPlaza").classList.toggle("inactive", !b.plaza);
byId("burgTemple").classList.toggle("inactive", !b.temple);
byId("burgShanty").classList.toggle("inactive", !b.shanty);
updateBurgLockIcon();
@ -135,8 +128,8 @@ function editBurg(id) {
function changeGroup() {
const id = +elSelected.attr("data-id");
pack.burgs[id].group = this.value;
moveBurgToGroup(id, this.value);
const burg = pack.burgs[id];
Burgs.changeGroup(burg, this.value);
}
function changeType() {
@ -165,21 +158,68 @@ function editBurg(id) {
}
function toggleFeature() {
const id = +elSelected.attr("data-id");
const burg = pack.burgs[id];
const feature = this.dataset.feature;
const turnOn = this.classList.contains("inactive");
if (feature === "port") togglePort(id);
else if (feature === "capital") toggleCapital(id);
else burg[feature] = +turnOn;
if (burg[feature]) this.classList.remove("inactive");
else if (!burg[feature]) this.classList.add("inactive");
const burgId = +elSelected.attr("data-id");
const burg = pack.burgs[burgId];
if (burg.port) byId("burgEditAnchorStyle").style.display = "inline-block";
else byId("burgEditAnchorStyle").style.display = "none";
const feature = this.dataset.feature;
const value = Number(this.classList.contains("inactive"));
if (feature === "port") togglePort(burgId);
else if (feature === "capital") toggleCapital(burgId);
else burg[feature] = value;
this.classList.toggle("inactive", !burg[feature]);
byId("burgEditAnchorStyle").style.display = burg.port ? "inline-block" : "none";
updateBurgPreview(burg);
}
function togglePort(burgId) {
const burg = pack.burgs[burgId];
if (burg.port) {
burg.port = 0;
const anchor = document.querySelector("#anchors [data-id='" + burgId + "']");
if (anchor) anchor.remove();
} else {
const haven = pack.cells.haven[burg.cell];
if (!haven) tip("Port haven is not found, system won't be able to make a searoute", false, "warn");
const portFeature = haven ? pack.cells.f[haven] : -1;
burg.port = portFeature;
anchors
.select("#" + burg.group)
.append("use")
.attr("href", "#icon-anchor")
.attr("id", "anchor" + burg.i)
.attr("data-id", burg.i)
.attr("x", burg.x)
.attr("y", burg.y);
}
}
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");
const stateId = burgs[burgId].state;
if (!stateId) return tip("Neutral lands cannot have a capital", false, "error");
const oldCapitalId = states[stateId].capital;
states[stateId].capital = burgId;
states[stateId].center = burgs[burgId].cell;
const capital = burgs[burgId];
capital.capital = 1;
Burgs.changeGroup(capital);
const oldCapital = burgs[oldCapitalId];
oldCapital.capital = 0;
Burgs.changeGroup(oldCapital);
}
function toggleBurgLockButton() {
const id = +elSelected.attr("data-id");
const burg = pack.burgs[id];
@ -354,10 +394,11 @@ function editBurg(id) {
}
function removeSelectedBurg() {
const id = +elSelected.attr("data-id");
if (pack.burgs[id].capital) {
alertMessage.innerHTML = /* html */ `You cannot remove the burg as it is a state capital.<br /><br />
You can change the capital using Burgs Editor (shift + T)`;
const burgId = +elSelected.attr("data-id");
const burg = pack.burgs[burgId];
if (burg.capital) {
alertMessage.innerHTML = /* html */ `You cannot remove the capital. You must change the state capital first`;
$("#alert").dialog({
resizable: false,
title: "Remove burg",
@ -373,7 +414,7 @@ function editBurg(id) {
message: "Are you sure you want to remove the burg? <br>This action cannot be reverted",
confirm: "Remove",
onConfirm: () => {
removeBurg(id); // see Editors module
Burgs.remove(burgId);
$("#burgEditor").dialog("close");
}
});

View file

@ -234,7 +234,7 @@ function editBurgGroups() {
if (lines.length < 2) return tip("At least one group should be defined", false, "error");
confirmationDialog({
title: this.dataset.tip,
title: "Remove group",
message:
"Are you sure you want to remove the group? <br>This WON'T change the burgs unless the changes are applied",
confirm: "Remove",

View file

@ -182,16 +182,16 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
}
function triggerBurgRemove() {
const burg = +this.parentNode.dataset.id;
if (pack.burgs[burg].capital)
return tip("You cannot remove the capital. Please change the capital first", false, "error");
const burgId = +this.parentNode.dataset.id;
if (pack.burgs[burgId].capital)
return tip("You cannot remove the capital. Please change the state capital first", false, "error");
confirmationDialog({
title: "Remove burg",
message: "Are you sure you want to remove the burg? <br>This action cannot be reverted",
confirm: "Remove",
onConfirm: () => {
removeBurg(burg);
Burgs.remove(burgId);
burgsOverviewAddLines();
}
});
@ -536,17 +536,15 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
title: `Remove ${number} burgs`,
message: `
Are you sure you want to remove all <i>unlocked</i> burgs except for capitals?
<br><i>To remove a capital you have to remove a state first</i>`,
<br><i>To remove a capital you have to remove its state first</i>`,
confirm: "Remove",
onConfirm: removeAllBurgs
onConfirm: () => {
pack.burgs.filter(b => b.i && !(b.capital || b.lock)).forEach(b => Burgs.remove(b.i));
burgsOverviewAddLines();
}
});
}
function removeAllBurgs() {
pack.burgs.filter(b => b.i && !(b.capital || b.lock)).forEach(b => removeBurg(b.i));
burgsOverviewAddLines();
}
function toggleLockAll() {
const activeBurgs = pack.burgs.filter(b => b.i && !b.removed);
const allLocked = activeBurgs.every(burg => burg.lock);

View file

@ -128,108 +128,6 @@ function applySorting(headers) {
.forEach(line => list.appendChild(line));
}
function moveBurgToGroup(id, g) {
const label = document.querySelector(`#burgLabels [data-id='${id}']`);
const icon = document.querySelector(`#burgIcons [data-id='${id}']`);
const anchor = document.querySelector(`#anchors [data-id='${id}']`);
if (!label || !icon) return tip("Cannot find label or icon for burg " + id, false, "error");
document.querySelector("#burgLabels > #" + g).appendChild(label);
document.querySelector("#burgIcons > #" + g).appendChild(icon);
if (anchor) document.querySelector("#anchors > #" + g).appendChild(anchor);
icon.setAttribute("href", icon.parentElement.dataset.icon);
const {dx, dy} = label.parentElement.dataset;
dx ? label.setAttribute("dx", dx + "em") : label.removeAttribute("dx");
dy ? label.setAttribute("dy", dy + "em") : label.removeAttribute("dy");
}
function moveAllBurgsToGroup(fromGroup, toGroup) {
const groupToMove = document.querySelector(`#burgIcons #${fromGroup}`);
const burgsToMove = Array.from(groupToMove.children).map(x => x.dataset.id);
addBurgsGroup(toGroup);
burgsToMove.forEach(x => moveBurgToGroup(x, toGroup));
}
function addBurgsGroup(group) {
if (document.querySelector(`#burgLabels > #${group}`)) return;
const labelCopy = document.querySelector("#burgLabels > #town").cloneNode(false);
const iconCopy = document.querySelector("#burgIcons > #town").cloneNode(false);
const anchorCopy = document.querySelector("#anchors > #town").cloneNode(false);
// FIXME: using the same id is against the spec!
document.querySelector("#burgLabels").appendChild(labelCopy).id = group;
document.querySelector("#burgIcons").appendChild(iconCopy).id = group;
document.querySelector("#anchors").appendChild(anchorCopy).id = group;
}
function removeBurg(id) {
document.querySelector("#burgLabels [data-id='" + id + "']")?.remove();
document.querySelector("#burgIcons [data-id='" + id + "']")?.remove();
document.querySelector("#anchors [data-id='" + id + "']")?.remove();
const cells = pack.cells;
const burg = pack.burgs[id];
burg.removed = true;
cells.burg[burg.cell] = 0;
const noteId = notes.findIndex(note => note.id === `burg${id}`);
if (noteId !== -1) notes.splice(noteId, 1);
if (burg.coa) {
const coaId = "burgCOA" + id;
if (byId(coaId)) byId(coaId).remove();
emblems.select(`#burgEmblems > use[data-i='${id}']`).remove();
delete burg.coa; // remove to save data
}
}
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");
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, "city");
moveBurgToGroup(prevCapitalId, "town");
}
function togglePort(burg) {
const anchor = document.querySelector("#anchors [data-id='" + burg + "']");
if (anchor) anchor.remove();
const b = pack.burgs[burg];
if (b.port) {
b.port = 0;
return;
} // not a port anymore
const haven = pack.cells.haven[b.cell];
const port = haven ? pack.cells.f[haven] : -1;
if (!haven) tip("Port haven is not found, system won't be able to make a searoute", false, "warn");
b.port = port;
const g = b.capital ? "city" : "town";
const group = anchors.select("g#" + g);
const size = +group.attr("size");
group
.append("use")
.attr("xlink:href", "#icon-anchor")
.attr("data-id", burg)
.attr("x", rn(b.x - size * 0.47, 2))
.attr("y", rn(b.y - size * 0.47, 2))
.attr("width", size)
.attr("height", size);
}
// draw legend box
function drawLegend(name, data) {
legend.selectAll("*").remove(); // fully redraw every time

View file

@ -409,7 +409,7 @@ function editHeightmap(options) {
b.feature = pack.cells.f[b.cell];
pack.cells.burg[b.cell] = b.i;
if (!b.capital && pack.cells.h[b.cell] < 20) removeBurg(b.i);
if (!b.capital && pack.cells.h[b.cell] < 20) Burgs.remove(b.i);
if (b.capital) pack.states[b.state].center = b.cell;
}

View file

@ -296,8 +296,9 @@ function editProvinces() {
const newStateId = states.length;
// turn province burg into a capital
burgs[burgId].capital = 1;
moveBurgToGroup(burgId, "city");
const capital = burgs[burgId];
capital.capital = 1;
Burgs.changeGroup(capital);
// move all burgs to a new state
province.burgs.forEach(b => (burgs[b].state = newStateId));

View file

@ -213,11 +213,11 @@ function recreateStates() {
// turn all old capitals into town, except for the capitals of locked states
for (const burg of validBurgs) {
if (!burg.capital) continue;
if (lockedStatesCapitals.includes(burg.i)) continue;
moveBurgToGroup(burg.i, "town");
burg.capital = 0;
if (burg.capital) {
if (lockedStatesCapitals.includes(burg.i)) continue;
burg.capital = 0;
Burgs.changeGroup(burg);
}
}
// remove labels and emblems for non-locked states
@ -304,7 +304,7 @@ function recreateStates() {
burg.capital = 1;
capital = burg;
capitalsTree.add([x, y]);
moveBurgToGroup(burg.i, "city");
Burgs.changeGroup(capital);
break;
}
@ -436,9 +436,11 @@ function regenerateBurgs() {
const burgId = Burgs.add([x, y]);
s.capital = burgId;
s.center = pack.burgs[burgId].cell;
pack.burgs[burgId].capital = 1;
pack.burgs[burgId].state = s.i;
moveBurgToGroup(burgId, "city");
const burg = pack.burgs[burgId];
burg.state = s.i;
burg.capital = 1;
Burgs.changeGroup(burg);
});
features.forEach(f => {