This commit is contained in:
Azgaar 2020-06-21 18:11:51 +03:00
parent 882d024e24
commit 2d00b3c25b
6 changed files with 111 additions and 82 deletions

View file

@ -1217,6 +1217,16 @@ div.slider .ui-slider-handle {
overflow-y: auto; overflow-y: auto;
} }
.overflow {
max-width: 93vw;
overflow: auto;
max-height: 75vh;
}
.overflow > div {
width: max-content;
}
div.header > div { div.header > div {
font-weight: bold; font-weight: bold;
font-size: .9em; font-size: .9em;
@ -1855,7 +1865,9 @@ div#notesHeader {
} }
div#notesBody { div#notesBody {
padding: 0 10px; padding: 0 1em;
max-height: 80vh;
overflow: auto;
} }
svg.button { svg.button {

View file

@ -2450,7 +2450,7 @@
<button id="regimentEmblemSelect" style="padding: 0; width: 4.5em">select</button> <button id="regimentEmblemSelect" style="padding: 0; width: 4.5em">select</button>
</div> </div>
<div id="regimentComposition" style="padding: .1em"></div> <div id="regimentComposition" class="table"></div>
</div> </div>
<div id="regimentBottom"> <div id="regimentBottom">
@ -2465,7 +2465,7 @@
</div> </div>
<div id="battleScreen" class="dialog stable" style="display: none"> <div id="battleScreen" class="dialog stable" style="display: none">
<div id="battleBody"> <div id="battleBody" class="overflow>
<template id="battlePhases_field"> <template id="battlePhases_field">
<button data-tip="Skirmish phase. Ranged units excel" data-phase="skirmish" class="icon-button-skirmish"></button> <button data-tip="Skirmish phase. Ranged units excel" data-phase="skirmish" class="icon-button-skirmish"></button>
<button data-tip="Melee phase. Melee units excel" data-phase="melee" class="icon-button-melee"></button> <button data-tip="Melee phase. Melee units excel" data-phase="melee" class="icon-button-melee"></button>
@ -3450,15 +3450,17 @@
</div> </div>
<div id="militaryOverview" class="dialog stable" style="display: none"> <div id="militaryOverview" class="dialog stable" style="display: none">
<div id="militaryHeader" class="header"> <div class="overflow">
<div data-tip="State name. Click to sort" style="left:1.8em; width: 7.4em;" class="sortable alphabetically" data-sortby="state">State&nbsp;</div> <div id="militaryHeader" class="header">
<div data-tip="Total military personnel (considering crew). Click to sort" id="militaryTotal" class="sortable icon-sort-number-down" data-sortby="total">Total&nbsp;</div> <div data-tip="State name. Click to sort" style="margin-left: 1.8em; width: 5.6em" class="sortable alphabetically" data-sortby="state">State&nbsp;</div>
<div data-tip="State population. Click to sort" style="width: 6.5em; margin-left: -1em" class="sortable" data-sortby="population">Population&nbsp;</div> <div data-tip="Total military personnel (considering crew). Click to sort" id="militaryTotal" class="sortable icon-sort-number-down" data-sortby="total">Total&nbsp;</div>
<div data-tip="Military personnel rate (% of state population). Depends on war alert. Click to sort" style="width: 3.7em" class="sortable" data-sortby="rate">Rate&nbsp;</div> <div data-tip="State population. Click to sort" style="width: 6.5em; margin-left: -1em" class="sortable" data-sortby="population">Population&nbsp;</div>
<div data-tip="War Alert. Modifier to military forces number, depends of political situation. Click to sort" class="sortable" data-sortby="alert">War Alert&nbsp;</div> <div data-tip="Military personnel rate (% of state population). Depends on war alert. Click to sort" style="width: 3.7em" class="sortable" data-sortby="rate">Rate&nbsp;</div>
</div> <div data-tip="War Alert. Modifier to military forces number, depends of political situation. Click to sort" class="sortable" data-sortby="alert">War Alert&nbsp;</div>
</div>
<div id="militaryBody" class="table" data-type="absolute"></div> <div id="militaryBody" data-type="absolute"></div>
</div>
<div id="militaryFooter" class="totalLine"> <div id="militaryFooter" class="totalLine">
<div data-tip="States number" style="margin-left: 4px">States:&nbsp;<span id="militaryFooterStates">0</span></div> <div data-tip="States number" style="margin-left: 4px">States:&nbsp;<span id="militaryFooterStates">0</span></div>
@ -3480,13 +3482,15 @@
</div> </div>
<div id="regimentsOverview" class="dialog stable" style="display: none"> <div id="regimentsOverview" class="dialog stable" style="display: none">
<div id="regimentsHeader" class="header"> <div class="overflow">
<div data-tip="State name. Click to sort" style="left:1.8em; width: 9em" class="sortable alphabetically" data-sortby="state">State&nbsp;</div> <div id="regimentsHeader" class="header">
<div data-tip="Regiment emblem and name. Click to sort by name" style="width: 12em" class="sortable alphabetically" data-sortby="name">Name&nbsp;</div> <div data-tip="State name. Click to sort" style="left:1.8em; width: 9em" class="sortable alphabetically" data-sortby="state">State&nbsp;</div>
<div data-tip="Total military personnel (not considering crew). Click to sort" style="margin-left: .8em" id="regimentsTotal" class="sortable icon-sort-number-down" data-sortby="total">Total&nbsp;</div> <div data-tip="Regiment emblem and name. Click to sort by name" style="width: 12em" class="sortable alphabetically" data-sortby="name">Name&nbsp;</div>
</div> <div data-tip="Total military personnel (not considering crew). Click to sort" style="margin-left: .8em" id="regimentsTotal" class="sortable icon-sort-number-down" data-sortby="total">Total&nbsp;</div>
</div>
<div id="regimentsBody" class="table" data-type="absolute"></div> <div id="regimentsBody" data-type="absolute"></div>
</div>
<div id="regimentsBottom"> <div id="regimentsBottom">
<button id="regimentsOverviewRefresh" data-tip="Refresh the overview screen" class="icon-cw"></button> <button id="regimentsOverviewRefresh" data-tip="Refresh the overview screen" class="icon-cw"></button>
@ -3498,22 +3502,24 @@
</div> </div>
<div id="militaryOptions" class="dialog stable" style="display: none"> <div id="militaryOptions" class="dialog stable" style="display: none">
<table id="militaryOptionsTable"> <div class="table">
<thead> <table id="militaryOptionsTable">
<tr> <thead>
<th data-tip="Unit icon">Icon</th> <tr>
<th data-tip="Unit name. If name is changed for existing unit, old unit will be replaced">Unit name</th> <th data-tip="Unit icon">Icon</th>
<th data-tip="Conscription percentage for rural population">Rural</th> <th data-tip="Unit name. If name is changed for existing unit, old unit will be replaced">Unit name</th>
<th data-tip="Conscription percentage for urban population">Urban</th> <th data-tip="Conscription percentage for rural population">Rural</th>
<th data-tip="Average number of people in crew (used for total personnel calculation)">Crew</th> <th data-tip="Conscription percentage for urban population">Urban</th>
<th data-tip="Unit military power (used for battle simulation)">Power</th> <th data-tip="Average number of people in crew (used for total personnel calculation)">Crew</th>
<th data-tip="Unit type to apply special rules on forces recalculation">Type</th> <th data-tip="Unit military power (used for battle simulation)">Power</th>
<th data-tip="Check if unit is separate and can be stacked only with units of the same type">Sep.</th> <th data-tip="Unit type to apply special rules on forces recalculation">Type</th>
</tr> <th data-tip="Check if unit is separate and can be stacked only with units of the same type">Sep.</th>
</thead> </tr>
<tbody> </thead>
</tbody> <tbody>
</table> </tbody>
</table>
</div>
</div> </div>
<div id="styleSaver" class="dialog stable textual" style="display: none"> <div id="styleSaver" class="dialog stable textual" style="display: none">

View file

@ -341,7 +341,8 @@ function showWelcomeMessage() {
This version is compatible with ${changelog}, loaded <i>.map</i> files will be auto-updated. This version is compatible with ${changelog}, loaded <i>.map</i> files will be auto-updated.
<ul>${post} <ul>${post}
<li>Battle simulation</li> <li>Military forces changes (${link("https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Military-Forces", "detailed description")})</li>
<li>Battle simulation (${link("https://github.com/Azgaar/Fantasy-Map-Generator/wiki/Battle-Simulator", "detailed description")})</li>
<li>Ice layer and Ice editor</li> <li>Ice layer and Ice editor</li>
<li>Route and River Elevation profile</li> <li>Route and River Elevation profile</li>
<li>Image Converter enhancement</li> <li>Image Converter enhancement</li>

View file

@ -24,7 +24,6 @@ function showEPForRiver(node) {
function showElevationProfile(data, routeLen, isRiver) { function showElevationProfile(data, routeLen, isRiver) {
// data is an array of cell indexes, routeLen is the distance (in actual metres/feet), isRiver should be true for rivers, false otherwise // data is an array of cell indexes, routeLen is the distance (in actual metres/feet), isRiver should be true for rivers, false otherwise
document.getElementById("epScaleRange").addEventListener("change", draw); document.getElementById("epScaleRange").addEventListener("change", draw);
document.getElementById("epCurve").addEventListener("change", draw); document.getElementById("epCurve").addEventListener("change", draw);
document.getElementById("epSave").addEventListener("click", downloadCSV); document.getElementById("epSave").addEventListener("click", downloadCSV);
@ -36,7 +35,7 @@ function showElevationProfile(data, routeLen, isRiver) {
}); });
// prevent river graphs from showing rivers as flowing uphill - remember the general slope // prevent river graphs from showing rivers as flowing uphill - remember the general slope
var slope = 0; let slope = 0;
if (isRiver) { if (isRiver) {
if (pack.cells.h[data[0]] < pack.cells.h[data[data.length-1]]) { if (pack.cells.h[data[0]] < pack.cells.h[data[data.length-1]]) {
slope = 1; // up-hill slope = 1; // up-hill
@ -45,21 +44,16 @@ function showElevationProfile(data, routeLen, isRiver) {
} }
} }
const chartWidth = window.innerWidth-180; const chartWidth = window.innerWidth-180, chartHeight = 300; // height of our land/sea profile, excluding the biomes data below
const chartHeight = 300; // height of our land/sea profile, excluding the biomes data below const xOffset = 80, yOffset = 80; // this is our drawing starting point from top-left (y = 0) of SVG
const xOffset = 80;
const yOffset = 80; // this is our drawing starting point from top-left (y = 0) of SVG
const biomesHeight = 40; const biomesHeight = 40;
let lastBurgIndex = 0; let lastBurgIndex = 0;
let lastBurgCell = 0; let lastBurgCell = 0;
let burgCount = 0; let burgCount = 0;
let chartData = {biome:[], burg:[], cell:[], height:[], mi:1000000, ma:0, mih: 100, mah: 0, points:[] } let chartData = {biome:[], burg:[], cell:[], height:[], mi:1000000, ma:0, mih: 100, mah: 0, points:[]};
for (let i=0, prevB=0, prevH=-1; i<data.length; i++) { for (let i=0, prevB=0, prevH=-1; i <data.length; i++) {
let cell = data[i]; let cell = data[i];
let h = pack.cells.h[cell]; let h = pack.cells.h[cell];
if (h < 20) h = 20; if (h < 20) h = 20;
@ -72,7 +66,6 @@ function showElevationProfile(data, routeLen, isRiver) {
} }
} }
prevH = h; prevH = h;
// river up-hill checks stop here
let b = pack.cells.burg[cell]; let b = pack.cells.burg[cell];
if (b == prevB) b = 0; if (b == prevB) b = 0;
@ -100,7 +93,7 @@ function showElevationProfile(data, routeLen, isRiver) {
function downloadCSV() { function downloadCSV() {
let data = "Point,X,Y,Cell,Height,Height value,Population,Burg,Burg population,Biome,Biome color,Culture,Culture color,Religion,Religion color,Province,Province color,State,State color\n"; // headers let data = "Point,X,Y,Cell,Height,Height value,Population,Burg,Burg population,Biome,Biome color,Culture,Culture color,Religion,Religion color,Province,Province color,State,State color\n"; // headers
for (let k=0; k<chartData.points.length; k++) { for (let k=0; k < chartData.points.length; k++) {
let cell = chartData.cell[k]; let cell = chartData.cell[k];
let burg = pack.cells.burg[cell]; let burg = pack.cells.burg[cell];
let biome = pack.cells.biome[cell]; let biome = pack.cells.biome[cell];
@ -146,7 +139,7 @@ function showElevationProfile(data, routeLen, isRiver) {
chartData.points = []; chartData.points = [];
let heightScale = 100 / parseInt(epScaleRange.value); let heightScale = 100 / parseInt(epScaleRange.value);
heightScale *= 0.90; // curves cause the heights to go slightly higher, adjust here heightScale *= .9; // curves cause the heights to go slightly higher, adjust here
const xscale = d3.scaleLinear().domain([0, data.length]).range([0, chartWidth]); const xscale = d3.scaleLinear().domain([0, data.length]).range([0, chartWidth]);
const yscale = d3.scaleLinear().domain([0, chartData.ma * heightScale]).range([chartHeight, 0]); const yscale = d3.scaleLinear().domain([0, chartData.ma * heightScale]).range([chartHeight, 0]);
@ -162,7 +155,7 @@ function showElevationProfile(data, routeLen, isRiver) {
chart.append("defs").append("marker").attr("id", "arrowhead").attr("orient", "auto").attr("markerWidth", "2").attr("markerHeight", "4").attr("refX", "0.1").attr("refY", "2").append("path").attr("d", "M0,0 V4 L2,2 Z").attr("fill", "darkgray"); chart.append("defs").append("marker").attr("id", "arrowhead").attr("orient", "auto").attr("markerWidth", "2").attr("markerHeight", "4").attr("refX", "0.1").attr("refY", "2").append("path").attr("d", "M0,0 V4 L2,2 Z").attr("fill", "darkgray");
let colors = getColorScheme(); let colors = getColorScheme();
var landdef = chart.select("defs").append("linearGradient").attr("id", "landdef").attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%"); const landdef = chart.select("defs").append("linearGradient").attr("id", "landdef").attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%");
if (chartData.mah == chartData.mih) { if (chartData.mah == chartData.mih) {
landdef.append("stop").attr("offset", "0%").attr("style", "stop-color:" + getColor(chartData.mih, colors) + ";stop-opacity:1"); landdef.append("stop").attr("offset", "0%").attr("style", "stop-color:" + getColor(chartData.mih, colors) + ";stop-opacity:1");
@ -188,18 +181,18 @@ function showElevationProfile(data, routeLen, isRiver) {
// copy the points so that we can add extra straight pieces, else we get curves at the ends of the chart // copy the points so that we can add extra straight pieces, else we get curves at the ends of the chart
let extra = chartData.points.slice(); let extra = chartData.points.slice();
var path = curve(extra); let path = curve(extra);
// this completes the right-hand side and bottom of our land "polygon" // this completes the right-hand side and bottom of our land "polygon"
path += " L" + parseInt(xscale(extra.length) + +xOffset) + "," + parseInt(extra[extra.length-1][1]); path += " L" + parseInt(xscale(extra.length) + +xOffset) + "," + parseInt(extra[extra.length-1][1]);
path += " L" + parseInt(xscale(extra.length) + +xOffset) + "," + parseInt(yscale(0) + +yOffset); path += " L" + parseInt(xscale(extra.length) + +xOffset) + "," + parseInt(yscale(0) + +yOffset);
path += " L" + parseInt(xscale(0) + +xOffset) +"," + parseInt(yscale(0) + +yOffset); path += " L" + parseInt(xscale(0) + +xOffset) +"," + parseInt(yscale(0) + +yOffset);
path += "Z"; path += "Z";
chart.append("g").attr("id", "epland").append("path").attr("d", path).attr("stroke", "purple").attr("stroke-width", "0").attr("fill", "url(#landdef)"); chart.append("g").attr("id", "epland").append("path").attr("d", path).attr("stroke", "purple").attr("stroke-width", "0").attr("fill", "url(#landdef)");
// biome / heights // biome / heights
let g = chart.append("g").attr("id", "epbiomes"); let g = chart.append("g").attr("id", "epbiomes");
const hu = heightUnit.value; const hu = heightUnit.value;
for(var k=0; k<chartData.points.length; k++) { for(let k=0; k < chartData.points.length; k++) {
const x = chartData.points[k][0]; const x = chartData.points[k][0];
const y = yOffset + chartHeight; const y = yOffset + chartHeight;
const c = biomesData.color[chartData.biome[k]]; const c = biomesData.color[chartData.biome[k]];
@ -245,10 +238,10 @@ function showElevationProfile(data, routeLen, isRiver) {
.attr("transform", "translate(" + xOffset + "," + yOffset + ")") .attr("transform", "translate(" + xOffset + "," + yOffset + ")")
.call(yGrid); .call(yGrid);
// draw city labels - try to avoid putting labels over one another // draw city labels - try to avoid putting labels over one another
g = chart.append("g").attr("id", "epburglabels"); g = chart.append("g").attr("id", "epburglabels");
var y1 = 0; let y1 = 0;
var add = 15; const add = 15;
let xwidth = chartData.points[1][0] - chartData.points[0][0]; let xwidth = chartData.points[1][0] - chartData.points[0][0];
for (let k=0; k<chartData.points.length; k++) for (let k=0; k<chartData.points.length; k++)
@ -258,11 +251,9 @@ function showElevationProfile(data, routeLen, isRiver) {
let x1 = chartData.points[k][0]; // left side of graph by default let x1 = chartData.points[k][0]; // left side of graph by default
if (k > 0) x1 += xwidth/2; // center it if not first if (k > 0) x1 += xwidth/2; // center it if not first
if (k == chartData.points.length-1) if (k == chartData.points.length-1) x1 = chartWidth + xOffset; // right part of graph
x1 = chartWidth + xOffset; // right part of graph
y1+=add; y1+=add;
if (y1 >= yOffset) { y1 = add; } if (y1 >= yOffset) y1 = add;
var d1 = 0;
// burg name // burg name
g.append("text").attr("id", "ep" + b).attr("class", "epburglabel").attr("x", x1).attr("y", y1).attr("text-anchor", "middle"); g.append("text").attr("id", "ep" + b).attr("class", "epburglabel").attr("x", x1).attr("y", y1).attr("text-anchor", "middle");
@ -284,4 +275,3 @@ function showElevationProfile(data, routeLen, isRiver) {
modules.elevation = false; modules.elevation = false;
} }
} }

View file

@ -71,7 +71,7 @@ document.getElementById("options").querySelector("div.tab").addEventListener("cl
// show popup with a list of Patreon supportes (updated manually, to be replaced with API call) // show popup with a list of Patreon supportes (updated manually, to be replaced with API call)
function showSupporters() { function showSupporters() {
const supporters = "Aaron Meyer, Ahmad Amerih, AstralJacks, aymeric, Billy Dean Goehring, Branndon Edwards, Chase Mayers, Curt Flood, cyninge, Dino Princip, E.M. White, es, Fondue, Fritjof Olsson, Gatsu, Johan Fröberg, Jonathan Moore, Joseph Miranda, Kate, KC138, Luke Nelson, Markus Finster, Massimo Vella, Mikey, Nathan Mitchell, Paavi1, Pat, Ryan Westcott, Sasquatch, Shawn Spencer, Sizz_TV, Timothée CALLET, UTG community, Vlad Tomash, Wil Sisney, William Merriott, Xariun, Gun Metal Games, Scott Marner, Spencer Sherman, Valerii Matskevych, Alloyed Clavicle, Stewart Walsh, Ruthlyn Mollett (Javan), Benjamin Mair-Pratt, Diagonath, Alexander Thomas, Ashley Wilson-Savoury, William Henry, Preston Brooks, JOSHUA QUALTIERI, Hilton Williams, Katharina Haase, Hisham Bedri, Ian arless, Karnat, Bird, Kevin, Jessica Thomas, Steve Hyatt, Logicspren, Alfred García, Jonathan Killstring, John Ackley, Invad3r233, Norbert Žigmund, Jennifer, PoliticsBuff, _gfx_, Maggie, Connor McMartin, Jared McDaris, BlastWind, Franc Casanova Ferrer, Dead & Devil, Michael Carmody, Valerie Elise, naikibens220, Jordon Phillips, William Pucs, The Dungeon Masters, Brady R Rathbun, J, Shadow, Matthew Tiffany, Huw Williams, Joseph Hamilton, FlippantFeline, Tamashi Toh, kms, Stephen Herron, MidnightMoon, Whakomatic x, Barished, Aaron bateson, Brice Moss, Diklyquill, PatronUser, Michael Greiner, Steven Bennett, Jacob Harrington, Miguel C., Reya C., Giant Monster Games, Noirbard, Brian Drennen, Ben Craigie, Alex Smolin, Endwords, Joshua E Goodwin, SirTobit , Allen S. Rout, Allen Bull Bear, Pippa Mitchell, R K, G0atfather, Ryan Lege, Caner Oleas Pekgönenç, Bradley Edwards, Tertiary , Austin Miller, Jesse Holmes, Jan Dvořák, Marten F, Erin D. Smale"; const supporters = "Aaron Meyer, Ahmad Amerih, AstralJacks, aymeric, Billy Dean Goehring, Branndon Edwards, Chase Mayers, Curt Flood, cyninge, Dino Princip, E.M. White, es, Fondue, Fritjof Olsson, Gatsu, Johan Fröberg, Jonathan Moore, Joseph Miranda, Kate, KC138, Luke Nelson, Markus Finster, Massimo Vella, Mikey, Nathan Mitchell, Paavi1, Pat, Ryan Westcott, Sasquatch, Shawn Spencer, Sizz_TV, Timothée CALLET, UTG community, Vlad Tomash, Wil Sisney, William Merriott, Xariun, Gun Metal Games, Scott Marner, Spencer Sherman, Valerii Matskevych, Alloyed Clavicle, Stewart Walsh, Ruthlyn Mollett (Javan), Benjamin Mair-Pratt, Diagonath, Alexander Thomas, Ashley Wilson-Savoury, William Henry, Preston Brooks, JOSHUA QUALTIERI, Hilton Williams, Katharina Haase, Hisham Bedri, Ian arless, Karnat, Bird, Kevin, Jessica Thomas, Steve Hyatt, Logicspren, Alfred García, Jonathan Killstring, John Ackley, Invad3r233, Norbert Žigmund, Jennifer, PoliticsBuff, _gfx_, Maggie, Connor McMartin, Jared McDaris, BlastWind, Franc Casanova Ferrer, Dead & Devil, Michael Carmody, Valerie Elise, naikibens220, Jordon Phillips, William Pucs, The Dungeon Masters, Brady R Rathbun, J, Shadow, Matthew Tiffany, Huw Williams, Joseph Hamilton, FlippantFeline, Tamashi Toh, kms, Stephen Herron, MidnightMoon, Whakomatic x, Barished, Aaron bateson, Brice Moss, Diklyquill, PatronUser, Michael Greiner, Steven Bennett, Jacob Harrington, Miguel C., Reya C., Giant Monster Games, Noirbard, Brian Drennen, Ben Craigie, Alex Smolin, Endwords, Joshua E Goodwin, SirTobit , Allen S. Rout, Allen Bull Bear, Pippa Mitchell, R K, G0atfather, Ryan Lege, Caner Oleas Pekgönenç, Bradley Edwards, Tertiary , Austin Miller, Jesse Holmes, Jan Dvořák, Marten F, Erin D. Smale, Maxwell Hill, Drunken_Legends, rob bee, Jesse Holmes, YYako, Detocroix";
alertMessage.innerHTML = "<ul style='column-count: 3; column-gap: 2em'>" + supporters.split(", ").sort().map(n => `<li>${n}</li>`).join("") + "</ul>"; alertMessage.innerHTML = "<ul style='column-count: 3; column-gap: 2em'>" + supporters.split(", ").sort().map(n => `<li>${n}</li>`).join("") + "</ul>";
$("#alert").dialog({resizable: false, title: "Patreon Supporters", width: "30vw", position: {my: "center", at: "center", of: "svg"}}); $("#alert").dialog({resizable: false, title: "Patreon Supporters", width: "30vw", position: {my: "center", at: "center", of: "svg"}});
} }

View file

@ -446,11 +446,31 @@ function editStates() {
pack.cells.province.forEach((pr, i) => {if(pr === p) pack.cells.province[i] = 0;}); pack.cells.province.forEach((pr, i) => {if(pr === p) pack.cells.province[i] = 0;});
}); });
// remove military
pack.states[state].military.forEach(m => {
const id = `regiment${state}-${m.i}`;
const index = notes.findIndex(n => n.id === id);
if (index != -1) notes.splice(index, 1);
});
armies.select("g#army"+state).remove();
const military = pack.states[elSelected.dataset.state].military;
const regIndex = military.indexOf(regiment());
if (regIndex === -1) return;
military.splice(regIndex, 1);
const index = notes.findIndex(n => n.id === elSelected.id);
if (index != -1) notes.splice(index, 1);
elSelected.remove();
const capital = pack.states[state].capital; const capital = pack.states[state].capital;
pack.burgs[capital].capital = 0; pack.burgs[capital].capital = 0;
pack.burgs[capital].state = 0; pack.burgs[capital].state = 0;
moveBurgToGroup(capital, "towns"); moveBurgToGroup(capital, "towns");
// clean state object
pack.states[state].military = [];
debug.selectAll(".highlight").remove(); debug.selectAll(".highlight").remove();
if (!layerIsOn("toggleStates")) toggleStates(); else drawStates(); if (!layerIsOn("toggleStates")) toggleStates(); else drawStates();
if (!layerIsOn("toggleBorders")) toggleBorders(); else drawBorders(); if (!layerIsOn("toggleBorders")) toggleBorders(); else drawBorders();