mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
fix add river on click
This commit is contained in:
parent
820cb22463
commit
2162c043c9
3 changed files with 63 additions and 67 deletions
|
|
@ -37,6 +37,55 @@
|
||||||
lake.shoreline = [...uniqueCells];
|
lake.shoreline = [...uniqueCells];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const prepareLakeData = h => {
|
||||||
|
const cells = pack.cells;
|
||||||
|
const ELEVATION_LIMIT = 10;
|
||||||
|
|
||||||
|
pack.features.forEach(f => {
|
||||||
|
if (f.type !== "lake") return;
|
||||||
|
delete f.flux;
|
||||||
|
delete f.inlets;
|
||||||
|
delete f.outlet;
|
||||||
|
delete f.height;
|
||||||
|
delete f.closed;
|
||||||
|
!f.shoreline && Lakes.getShoreline(f);
|
||||||
|
|
||||||
|
// lake surface height is as lowest land cells around
|
||||||
|
const min = f.shoreline.sort((a, b) => h[a] - h[b])[0];
|
||||||
|
f.height = h[min] - 0.1;
|
||||||
|
|
||||||
|
// check if lake can be open (not in deep depression)
|
||||||
|
let deep = true;
|
||||||
|
const treshold = f.height + ELEVATION_LIMIT;
|
||||||
|
const queue = [min];
|
||||||
|
const checked = [];
|
||||||
|
checked[min] = true;
|
||||||
|
|
||||||
|
// check if elevated lake can potentially pour to another water body
|
||||||
|
while (deep && queue.length) {
|
||||||
|
const q = queue.pop();
|
||||||
|
|
||||||
|
for (const n of cells.c[q]) {
|
||||||
|
if (checked[n]) continue;
|
||||||
|
if (h[n] >= treshold) continue;
|
||||||
|
|
||||||
|
if (h[n] < 20) {
|
||||||
|
const nFeature = pack.features[cells.f[n]];
|
||||||
|
if (nFeature.type === "ocean" || f.height > nFeature.height) {
|
||||||
|
deep = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checked[n] = true;
|
||||||
|
queue.push(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f.closed = deep;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const cleanupLakeData = function () {
|
const cleanupLakeData = function () {
|
||||||
for (const feature of pack.features) {
|
for (const feature of pack.features) {
|
||||||
if (feature.type !== "lake") continue;
|
if (feature.type !== "lake") continue;
|
||||||
|
|
@ -95,5 +144,5 @@
|
||||||
return "freshwater";
|
return "freshwater";
|
||||||
}
|
}
|
||||||
|
|
||||||
return {setClimateData, cleanupLakeData, defineGroup, generateName, getName, getShoreline};
|
return {setClimateData, cleanupLakeData, prepareLakeData, defineGroup, generateName, getName, getShoreline};
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
let riverNext = 1; // first river id is 1
|
let riverNext = 1; // first river id is 1
|
||||||
|
|
||||||
const h = alterHeights();
|
const h = alterHeights();
|
||||||
prepareLakeData();
|
Lakes.prepareLakeData(h);
|
||||||
resolveDepressions(h, 200);
|
resolveDepressions(h, 200);
|
||||||
drainWater();
|
drainWater();
|
||||||
defineRivers();
|
defineRivers();
|
||||||
|
|
@ -26,54 +26,6 @@
|
||||||
|
|
||||||
TIME && console.timeEnd("generateRivers");
|
TIME && console.timeEnd("generateRivers");
|
||||||
|
|
||||||
function prepareLakeData() {
|
|
||||||
const ELEVATION_LIMIT = 10;
|
|
||||||
|
|
||||||
features.forEach(f => {
|
|
||||||
if (f.type !== "lake") return;
|
|
||||||
delete f.flux;
|
|
||||||
delete f.inlets;
|
|
||||||
delete f.outlet;
|
|
||||||
delete f.height;
|
|
||||||
delete f.closed;
|
|
||||||
!f.shoreline && Lakes.getShoreline(f);
|
|
||||||
|
|
||||||
// lake surface height is as lowest land cells around
|
|
||||||
const min = f.shoreline.sort((a, b) => h[a] - h[b])[0];
|
|
||||||
f.height = h[min] - 0.1;
|
|
||||||
|
|
||||||
// check if lake can be open (not in deep depression)
|
|
||||||
let deep = true;
|
|
||||||
const treshold = f.height + ELEVATION_LIMIT;
|
|
||||||
const queue = [min];
|
|
||||||
const checked = [];
|
|
||||||
checked[min] = true;
|
|
||||||
|
|
||||||
// check if elevated lake can potentially pour to another water body
|
|
||||||
while (deep && queue.length) {
|
|
||||||
const q = queue.pop();
|
|
||||||
|
|
||||||
for (const n of cells.c[q]) {
|
|
||||||
if (checked[n]) continue;
|
|
||||||
if (h[n] >= treshold) continue;
|
|
||||||
|
|
||||||
if (h[n] < 20) {
|
|
||||||
const nFeature = features[cells.f[n]];
|
|
||||||
if (nFeature.type === "ocean" || f.height > nFeature.height) {
|
|
||||||
deep = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checked[n] = true;
|
|
||||||
queue.push(n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
f.closed = deep;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function drainWater() {
|
function drainWater() {
|
||||||
const MIN_FLUX_TO_FORM_RIVER = 30;
|
const MIN_FLUX_TO_FORM_RIVER = 30;
|
||||||
const land = cells.i.filter(i => h[i] >= 20).sort((a, b) => h[b] - h[a]);
|
const land = cells.i.filter(i => h[i] >= 20).sort((a, b) => h[b] - h[a]);
|
||||||
|
|
@ -223,13 +175,13 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
// add distance to water value to land cells to make map less depressed
|
// add distance to water value to land cells to make map less depressed
|
||||||
function alterHeights() {
|
const alterHeights = () => {
|
||||||
const cells = pack.cells;
|
const cells = pack.cells;
|
||||||
return Array.from(cells.h).map((h, i) => {
|
return Array.from(cells.h).map((h, i) => {
|
||||||
if (h < 20 || cells.t[i] < 1) return h;
|
if (h < 20 || cells.t[i] < 1) return h;
|
||||||
return h + cells.t[i] / 100 + d3.mean(cells.c[i].map(c => cells.t[c])) / 10000;
|
return h + cells.t[i] / 100 + d3.mean(cells.c[i].map(c => cells.t[c])) / 10000;
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
// depression filling algorithm (for a correct water flux modeling)
|
// depression filling algorithm (for a correct water flux modeling)
|
||||||
const resolveDepressions = function (h, maxIterations) {
|
const resolveDepressions = function (h, maxIterations) {
|
||||||
|
|
@ -426,5 +378,5 @@
|
||||||
return getBasin(parent);
|
return getBasin(parent);
|
||||||
};
|
};
|
||||||
|
|
||||||
return {generate, resolveDepressions, addMeandering, getPath, specify, getName, getBasin, remove};
|
return {generate, alterHeights, resolveDepressions, addMeandering, getPath, specify, getName, getBasin, remove};
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -539,25 +539,19 @@ function addRiverOnClick() {
|
||||||
let river = +getNextId("river").slice(5); // river id
|
let 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
|
||||||
|
|
||||||
// height with added t value to make map less depressed
|
const h = Rivers.alterHeights();
|
||||||
const h = Array.from(cells.h)
|
Lakes.prepareLakeData(h);
|
||||||
.map((h, i) => (h < 20 || cells.t[i] < 1 ? h : h + cells.t[i] / 100))
|
|
||||||
.map((h, i) => (h < 20 || cells.t[i] < 1 ? h : h + d3.mean(cells.c[i].map(c => cells.t[c])) / 10000));
|
|
||||||
Rivers.resolveDepressions(h, 200);
|
Rivers.resolveDepressions(h, 200);
|
||||||
|
|
||||||
while (i) {
|
while (i) {
|
||||||
cells.r[i] = river;
|
cells.r[i] = river;
|
||||||
const x = cells.p[i][0],
|
const [x, y] = cells.p[i];
|
||||||
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) => h[a] - h[b])]; // downhill cell
|
const min = cells.c[i].sort((a, b) => h[a] - h[b])[0]; // downhill cell
|
||||||
if (h[i] <= h[min]) {
|
if (h[i] <= h[min]) return tip(`Cell ${i} is depressed, river cannot flow further`, false, "error");
|
||||||
tip(`Cell ${i} is depressed, river cannot flow further`, false, "error");
|
|
||||||
return;
|
const [tx, ty] = cells.p[min];
|
||||||
}
|
|
||||||
const tx = cells.p[min][0],
|
|
||||||
ty = cells.p[min][1];
|
|
||||||
|
|
||||||
if (h[min] < 20) {
|
if (h[min] < 20) {
|
||||||
// pour to water body
|
// pour to water body
|
||||||
|
|
@ -572,7 +566,7 @@ function addRiverOnClick() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// hadnle case when lowest cell already has a river
|
// handle case when lowest cell already has a river
|
||||||
const r = cells.r[min];
|
const r = cells.r[min];
|
||||||
const riverCells = cells.i.filter(i => cells.r[i] === r);
|
const riverCells = cells.i.filter(i => cells.r[i] === r);
|
||||||
const riverCellsUpper = riverCells.filter(i => h[i] > h[min]);
|
const riverCellsUpper = riverCells.filter(i => h[i] > h[min]);
|
||||||
|
|
@ -625,6 +619,7 @@ function addRiverOnClick() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d3.event.shiftKey === false) {
|
if (d3.event.shiftKey === false) {
|
||||||
|
Lakes.cleanupLakeData();
|
||||||
unpressClickToAddButton();
|
unpressClickToAddButton();
|
||||||
document.getElementById("addNewRiver").classList.remove("pressed");
|
document.getElementById("addNewRiver").classList.remove("pressed");
|
||||||
if (addNewRiver.offsetParent) riversOverviewRefresh.click();
|
if (addNewRiver.offsetParent) riversOverviewRefresh.click();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue