diff --git a/index.css b/index.css
index 4390c271..d104ffb3 100644
--- a/index.css
+++ b/index.css
@@ -1361,10 +1361,7 @@ div.states>.culturePopulation {
cursor: pointer;
}
-div.states > .cultureBase,
-div.states > .cultureType,
-div.states > .stateCulture,
-div.states > .diplomacyRelations {
+div.states > select {
width: 4.6em;
cursor: pointer;
border: 0;
@@ -1374,10 +1371,7 @@ div.states > .diplomacyRelations {
appearance: none;
}
-div.states > .cultureBase {
- width: 6em;
-}
-
+div.states > .cultureBase,
div.states > .burgName,
div.states > .burgState,
div.states > .burgCulture {
diff --git a/index.html b/index.html
index 3cb08413..2218f7a5 100644
--- a/index.html
+++ b/index.html
@@ -2604,6 +2604,7 @@
Area
Population
Namesbase
+ Emblems
diff --git a/modules/coa-generator.js b/modules/coa-generator.js
index e3071f9e..22265084 100644
--- a/modules/coa-generator.js
+++ b/modules/coa-generator.js
@@ -196,6 +196,18 @@
}
};
+ const shields = {
+ types: {basic: 10, regional: 2, historical: 1, specific: 1, banner: 1, simple: 2, fantasy: 1, middleEarth: 0},
+ basic: {heater: 12, spanish: 6, french: 1},
+ regional: {horsehead: 1, horsehead2: 1, polish: 1, hessen: 1, swiss: 1},
+ historical: {boeotian: 1, roman: 2, kite: 1, oldFrench: 5, renaissance: 2, baroque: 2},
+ specific: {targe: 1, targe2: 0, pavise: 5, wedged: 10},
+ banner: {flag: 1, pennon: 0, guidon: 0, banner: 0, dovetail: 1, gonfalon: 5, pennant: 0},
+ simple: {round: 12, oval: 6, vesicaPiscis: 1, square: 1, diamond: 2, no: 0},
+ fantasy: {fantasy1: 2, fantasy2: 2, fantasy3: 1, fantasy4: 1, fantasy5: 3},
+ middleEarth: {noldor: 1, gondor: 1, easterling: 1, erebor: 1, ironHills: 1, urukHai: 1, moriaOrc: 1}
+ }
+
const generate = function(parent, kinship, dominion, type) {
if (parent === "custom") parent = null;
let usedPattern = null, usedTinctures = [];
@@ -471,8 +483,11 @@
}
const getShield = function(culture, state) {
- const emblemShape = document.getElementById("emblemShape").value;
- if (emblemShape === "state" && state && pack.states[state].coa) return pack.states[state].coa.shield;
+ const emblemShape = document.getElementById("emblemShape");
+ const shapeGroup = emblemShape.selectedOptions[0].parentNode.label;
+ if (shapeGroup !== "Diversiform") return emblemShape.value;
+
+ if (emblemShape.value === "state" && state && pack.states[state].coa) return pack.states[state].coa.shield;
if (pack.cultures[culture].shield) return pack.cultures[culture].shield;
console.error("Shield shape is not defined on culture level", pack.cultures[culture]);
return "heater";
@@ -481,6 +496,6 @@
const toString = coa => JSON.stringify(coa).replaceAll("#", "%23");
const copy = coa => JSON.parse(JSON.stringify(coa));
- return {generate, toString, copy, getShield};
+ return {generate, toString, copy, getShield, shields};
})));
\ No newline at end of file
diff --git a/modules/cultures-generator.js b/modules/cultures-generator.js
index 4e4d4e62..d0e37161 100644
--- a/modules/cultures-generator.js
+++ b/modules/cultures-generator.js
@@ -56,7 +56,6 @@
c.code = getCode(c.name);
cells.culture[cell] = i+1;
if (emblemShape === "random") c.shield = getRandomShield();
- else if (emblemShape !== "culture" && emblemShape !== "state") c.shield = emblemShape;
});
function placeCenter(v) {
@@ -147,10 +146,9 @@
const color = d3.color(d3.scaleSequential(d3.interpolateRainbow)(Math.random())).hex();
// define emblem shape
- const emblemShape = document.getElementById("emblemShape").value;
let shield = culture.shield;
+ const emblemShape = document.getElementById("emblemShape").value;
if (emblemShape === "random") shield = getRandomShield();
- else if (emblemShape !== "culture" && emblemShape !== "state") shield = emblemShape;
pack.cultures.push({name, color, base, center, i, expansionism:1, type:"Generic", cells:0, area:0, rural:0, urban:0, origin:0, code, shield});
}
@@ -420,19 +418,8 @@
}
const getRandomShield = function() {
- const shields = {
- types: {basic: 10, regional: 2, historical: 1, specific: 1, banner: 1, simple: 2, fantasy: 1, middleEarth: 0},
- basic: {heater: 12, spanish: 6, french: 1},
- regional: {horsehead: 1, horsehead2: 1, polish: 1, hessen: 1, swiss: 1},
- historical: {boeotian: 1, roman: 2, kite: 1, oldFrench: 5, renaissance: 2, baroque: 2},
- specific: {targe: 1, targe2: 0, pavise: 5, wedged: 10},
- banner: {flag: 1, pennon: 0, guidon: 0, banner: 0, dovetail: 1, gonfalon: 5, pennant: 0},
- simple: {round: 12, oval: 6, vesicaPiscis: 1, square: 1, diamond: 2, no: 0},
- fantasy: {fantasy1: 2, fantasy2: 2, fantasy3: 1, fantasy4: 1, fantasy5: 3},
- middleEarth: {noldor: 1, gondor: 1, easterling: 1, erebor: 1, ironHills: 1, urukHai: 1, moriaOrc: 1}
- }
- const type = rw(shields.types);
- return rw(shields[type]);
+ const type = rw(COA.shields.types);
+ return rw(COA.shields[type]);
}
return {generate, add, expand, getDefault, getRandomShield};
diff --git a/modules/ui/cultures-editor.js b/modules/ui/cultures-editor.js
index c7a6c45e..5f25fb38 100644
--- a/modules/ui/cultures-editor.js
+++ b/modules/ui/cultures-editor.js
@@ -60,6 +60,9 @@ function editCultures() {
const unit = areaUnit.value === "square" ? " " + distanceUnitInput.value + "²" : " " + areaUnit.value;
let lines = "", totalArea = 0, totalPopulation = 0;
+ const emblemShapeGroup = document.getElementById("emblemShape").selectedOptions[0].parentNode.label;
+ const selectShape = emblemShapeGroup === "Diversiform"
+
for (const c of pack.cultures) {
if (c.removed) continue;
const area = c.area * (distanceScaleInput.value ** 2);
@@ -73,7 +76,7 @@ function editCultures() {
if (!c.i) {
// Uncultured (neutral) line
lines += `
+ data-area=${area} data-population=${population} data-base=${c.base} data-type="" data-expansionism="" data-emblems="${c.shield}">
@@ -86,26 +89,28 @@ function editCultures() {
${si(population)}
-
+
+ ${selectShape ? `
` : ""}
`;
continue;
}
lines += `
+ data-area=${area} data-population=${population} data-base=${c.base} data-type=${c.type} data-expansionism=${c.expansionism} data-emblems="${c.shield}">
${c.cells}
-
+
${si(area) + unit}
${si(population)}
-
+
+ ${selectShape ? `
` : ""}
`;
}
@@ -128,6 +133,7 @@ function editCultures() {
body.querySelectorAll("div > input.statePower").forEach(el => el.addEventListener("input", cultureChangeExpansionism));
body.querySelectorAll("div > select.cultureType").forEach(el => el.addEventListener("change", cultureChangeType));
body.querySelectorAll("div > select.cultureBase").forEach(el => el.addEventListener("change", cultureChangeBase));
+ body.querySelectorAll("div > select.cultureShape").forEach(el => el.addEventListener("change", cultureChangeShape));
body.querySelectorAll("div > div.culturePopulation").forEach(el => el.addEventListener("click", changePopulation));
body.querySelectorAll("div > span.icon-arrows-cw").forEach(el => el.addEventListener("click", cultureRegenerateBurgs));
body.querySelectorAll("div > span.icon-trash-empty").forEach(el => el.addEventListener("click", cultureRemove));
@@ -150,6 +156,11 @@ function editCultures() {
return options;
}
+ function getShapeOptions(selected) {
+ const shapes = Object.keys(COA.shields.types).map(type => Object.keys(COA.shields[type])).flat();
+ return shapes.map(shape => ``);
+ }
+
function cultureHighlightOn(event) {
const culture = +event.target.dataset.id;
const info = document.getElementById("cultureInfo");
@@ -225,6 +236,40 @@ function editCultures() {
this.parentNode.dataset.base = pack.cultures[culture].base = v;
}
+ function cultureChangeShape() {
+ const culture = +this.parentNode.dataset.id;
+ const shape = this.value;
+ this.parentNode.dataset.emblems = pack.cultures[culture].shield = shape;
+
+ const rerenderCOA = (id, coa) => {
+ const coaEl = document.getElementById(id);
+ if (!coaEl) return; // not rendered
+ coaEl.remove();
+ COArenderer.trigger(id, coa);
+ }
+
+ pack.states.forEach(state => {
+ if (state.culture !== culture || !state.i || state.removed || !state.coa || state.coa === "custom") return;
+ if (shape === state.coa.shield) return;
+ state.coa.shield = shape;
+ rerenderCOA("stateCOA" + state.i, state.coa);
+ });
+
+ pack.provinces.forEach(province => {
+ if (pack.cells.culture[province.center] !== culture || !province.i || province.removed || !province.coa || province.coa === "custom") return;
+ if (shape === province.coa.shield) return;
+ province.coa.shield = shape;
+ rerenderCOA("provinceCOA" + province.i, province.coa);
+ });
+
+ pack.burgs.forEach(burg => {
+ if (burg.culture !== culture || !burg.i || burg.removed || !burg.coa || burg.coa === "custom") return;
+ if (shape === burg.coa.shield) return;
+ burg.coa.shield = shape
+ rerenderCOA("burgCOA" + burg.i, burg.coa);
+ });
+ }
+
function changePopulation() {
const culture = +this.parentNode.dataset.id;
const c = pack.cultures[culture];
@@ -293,7 +338,7 @@ function editCultures() {
b.name = Names.getCulture(culture);
labels.select("[data-id='" + b.i +"']").text(b.name);
});
- tip(`Names for ${cBurgs.length} burgs are re-generated`);
+ tip(`Names for ${cBurgs.length} burgs are regenerated`, false, "success");
}
function cultureRemove() {
@@ -306,12 +351,12 @@ function editCultures() {
Remove: function() {
cults.select("#culture"+culture).remove();
debug.select("#cultureCenter"+culture).remove();
-
+
pack.burgs.filter(b => b.culture == culture).forEach(b => b.culture = 0);
pack.states.forEach((s, i) => {if(s.culture === culture) s.culture = 0;});
pack.cells.culture.forEach((c, i) => {if(c === culture) pack.cells.culture[i] = 0;});
pack.cultures[culture].removed = true;
-
+
const origin = pack.cultures[culture].origin;
pack.cultures.forEach(c => {if(c.origin === culture) c.origin = origin;});
refreshCulturesEditor();
@@ -493,8 +538,8 @@ function editCultures() {
culturesEditor.querySelectorAll(".hide").forEach(el => el.classList.add("hidden"));
culturesHeader.querySelector("div[data-sortby='type']").style.left = "8.8em";
+ culturesHeader.querySelector("div[data-sortby='base']").style.left = "13.6em";
culturesFooter.style.display = "none";
- culturesHeader.querySelector("div[data-sortby='base']").style.marginLeft = "20px";
body.querySelectorAll("div > input, select, span, svg").forEach(e => e.style.pointerEvents = "none");
$("#culturesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg"}});
@@ -589,8 +634,8 @@ function editCultures() {
culturesEditor.querySelectorAll(".hide").forEach(el => el.classList.remove("hidden"));
culturesHeader.querySelector("div[data-sortby='type']").style.left = "18.6em";
+ culturesHeader.querySelector("div[data-sortby='base']").style.left = "35.8em";
culturesFooter.style.display = "block";
- culturesHeader.querySelector("div[data-sortby='base']").style.marginLeft = "2px";
body.querySelectorAll("div > input, select, span, svg").forEach(e => e.style.pointerEvents = "all");
if(!close) $("#culturesEditor").dialog({position: {my: "right top", at: "right-10 top+10", of: "svg"}});
@@ -634,7 +679,7 @@ function editCultures() {
function downloadCulturesData() {
const unit = areaUnit.value === "square" ? distanceUnitInput.value + "2" : areaUnit.value;
- let data = "Id,Culture,Color,Cells,Expansionism,Type,Area "+unit+",Population,Namesbase\n"; // headers
+ let data = "Id,Culture,Color,Cells,Expansionism,Type,Area "+unit+",Population,Namesbase,Emblems Shape\n"; // headers
body.querySelectorAll(":scope > div").forEach(function(el) {
data += el.dataset.id + ",";
@@ -646,7 +691,8 @@ function editCultures() {
data += el.dataset.area + ",";
data += el.dataset.population + ",";
const base = +el.dataset.base;
- data += nameBases[base].name + "\n";
+ data += nameBases[base].name + ",";
+ data += el.dataset.emblems + "\n";
});
const name = getFileName("Cultures") + ".csv";
diff --git a/modules/ui/options.js b/modules/ui/options.js
index 25b27ded..875438be 100644
--- a/modules/ui/options.js
+++ b/modules/ui/options.js
@@ -299,7 +299,8 @@ function changeEmblemShape(emblemShape) {
const rerenderCOA = (id, coa) => {
const coaEl = document.getElementById(id);
- if (coaEl) coaEl.remove();
+ if (!coaEl) return; // not rendered
+ coaEl.remove();
COArenderer.trigger(id, coa);
}