mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +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
|
|
@ -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