mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-16 17:31:24 +01:00
v 0.8.32b
This commit is contained in:
parent
83585c3081
commit
dd83a8c0a0
4 changed files with 87 additions and 14 deletions
|
|
@ -1010,10 +1010,10 @@
|
||||||
<button id="regenerateStateLabels" data-tip="Click to update state labels placement based on current borders">State labels</button>
|
<button id="regenerateStateLabels" data-tip="Click to update state labels placement based on current borders">State labels</button>
|
||||||
<button id="regenerateReliefIcons" data-tip="Click to regenerate all relief icons based on current cell biome and elevation">Relief icons</button>
|
<button id="regenerateReliefIcons" data-tip="Click to regenerate all relief icons based on current cell biome and elevation">Relief icons</button>
|
||||||
<button id="regenerateRoutes" data-tip="Click to regenerate all routes">Routes</button>
|
<button id="regenerateRoutes" data-tip="Click to regenerate all routes">Routes</button>
|
||||||
<button id="regenerateRivers" data-tip="Click to regenerate all rivers. Please note map heights can be changed by water flow">Rivers</button>
|
<button id="regenerateRivers" data-tip="Click to regenerate all rivers">Rivers</button>
|
||||||
<button id="regeneratePopulation" data-tip="Click to recalculate rural and urban population">Population</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">Burgs</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 regenerate states">States</button> -->
|
<button id="regenerateStates" data-tip="Click to select new capitals and regenerate states. Burgs will remain as they are">States</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="addFeature">
|
<div id="addFeature">
|
||||||
|
|
|
||||||
|
|
@ -112,24 +112,30 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// depression filling algorithm (for a correct water flux modeling)
|
// depression filling algorithm (for a correct water flux modeling)
|
||||||
function resolveDepressions() {
|
const resolveDepressions = function() {
|
||||||
console.time('resolveDepressions');
|
console.time('resolveDepressions');
|
||||||
const cells = pack.cells;
|
const cells = pack.cells;
|
||||||
const land = cells.i.filter(i => cells.h[i] >= 20 && cells.h[i] < 95 && !cells.b[i]); // exclude near-border cells
|
const land = cells.i.filter(i => cells.h[i] >= 20 && cells.h[i] < 95 && !cells.b[i]); // exclude near-border cells
|
||||||
land.sort(highest); // highest cells go first
|
land.sort(highest); // highest cells go first
|
||||||
|
let depressed = false;
|
||||||
|
|
||||||
for (let l = 0, depression = Infinity; depression > 1 && l < 100; l++) {
|
for (let l = 0, depression = Infinity; depression > 1 && l < 100; l++) {
|
||||||
depression = 0;
|
depression = 0;
|
||||||
for (const i of land) {
|
for (const i of land) {
|
||||||
const minHeight = d3.min(cells.c[i].map(c => cells.h[c]));
|
const minHeight = d3.min(cells.c[i].map(c => cells.h[c]));
|
||||||
if (minHeight === 100) continue; // already max height
|
if (minHeight === 100) continue; // already max height
|
||||||
if (cells.h[i] <= minHeight) {cells.h[i] = minHeight + 1; depression++;}
|
if (cells.h[i] <= minHeight) {
|
||||||
|
cells.h[i] = minHeight + 1;
|
||||||
|
depression++;
|
||||||
|
depressed = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.timeEnd('resolveDepressions');
|
console.timeEnd('resolveDepressions');
|
||||||
//const depressed = cells.i.filter(i => cells.h[i] >= 20 && cells.h[i] < 95 && !cells.b[i] && cells.h[i] <= d3.min(cells.c[i].map(c => cells.h[c])));
|
//const depressed = cells.i.filter(i => cells.h[i] >= 20 && cells.h[i] < 95 && !cells.b[i] && cells.h[i] <= d3.min(cells.c[i].map(c => cells.h[c])));
|
||||||
//debug.selectAll(".deps").data(depressed).enter().append("circle").attr("r", 0.8).attr("cx", d => cells.p[d][0]).attr("cy", d => cells.p[d][1]);
|
//debug.selectAll(".deps").data(depressed).enter().append("circle").attr("r", 0.8).attr("cx", d => cells.p[d][0]).attr("cy", d => cells.p[d][1]);
|
||||||
|
return depressed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add more river points on 1/3 and 2/3 of length
|
// add more river points on 1/3 and 2/3 of length
|
||||||
|
|
@ -221,6 +227,6 @@
|
||||||
return round(right + left, 2);
|
return round(right + left, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {generate, addMeandring, getPath};
|
return {generate, resolveDepressions, addMeandring, getPath};
|
||||||
|
|
||||||
})));
|
})));
|
||||||
|
|
@ -17,7 +17,7 @@ function editBurgs() {
|
||||||
});
|
});
|
||||||
|
|
||||||
// add listeners
|
// add listeners
|
||||||
document.getElementById("burgsEditorRefresh").addEventListener("click", burgsEditorAddLines);
|
document.getElementById("burgsEditorRefresh").addEventListener("click", refreshBurgsEditor);
|
||||||
document.getElementById("burgsFilterState").addEventListener("change", burgsEditorAddLines);
|
document.getElementById("burgsFilterState").addEventListener("change", burgsEditorAddLines);
|
||||||
document.getElementById("burgsFilterCulture").addEventListener("change", burgsEditorAddLines);
|
document.getElementById("burgsFilterCulture").addEventListener("change", burgsEditorAddLines);
|
||||||
document.getElementById("regenerateBurgNames").addEventListener("click", regenerateNames);
|
document.getElementById("regenerateBurgNames").addEventListener("click", regenerateNames);
|
||||||
|
|
@ -27,6 +27,11 @@ function editBurgs() {
|
||||||
document.getElementById("burgsListToLoad").addEventListener("change", importBurgNames);
|
document.getElementById("burgsListToLoad").addEventListener("change", importBurgNames);
|
||||||
document.getElementById("burgsRemoveAll").addEventListener("click", triggerAllBurgsRemove);
|
document.getElementById("burgsRemoveAll").addEventListener("click", triggerAllBurgsRemove);
|
||||||
|
|
||||||
|
function refreshBurgsEditor() {
|
||||||
|
updateFilter();
|
||||||
|
burgsEditorAddLines();
|
||||||
|
}
|
||||||
|
|
||||||
function updateFilter() {
|
function updateFilter() {
|
||||||
const stateFilter = document.getElementById("burgsFilterState");
|
const stateFilter = document.getElementById("burgsFilterState");
|
||||||
const selectedState = stateFilter.value || 1;
|
const selectedState = stateFilter.value || 1;
|
||||||
|
|
|
||||||
|
|
@ -95,10 +95,55 @@ function regenerateBurgs() {
|
||||||
BurgsAndStates.specifyBurgs();
|
BurgsAndStates.specifyBurgs();
|
||||||
BurgsAndStates.drawBurgs();
|
BurgsAndStates.drawBurgs();
|
||||||
Routes.regenerate();
|
Routes.regenerate();
|
||||||
|
|
||||||
|
document.getElementById("statesBodySection").innerHTML = "<i>Please refresh the editor!</i>";
|
||||||
|
document.getElementById("burgsBody").innerHTML = "<i>Please refresh the editor!</i>";
|
||||||
|
document.getElementById("burgsFilterState").options.length = 0;
|
||||||
|
document.getElementById("burgsFilterCulture").options.length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function regenerateStates() {
|
function regenerateStates() {
|
||||||
|
const burgs = pack.burgs.filter(b => b.i && !b.removed), states = pack.states.filter(s => s.i && !s.removed);
|
||||||
|
const capitalsTree = d3.quadtree();
|
||||||
|
let spacing = (graphWidth + graphHeight) / 2 / states.length; // min distance between capitals
|
||||||
|
|
||||||
|
// turn all old capitals into towns
|
||||||
|
states.forEach(s => {
|
||||||
|
moveBurgToGroup(s.capital, "towns");
|
||||||
|
s.capital = 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
states.forEach(s => {
|
||||||
|
let newCapital = 0, x = 0, y = 0;
|
||||||
|
|
||||||
|
while (!newCapital) {
|
||||||
|
newCapital = burgs[biased(1, burgs.length-1, 3)];
|
||||||
|
x = newCapital.x, y = newCapital.y;
|
||||||
|
if (capitalsTree.find(x, y, spacing) !== undefined) {
|
||||||
|
spacing -= 1;
|
||||||
|
if (spacing < 1) spacing = 1;
|
||||||
|
newCapital = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
capitalsTree.add([x, y]);
|
||||||
|
s.capital = newCapital.i;
|
||||||
|
s.center = newCapital.cell;
|
||||||
|
s.culture = newCapital.culture;
|
||||||
|
s.expansionism = rn(Math.random() * powerInput.value / 2 + 1, 1);
|
||||||
|
const basename = newCapital.name.length < 9 && newCapital.cell%5 === 0 ? newCapital.name : Names.getCulture(s.culture, 3, 6, "", 0);
|
||||||
|
s.name = Names.getState(basename, s.culture);
|
||||||
|
moveBurgToGroup(newCapital.i, "cities");
|
||||||
|
|
||||||
|
document.getElementById("statesBodySection").innerHTML = "<i>Please refresh the editor!</i>";
|
||||||
|
document.getElementById("burgsBody").innerHTML = "<i>Please refresh the editor!</i>";
|
||||||
|
document.getElementById("burgsFilterState").options.length = 0;
|
||||||
|
document.getElementById("burgsFilterCulture").options.length = 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
BurgsAndStates.expandStates();
|
||||||
|
if (!layerIsOn("toggleStates")) toggleStates(); else drawStatesWithBorders();
|
||||||
|
BurgsAndStates.drawStateLabels();
|
||||||
}
|
}
|
||||||
|
|
||||||
function unpressClickToAddButton() {
|
function unpressClickToAddButton() {
|
||||||
|
|
@ -172,19 +217,20 @@ function addRiverOnClick() {
|
||||||
const dataRiver = []; // to store river points
|
const dataRiver = []; // to store river points
|
||||||
const river = +getNextId("river").slice(5); // river id
|
const river = +getNextId("river").slice(5); // river id
|
||||||
cells.fl[i] = grid.cells.prec[cells.g[i]]; // initial flux
|
cells.fl[i] = grid.cells.prec[cells.g[i]]; // initial flux
|
||||||
let render = true;
|
let depressed = false;
|
||||||
|
const heights = new Uint8Array(pack.cells.h); // initial heights
|
||||||
|
|
||||||
while (i) {
|
while (i) {
|
||||||
cells.r[i] = river;
|
cells.r[i] = river;
|
||||||
const x = cells.p[i][0], y = cells.p[i][1];
|
const x = cells.p[i][0], y = cells.p[i][1];
|
||||||
dataRiver.push({x, y, cell:i});
|
dataRiver.push({x, y, cell:i});
|
||||||
|
|
||||||
const min = cells.c[i][d3.scan(cells.c[i], (a, b) => cells.h[a] - cells.h[b])]; // downhill cell
|
let min = cells.c[i][d3.scan(cells.c[i], (a, b) => cells.h[a] - cells.h[b])]; // downhill cell
|
||||||
|
|
||||||
if (cells.h[i] <= cells.h[min]) {
|
if (cells.h[i] <= cells.h[min]) {
|
||||||
tip(`Clicked cell is depressed! To resolve edit the heightmap and allow system to change heights`, false, "error");
|
if (depressed) {tip("The heightmap is too depressed, please try again", false, "error"); return;}
|
||||||
render = false;
|
depressed = Rivers.resolveDepressions();
|
||||||
break;
|
min = cells.c[i][d3.scan(cells.c[i], (a, b) => cells.h[a] - cells.h[b])];
|
||||||
}
|
}
|
||||||
|
|
||||||
const tx = cells.p[min][0], ty = cells.p[min][1];
|
const tx = cells.p[min][0], ty = cells.p[min][1];
|
||||||
|
|
@ -224,13 +270,29 @@ function addRiverOnClick() {
|
||||||
i = min;
|
i = min;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!render) return;
|
|
||||||
const points = Rivers.addMeandring(dataRiver, Math.random() * .5 + .1);
|
const points = Rivers.addMeandring(dataRiver, Math.random() * .5 + .1);
|
||||||
const width = Math.random() * .5 + .9;
|
const width = Math.random() * .5 + .9;
|
||||||
const increment = Math.random() * .4 + .8;
|
const increment = Math.random() * .4 + .8;
|
||||||
const d = Rivers.getPath(points, width, increment);
|
const d = Rivers.getPath(points, width, increment);
|
||||||
rivers.append("path").attr("d", d).attr("id", "river"+river).attr("data-width", width).attr("data-increment", increment);
|
rivers.append("path").attr("d", d).attr("id", "river"+river).attr("data-width", width).attr("data-increment", increment);
|
||||||
|
|
||||||
|
if (depressed) {
|
||||||
|
if (layerIsOn("toggleHeight")) drawHeightmap();
|
||||||
|
alertMessage.innerHTML = `<p>Heightmap is depressed and the system had to change the heightmap to allow water flux.</p>
|
||||||
|
Would you like to <i>keep</i> the changes or <i>restore</i> the initial heightmap?`;
|
||||||
|
|
||||||
|
$("#alert").dialog({resizable: false, title: "Heightmap is changed", width: 300, modal: true,
|
||||||
|
buttons: {
|
||||||
|
Keep: function() {$(this).dialog("close");},
|
||||||
|
Restore: function() {
|
||||||
|
$(this).dialog("close");
|
||||||
|
pack.cells.h = new Uint8Array(heights);
|
||||||
|
if (layerIsOn("toggleHeight")) drawHeightmap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (d3.event.shiftKey === false) unpressClickToAddButton();
|
if (d3.event.shiftKey === false) unpressClickToAddButton();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue