diff --git a/index.css b/index.css index 149db0b6..a7e09155 100644 --- a/index.css +++ b/index.css @@ -132,7 +132,13 @@ button, select, a, .pointer { user-select: none; } -#statesBody, #provincesBody, #relig, #biomes, #cults { +#statesBody, #provincesBody { + stroke-width: 2; + fill-rule: evenodd; + mask: url(#land); +} + +#relig, #biomes, #cults { stroke-width: .6; fill-rule: evenodd; mask: url(#land); @@ -141,7 +147,6 @@ button, select, a, .pointer { #statesHalo { fill: none; filter: url(#blur5); - /*animation: hideshow 3s infinite;*/ } #borders { @@ -156,11 +161,6 @@ button, select, a, .pointer { font-size: 9px; } -@keyframes hideshow { - 0% {stroke-width: 1;} - 50% {stroke-width: 10;} -} - #rivers { stroke: none; mask: url(#land); diff --git a/main.js b/main.js index c1c89d15..838922da 100644 --- a/main.js +++ b/main.js @@ -1732,7 +1732,11 @@ function addZones(number = 1) { function showStatistics() { const template = templateInput.value; const templateRandom = locked("template") ? "" : "(random)"; - const stats = ` Seed: ${seed} + + mapId = Date.now(); // unique map id is it's creation date number + mapHistory.push({seed, width:graphWidth, height:graphHeight, template, created:mapId}); + console.log(` + Seed: ${seed} Canvas size: ${graphWidth}x${graphHeight} Template: ${template} ${templateRandom} Points: ${grid.points.length} @@ -1743,11 +1747,7 @@ function showStatistics() { Burgs: ${pack.burgs.length-1} Religions: ${pack.religions.length-1} Culture set: ${culturesSet.selectedOptions[0].innerText} - Cultures: ${pack.cultures.length-1}`; - - mapId = Date.now(); // unique map id is it's creation date number - mapHistory.push({seed, width:graphWidth, height:graphHeight, template, created:mapId}); - console.log(stats); + Cultures: ${pack.cultures.length-1}`); } const regenerateMap = debounce(function() { diff --git a/modules/coa-generator.js b/modules/coa-generator.js index 71f119d4..274ecff1 100644 --- a/modules/coa-generator.js +++ b/modules/coa-generator.js @@ -203,7 +203,7 @@ // define emblems layer style for all styles // add coa on click events for loaded map // generatate state/prov/burg - remove all rendered coas - // remove state/prov/burg - remove rendered coa + // remove state/prov/burg - remove rendered coa [burg - done, provice - done, state] // style settings for emblems layer // fix download svg/png // test in FF diff --git a/modules/coa-renderer.js b/modules/coa-renderer.js index 6318a98a..6a4be2fb 100644 --- a/modules/coa-renderer.js +++ b/modules/coa-renderer.js @@ -878,6 +878,10 @@ // async render coa if it does not exist const trigger = function(id, coa) { + if (!coa) { + console.warn(id, "emblem is undefined"); + return; + } if (!document.getElementById(id)) draw(id, coa); } diff --git a/modules/river-generator.js b/modules/river-generator.js index 078392e1..69e3c571 100644 --- a/modules/river-generator.js +++ b/modules/river-generator.js @@ -126,11 +126,8 @@ } } - // drawRivers - rivers.selectAll("path").remove(); - rivers.selectAll("path").data(riverPaths).enter() - .append("path").attr("d", d => d[1]).attr("id", d => "river"+d[0]) - .attr("data-width", d => d[2]).attr("data-increment", d => d[3]); + const html = riverPaths.map(r =>``).join(""); + rivers.html(html); }() // apply change heights as basic one diff --git a/modules/ui/burgs-overview.js b/modules/ui/burgs-overview.js index 35d668a6..d5e37f79 100644 --- a/modules/ui/burgs-overview.js +++ b/modules/ui/burgs-overview.js @@ -456,7 +456,7 @@ function overviewBurgs() { function triggerAllBurgsRemove() { alertMessage.innerHTML = `Are you sure you want to remove all burgs except of capitals? -
To remove a capital you have to remove its state first`; +
To remove a capital you have to remove a state first`; $("#alert").dialog({resizable: false, title: "Remove all burgs", buttons: { Remove: function() { @@ -472,5 +472,4 @@ function overviewBurgs() { pack.burgs.filter(b => b.i && !b.capital).forEach(b => removeBurg(b.i)); burgsOverviewAddLines(); } - } diff --git a/modules/ui/editors.js b/modules/ui/editors.js index ed70c203..3544a8ef 100644 --- a/modules/ui/editors.js +++ b/modules/ui/editors.js @@ -172,6 +172,13 @@ function removeBurg(id) { const cells = pack.cells, burg = pack.burgs[id]; burg.removed = true; cells.burg[burg.cell] = 0; + + if (burg.coa) { + const coaId = "burgCOA" + id; + if (document.getElementById(coaId)) document.getElementById(coaId).remove(); + emblems.select(`#burgEmblems > use[data-i='${id}']`).remove(); + delete burg.coa; // remove to save data + } } function toggleCapital(burg) { diff --git a/modules/ui/emblems-editor.js b/modules/ui/emblems-editor.js index 43416eeb..f5b6ff18 100644 --- a/modules/ui/emblems-editor.js +++ b/modules/ui/emblems-editor.js @@ -8,7 +8,6 @@ function editEmblem(type, id, el) { const emblemStates = document.getElementById("emblemStates"); const emblemProvinces = document.getElementById("emblemProvinces"); const emblemBurgs = document.getElementById("emblemBurgs"); - const {states, provinces, burgs, cells} = pack; updateElementSelectors(type, id, el); @@ -55,28 +54,30 @@ function editEmblem(type, id, el) { if (type === "state") state = el.i; else if (type === "province") { province = el.i - state = states[el.state].i; + state = pack.states[el.state].i; } else { burg = el.i; - province = cells.province[el.cell] ? provinces[cells.province[el.cell]].i : 0; - state = provinces[province].state || 0; + province = pack.cells.province[el.cell] ? pack.provinces[pack.cells.province[el.cell]].i : 0; + state = el.state; } + const validBurgs = pack.burgs.filter(burg => burg.i && !burg.removed && burg.coa); + // update option list and select actual values emblemStates.options.length = 0; - const neutralBurgs = burgs.filter(burg => burg.i && !burg.removed && !burg.state); - if (neutralBurgs.length) emblemStates.options.add(new Option(states[0].name, 0, false, !state)); - const stateList = states.filter(state => state.i && !state.removed); + const neutralBurgs = validBurgs.filter(burg => !burg.state); + if (neutralBurgs.length) emblemStates.options.add(new Option(pack.states[0].name, 0, false, !state)); + const stateList = pack.states.filter(state => state.i && !state.removed); stateList.forEach(s => emblemStates.options.add(new Option(s.name, s.i, false, s.i === state))); emblemProvinces.options.length = 0; emblemProvinces.options.add(new Option("", 0, false, !province)); - const provinceList = provinces.filter(province => !province.removed && province.state === state); + const provinceList = pack.provinces.filter(province => !province.removed && province.state === state); provinceList.forEach(p => emblemProvinces.options.add(new Option(p.name, p.i, false, p.i === province))); emblemBurgs.options.length = 0; emblemBurgs.options.add(new Option("", 0, false, !burg)); - const burgList = burgs.filter(burg => !burg.removed && province ? cells.province[burg.cell] === province : burg.state === state); + const burgList = validBurgs.filter(burg => province ? pack.cells.province[burg.cell] === province : burg.state === state); burgList.forEach(b => emblemBurgs.options.add(new Option(b.capital ? "👑 " + b.name : b.name, b.i, false, b.i === burg))); emblemBurgs.options[0].disabled = true; @@ -97,11 +98,11 @@ function editEmblem(type, id, el) { const state = +this.value; if (state) { type = "state"; - el = states[state]; + el = pack.states[state]; id = "stateCOA"+ state; } else { // select neutral burg if state is changed to Neutrals - const neutralBurgs = burgs.filter(burg => burg.i && !burg.removed && !burg.state); + const neutralBurgs = pack.burgs.filter(burg => burg.i && !burg.removed && !burg.state); if (!neutralBurgs.length) return; type = "burg"; el = neutralBurgs[0]; @@ -115,13 +116,13 @@ function editEmblem(type, id, el) { if (province) { type = "province"; - el = provinces[province]; + el = pack.provinces[province]; id = "provinceCOA"+ province; } else { // select state if province is changed to null value const state = +emblemStates.value; type = "state"; - el = states[state]; + el = pack.states[state]; id = "stateCOA"+ state; } @@ -131,7 +132,7 @@ function editEmblem(type, id, el) { function selectBurg() { const burg = +this.value; type = "burg"; - el = burgs[burg]; + el = pack.burgs[burg]; id = "burgCOA"+ burg; updateElementSelectors(type, id, el); } @@ -239,9 +240,9 @@ function editEmblem(type, id, el) { function downloadGallery() { const name = getFileName("Emblems Gallery"); - const validStates = states.filter(s => s.i && !s.removed && s.coa); - const validProvinces = provinces.filter(p => p.i && !p.removed && p.coa); - const validBurgs = burgs.filter(b => b.i && !b.removed && b.coa); + const validStates = pack.states.filter(s => s.i && !s.removed && s.coa); + const validProvinces = pack.provinces.filter(p => p.i && !p.removed && p.coa); + const validBurgs = pack.burgs.filter(b => b.i && !b.removed && b.coa); triggerCOALoad(validStates, validProvinces, validBurgs); const timeout = (validStates.length + validProvinces.length + validBurgs.length) * 8; tip("Preparing to download...", true, "warn", timeout); @@ -255,28 +256,28 @@ function editEmblem(type, id, el) { }).join("") + ``; const provinceSections = validStates.map(state => { - const figures = validProvinces.filter(p => p.state === state.i).map(province => { + const stateProvinces = validProvinces.filter(p => p.state === state.i); + const figures = stateProvinces.map(province => { const el = document.getElementById("provinceCOA"+province.i); const svg = getSVG(el, province.coa, 200); return `
${province.fullName}
${svg}
`; }).join(""); - return `

${state.fullName} provinces

${figures}
`; + return stateProvinces.length ? `

${state.fullName} provinces

${figures}
` : ""; }).join(""); const burgSections = validStates.map(state => { const stateBurgs = validBurgs.filter(b => b.state === state.i); let stateBurgSections = validProvinces.filter(p => p.state === state.i).map(province => { - const provinceBurgs = stateBurgs.filter(b => cells.province[b.cell] === province.i); - if (!provinceBurgs.length) return ""; + const provinceBurgs = stateBurgs.filter(b => pack.cells.province[b.cell] === province.i); const provinceBurgFigures = provinceBurgs.map(burg => { const el = document.getElementById("burgCOA"+burg.i); const svg = getSVG(el, burg.coa, 200); return `
${burg.name}
${svg}
`; }).join(""); - return `

${province.fullName} burgs

${provinceBurgFigures}
`; + return provinceBurgs.length ? `

${province.fullName} burgs

${provinceBurgFigures}
` : ""; }).join(""); - const stateBurgOutOfProvinces = stateBurgs.filter(b => !cells.province[b.cell]); + const stateBurgOutOfProvinces = stateBurgs.filter(b => !pack.cells.province[b.cell]); const stateBurgOutOfProvincesFigures = stateBurgOutOfProvinces.map(burg => { const el = document.getElementById("burgCOA"+burg.i); const svg = getSVG(el, burg.coa, 200); diff --git a/modules/ui/layers.js b/modules/ui/layers.js index a3a68703..87b545da 100644 --- a/modules/ui/layers.js +++ b/modules/ui/layers.js @@ -714,15 +714,16 @@ function drawStates() { }); const bodyData = body.map((p, i) => [p.length > 10 ? p : null, i, states[i].color]).filter(d => d[0]); - statesBody.selectAll("path").data(bodyData).enter().append("path").attr("d", d => d[0]).attr("fill", d => d[2]).attr("stroke", "none").attr("id", d => "state"+d[1]); const gapData = gap.map((p, i) => [p.length > 10 ? p : null, i, states[i].color]).filter(d => d[0]); - statesBody.selectAll(".path").data(gapData).enter().append("path").attr("d", d => d[0]).attr("fill", "none").attr("stroke", d => d[2]).attr("id", d => "state-gap"+d[1]); - defs.select("#statePaths").selectAll("clipPath").remove(); - defs.select("#statePaths").selectAll("clipPath").data(bodyData).enter().append("clipPath").attr("id", d => "state-clip"+d[1]).append("use").attr("href", d => "#state"+d[1]); - statesHalo.selectAll(".path").data(bodyData).enter().append("path") - .attr("d", d => d[0]).attr("stroke", d => d3.color(d[2]) ? d3.color(d[2]).darker().hex() : "#666666") - .attr("id", d => "state-border"+d[1]).attr("clip-path", d => "url(#state-clip"+d[1]+")"); + const bodyString = bodyData.map(d => ``).join(""); + const gapString = gapData.map(d => ``).join(""); + const clipString = bodyData.map(d => ``).join(""); + const haloString = bodyData.map(d => ``).join(""); + + statesBody.html(bodyString + gapString); + defs.select("#statePaths").html(clipString); + statesHalo.html(haloString); // connect vertices to chain function connectVertices(start, t, state) { diff --git a/modules/ui/provinces-editor.js b/modules/ui/provinces-editor.js index 27f684b0..28788e12 100644 --- a/modules/ui/provinces-editor.js +++ b/modules/ui/provinces-editor.js @@ -336,7 +336,6 @@ function editProvinces() { refreshProvincesEditor(); } - } function toggleFog(p, cl) { @@ -346,17 +345,26 @@ function editProvinces() { } function removeProvince(p) { - alertMessage.innerHTML = `Are you sure you want to remove the province?
This action cannot be reverted`; $("#alert").dialog({resizable: false, title: "Remove province", buttons: { Remove: function() { - pack.cells.province.forEach((province, i) => {if(province === p) pack.cells.province[i] = 0;}); - const state = pack.provinces[p].state; - if (pack.states[state].provinces.includes(p)) pack.states[state].provinces.splice(pack.states[state].provinces.indexOf(p), 1); - pack.provinces[p].removed = true; + pack.cells.province.forEach((province, i) => { + if(province === p) pack.cells.province[i] = 0; + }); + const province = pack.provinces[p]; + const s = province.state, state = pack.states[s]; + if (state.provinces.includes(p)) state.provinces.splice(state.provinces.indexOf(p), 1); + province.removed = true; unfog("focusProvince"+p); - + + if (province.coa) { + const coaId = "provinceCOA" + p; + if (document.getElementById(coaId)) document.getElementById(coaId).remove(); + emblems.select(`#provinceEmblems > use[data-i='${p}']`).remove(); + delete province.coa; // remove to save data + } + const g = provs.select("#provincesBody"); g.select("#province"+p).remove(); g.select("#province-gap"+p).remove(); @@ -367,8 +375,6 @@ function editProvinces() { Cancel: function() {$(this).dialog("close");} } }); - - } function editProvinceName(province) { @@ -829,13 +835,17 @@ function editProvinces() { buttons: { Remove: function() { $(this).dialog("close"); - pack.provinces.filter(p => p.i).forEach(p => { - p.removed = true; - unfog("focusProvince"+p.i); - }); - pack.cells.i.forEach(i => pack.cells.province[i] = 0); - pack.states.filter(s => s.i && !s.removed).forEach(s => s.provinces = []); + // remove emblems + document.querySelectorAll("[id^='provinceCOA']").forEach(el => el.remove()); + emblems.select("#provinceEmblems").selectAll("*").remove(); + + // remove data + pack.provinces = [0]; + pack.cells.province = new Uint16Array(pack.cells.i.length); + pack.states.forEach(s => s.provinces = []); + + unfog(); if (!layerIsOn("toggleBorders")) toggleBorders(); else drawBorders(); provs.select("#provincesBody").remove(); turnButtonOff("toggleProvinces"); diff --git a/modules/ui/style.js b/modules/ui/style.js index 400c98de..f337f024 100644 --- a/modules/ui/style.js +++ b/modules/ui/style.js @@ -718,7 +718,7 @@ function applyDefaultStyle() { biomes.attr("opacity", null).attr("filter", null).attr("mask", null); ice.attr("opacity", .8).attr("fill", "#e8f0f6").attr("stroke", "#e8f0f6").attr("stroke-width", 1).attr("filter", "url(#dropShadow05)"); stateBorders.attr("opacity", .8).attr("stroke", "#56566d").attr("stroke-width", 1).attr("stroke-dasharray", "2").attr("stroke-linecap", "butt").attr("filter", null); - provinceBorders.attr("opacity", .8).attr("stroke", "#56566d").attr("stroke-width", .2).attr("stroke-dasharray", "1").attr("stroke-linecap", "butt").attr("filter", null); + provinceBorders.attr("opacity", .8).attr("stroke", "#56566d").attr("stroke-width", .5).attr("stroke-dasharray", "0 2").attr("stroke-linecap", "round").attr("filter", null); cells.attr("opacity", null).attr("stroke", "#808080").attr("stroke-width", .1).attr("filter", null).attr("mask", null); gridOverlay.attr("opacity", .8).attr("type", "pointyHex").attr("size", 20).attr("stroke", "#808080").attr("stroke-width", .5).attr("stroke-dasharray", null).attr("transform", null).attr("filter", null).attr("mask", null);