mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
generation flow for heightmap select
This commit is contained in:
parent
ff31e23a27
commit
6766de46ef
9 changed files with 132 additions and 100 deletions
|
|
@ -297,7 +297,7 @@
|
||||||
id="regenerate"
|
id="regenerate"
|
||||||
data-t="tipRegenerate"
|
data-t="tipRegenerate"
|
||||||
data-tip="Click to generate a new map. Shortcut: F2"
|
data-tip="Click to generate a new map. Shortcut: F2"
|
||||||
onclick="regeneratePrompt('drawer')"
|
onclick="regeneratePrompt()"
|
||||||
class="options"
|
class="options"
|
||||||
style="display: none"
|
style="display: none"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
44
main.js
44
main.js
|
|
@ -628,18 +628,24 @@ void (function addDragToUpload() {
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
|
||||||
async function generate() {
|
async function generate(options) {
|
||||||
try {
|
try {
|
||||||
const timeStart = performance.now();
|
const timeStart = performance.now();
|
||||||
|
const {seed: precreatedSeed} = options || {};
|
||||||
|
|
||||||
invokeActiveZooming();
|
invokeActiveZooming();
|
||||||
generateSeed();
|
setSeed(precreatedSeed);
|
||||||
INFO && console.group("Generated Map " + seed);
|
INFO && console.group("Generated Map " + seed);
|
||||||
|
|
||||||
applyMapSize();
|
applyMapSize();
|
||||||
randomizeOptions();
|
randomizeOptions();
|
||||||
|
|
||||||
|
if (shouldRegenerateGrid()) {
|
||||||
placePoints();
|
placePoints();
|
||||||
calculateVoronoi(grid, grid.points);
|
calculateVoronoi(grid, grid.points);
|
||||||
drawScaleBar(scale);
|
}
|
||||||
await HeightmapGenerator.generate();
|
await HeightmapGenerator.generate();
|
||||||
|
|
||||||
markFeatures();
|
markFeatures();
|
||||||
markupGridOcean();
|
markupGridOcean();
|
||||||
addLakesInDeepDepressions();
|
addLakesInDeepDepressions();
|
||||||
|
|
@ -677,6 +683,8 @@ async function generate() {
|
||||||
Military.generate();
|
Military.generate();
|
||||||
Markers.generate();
|
Markers.generate();
|
||||||
addZones();
|
addZones();
|
||||||
|
|
||||||
|
drawScaleBar(scale);
|
||||||
Names.getMapName();
|
Names.getMapName();
|
||||||
|
|
||||||
WARN && console.warn(`TOTAL: ${rn((performance.now() - timeStart) / 1000, 2)}s`);
|
WARN && console.warn(`TOTAL: ${rn((performance.now() - timeStart) / 1000, 2)}s`);
|
||||||
|
|
@ -711,8 +719,9 @@ async function generate() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate map seed (string!) or get it from URL searchParams
|
// set map seed (string!)
|
||||||
function generateSeed() {
|
function setSeed(precreatedSeed) {
|
||||||
|
if (!precreatedSeed) {
|
||||||
const first = !mapHistory[0];
|
const first = !mapHistory[0];
|
||||||
const url = new URL(window.location.href);
|
const url = new URL(window.location.href);
|
||||||
const params = url.searchParams;
|
const params = url.searchParams;
|
||||||
|
|
@ -720,18 +729,31 @@ function generateSeed() {
|
||||||
if (first && params.get("from") === "MFCG" && urlSeed.length === 13) seed = urlSeed.slice(0, -4);
|
if (first && params.get("from") === "MFCG" && urlSeed.length === 13) seed = urlSeed.slice(0, -4);
|
||||||
else if (first && urlSeed) seed = urlSeed;
|
else if (first && urlSeed) seed = urlSeed;
|
||||||
else if (optionsSeed.value && optionsSeed.value != seed) seed = optionsSeed.value;
|
else if (optionsSeed.value && optionsSeed.value != seed) seed = optionsSeed.value;
|
||||||
else seed = Math.floor(Math.random() * 1e9).toString();
|
else seed = generateSeed();
|
||||||
optionsSeed.value = seed;
|
} else {
|
||||||
|
seed = precreatedSeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
byId("optionsSeed").value = seed;
|
||||||
Math.random = aleaPRNG(seed);
|
Math.random = aleaPRNG(seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if new grid graph should be generated or we can use the existing one
|
||||||
|
function shouldRegenerateGrid() {
|
||||||
|
if (!grid.spacing) return true;
|
||||||
|
const cellsDesired = +byId("pointsInput").dataset.cells;
|
||||||
|
const newSpacing = rn(Math.sqrt((graphWidth * graphHeight) / cellsDesired), 2);
|
||||||
|
return grid.spacing !== newSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
// Place points to calculate Voronoi diagram
|
// Place points to calculate Voronoi diagram
|
||||||
function placePoints() {
|
function placePoints() {
|
||||||
TIME && console.time("placePoints");
|
TIME && console.time("placePoints");
|
||||||
Math.random = aleaPRNG(seed); // reset PRNG
|
Math.random = aleaPRNG(seed); // reset PRNG
|
||||||
|
|
||||||
const cellsDesired = +pointsInput.dataset.cells;
|
const cellsDesired = +byId("pointsInput").dataset.cells;
|
||||||
const spacing = (grid.spacing = rn(Math.sqrt((graphWidth * graphHeight) / cellsDesired), 2)); // spacing between points before jirrering
|
const spacing = rn(Math.sqrt((graphWidth * graphHeight) / cellsDesired), 2); // spacing between points before jirrering
|
||||||
|
grid.spacing = spacing;
|
||||||
grid.boundary = getBoundaryPoints(graphWidth, graphHeight, spacing);
|
grid.boundary = getBoundaryPoints(graphWidth, graphHeight, spacing);
|
||||||
grid.points = getJitteredGrid(graphWidth, graphHeight, spacing); // jittered square grid
|
grid.points = getJitteredGrid(graphWidth, graphHeight, spacing); // jittered square grid
|
||||||
grid.cellsX = Math.floor((graphWidth + 0.5 * spacing - 1e-10) / spacing);
|
grid.cellsX = Math.floor((graphWidth + 0.5 * spacing - 1e-10) / spacing);
|
||||||
|
|
@ -1921,14 +1943,14 @@ function showStatistics() {
|
||||||
INFO && console.log(stats);
|
INFO && console.log(stats);
|
||||||
}
|
}
|
||||||
|
|
||||||
const regenerateMap = debounce(async function () {
|
const regenerateMap = debounce(async function (options) {
|
||||||
WARN && console.warn("Generate new random map");
|
WARN && console.warn("Generate new random map");
|
||||||
showLoading();
|
showLoading();
|
||||||
closeDialogs("#worldConfigurator, #options3d");
|
closeDialogs("#worldConfigurator, #options3d");
|
||||||
customization = 0;
|
customization = 0;
|
||||||
resetZoom(1000);
|
resetZoom(1000);
|
||||||
undraw();
|
undraw();
|
||||||
await generate();
|
await generate(options);
|
||||||
restoreLayers();
|
restoreLayers();
|
||||||
if (ThreeD.options.isOn) ThreeD.redraw();
|
if (ThreeD.options.isOn) ThreeD.redraw();
|
||||||
if ($("#worldConfigurator").is(":visible")) editWorld();
|
if ($("#worldConfigurator").is(":visible")) editWorld();
|
||||||
|
|
|
||||||
|
|
@ -1077,7 +1077,7 @@ window.BurgsAndStates = (function () {
|
||||||
|
|
||||||
const generateProvinces = function (regenerate) {
|
const generateProvinces = function (regenerate) {
|
||||||
TIME && console.time("generateProvinces");
|
TIME && console.time("generateProvinces");
|
||||||
const localSeed = regenerate ? Math.floor(Math.random() * 1e9).toString() : seed;
|
const localSeed = regenerate ? generateSeed() : seed;
|
||||||
Math.random = aleaPRNG(localSeed);
|
Math.random = aleaPRNG(localSeed);
|
||||||
|
|
||||||
const {cells, states, burgs} = pack;
|
const {cells, states, burgs} = pack;
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,6 @@ const heightmaps = [
|
||||||
{id: "world-from-pacific", name: "World from Pacific"}
|
{id: "world-from-pacific", name: "World from Pacific"}
|
||||||
];
|
];
|
||||||
|
|
||||||
let seed = Math.floor(Math.random() * 1e9);
|
|
||||||
|
|
||||||
appendStyleSheet();
|
appendStyleSheet();
|
||||||
insertEditorHtml();
|
insertEditorHtml();
|
||||||
addListeners();
|
addListeners();
|
||||||
|
|
@ -62,7 +60,20 @@ export function open() {
|
||||||
$(this).dialog("close");
|
$(this).dialog("close");
|
||||||
},
|
},
|
||||||
Select: function () {
|
Select: function () {
|
||||||
$templateInput.value = getSelected();
|
const id = getSelected();
|
||||||
|
$templateInput.value = id;
|
||||||
|
lock("template");
|
||||||
|
$(this).dialog("close");
|
||||||
|
},
|
||||||
|
"New Map": function () {
|
||||||
|
const id = getSelected();
|
||||||
|
$templateInput.value = id;
|
||||||
|
lock("template");
|
||||||
|
|
||||||
|
const seed = getSeed();
|
||||||
|
Math.random = aleaPRNG(seed);
|
||||||
|
|
||||||
|
regeneratePrompt({seed});
|
||||||
$(this).dialog("close");
|
$(this).dialog("close");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -133,13 +144,12 @@ function appendStyleSheet() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function insertEditorHtml() {
|
function insertEditorHtml() {
|
||||||
|
const seed = generateSeed();
|
||||||
|
|
||||||
const templatesHtml = templates
|
const templatesHtml = templates
|
||||||
.map(({id, name}) => {
|
.map(({id, name}) => {
|
||||||
Math.random = aleaPRNG(seed);
|
Math.random = aleaPRNG(seed);
|
||||||
|
const heights = generateHeightmap(id);
|
||||||
HeightmapGenerator.resetHeights();
|
|
||||||
const heights = HeightmapGenerator.fromTemplate(id);
|
|
||||||
HeightmapGenerator.cleanup();
|
|
||||||
const dataUrl = drawHeights(heights);
|
const dataUrl = drawHeights(heights);
|
||||||
|
|
||||||
return /* html */ `<article data-id="${id}" data-seed="${seed}">
|
return /* html */ `<article data-id="${id}" data-seed="${seed}">
|
||||||
|
|
@ -154,7 +164,7 @@ function insertEditorHtml() {
|
||||||
|
|
||||||
const heightmapsHtml = heightmaps
|
const heightmapsHtml = heightmaps
|
||||||
.map(({id, name}) => {
|
.map(({id, name}) => {
|
||||||
return /* html */ `<article data-id="${id}">
|
return /* html */ `<article data-id="${id}" data-seed="${seed}">
|
||||||
<img src="../../heightmaps/${id}.png" alt="${name}" class="heightmap-selection_precreated" />
|
<img src="../../heightmaps/${id}.png" alt="${name}" class="heightmap-selection_precreated" />
|
||||||
<div>${name}</div>
|
<div>${name}</div>
|
||||||
</article>`;
|
</article>`;
|
||||||
|
|
@ -202,6 +212,10 @@ function setSelected(id) {
|
||||||
$heightmapSelection.querySelector(`[data-id="${id}"]`)?.classList?.add("selected");
|
$heightmapSelection.querySelector(`[data-id="${id}"]`)?.classList?.add("selected");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getSeed() {
|
||||||
|
return byId("heightmapSelection").querySelector(".selected")?.dataset?.seed;
|
||||||
|
}
|
||||||
|
|
||||||
function drawHeights(heights) {
|
function drawHeights(heights) {
|
||||||
const canvas = document.createElement("canvas");
|
const canvas = document.createElement("canvas");
|
||||||
canvas.width = grid.cellsX;
|
canvas.width = grid.cellsX;
|
||||||
|
|
@ -222,14 +236,19 @@ function drawHeights(heights) {
|
||||||
return canvas.toDataURL("image/png");
|
return canvas.toDataURL("image/png");
|
||||||
}
|
}
|
||||||
|
|
||||||
function regeneratePreview(article, id) {
|
function generateHeightmap(id) {
|
||||||
seed = Math.floor(Math.random() * 1e9);
|
|
||||||
article.dataset.seed = seed;
|
|
||||||
Math.random = aleaPRNG(seed);
|
|
||||||
|
|
||||||
HeightmapGenerator.resetHeights();
|
HeightmapGenerator.resetHeights();
|
||||||
const heights = HeightmapGenerator.fromTemplate(id);
|
const heights = HeightmapGenerator.fromTemplate(id);
|
||||||
HeightmapGenerator.cleanup();
|
HeightmapGenerator.cleanup();
|
||||||
|
return heights;
|
||||||
|
}
|
||||||
|
|
||||||
|
function regeneratePreview(article, id) {
|
||||||
|
const seed = generateSeed();
|
||||||
|
article.dataset.seed = seed;
|
||||||
|
Math.random = aleaPRNG(seed);
|
||||||
|
|
||||||
|
const heights = generateHeightmap(id);
|
||||||
const dataUrl = drawHeights(heights);
|
const dataUrl = drawHeights(heights);
|
||||||
article.querySelector("img").src = dataUrl;
|
article.querySelector("img").src = dataUrl;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,61 +7,6 @@ window.HeightmapGenerator = (function () {
|
||||||
const getHeights = () => heights;
|
const getHeights = () => heights;
|
||||||
const cleanup = () => (heights = null);
|
const cleanup = () => (heights = null);
|
||||||
|
|
||||||
const generate = async function () {
|
|
||||||
resetHeights();
|
|
||||||
|
|
||||||
const input = document.getElementById("templateInput");
|
|
||||||
const selectedId = input.selectedIndex >= 0 ? input.selectedIndex : 0;
|
|
||||||
const type = input.options[selectedId]?.parentElement?.label;
|
|
||||||
|
|
||||||
if (type === "Specific") {
|
|
||||||
// pre-defined heightmap
|
|
||||||
TIME && console.time("defineHeightmap");
|
|
||||||
return new Promise(resolve => {
|
|
||||||
// create canvas where 1px correcponds to a cell
|
|
||||||
const canvas = document.createElement("canvas");
|
|
||||||
const ctx = canvas.getContext("2d");
|
|
||||||
const {cellsX, cellsY} = grid;
|
|
||||||
canvas.width = cellsX;
|
|
||||||
canvas.height = cellsY;
|
|
||||||
|
|
||||||
// load heightmap into image and render to canvas
|
|
||||||
const img = new Image();
|
|
||||||
img.src = `./heightmaps/${input.value}.png`;
|
|
||||||
img.onload = () => {
|
|
||||||
ctx.drawImage(img, 0, 0, cellsX, cellsY);
|
|
||||||
const imageData = ctx.getImageData(0, 0, cellsX, cellsY);
|
|
||||||
assignColorsToHeight(imageData.data);
|
|
||||||
canvas.remove();
|
|
||||||
img.remove();
|
|
||||||
|
|
||||||
grid.cells.h = heights;
|
|
||||||
cleanup();
|
|
||||||
TIME && console.timeEnd("defineHeightmap");
|
|
||||||
resolve();
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// heightmap template
|
|
||||||
TIME && console.time("generateHeightmap");
|
|
||||||
const template = input.value;
|
|
||||||
const templateString = HeightmapTemplates[template];
|
|
||||||
const steps = templateString.split("\n");
|
|
||||||
|
|
||||||
if (!steps.length) throw new Error(`Heightmap template: no steps. Template: ${template}. Steps: ${steps}`);
|
|
||||||
|
|
||||||
for (const step of steps) {
|
|
||||||
const elements = step.trim().split(" ");
|
|
||||||
if (elements.length < 2) throw new Error(`Heightmap template: steps < 2. Template: ${template}. Step: ${elements}`);
|
|
||||||
addStep(...elements);
|
|
||||||
}
|
|
||||||
|
|
||||||
grid.cells.h = heights;
|
|
||||||
cleanup();
|
|
||||||
TIME && console.timeEnd("generateHeightmap");
|
|
||||||
};
|
|
||||||
|
|
||||||
const fromTemplate = template => {
|
const fromTemplate = template => {
|
||||||
const templateString = HeightmapTemplates[template];
|
const templateString = HeightmapTemplates[template];
|
||||||
const steps = templateString.split("\n");
|
const steps = templateString.split("\n");
|
||||||
|
|
@ -77,6 +22,49 @@ window.HeightmapGenerator = (function () {
|
||||||
return heights;
|
return heights;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fromPrecreated = id => {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
TIME && console.time("defineHeightmap");
|
||||||
|
// create canvas where 1px corresponts to a cell
|
||||||
|
const canvas = document.createElement("canvas");
|
||||||
|
const ctx = canvas.getContext("2d");
|
||||||
|
const {cellsX, cellsY} = grid;
|
||||||
|
canvas.width = cellsX;
|
||||||
|
canvas.height = cellsY;
|
||||||
|
|
||||||
|
// load heightmap into image and render to canvas
|
||||||
|
const img = new Image();
|
||||||
|
img.src = `./heightmaps/${id}.png`;
|
||||||
|
img.onload = () => {
|
||||||
|
ctx.drawImage(img, 0, 0, cellsX, cellsY);
|
||||||
|
const imageData = ctx.getImageData(0, 0, cellsX, cellsY);
|
||||||
|
assignColorsToHeight(imageData.data);
|
||||||
|
canvas.remove();
|
||||||
|
img.remove();
|
||||||
|
|
||||||
|
grid.cells.h = heights;
|
||||||
|
cleanup();
|
||||||
|
TIME && console.timeEnd("defineHeightmap");
|
||||||
|
resolve();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const generate = async function () {
|
||||||
|
Math.random = aleaPRNG(seed);
|
||||||
|
resetHeights();
|
||||||
|
const id = byId("templateInput").value;
|
||||||
|
|
||||||
|
if (HeightmapTemplates[id]) {
|
||||||
|
TIME && console.time("generateHeightmap");
|
||||||
|
grid.cells.h = fromTemplate(id);
|
||||||
|
cleanup();
|
||||||
|
TIME && console.timeEnd("generateHeightmap");
|
||||||
|
} else {
|
||||||
|
return fromPrecreated(id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function addStep(tool, a2, a3, a4, a5) {
|
function addStep(tool, a2, a3, a4, a5) {
|
||||||
if (tool === "Hill") return addHill(a2, a3, a4, a5);
|
if (tool === "Hill") return addHill(a2, a3, a4, a5);
|
||||||
if (tool === "Pit") return addPit(a2, a3, a4, a5);
|
if (tool === "Pit") return addPit(a2, a3, a4, a5);
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ function handleKeyup(event) {
|
||||||
const alt = altKey || key === "Alt";
|
const alt = altKey || key === "Alt";
|
||||||
|
|
||||||
if (code === "F1") showInfo();
|
if (code === "F1") showInfo();
|
||||||
else if (code === "F2") regeneratePrompt("hotkey");
|
else if (code === "F2") regeneratePrompt();
|
||||||
else if (code === "F6") quickSave();
|
else if (code === "F6") quickSave();
|
||||||
else if (code === "F9") quickLoad();
|
else if (code === "F9") quickLoad();
|
||||||
else if (code === "Tab") toggleOptions(event);
|
else if (code === "Tab") toggleOptions(event);
|
||||||
|
|
|
||||||
|
|
@ -249,9 +249,9 @@ function testSpeaker() {
|
||||||
speechSynthesis.speak(speaker);
|
speechSynthesis.speak(speaker);
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateMapWithSeed(source) {
|
function generateMapWithSeed() {
|
||||||
if (optionsSeed.value == seed) return tip("The current map already has this seed", false, "error");
|
if (optionsSeed.value == seed) return tip("The current map already has this seed", false, "error");
|
||||||
regeneratePrompt(source);
|
regeneratePrompt();
|
||||||
}
|
}
|
||||||
|
|
||||||
function showSeedHistoryDialog() {
|
function showSeedHistoryDialog() {
|
||||||
|
|
@ -280,7 +280,7 @@ function restoreSeed(id) {
|
||||||
mapHeightInput.value = mapHistory[id].height;
|
mapHeightInput.value = mapHistory[id].height;
|
||||||
templateInput.value = mapHistory[id].template;
|
templateInput.value = mapHistory[id].template;
|
||||||
if (locked("template")) unlock("template");
|
if (locked("template")) unlock("template");
|
||||||
regeneratePrompt("seed history");
|
regeneratePrompt();
|
||||||
}
|
}
|
||||||
|
|
||||||
function restoreDefaultZoomExtent() {
|
function restoreDefaultZoomExtent() {
|
||||||
|
|
@ -513,7 +513,6 @@ function applyStoredOptions() {
|
||||||
|
|
||||||
// randomize options if randomization is allowed (not locked or options='default')
|
// randomize options if randomization is allowed (not locked or options='default')
|
||||||
function randomizeOptions() {
|
function randomizeOptions() {
|
||||||
Math.random = aleaPRNG(seed); // reset seed to initial one
|
|
||||||
const randomize = new URL(window.location.href).searchParams.get("options") === "default"; // ignore stored options
|
const randomize = new URL(window.location.href).searchParams.get("options") === "default"; // ignore stored options
|
||||||
|
|
||||||
// 'Options' settings
|
// 'Options' settings
|
||||||
|
|
@ -638,17 +637,17 @@ function restoreDefaultOptions() {
|
||||||
// Sticked menu Options listeners
|
// Sticked menu Options listeners
|
||||||
document.getElementById("sticked").addEventListener("click", function (event) {
|
document.getElementById("sticked").addEventListener("click", function (event) {
|
||||||
const id = event.target.id;
|
const id = event.target.id;
|
||||||
if (id === "newMapButton") regeneratePrompt("sticky button");
|
if (id === "newMapButton") regeneratePrompt();
|
||||||
else if (id === "saveButton") showSavePane();
|
else if (id === "saveButton") showSavePane();
|
||||||
else if (id === "exportButton") showExportPane();
|
else if (id === "exportButton") showExportPane();
|
||||||
else if (id === "loadButton") showLoadPane();
|
else if (id === "loadButton") showLoadPane();
|
||||||
else if (id === "zoomReset") resetZoom(1000);
|
else if (id === "zoomReset") resetZoom(1000);
|
||||||
});
|
});
|
||||||
|
|
||||||
function regeneratePrompt(source) {
|
function regeneratePrompt(options) {
|
||||||
if (customization) return tip("New map cannot be generated when edit mode is active, please exit the mode and retry", false, "error");
|
if (customization) return tip("New map cannot be generated when edit mode is active, please exit the mode and retry", false, "error");
|
||||||
const workingTime = (Date.now() - last(mapHistory).created) / 60000; // minutes
|
const workingTime = (Date.now() - last(mapHistory).created) / 60000; // minutes
|
||||||
if (workingTime < 5) return regenerateMap(source);
|
if (workingTime < 5) return regenerateMap(options);
|
||||||
|
|
||||||
alertMessage.innerHTML = /* html */ `Are you sure you want to generate a new map?<br />
|
alertMessage.innerHTML = /* html */ `Are you sure you want to generate a new map?<br />
|
||||||
All unsaved changes made to the current map will be lost`;
|
All unsaved changes made to the current map will be lost`;
|
||||||
|
|
@ -661,7 +660,7 @@ function regeneratePrompt(source) {
|
||||||
},
|
},
|
||||||
Generate: function () {
|
Generate: function () {
|
||||||
closeDialogs();
|
closeDialogs();
|
||||||
regenerateMap(source);
|
regenerateMap(options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -137,7 +137,7 @@ function recalculatePopulation() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function regenerateStates() {
|
function regenerateStates() {
|
||||||
const localSeed = Math.floor(Math.random() * 1e9); // new random seed
|
const localSeed = generateSeed();
|
||||||
Math.random = aleaPRNG(localSeed);
|
Math.random = aleaPRNG(localSeed);
|
||||||
|
|
||||||
const statesCount = +regionsOutput.value;
|
const statesCount = +regionsOutput.value;
|
||||||
|
|
|
||||||
|
|
@ -74,3 +74,7 @@ function getNumberInRange(r) {
|
||||||
}
|
}
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function generateSeed() {
|
||||||
|
return String(Math.floor(Math.random() * 1e9));
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue