diff --git a/main.js b/main.js
index 9753d659..8dc5a8f0 100644
--- a/main.js
+++ b/main.js
@@ -122,6 +122,7 @@ let customization = 0;
let biomesData = applyDefaultBiomesSystem();
let nameBases = Names.getNameBases(); // cultures-related data
+const zoneTypes = ["Invasion", "Rebels", "Proselytism", "Crusade", "Disease", "Disaster"];
let color = d3.scaleSequential(d3.interpolateSpectral); // default color scheme
const lineGen = d3.line().curve(d3.curveBasis); // d3 line generator with default curve interpolation
@@ -1871,6 +1872,14 @@ function addZones(number = 1) {
TIME && console.timeEnd("addZones");
}
+// Update zone types
+function updateZoneType(zoneId, newType) {
+ const zone = document.getElementById(zoneId);
+ if (zone) {
+ zone.dataset.type = newType;
+ }
+}
+
// show map stats on generation complete
function showStatistics() {
const template = templateInput.options[templateInput.selectedIndex].text;
diff --git a/modules/ui/zones-editor.js b/modules/ui/zones-editor.js
index 13e8b31b..10cd6758 100644
--- a/modules/ui/zones-editor.js
+++ b/modules/ui/zones-editor.js
@@ -18,7 +18,9 @@ function editZones() {
});
// add listeners
- document.getElementById("zonesEditorRefresh").addEventListener("click", zonesEditorAddLines);
+ document.getElementById("zonesFilterType").addEventListener("change", refreshZonesEditor);
+ document.getElementById("zonesFilterButton").addEventListener("click", toggleFilterTable);
+ document.getElementById("zonesEditorRefresh").addEventListener("click", refreshZonesEditor);
document.getElementById("zonesEditStyle").addEventListener("click", () => editStyle("zones"));
document.getElementById("zonesLegend").addEventListener("click", toggleLegend);
document.getElementById("zonesPercentage").addEventListener("click", togglePercentageMode);
@@ -26,6 +28,8 @@ function editZones() {
document.getElementById("zonesManuallyApply").addEventListener("click", applyZonesManualAssignent);
document.getElementById("zonesManuallyCancel").addEventListener("click", cancelZonesManualAssignent);
document.getElementById("zonesAdd").addEventListener("click", addZonesLayer);
+ document.getElementById("zonesEditTypes").addEventListener("click", addZonesDialog);
+ document.getElementById("zonesNewTypeButton").addEventListener("click", addZonesType);
document.getElementById("zonesExport").addEventListener("click", downloadZonesData);
document.getElementById("zonesRemove").addEventListener("click", toggleEraseMode);
@@ -47,13 +51,60 @@ function editZones() {
zone = el.parentNode.dataset.id;
if (el.classList.contains("religionName")) zones.select("#" + zone).attr("data-description", el.value);
});
+
+ function refreshZonesEditor() {
+ updateSVG();
+ zonesEditorAddLines();
+ }
+
+ function updateSVG() {
+ const value = document.getElementById("zonesFilterType").value;
- // add line for each zone
+ zones.selectAll("g").each(function () {
+ if (value == "All" || this.dataset.type == value) {
+ this.style.display = "block";
+ } else {
+ this.style.display = "none";
+ }
+ });
+ }
+
+ function getZoneTypesList(zoneId, currentType) {
+ let res = `
';
+
+ return res;
+ }
+
+// add line for each zone
function zonesEditorAddLines() {
const unit = areaUnit.value === "square" ? " " + distanceUnitInput.value + "²" : " " + areaUnit.value;
let lines = "";
+ // make sure all zone types are loaded from the SVG
zones.selectAll("g").each(function () {
+ const zoneType = this.dataset.type;
+ if (!zoneTypes.includes(zoneType)) { zoneTypes.push(zoneType); }
+ });
+
+ const selectedType = zonesFilterType.value || "All";
+ zonesFilterType.options.length=0;
+ zonesFilterType.options.add(new Option("All", "All", false, selectedType=="All"));
+ zoneTypes.forEach(function(z, i) {
+ zonesFilterType.options.add(new Option(z, z, false, selectedType==z));
+ });
+
+ let zoneCount=0;
+ zones.selectAll("g").each(function () {
+ zoneCount++;
+ const zoneType = this.dataset.type;
+ if (selectedType !== "All" && (zonesFilterButton.classList.contains("pressed") && zoneType !== selectedType)) return;
+
const c = this.dataset.cells ? this.dataset.cells.split(",").map(c => +c) : [];
const description = this.dataset.description;
const fill = this.getAttribute("fill");
@@ -61,6 +112,7 @@ function editZones() {
const rural = d3.sum(c.map(i => pack.cells.pop[i])) * populationRate;
const urban = d3.sum(c.map(i => pack.cells.burg[i]).map(b => pack.burgs[b].population)) * populationRate * urbanization;
const population = rural + urban;
+ const zoneTypeList = getZoneTypesList(this.id, this.dataset.type);
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();
@@ -75,6 +127,7 @@ function editZones() {
${si(area) + unit}
${si(population)}
+ ${zoneTypeList}
@@ -83,6 +136,15 @@ function editZones() {
});
body.innerHTML = lines;
+ if (body.innerHTML === "") { body.innerHTML = `
Zero entries for this type. To see entries again, select "All" or disable the filter button
+
`; }
+
+ for (let i=0; i
${z}${count}`;
+ if (i > 5) {
+ let id="removeZoneType" + i;
+ lines += ``;
+ }
+ lines += '';
+ });
+ zoneTypeListBody.innerHTML = lines;
+ zonesTypesFooterNumber.innerHTML = zoneTypes.length;
+
+ for (let i=0; i