feat: burgs - editors

This commit is contained in:
Azgaar 2024-10-01 21:10:14 +02:00
parent 4a8ce1af0e
commit 32808605b3
5 changed files with 153 additions and 279 deletions

View file

@ -1505,12 +1505,6 @@ div.states > select {
appearance: none;
}
div.states > .burgName,
div.states > .burgState,
div.states > .burgCulture {
width: 6em;
}
div.states span.inactive {
color: #c6c2c2;
}

View file

@ -3361,6 +3361,16 @@
></span>
</div>
<div data-tip="Select burg group. Groups defines burg icon, label size and style">
<div class="label">Group:</div>
<select id="burgGroup" style="width: 9em"></select>
<span
id="burgGroupEdit"
data-tip="Edit burg groups"
class="icon-pencil pointer"
></span>
</div>
<div data-tip="Select burg type. Type slightly affects emblem generation">
<div class="label">Type:</div>
<select id="burgType" style="width: 9em">
@ -3475,20 +3485,6 @@
</div>
<div id="burgBottom">
<button id="burgGroupShow" data-tip="Show group change section" class="icon-tags"></button>
<div id="burgGroupSection" style="display: none">
<button id="burgGroupHide" data-tip="Hide group change section" class="icon-tags"></button>
<select id="burgSelectGroup" data-tip="Select a group for this burg" style="width: 10em"></select>
<input
id="burgInputGroup"
placeholder="new group name"
data-tip="Create a new Group for the Burg"
style="display: none; width: 10em"
/>
<i id="burgAddGroup" data-tip="Create a new group for the burg" class="icon-plus pointer"></i>
<i id="burgRemoveGroup" data-tip="Remove selected burg group" class="icon-trash pointer"></i>
</div>
<button id="burgStyleShow" data-tip="Show style edit section" class="icon-brush"></button>
<div id="burgStyleSection" style="display: none">
<button id="burgStyleHide" data-tip="Hide style edit section" class="icon-brush"></button>
@ -5280,7 +5276,7 @@
</div>
<div id="burgsOverview" class="dialog stable" style="display: none">
<div id="burgsHeader" class="header" style="grid-template-columns: 8em 6em 6em 6em 8em 6em">
<div id="burgsHeader" class="header" style="grid-template-columns: 9em 7em 7em 7em 7em 7em 6em">
<div data-tip="Click to sort by burg name" class="sortable alphabetically" data-sortby="name">Burg</div>
<div data-tip="Click to sort by province name" class="sortable alphabetically" data-sortby="province">
Province
@ -5289,6 +5285,9 @@
<div data-tip="Click to sort by culture name" class="sortable alphabetically" data-sortby="culture">
Culture
</div>
<div data-tip="Click to sort by culture group" class="sortable alphabetically" data-sortby="group">
Group
</div>
<div
data-tip="Click to sort by burg population"
class="sortable icon-sort-number-down"
@ -8139,6 +8138,7 @@
<script defer src="modules/ui/rivers-creator.js?v=1.99.00"></script>
<script defer src="modules/ui/relief-editor.js?v=1.99.00"></script>
<script defer src="modules/ui/burg-editor.js?v=1.102.00"></script>
<script defer src="modules/ui/burg-group-editor.js?v=1.106.0"></script>
<script defer src="modules/ui/units-editor.js?v=1.104.0"></script>
<script defer src="modules/ui/notes-editor.js?v=1.99.06"></script>
<script defer src="modules/ui/ai-generator.js?v=1.99.09"></script>

View file

@ -8,6 +8,7 @@ function editBurg(id) {
const burg = id || d3.event.target.dataset.id;
elSelected = burgLabels.select("[data-id='" + burg + "']");
burgLabels.selectAll("text").call(d3.drag().on("start", dragBurgLabel)).classed("draggable", true);
updateGroupsList();
updateBurgValues();
$("#burgEditor").dialog({
@ -21,38 +22,40 @@ function editBurg(id) {
modules.editBurg = true;
// add listeners
byId("burgGroupShow").addEventListener("click", showGroupSection);
byId("burgGroupHide").addEventListener("click", hideGroupSection);
byId("burgSelectGroup").addEventListener("change", changeGroup);
byId("burgInputGroup").addEventListener("change", createNewGroup);
byId("burgAddGroup").addEventListener("click", toggleNewGroupInput);
byId("burgRemoveGroup").addEventListener("click", removeBurgsGroup);
byId("burgName").on("input", changeName);
byId("burgNameReRandom").on("click", generateNameRandom);
byId("burgGroup").on("change", changeGroup);
byId("burgGroupEdit").on("change", editBurgGroups);
byId("burgType").on("change", changeType);
byId("burgCulture").on("change", changeCulture);
byId("burgNameReCulture").on("click", generateNameCulture);
byId("burgPopulation").on("change", changePopulation);
burgBody.querySelectorAll(".burgFeature").forEach(el => el.on("click", toggleFeature));
byId("burgLinkOpen").on("click", openBurgLink);
byId("burgLinkEdit").on("click", changeBurgLink);
byId("burgName").addEventListener("input", changeName);
byId("burgNameReRandom").addEventListener("click", generateNameRandom);
byId("burgType").addEventListener("input", changeType);
byId("burgCulture").addEventListener("input", changeCulture);
byId("burgNameReCulture").addEventListener("click", generateNameCulture);
byId("burgPopulation").addEventListener("change", changePopulation);
burgBody.querySelectorAll(".burgFeature").forEach(el => el.addEventListener("click", toggleFeature));
byId("burgLinkOpen").addEventListener("click", openBurgLink);
byId("burgLinkEdit").addEventListener("click", changeBurgLink);
byId("burgStyleShow").on("click", showStyleSection);
byId("burgStyleHide").on("click", hideStyleSection);
byId("burgEditLabelStyle").on("click", editGroupLabelStyle);
byId("burgEditIconStyle").on("click", editGroupIconStyle);
byId("burgEditAnchorStyle").on("click", editGroupAnchorStyle);
byId("burgStyleShow").addEventListener("click", showStyleSection);
byId("burgStyleHide").addEventListener("click", hideStyleSection);
byId("burgEditLabelStyle").addEventListener("click", editGroupLabelStyle);
byId("burgEditIconStyle").addEventListener("click", editGroupIconStyle);
byId("burgEditAnchorStyle").addEventListener("click", editGroupAnchorStyle);
byId("burgEmblem").on("click", openEmblemEdit);
byId("burgTogglePreview").on("click", toggleBurgPreview);
byId("burgEditEmblem").on("click", openEmblemEdit);
byId("burgLocate").on("click", zoomIntoBurg);
byId("burgRelocate").on("click", toggleRelocateBurg);
byId("burglLegend").on("click", editBurgLegend);
byId("burgLock").on("click", toggleBurgLockButton);
byId("burgRemove").on("click", removeSelectedBurg);
byId("burgTemperatureGraph").on("click", showTemperatureGraph);
byId("burgEmblem").addEventListener("click", openEmblemEdit);
byId("burgTogglePreview").addEventListener("click", toggleBurgPreview);
byId("burgEditEmblem").addEventListener("click", openEmblemEdit);
byId("burgLocate").addEventListener("click", zoomIntoBurg);
byId("burgRelocate").addEventListener("click", toggleRelocateBurg);
byId("burglLegend").addEventListener("click", editBurgLegend);
byId("burgLock").addEventListener("click", toggleBurgLockButton);
byId("burgRemove").addEventListener("click", removeSelectedBurg);
byId("burgTemperatureGraph").addEventListener("click", showTemperatureGraph);
function updateGroupsList() {
byId("burgGroup").options.length = 0; // remove all options
for (const {name} of options.burgs.groups) {
byId("burgGroup").options.add(new Option(name, name));
}
}
function updateBurgValues() {
const id = +elSelected.attr("data-id");
@ -63,6 +66,7 @@ function editBurg(id) {
byId("burgProvinceAndState").innerHTML = provinceName + stateName;
byId("burgName").value = b.name;
byId("burgGroup").value = b.group;
byId("burgType").value = b.type || "Generic";
byId("burgPopulation").value = rn(b.population * populationRate * urbanization);
byId("burgEditAnchorStyle").style.display = +b.port ? "inline-block" : "none";
@ -94,18 +98,8 @@ function editBurg(id) {
if (b.shanty) byId("burgShanty").classList.remove("inactive");
else byId("burgShanty").classList.add("inactive");
//toggle lock
updateBurgLockIcon();
// select group
const group = elSelected.node().parentNode.id;
const select = byId("burgSelectGroup");
select.options.length = 0; // remove all options
burgLabels.selectAll("g").each(function () {
select.options.add(new Option(this.id, this.id, false, this.id === group));
});
// set emlem image
const coaID = "burgCOA" + id;
COArenderer.trigger(coaID, b.coa);
@ -132,128 +126,6 @@ function editBurg(id) {
});
}
function showGroupSection() {
document.querySelectorAll("#burgBottom > button").forEach(el => (el.style.display = "none"));
byId("burgGroupSection").style.display = "inline-block";
}
function hideGroupSection() {
document.querySelectorAll("#burgBottom > button").forEach(el => (el.style.display = "inline-block"));
byId("burgGroupSection").style.display = "none";
byId("burgInputGroup").style.display = "none";
byId("burgInputGroup").value = "";
byId("burgSelectGroup").style.display = "inline-block";
}
function changeGroup() {
const id = +elSelected.attr("data-id");
moveBurgToGroup(id, this.value);
}
function toggleNewGroupInput() {
if (burgInputGroup.style.display === "none") {
burgInputGroup.style.display = "inline-block";
burgInputGroup.focus();
burgSelectGroup.style.display = "none";
} else {
burgInputGroup.style.display = "none";
burgSelectGroup.style.display = "inline-block";
}
}
function createNewGroup() {
if (!this.value) {
tip("Please provide a valid group name", false, "error");
return;
}
const group = this.value
.toLowerCase()
.replace(/ /g, "_")
.replace(/[^\w\s]/gi, "");
if (byId(group)) {
tip("Element with this id already exists. Please provide a unique name", false, "error");
return;
}
if (Number.isFinite(+group.charAt(0))) {
tip("Group name should start with a letter", false, "error");
return;
}
const id = +elSelected.attr("data-id");
const oldGroup = elSelected.node().parentNode.id;
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) {
ERROR && console.error("Cannot find label or icon elements");
return;
}
const labelG = document.querySelector("#burgLabels > #" + oldGroup);
const iconG = document.querySelector("#burgIcons > #" + oldGroup);
const anchorG = document.querySelector("#anchors > #" + oldGroup);
// just rename if only 1 element left
const count = elSelected.node().parentNode.childElementCount;
if (oldGroup !== "cities" && oldGroup !== "towns" && count === 1) {
byId("burgSelectGroup").selectedOptions[0].remove();
byId("burgSelectGroup").options.add(new Option(group, group, false, true));
toggleNewGroupInput();
byId("burgInputGroup").value = "";
labelG.id = group;
iconG.id = group;
if (anchor) anchorG.id = group;
return;
}
// create new groups
byId("burgSelectGroup").options.add(new Option(group, group, false, true));
toggleNewGroupInput();
byId("burgInputGroup").value = "";
addBurgsGroup(group);
moveBurgToGroup(id, group);
}
function removeBurgsGroup() {
const group = elSelected.node().parentNode;
const basic = group.id === "cities" || group.id === "towns";
const burgsInGroup = [];
for (let i = 0; i < group.children.length; i++) {
burgsInGroup.push(+group.children[i].dataset.id);
}
const burgsToRemove = burgsInGroup.filter(b => !(pack.burgs[b].capital || pack.burgs[b].lock));
const capital = burgsToRemove.length < burgsInGroup.length;
confirmationDialog({
title: "Remove burg group",
message: `Are you sure you want to remove ${
basic || capital ? "all unlocked elements in the burg group" : "the entire burg group"
}?<br />Please note that capital or locked burgs will not be deleted. <br /><br />Burgs to be removed: ${
burgsToRemove.length
}. This action cannot be reverted`,
confirm: "Remove",
onConfirm: () => {
$("#burgEditor").dialog("close");
hideGroupSection();
burgsToRemove.forEach(b => removeBurg(b));
if (!basic && !capital) {
const labelG = document.querySelector("#burgLabels > #" + group.id);
const iconG = document.querySelector("#burgIcons > #" + group.id);
const anchorG = document.querySelector("#anchors > #" + group.id);
if (labelG) labelG.remove();
if (iconG) iconG.remove();
if (anchorG) anchorG.remove();
}
}
});
}
function changeName() {
const id = +elSelected.attr("data-id");
pack.burgs[id].name = burgName.value;
@ -266,6 +138,12 @@ function editBurg(id) {
changeName();
}
function changeGroup() {
const id = +elSelected.attr("data-id");
pack.burgs[id].group = this.value;
moveBurgToGroup(id, this.value);
}
function changeType() {
const id = +elSelected.attr("data-id");
pack.burgs[id].type = this.value;

View file

@ -0,0 +1,84 @@
"use strict";
function editBurgGroups() {
if (customization) return;
if (!layerIsOn("toggleBurgs")) toggleBurgs();
addLines();
$("#burgGroupsEditor").dialog({
title: "Edit Burg groups",
resizable: false,
position: {my: "left top", at: "left+10 top+140", of: "#map"}
});
if (modules.editBurgGroups) return;
modules.editBurgGroups = true;
// add listeners
byId("burgGroupsEditorAdd").addEventListener("click", addGroup);
byId("burgGroupsEditorBody").on("click", ev => {
const group = ev.target.closest(".states")?.dataset.id;
if (ev.target.classList.contains("editStyle")) editStyle("burgs", group);
else if (ev.target.classList.contains("removeGroup")) removeGroup(group);
});
function addLines() {
byId("burgGroupsEditorBody").innerHTML = "";
const lines = Array.from(burgs.selectAll("g")._groups[0]).map(el => {
const count = el.children.length;
return /* html */ `<div data-id="${el.id}" class="states" style="display: flex; justify-content: space-between;">
<span>${el.id} (${count})</span>
<div style="width: auto; display: flex; gap: 0.4em;">
<span data-tip="Edit style" class="editStyle icon-brush pointer" style="font-size: smaller;"></span>
<span data-tip="Remove group" class="removeGroup icon-trash pointer"></span>
</div>
</div>`;
});
byId("burgGroupsEditorBody").innerHTML = lines.join("");
}
const DEFAULT_GROUPS = ["roads", "trails", "seaburgs"];
function addGroup() {
prompt("Type group name", {default: "burg-group-new"}, v => {
let group = v
.toLowerCase()
.replace(/ /g, "_")
.replace(/[^\w\s]/gi, "");
if (!group) return tip("Invalid group name", false, "error");
if (!group.startsWith("burg-")) group = "burg-" + group;
if (byId(group)) return tip("Element with this name already exists. Provide a unique name", false, "error");
if (Number.isFinite(+group.charAt(0))) return tip("Group name should start with a letter", false, "error");
burgs
.append("g")
.attr("id", group)
.attr("stroke", "#000000")
.attr("stroke-width", 0.5)
.attr("stroke-dasharray", "1 0.5")
.attr("stroke-linecap", "butt");
byId("burgGroup")?.options.add(new Option(group, group));
addLines();
byId("burgCreatorGroupSelect").options.add(new Option(group, group));
});
}
function removeGroup(group) {
confirmationDialog({
title: "Remove burg group",
message:
"Are you sure you want to remove the entire burg group? All burgs in this group will be removed.<br>This action can't be reverted",
confirm: "Remove",
onConfirm: () => {
pack.burgs.filter(r => r.group === group).forEach(Burgs.remove);
if (!DEFAULT_GROUPS.includes(group)) burgs.select(`#${group}`).remove();
addLines();
}
});
}
}

View file

@ -24,7 +24,7 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
// add listeners
byId("burgsOverviewRefresh").addEventListener("click", refreshBurgsEditor);
byId("burgsGroupsEditorButton").addEventListener("click", openBurgGroupsEditor);
byId("burgsGroupsEditorButton").addEventListener("click", editBurgGroups);
byId("burgsChart").addEventListener("click", showBurgsChart);
byId("burgsFilterState").addEventListener("change", burgsOverviewAddLines);
byId("burgsFilterCulture").addEventListener("change", burgsOverviewAddLines);
@ -89,29 +89,24 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
data-state="${state}"
data-province="${province}"
data-culture="${culture}"
data-group="${b.group}"
data-population=${population}
data-features="${features}"
>
<span data-tip="Click to zoom into view" class="icon-dot-circled pointer"></span>
<input data-tip="Burg name. Click and type to change" class="burgName" value="${
b.name
}" autocorrect="off" spellcheck="false" />
<input data-tip="Burg province" class="burgState" value="${province}" disabled />
<input data-tip="Burg state" class="burgState" value="${state}" disabled />
<select data-tip="Dominant culture. Click to change burg culture (to change cell culture use Cultures Editor)" class="stateCulture">
${getCultureOptions(b.culture)}
</select>
<input data-tip="Burg name" class="burgName" value="${b.name}" disabled />
<input data-tip="Burg province" value="${province}" disabled />
<input data-tip="Burg state" value="${state}" disabled />
<input data-tip="Dominant culture" value="${culture}" disabled />
<input data-tip="Burg group" value="${b.group}" disabled />
<span data-tip="Burg population" class="icon-male"></span>
<input data-tip="Burg population. Type to change" value=${si(
population
)} class="burgPopulation" style="width: 5em" />
<input data-tip="Burg population" value=${si(population)} style="width: 5em" disabled />
<div style="width: 3em">
<span
data-tip="${b.capital ? " This burg is a state capital" : "Click to assign a capital status"}"
class="icon-star-empty${b.capital ? "" : " inactive pointer"}" style="padding: 0 1px;"></span>
<span data-tip="Click to toggle port status" class="icon-anchor pointer${
b.port ? "" : " inactive"
}" style="font-size: .9em; padding: 0 1px;"></span>
data-tip="${b.capital ? " This burg is a state capital" : "This burg is a NOT state capital"}"
class="icon-star-empty${b.capital ? "" : " inactive"}" style="padding: 0 1px;"></span>
<span data-tip="${b.port ? " This burg is a port" : "This burg is NOT a port"}"
class="icon-anchor${b.port ? "" : " inactive"}" style="font-size: .9em; padding: 0 1px;"></span>
</div>
<span data-tip="Edit burg" class="icon-pencil"></span>
<span class="locks pointer ${
@ -130,16 +125,7 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
// add listeners
body.querySelectorAll("div.states").forEach(el => el.addEventListener("mouseenter", ev => burgHighlightOn(ev)));
body.querySelectorAll("div.states").forEach(el => el.addEventListener("mouseleave", ev => burgHighlightOff(ev)));
body.querySelectorAll("div > input.burgName").forEach(el => el.addEventListener("input", changeBurgName));
body.querySelectorAll("div > span.icon-dot-circled").forEach(el => el.addEventListener("click", zoomIntoBurg));
body.querySelectorAll("div > select.stateCulture").forEach(el => el.addEventListener("change", changeBurgCulture));
body
.querySelectorAll("div > input.burgPopulation")
.forEach(el => el.addEventListener("change", changeBurgPopulation));
body
.querySelectorAll("div > span.icon-star-empty")
.forEach(el => el.addEventListener("click", toggleCapitalStatus));
body.querySelectorAll("div > span.icon-anchor").forEach(el => el.addEventListener("click", togglePortStatus));
body.querySelectorAll("div > span.locks").forEach(el => el.addEventListener("click", toggleBurgLockStatus));
body.querySelectorAll("div > span.icon-pencil").forEach(el => el.addEventListener("click", openBurgEditor));
body.querySelectorAll("div > span.icon-trash-empty").forEach(el => el.addEventListener("click", triggerBurgRemove));
@ -165,15 +151,6 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
burgLabels.selectAll("text.drag").classed("drag", false);
}
function changeBurgName() {
if (this.value == "") tip("Please provide a name", false, "error");
const burg = +this.parentNode.dataset.id;
pack.burgs[burg].name = this.value;
this.parentNode.dataset.name = this.value;
const label = document.querySelector("#burgLabels [data-id='" + burg + "']");
if (label) label.innerHTML = this.value;
}
function zoomIntoBurg() {
const burg = +this.parentNode.dataset.id;
const label = document.querySelector("#burgLabels [data-id='" + burg + "']");
@ -182,42 +159,6 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
zoomTo(x, y, 8, 2000);
}
function changeBurgCulture() {
const burg = +this.parentNode.dataset.id;
const v = +this.value;
pack.burgs[burg].culture = v;
this.parentNode.dataset.culture = pack.cultures[v].name;
}
function changeBurgPopulation() {
const burg = +this.parentNode.dataset.id;
if (this.value == "" || isNaN(+this.value)) {
tip("Please provide an integer number (like 10000, not 10K)", false, "error");
this.value = si(pack.burgs[burg].population * populationRate * urbanization);
return;
}
pack.burgs[burg].population = this.value / populationRate / urbanization;
this.parentNode.dataset.population = this.value;
this.value = si(this.value);
const population = [];
body.querySelectorAll(":scope > div").forEach(el => population.push(+getInteger(el.dataset.population)));
burgsFooterPopulation.innerHTML = si(d3.mean(population));
}
function toggleCapitalStatus() {
const burg = +this.parentNode.parentNode.dataset.id;
toggleCapital(burg);
burgsOverviewAddLines();
}
function togglePortStatus() {
const burg = +this.parentNode.parentNode.dataset.id;
togglePort(burg);
if (this.classList.contains("inactive")) this.classList.remove("inactive");
else this.classList.add("inactive");
}
function toggleBurgLockStatus() {
const burgId = +this.parentNode.dataset.id;
@ -303,30 +244,6 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
if (addNewBurg.classList.contains("pressed")) addNewBurg.classList.remove("pressed");
}
function openBurgGroupsEditor() {
$("#burgGroupsEditor").dialog({
title: "Edit Burgs Groups",
resizable: false,
position: {my: "center", at: "center", of: "svg"},
buttons: {
Apply: applyMilitaryOptions,
Restore: restoreDefaultUnits,
Cancel: function () {
$(this).dialog("close");
}
},
open: function () {
const buttons = $(this).dialog("widget").find(".ui-dialog-buttonset > button");
buttons[0].addEventListener("mousemove", () =>
tip("Apply military units settings. <span style='color:#cb5858'>All forces will be recalculated!</span>")
);
buttons[1].addEventListener("mousemove", () => tip("Add new military unit to the table"));
buttons[2].addEventListener("mousemove", () => tip("Restore default military units and settings"));
buttons[3].addEventListener("mousemove", () => tip("Close the window without saving the changes"));
}
});
}
function showBurgsChart() {
// build hierarchy tree
const states = pack.states.map(s => {
@ -506,7 +423,7 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
}
function downloadBurgsData() {
let data = `Id,Burg,Province,Province Full Name,State,State Full Name,Culture,Religion,Population,X,Y,Latitude,Longitude,Elevation (${heightUnit.value}),Temperature,Temperature likeness,Capital,Port,Citadel,Walls,Plaza,Temple,Shanty Town,Emblem,City Generator Link\n`; // headers
let data = `Id,Burg,Province,Province Full Name,State,State Full Name,Culture,Religion,Group,Population,X,Y,Latitude,Longitude,Elevation (${heightUnit.value}),Temperature,Temperature likeness,Capital,Port,Citadel,Walls,Plaza,Temple,Shanty Town,Emblem,City Generator Link\n`; // headers
const valid = pack.burgs.filter(b => b.i && !b.removed); // all valid burgs
valid.forEach(b => {
@ -519,6 +436,7 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
data += pack.states[b.state].fullName + ",";
data += pack.cultures[b.culture].name + ",";
data += pack.religions[pack.cells.religion[b.cell]].name + ",";
data += b.group + ",";
data += rn(b.population * populationRate * urbanization) + ",";
// add geography data
@ -633,7 +551,7 @@ function overviewBurgs(settings = {stateId: null, cultureId: null}) {
const activeBurgs = pack.burgs.filter(b => b.i && !b.removed);
const allLocked = activeBurgs.every(burg => burg.lock);
pack.burgs.forEach(burg => {
activeBurgs.forEach(burg => {
burg.lock = !allLocked;
});