mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 01:41:22 +01:00
v1.5.05 - emblems regeneration
This commit is contained in:
parent
24d2efe8b6
commit
925e7accbd
8 changed files with 222 additions and 153 deletions
|
|
@ -1930,9 +1930,10 @@
|
|||
<button id="regenerateRoutes" data-tip="Click to regenerate all routes">Routes</button>
|
||||
<button id="regenerateRivers" data-tip="Click to regenerate all rivers (restore default state)">Rivers</button>
|
||||
<button id="regeneratePopulation" data-tip="Click to recalculate rural and urban population">Population</button>
|
||||
<button id="regenerateBurgs" data-tip="Click to regenerate all burgs and routes. States will remain as they are">Burgs</button>
|
||||
<button id="regenerateStates" data-tip="Click to select new capitals and regenerate states. Military forces will be regenerated as well, burgs will remain as they are">States</button>
|
||||
<button id="regenerateProvinces" data-tip="Click to regenerate provinces. States will remain as they are">Provinces</button>
|
||||
<button id="regenerateBurgs" data-tip="Click to regenerate all burgs and routes. States will remain as they are">Burgs</button>
|
||||
<button id="regenerateEmblems" data-tip="Click to regenerate all emblems">Emblems</button>
|
||||
<button id="regenerateReligions" data-tip="Click to regenerate religions">Religions</button>
|
||||
<button id="regenerateCultures" data-tip="Click to regenerate cultures">Cultures</button>
|
||||
<button id="regenerateMilitary" data-tip="Click to recalculate military forces based on current military options">Military</button>
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@
|
|||
const nomadic = [1, 2, 3, 4].includes(cells.biome[b.cell]);
|
||||
const type = nomadic ? "Nomadic" : cultures[b.culture].type === "Nomadic" ? "Generic" : cultures[b.culture].type;
|
||||
const coa = COA.generate(null);
|
||||
coa.shield = getShield(b.culture, null);
|
||||
coa.shield = COA.getShield(b.culture, null);
|
||||
states.push({i, color: colors[i-1], name, expansionism, capital: i, type, center: b.cell, culture: b.culture, coa});
|
||||
cells.burg[b.cell] = i;
|
||||
});
|
||||
|
|
@ -139,14 +139,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
function getShield(culture, state) {
|
||||
const emblemShape = document.getElementById("emblemShape").value;
|
||||
if (emblemShape === "state" && state && pack.states[state].coa) return pack.states[state].coa.shield;
|
||||
if (pack.cultures[culture].shield) return pack.cultures[culture].shield;
|
||||
console.error("Emblem shape is not defined on culture level", pack.cultures[culture]);
|
||||
return "heater";
|
||||
}
|
||||
|
||||
// define burg coordinates, coa, port status and define details
|
||||
const specifyBurgs = function() {
|
||||
TIME && console.time("specifyBurgs");
|
||||
|
|
@ -194,7 +186,7 @@
|
|||
else if (b.port) kinship -= .1;
|
||||
if (b.culture !== state.culture) kinship -= .25;
|
||||
b.coa = COA.generate(stateCOA, kinship);
|
||||
b.coa.shield = getShield(b.culture, b.state);
|
||||
b.coa.shield = COA.getShield(b.culture, b.state);
|
||||
}
|
||||
|
||||
// de-assign port status if it's the only one on feature
|
||||
|
|
@ -592,6 +584,7 @@
|
|||
TIME && console.time("collectStatistics");
|
||||
const cells = pack.cells, states = pack.states;
|
||||
states.forEach(s => {
|
||||
if (s.removed) return;
|
||||
s.cells = s.area = s.burgs = s.rural = s.urban = 0;
|
||||
s.neighbors = new Set();
|
||||
});
|
||||
|
|
@ -614,7 +607,10 @@
|
|||
}
|
||||
|
||||
// convert neighbors Set object into array
|
||||
states.forEach(s => s.neighbors = Array.from(s.neighbors));
|
||||
states.forEach(s => {
|
||||
if (!s.neighbors) return;
|
||||
s.neighbors = Array.from(s.neighbors);
|
||||
});
|
||||
|
||||
TIME && console.timeEnd("collectStatistics");
|
||||
}
|
||||
|
|
@ -957,7 +953,7 @@
|
|||
const color = getMixedColor(s.color);
|
||||
const kinship = nameByBurg ? .8 : .4;
|
||||
const coa = COA.generate(stateBurgs[i].coa, kinship);
|
||||
coa.shield = getShield(c, s.i);
|
||||
coa.shield = COA.getShield(c, s.i);
|
||||
provinces.push({i:province, state:s.i, center, burg, name, formName, fullName, color, coa});
|
||||
}
|
||||
});
|
||||
|
|
@ -1055,7 +1051,7 @@
|
|||
const dominion = colony ? P(.95) : singleIsle || isleGroup ? P(.7) : P(.3);
|
||||
const kinship = dominion ? 0 : .4;
|
||||
const coa = COA.generate(s.coa, kinship, dominion);
|
||||
coa.shield = getShield(c, s.i);
|
||||
coa.shield = COA.getShield(c, s.i);
|
||||
provinces.push({i:province, state:s.i, center, burg, name, formName, fullName, color, coa});
|
||||
s.provinces.push(province);
|
||||
|
||||
|
|
|
|||
|
|
@ -196,18 +196,14 @@
|
|||
// TODO
|
||||
// seafaring
|
||||
// stringify coa on save and load
|
||||
// regenerateAll
|
||||
// generate on new item creation
|
||||
// old versions auto migration: coa generation for cultures and states etc.
|
||||
// emblems layer for old maps
|
||||
// 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 [burg - done, provice - done, state]
|
||||
// style settings for emblems layer
|
||||
// fix download svg/png
|
||||
// fix map download svg/png
|
||||
// test in FF
|
||||
// generate all?
|
||||
// layout preset
|
||||
// burg editor - add emblem
|
||||
// other editors
|
||||
|
|
@ -340,11 +336,13 @@
|
|||
}
|
||||
|
||||
// dominions have canton with parent coa
|
||||
if (P(dominion)) {
|
||||
const t = getType(parent.t1) === getType(coa.t1) ? getTincture("division", usedTinctures, coa.t1) : parent.t1;
|
||||
if (P(dominion) && parent.charges) {
|
||||
const invert = isSameType(parent.t1, coa.t1);
|
||||
const t = invert ? getTincture("division", usedTinctures, coa.t1) : parent.t1;
|
||||
const canton = {ordinary: "canton", t};
|
||||
if (coa.charges) {
|
||||
coa.charges.forEach((charge, i) => {
|
||||
if (charge.size === 1.5) charge.size = 1.4;
|
||||
if (charge.p.includes("a")) charge.p = charge.p.replaceAll("a", "");
|
||||
if (charge.p.includes("j")) charge.p = charge.p.replaceAll("j", "");
|
||||
if (charge.p.includes("y")) charge.p = charge.p.replaceAll("y", "");
|
||||
|
|
@ -352,17 +350,20 @@
|
|||
});
|
||||
}
|
||||
|
||||
if (parent.charges) {
|
||||
let charge = parent.charges[0].charge;
|
||||
if (charge === "inescutcheon" && parent.charges[1]) charge = parent.charges[1].charge;
|
||||
let charge = parent.charges[0].charge;
|
||||
if (charge === "inescutcheon" && parent.charges[1]) charge = parent.charges[1].charge;
|
||||
|
||||
let t2 = parent.charges[0].t;
|
||||
if (getType(t) === getType(t2)) t2 = getTincture("charge", usedTinctures, t);
|
||||
let t2 = invert ? parent.t1 : parent.charges[0].t;
|
||||
if (isSameType(t, t2)) t2 = getTincture("charge", usedTinctures, t);
|
||||
|
||||
if (!coa.charges) coa.charges = [];
|
||||
coa.charges.push({charge, t: t2, p: "y", size: 0.5});
|
||||
|
||||
if (!coa.charges) coa.charges = [];
|
||||
coa.charges.push({charge, t: t2, p: "y", size: 0.5});
|
||||
} else canton.above = 1;
|
||||
coa.ordinaries ? coa.ordinaries.push(canton) : coa.ordinaries = [canton];
|
||||
|
||||
console.log(encodeURI(`https://azgaar.github.io/Armoria/?coa=${JSON.stringify(coa)}`));
|
||||
console.log(encodeURI(`https://azgaar.github.io/Armoria/?coa=${JSON.stringify(parent)}`));
|
||||
console.log("-------");
|
||||
}
|
||||
|
||||
function selectCharge(set) {
|
||||
|
|
@ -398,6 +399,18 @@
|
|||
if (Object.keys(tinctures.stains).includes(tincture)) return "stains";
|
||||
}
|
||||
|
||||
function isSameType(t1, t2) {
|
||||
return type(t1) === type(t2);
|
||||
|
||||
function type(tincture) {
|
||||
if (Object.keys(tinctures.metals).includes(tincture)) return "metals";
|
||||
if (Object.keys(tinctures.colours).includes(tincture)) return "colours";
|
||||
if (Object.keys(tinctures.stains).includes(tincture)) return "stains";
|
||||
else return "pattern";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function definePattern(pattern, element, size = "") {
|
||||
let t1 = null, t2 = null;
|
||||
if (P(.15)) size = "-small";
|
||||
|
|
@ -465,19 +478,17 @@
|
|||
return coa;
|
||||
}
|
||||
|
||||
const generateAll = function() {
|
||||
const states = pack.states, burgs = pack.burgs, provinces = pack.provinces;
|
||||
|
||||
states.forEach(state => {
|
||||
if (!state.i || state.removed) return;
|
||||
const coa = generate();
|
||||
s.coa = coa;
|
||||
});
|
||||
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;
|
||||
if (pack.cultures[culture].shield) return pack.cultures[culture].shield;
|
||||
console.error("Emblem shape is not defined on culture level", pack.cultures[culture]);
|
||||
return "heater";
|
||||
}
|
||||
|
||||
const toString = coa => JSON.stringify(coa).replaceAll("#", "%23");
|
||||
const copy = coa => JSON.parse(JSON.stringify(coa));
|
||||
|
||||
return {generate, generateAll, toString, copy};
|
||||
return {generate, toString, copy, getShield};
|
||||
|
||||
})));
|
||||
|
|
@ -3,7 +3,7 @@ function editEmblem(type, id, el) {
|
|||
if (customization) return;
|
||||
if (!id && d3.event) defineEmblemData(d3.event);
|
||||
|
||||
emblems.selectAll(":scope > use").call(d3.drag().on("drag", dragEmblem)).classed("draggable", true);
|
||||
emblems.selectAll("use").call(d3.drag().on("drag", dragEmblem)).classed("draggable", true);
|
||||
|
||||
const emblemStates = document.getElementById("emblemStates");
|
||||
const emblemProvinces = document.getElementById("emblemProvinces");
|
||||
|
|
@ -337,6 +337,6 @@ function editEmblem(type, id, el) {
|
|||
}
|
||||
|
||||
function closeEmblemEditor() {
|
||||
emblems.selectAll(":scope > use").call(d3.drag().on("drag", null)).attr("class", null);
|
||||
emblems.selectAll("use").call(d3.drag().on("drag", null)).attr("class", null);
|
||||
}
|
||||
}
|
||||
|
|
@ -1297,32 +1297,23 @@ function drawEmblems() {
|
|||
.force('collision', d3.forceCollide().radius(d => d.size/2))
|
||||
.stop();
|
||||
|
||||
// debug.attr("fill", "#fff").attr("stroke", "#000")
|
||||
// .selectAll("circle").data(nodes).join("circle")
|
||||
// .attr("cx", d => d.x)
|
||||
// .attr("cy", d => d.y)
|
||||
// .attr("r", 2);
|
||||
|
||||
d3.timeout(function() {
|
||||
const n = Math.ceil(Math.log(simulation.alphaMin()) / Math.log(1 - simulation.alphaDecay()));
|
||||
for (let i = 0; i < n; ++i) {
|
||||
simulation.tick();
|
||||
}
|
||||
|
||||
emblems.select("#burgEmblems").attr("font-size", sizeBurgs)
|
||||
.selectAll("use").data(nodes.filter(node => node.type === "burg")).join("use")
|
||||
.attr("x", d => d.x - d.size / 2).attr("y", d => d.y - d.size / 2)
|
||||
.attr("width", "1em").attr("height", "1em").attr("data-i", d => d.i);
|
||||
const burgNodes = nodes.filter(node => node.type === "burg");
|
||||
const burgString = burgNodes.map(d => `<use data-i="${d.i}" x="${d.x - d.size / 2}" y="${d.y - d.size / 2}" width="1em" height="1em"/>`).join("");
|
||||
emblems.select("#burgEmblems").attr("font-size", sizeBurgs).html(burgString);
|
||||
|
||||
emblems.select("#provinceEmblems").attr("font-size", sizeProvinces)
|
||||
.selectAll("use").data(nodes.filter(node => node.type === "province")).join("use")
|
||||
.attr("x", d => d.x - d.size / 2).attr("y", d => d.y - d.size / 2)
|
||||
.attr("width", "1em").attr("height", "1em").attr("data-i", d => d.i);
|
||||
const provinceNodes = nodes.filter(node => node.type === "province");
|
||||
const provinceString = provinceNodes.map(d => `<use data-i="${d.i}" x="${d.x - d.size / 2}" y="${d.y - d.size / 2}" width="1em" height="1em"/>`).join("");
|
||||
emblems.select("#provinceEmblems").attr("font-size", sizeProvinces).html(provinceString);
|
||||
|
||||
emblems.select("#stateEmblems").attr("font-size", sizeStates)
|
||||
.selectAll("use").data(nodes.filter(node => node.type === "state")).join("use")
|
||||
.attr("x", d => d.x - d.size / 2).attr("y", d => d.y - d.size / 2)
|
||||
.attr("width", "1em").attr("height", "1em").attr("data-i", d => d.i);
|
||||
const stateNodes = nodes.filter(node => node.type === "state");
|
||||
const stateString = stateNodes.map(d => `<use data-i="${d.i}" x="${d.x - d.size / 2}" y="${d.y - d.size / 2}" width="1em" height="1em"/>`).join("");
|
||||
emblems.select("#stateEmblems").attr("font-size", sizeStates).html(stateString);
|
||||
|
||||
invokeActiveZooming();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -352,18 +352,16 @@ function editProvinces() {
|
|||
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 coaId = "provinceCOA" + p;
|
||||
if (document.getElementById(coaId)) document.getElementById(coaId).remove();
|
||||
emblems.select(`#provinceEmblems > use[data-i='${p}']`).remove();
|
||||
|
||||
pack.provinces[p] = {i: p, removed: true};
|
||||
|
||||
const g = provs.select("#provincesBody");
|
||||
g.select("#province"+p).remove();
|
||||
|
|
|
|||
|
|
@ -422,17 +422,28 @@ function editStates() {
|
|||
statesBody.select("#state"+state).remove();
|
||||
statesBody.select("#state-gap"+state).remove();
|
||||
statesHalo.select("#state-border"+state).remove();
|
||||
labels.select("#stateLabel"+state).remove();
|
||||
defs.select("#textPath_stateLabel"+state).remove();
|
||||
|
||||
unfog("focusState"+state);
|
||||
const label = document.querySelector("#stateLabel"+state);
|
||||
if (label) label.remove();
|
||||
pack.burgs.forEach(b => {if(b.state === state) b.state = 0;});
|
||||
pack.cells.state.forEach((s, i) => {if(s === state) pack.cells.state[i] = 0;});
|
||||
pack.states[state].removed = true;
|
||||
|
||||
// remove emblem
|
||||
const coaId = "stateCOA" + state;
|
||||
document.getElementById(coaId).remove();
|
||||
emblems.select(`#stateEmblems > use[data-i='${state}']`).remove();
|
||||
|
||||
// remove provinces
|
||||
pack.states[state].provinces.forEach(p => {
|
||||
pack.provinces[p].removed = true;
|
||||
pack.provinces[p] = {i: p, removed: true};
|
||||
pack.cells.province.forEach((pr, i) => {if(pr === p) pack.cells.province[i] = 0;});
|
||||
const coaId = "provinceCOA" + p;
|
||||
if (document.getElementById(coaId)) document.getElementById(coaId).remove();
|
||||
emblems.select(`#provinceEmblems > use[data-i='${p}']`).remove();
|
||||
const g = provs.select("#provincesBody");
|
||||
g.select("#province"+p).remove();
|
||||
g.select("#province-gap"+p).remove();
|
||||
});
|
||||
|
||||
// remove military
|
||||
|
|
@ -448,8 +459,7 @@ function editStates() {
|
|||
pack.burgs[capital].state = 0;
|
||||
moveBurgToGroup(capital, "towns");
|
||||
|
||||
// clean state object
|
||||
pack.states[state].military = [];
|
||||
pack.states[state] = {i: state, removed: true};
|
||||
|
||||
debug.selectAll(".highlight").remove();
|
||||
if (!layerIsOn("toggleStates")) toggleStates(); else drawStates();
|
||||
|
|
|
|||
|
|
@ -60,9 +60,10 @@ function processFeatureRegeneration(event, button) {
|
|||
if (button === "regenerateRoutes") {Routes.regenerate(); if (!layerIsOn("toggleRoutes")) toggleRoutes();} else
|
||||
if (button === "regenerateRivers") regenerateRivers(); else
|
||||
if (button === "regeneratePopulation") recalculatePopulation(); else
|
||||
if (button === "regenerateBurgs") regenerateBurgs(); else
|
||||
if (button === "regenerateStates") regenerateStates(); else
|
||||
if (button === "regenerateProvinces") regenerateProvinces(); else
|
||||
if (button === "regenerateBurgs") regenerateBurgs(); else
|
||||
if (button === "regenerateEmblems") regenerateEmblems(); else
|
||||
if (button === "regenerateReligions") regenerateReligions(); else
|
||||
if (button === "regenerateCultures") regenerateCultures(); else
|
||||
if (button === "regenerateMilitary") regenerateMilitary(); else
|
||||
|
|
@ -95,6 +96,108 @@ function recalculatePopulation() {
|
|||
});
|
||||
}
|
||||
|
||||
function regenerateStates() {
|
||||
Math.seedrandom(Math.floor(Math.random() * 1e9)); // new random seed
|
||||
const burgs = pack.burgs.filter(b => b.i && !b.removed);
|
||||
if (!burgs.length) {
|
||||
tip("No burgs to generate states. Please create burgs first", false, "error");
|
||||
return;
|
||||
}
|
||||
if (burgs.length < +regionsInput.value) {
|
||||
tip(`Not enough burgs to generate ${regionsInput.value} states. Will generate only ${burgs.length} states`, false, "warn");
|
||||
}
|
||||
|
||||
// burg local ids sorted by a bit randomized population:
|
||||
const sorted = burgs.map((b, i) => [i, b.population * Math.random()]).sort((a, b) => b[1] - a[1]).map(b => b[0]);
|
||||
const capitalsTree = d3.quadtree();
|
||||
|
||||
// turn all old capitals into towns
|
||||
burgs.filter(b => b.capital).forEach(b => {
|
||||
moveBurgToGroup(b.i, "towns");
|
||||
b.capital = 0;
|
||||
});
|
||||
|
||||
unfog();
|
||||
|
||||
// if desired states number is 0
|
||||
if (regionsInput.value == 0) {
|
||||
tip(`Cannot generate zero states. Please check the <i>States Number</i> option`, false, "warn");
|
||||
pack.states = pack.states.slice(0,1); // remove all except of neutrals
|
||||
pack.states[0].diplomacy = []; // clear diplomacy
|
||||
pack.provinces = [0]; // remove all provinces
|
||||
pack.cells.state = new Uint16Array(pack.cells.i.length); // reset cells data
|
||||
borders.selectAll("path").remove(); // remove borders
|
||||
regions.selectAll("path").remove(); // remove states fill
|
||||
labels.select("#states").selectAll("text"); // remove state labels
|
||||
defs.select("#textPaths").selectAll("path[id*='stateLabel']").remove(); // remove state labels paths
|
||||
|
||||
// remove emblems
|
||||
document.querySelectorAll("[id^=stateCOA]").forEach(el => el.remove());
|
||||
document.querySelectorAll("[id^=provinceCOA]").forEach(el => el.remove());
|
||||
emblems.selectAll("use").remove();
|
||||
|
||||
if (document.getElementById("burgsOverviewRefresh").offsetParent) burgsOverviewRefresh.click();
|
||||
if (document.getElementById("statesEditorRefresh").offsetParent) statesEditorRefresh.click();
|
||||
return;
|
||||
}
|
||||
|
||||
const neutral = pack.states[0].name;
|
||||
const count = Math.min(+regionsInput.value, burgs.length);
|
||||
let spacing = (graphWidth + graphHeight) / 2 / count; // min distance between capitals
|
||||
pack.states = d3.range(count).map(i => {
|
||||
if (!i) return {i, name: neutral};
|
||||
|
||||
let capital = null, x = 0, y = 0;
|
||||
for (const i of sorted) {
|
||||
capital = burgs[i];
|
||||
x = capital.x, y = capital.y;
|
||||
if (capitalsTree.find(x, y, spacing) === undefined) break;
|
||||
spacing = Math.max(spacing - 1, 1);
|
||||
}
|
||||
|
||||
capitalsTree.add([x, y]);
|
||||
capital.capital = 1;
|
||||
moveBurgToGroup(capital.i, "cities");
|
||||
|
||||
const culture = capital.culture;
|
||||
const basename = capital.name.length < 9 && capital.cell%5 === 0 ? capital.name : Names.getCulture(culture, 3, 6, "", 0);
|
||||
const name = Names.getState(basename, culture);
|
||||
const nomadic = [1, 2, 3, 4].includes(pack.cells.biome[capital.cell]);
|
||||
const type = nomadic ? "Nomadic" : pack.cultures[culture].type === "Nomadic" ? "Generic" : pack.cultures[culture].type;
|
||||
const expansionism = rn(Math.random() * powerInput.value + 1, 1);
|
||||
|
||||
const coa = COA.generate(capital.coa, .3);
|
||||
coa.shield = capital.coa.shield;
|
||||
|
||||
return {i, name, type, capital:capital.i, center:capital.cell, culture, expansionism, coa};
|
||||
});
|
||||
|
||||
BurgsAndStates.expandStates();
|
||||
BurgsAndStates.normalizeStates();
|
||||
BurgsAndStates.collectStatistics();
|
||||
BurgsAndStates.assignColors();
|
||||
BurgsAndStates.generateCampaigns();
|
||||
BurgsAndStates.generateDiplomacy();
|
||||
BurgsAndStates.defineStateForms();
|
||||
BurgsAndStates.generateProvinces(true);
|
||||
if (!layerIsOn("toggleStates")) toggleStates(); else drawStates();
|
||||
if (!layerIsOn("toggleBorders")) toggleBorders(); else drawBorders();
|
||||
BurgsAndStates.drawStateLabels();
|
||||
Military.generate();
|
||||
if (layerIsOn("toggleEmblems")) drawEmblems(); // redrawEmblems
|
||||
|
||||
if (document.getElementById("burgsOverviewRefresh").offsetParent) burgsOverviewRefresh.click();
|
||||
if (document.getElementById("statesEditorRefresh").offsetParent) statesEditorRefresh.click();
|
||||
if (document.getElementById("militaryOverviewRefresh").offsetParent) militaryOverviewRefresh.click();
|
||||
}
|
||||
|
||||
function regenerateProvinces() {
|
||||
unfog();
|
||||
BurgsAndStates.generateProvinces(true);
|
||||
drawBorders();
|
||||
if (layerIsOn("toggleProvinces")) drawProvinces();
|
||||
}
|
||||
|
||||
function regenerateBurgs() {
|
||||
const cells = pack.cells, states = pack.states;
|
||||
rankCells();
|
||||
|
|
@ -148,96 +251,55 @@ function regenerateBurgs() {
|
|||
if (document.getElementById("statesEditorRefresh").offsetParent) statesEditorRefresh.click();
|
||||
}
|
||||
|
||||
function regenerateStates() {
|
||||
Math.seedrandom(Math.floor(Math.random() * 1e9)); // new random seed
|
||||
const burgs = pack.burgs.filter(b => b.i && !b.removed);
|
||||
if (!burgs.length) {
|
||||
tip("No burgs to generate states. Please create burgs first", false, "error");
|
||||
return;
|
||||
}
|
||||
if (burgs.length < +regionsInput.value) {
|
||||
tip(`Not enough burgs to generate ${regionsInput.value} states. Will generate only ${burgs.length} states`, false, "warn");
|
||||
}
|
||||
function regenerateEmblems() {
|
||||
// remove old emblems
|
||||
document.querySelectorAll("[id^=stateCOA]").forEach(el => el.remove());
|
||||
document.querySelectorAll("[id^=provinceCOA]").forEach(el => el.remove());
|
||||
document.querySelectorAll("[id^=burgCOA]").forEach(el => el.remove());
|
||||
emblems.selectAll("use").remove();
|
||||
|
||||
// burg local ids sorted by a bit randomized population:
|
||||
const sorted = burgs.map((b, i) => [i, b.population * Math.random()]).sort((a, b) => b[1] - a[1]).map(b => b[0]);
|
||||
const capitalsTree = d3.quadtree();
|
||||
|
||||
// turn all old capitals into towns
|
||||
burgs.filter(b => b.capital).forEach(b => {
|
||||
moveBurgToGroup(b.i, "towns");
|
||||
b.capital = 0;
|
||||
// generate new emblems
|
||||
pack.states.forEach(state => {
|
||||
if (!state.i || state.removed) return;
|
||||
state.coa = COA.generate(null);
|
||||
state.coa.shield = COA.getShield(state.culture, null);
|
||||
});
|
||||
|
||||
unfog();
|
||||
pack.burgs.forEach(burg => {
|
||||
if (!burg.i || burg.removed) return;
|
||||
const state = pack.states[burg.state];
|
||||
|
||||
// if desired states number is 0
|
||||
if (regionsInput.value == 0) {
|
||||
tip(`Cannot generate zero states. Please check the <i>States Number</i> option`, false, "warn");
|
||||
pack.states = pack.states.slice(0,1); // remove all except of neutrals
|
||||
pack.states[0].diplomacy = []; // clear diplomacy
|
||||
pack.provinces = [0]; // remove all provinces
|
||||
pack.cells.state = new Uint16Array(pack.cells.i.length); // reset cells data
|
||||
borders.selectAll("path").remove(); // remove borders
|
||||
regions.selectAll("path").remove(); // remove states fill
|
||||
labels.select("#states").selectAll("text"); // remove state labels
|
||||
defs.select("#textPaths").selectAll("path[id*='stateLabel']").remove(); // remove state labels paths
|
||||
let kinship = .25;
|
||||
if (burg.capital) kinship += .1;
|
||||
else if (burg.port) kinship -= .1;
|
||||
if (burg.culture !== state.culture) kinship -= .25;
|
||||
burg.coa = COA.generate(state.coa, kinship);
|
||||
burg.coa.shield = COA.getShield(burg.culture, burg.state);
|
||||
});
|
||||
|
||||
if (document.getElementById("burgsOverviewRefresh").offsetParent) burgsOverviewRefresh.click();
|
||||
if (document.getElementById("statesEditorRefresh").offsetParent) statesEditorRefresh.click();
|
||||
return;
|
||||
}
|
||||
pack.provinces.forEach(province => {
|
||||
if (!province.i || province.removed) return;
|
||||
const parent = province.burg ? pack.burgs[province.burg] : pack.states[province.state];
|
||||
|
||||
const neutral = pack.states[0].name;
|
||||
const count = Math.min(+regionsInput.value, burgs.length);
|
||||
let spacing = (graphWidth + graphHeight) / 2 / count; // min distance between capitals
|
||||
pack.states = d3.range(count).map(i => {
|
||||
if (!i) return {i, name: neutral};
|
||||
|
||||
let capital = null, x = 0, y = 0;
|
||||
for (const i of sorted) {
|
||||
capital = burgs[i];
|
||||
x = capital.x, y = capital.y;
|
||||
if (capitalsTree.find(x, y, spacing) === undefined) break;
|
||||
spacing = Math.max(spacing - 1, 1);
|
||||
let dominion = false;
|
||||
if (province.burg) {
|
||||
dominion = P(.2);
|
||||
if (province.formName === "Colony") dominion = P(.95); else
|
||||
if (province.formName === "Island") dominion = P(.6); else
|
||||
if (province.formName === "Islands") dominion = P(.5); else
|
||||
if (province.formName === "Territory") dominion = P(.4); else
|
||||
if (province.formName === "Land") dominion = P(.3);
|
||||
}
|
||||
|
||||
capitalsTree.add([x, y]);
|
||||
capital.capital = 1;
|
||||
moveBurgToGroup(capital.i, "cities");
|
||||
const nameByBurg = province.burg && province.name.slice(0, 3) === parent.name.slice(0, 3);
|
||||
const kinship = dominion ? 0 : nameByBurg ? .8 : .4;
|
||||
const culture = pack.cells.culture[province.center];
|
||||
|
||||
const culture = capital.culture;
|
||||
const basename = capital.name.length < 9 && capital.cell%5 === 0 ? capital.name : Names.getCulture(culture, 3, 6, "", 0);
|
||||
const name = Names.getState(basename, culture);
|
||||
const nomadic = [1, 2, 3, 4].includes(pack.cells.biome[capital.cell]);
|
||||
const type = nomadic ? "Nomadic" : pack.cultures[culture].type === "Nomadic" ? "Generic" : pack.cultures[culture].type;
|
||||
const expansionism = rn(Math.random() * powerInput.value + 1, 1);
|
||||
return {i, name, type, capital:capital.i, center:capital.cell, culture, expansionism};
|
||||
province.coa = COA.generate(parent.coa, kinship, dominion);
|
||||
province.coa.shield = COA.getShield(culture, province.state);
|
||||
});
|
||||
|
||||
BurgsAndStates.expandStates();
|
||||
BurgsAndStates.normalizeStates();
|
||||
BurgsAndStates.collectStatistics();
|
||||
BurgsAndStates.assignColors();
|
||||
BurgsAndStates.generateCampaigns();
|
||||
BurgsAndStates.generateDiplomacy();
|
||||
BurgsAndStates.defineStateForms();
|
||||
BurgsAndStates.generateProvinces(true);
|
||||
if (!layerIsOn("toggleStates")) toggleStates(); else drawStates();
|
||||
if (!layerIsOn("toggleBorders")) toggleBorders(); else drawBorders();
|
||||
BurgsAndStates.drawStateLabels();
|
||||
Military.generate();
|
||||
|
||||
if (document.getElementById("burgsOverviewRefresh").offsetParent) burgsOverviewRefresh.click();
|
||||
if (document.getElementById("statesEditorRefresh").offsetParent) statesEditorRefresh.click();
|
||||
if (document.getElementById("militaryOverviewRefresh").offsetParent) militaryOverviewRefresh.click();
|
||||
}
|
||||
|
||||
function regenerateProvinces() {
|
||||
unfog();
|
||||
BurgsAndStates.generateProvinces(true);
|
||||
drawBorders();
|
||||
if (layerIsOn("toggleProvinces")) drawProvinces();
|
||||
if (layerIsOn("toggleEmblems")) drawEmblems(); // redrawEmblems
|
||||
}
|
||||
|
||||
function regenerateReligions() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue