diff --git a/index.html b/index.html index bff23c0e..7e4d5d93 100644 --- a/index.html +++ b/index.html @@ -1010,10 +1010,10 @@ - + - - + +
diff --git a/modules/river-generator.js b/modules/river-generator.js index 8b440309..002fb39e 100644 --- a/modules/river-generator.js +++ b/modules/river-generator.js @@ -112,24 +112,30 @@ } // depression filling algorithm (for a correct water flux modeling) - function resolveDepressions() { + const resolveDepressions = function() { console.time('resolveDepressions'); 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 land.sort(highest); // highest cells go first + let depressed = false; for (let l = 0, depression = Infinity; depression > 1 && l < 100; l++) { depression = 0; for (const i of land) { const minHeight = d3.min(cells.c[i].map(c => cells.h[c])); 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'); //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]); + return depressed; } // add more river points on 1/3 and 2/3 of length @@ -221,6 +227,6 @@ return round(right + left, 2); } - return {generate, addMeandring, getPath}; + return {generate, resolveDepressions, addMeandring, getPath}; }))); \ No newline at end of file diff --git a/modules/ui/burgs-editor.js b/modules/ui/burgs-editor.js index 17824974..7c233800 100644 --- a/modules/ui/burgs-editor.js +++ b/modules/ui/burgs-editor.js @@ -17,7 +17,7 @@ function editBurgs() { }); // add listeners - document.getElementById("burgsEditorRefresh").addEventListener("click", burgsEditorAddLines); + document.getElementById("burgsEditorRefresh").addEventListener("click", refreshBurgsEditor); document.getElementById("burgsFilterState").addEventListener("change", burgsEditorAddLines); document.getElementById("burgsFilterCulture").addEventListener("change", burgsEditorAddLines); document.getElementById("regenerateBurgNames").addEventListener("click", regenerateNames); @@ -27,6 +27,11 @@ function editBurgs() { document.getElementById("burgsListToLoad").addEventListener("change", importBurgNames); document.getElementById("burgsRemoveAll").addEventListener("click", triggerAllBurgsRemove); + function refreshBurgsEditor() { + updateFilter(); + burgsEditorAddLines(); + } + function updateFilter() { const stateFilter = document.getElementById("burgsFilterState"); const selectedState = stateFilter.value || 1; diff --git a/modules/ui/tools.js b/modules/ui/tools.js index 66966f4f..b9b8cde4 100644 --- a/modules/ui/tools.js +++ b/modules/ui/tools.js @@ -95,10 +95,55 @@ function regenerateBurgs() { BurgsAndStates.specifyBurgs(); BurgsAndStates.drawBurgs(); Routes.regenerate(); + + document.getElementById("statesBodySection").innerHTML = "Please refresh the editor!"; + document.getElementById("burgsBody").innerHTML = "Please refresh the editor!"; + document.getElementById("burgsFilterState").options.length = 0; + document.getElementById("burgsFilterCulture").options.length = 0; } 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 = "Please refresh the editor!"; + document.getElementById("burgsBody").innerHTML = "Please refresh the editor!"; + document.getElementById("burgsFilterState").options.length = 0; + document.getElementById("burgsFilterCulture").options.length = 0; + }); + + BurgsAndStates.expandStates(); + if (!layerIsOn("toggleStates")) toggleStates(); else drawStatesWithBorders(); + BurgsAndStates.drawStateLabels(); } function unpressClickToAddButton() { @@ -172,19 +217,20 @@ function addRiverOnClick() { const dataRiver = []; // to store river points const river = +getNextId("river").slice(5); // river id 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) { cells.r[i] = river; const x = cells.p[i][0], y = cells.p[i][1]; 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]) { - tip(`Clicked cell is depressed! To resolve edit the heightmap and allow system to change heights`, false, "error"); - render = false; - break; + if (depressed) {tip("The heightmap is too depressed, please try again", false, "error"); return;} + depressed = Rivers.resolveDepressions(); + 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]; @@ -224,13 +270,29 @@ function addRiverOnClick() { i = min; } - if (!render) return; const points = Rivers.addMeandring(dataRiver, Math.random() * .5 + .1); const width = Math.random() * .5 + .9; const increment = Math.random() * .4 + .8; 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); + if (depressed) { + if (layerIsOn("toggleHeight")) drawHeightmap(); + alertMessage.innerHTML = `

Heightmap is depressed and the system had to change the heightmap to allow water flux.

+ Would you like to keep the changes or restore 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(); }