mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-22 12:01:23 +01:00
commit
8fd9b82554
30 changed files with 1761 additions and 613 deletions
|
|
@ -1176,18 +1176,18 @@ function refreshAllEditors() {
|
|||
// dynamically loaded editors
|
||||
async function editStates() {
|
||||
if (customization) return;
|
||||
const Editor = await import("../dynamic/editors/states-editor.js?v=12062022");
|
||||
const Editor = await import("../dynamic/editors/states-editor.js?v=1.89.05");
|
||||
Editor.open();
|
||||
}
|
||||
|
||||
async function editCultures() {
|
||||
if (customization) return;
|
||||
const Editor = await import("../dynamic/editors/cultures-editor.js?v=1.88.06");
|
||||
const Editor = await import("../dynamic/editors/cultures-editor.js?v=1.89.09");
|
||||
Editor.open();
|
||||
}
|
||||
|
||||
async function editReligions() {
|
||||
if (customization) return;
|
||||
const Editor = await import("../dynamic/editors/religions-editor.js?v=1.88.06");
|
||||
const Editor = await import("../dynamic/editors/religions-editor.js?v=1.89.10");
|
||||
Editor.open();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -204,6 +204,13 @@ function editHeightmap(options) {
|
|||
INFO && console.group("Edit Heightmap");
|
||||
TIME && console.time("regenerateErasedData");
|
||||
|
||||
// remove data
|
||||
pack.cultures = [];
|
||||
pack.burgs = [];
|
||||
pack.states = [];
|
||||
pack.provinces = [];
|
||||
pack.religions = [];
|
||||
|
||||
const erosionAllowed = allowErosion.checked;
|
||||
markFeatures();
|
||||
markupGridOcean();
|
||||
|
|
@ -231,8 +238,10 @@ function editHeightmap(options) {
|
|||
Lakes.defineGroup();
|
||||
defineBiomes();
|
||||
rankCells();
|
||||
|
||||
Cultures.generate();
|
||||
Cultures.expand();
|
||||
|
||||
BurgsAndStates.generate();
|
||||
Religions.generate();
|
||||
BurgsAndStates.defineStateForms();
|
||||
|
|
|
|||
|
|
@ -67,11 +67,11 @@ function editIce() {
|
|||
function addIcebergOnClick() {
|
||||
const [x, y] = d3.mouse(this);
|
||||
const i = findGridCell(x, y, grid);
|
||||
const c = grid.points[i];
|
||||
const s = +document.getElementById("iceSize").value;
|
||||
const [cx, cy] = grid.points[i];
|
||||
const size = +document.getElementById("iceSize")?.value || 1;
|
||||
|
||||
const points = getGridPolygon(i).map(p => [(p[0] + (c[0] - p[0]) / s) | 0, (p[1] + (c[1] - p[1]) / s) | 0]);
|
||||
const iceberg = ice.append("polygon").attr("points", points).attr("cell", i).attr("size", s);
|
||||
const points = getGridPolygon(i).map(([x, y]) => [rn(lerp(cx, x, size), 2), rn(lerp(cy, y, size), 2)]);
|
||||
const iceberg = ice.append("polygon").attr("points", points).attr("cell", i).attr("size", size);
|
||||
iceberg.call(d3.drag().on("drag", dragElement));
|
||||
if (d3.event.shiftKey === false) toggleAdd();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -671,11 +671,10 @@ function toggleIce(event) {
|
|||
}
|
||||
|
||||
function drawIce() {
|
||||
const cells = grid.cells,
|
||||
vertices = grid.vertices,
|
||||
n = cells.i.length,
|
||||
temp = cells.temp,
|
||||
h = cells.h;
|
||||
const {cells, vertices} = grid;
|
||||
const {temp, h} = cells;
|
||||
const n = cells.i.length;
|
||||
|
||||
const used = new Uint8Array(cells.i.length);
|
||||
Math.random = aleaPRNG(seed);
|
||||
|
||||
|
|
@ -700,23 +699,22 @@ function drawIce() {
|
|||
continue;
|
||||
}
|
||||
|
||||
const tNormalized = normalize(t, -8, 2);
|
||||
const randomFactor = t > -5 ? 0.4 + rand() * 1.2 : 1;
|
||||
|
||||
// mildly cold: iceberd
|
||||
if (P(normalize(t, -7, 2.5))) continue; // t[-5; 2] cold: skip some cells
|
||||
if (P(tNormalized ** 0.5 * randomFactor)) continue; // cold: skip some cells
|
||||
if (grid.features[cells.f[i]].type === "lake") continue; // lake: no icebers
|
||||
let size = (6.5 + t) / 10; // iceberg size: 0 = full size, 1 = zero size
|
||||
if (cells.t[i] === -1) size *= 1.3; // coasline: smaller icebers
|
||||
size = Math.min(size * (0.4 + rand() * 1.2), 0.95); // randomize iceberg size
|
||||
resizePolygon(i, size);
|
||||
|
||||
let size = 1 - tNormalized; // iceberg size: 0 = zero size, 1 = full size
|
||||
if (cells.t[i] === -1) size /= 1.3; // coasline: smaller icebers
|
||||
resizePolygon(i, minmax(rn(size * randomFactor, 2), 0.08, 1));
|
||||
}
|
||||
|
||||
function resizePolygon(i, s) {
|
||||
const c = grid.points[i];
|
||||
const points = getGridPolygon(i).map(p => [(p[0] + (c[0] - p[0]) * s) | 0, (p[1] + (c[1] - p[1]) * s) | 0]);
|
||||
ice
|
||||
.append("polygon")
|
||||
.attr("points", points)
|
||||
.attr("cell", i)
|
||||
.attr("size", rn(1 - s, 2));
|
||||
function resizePolygon(i, size) {
|
||||
const [cx, cy] = grid.points[i];
|
||||
const points = getGridPolygon(i).map(([x, y]) => [rn(lerp(cx, x, size), 2), rn(lerp(cy, y, size), 2)]);
|
||||
ice.append("polygon").attr("points", points).attr("cell", i).attr("size", size);
|
||||
}
|
||||
|
||||
// connect vertices to chain
|
||||
|
|
|
|||
|
|
@ -42,12 +42,11 @@ function editNotes(id, name) {
|
|||
|
||||
$("#notesEditor").dialog({
|
||||
title: "Notes Editor",
|
||||
width: "minmax(80vw, 540px)",
|
||||
width: window.innerWidth * 0.8,
|
||||
height: window.innerHeight * 0.75,
|
||||
position: {my: "center", at: "center", of: "svg"},
|
||||
close: removeEditor
|
||||
});
|
||||
$("[aria-describedby='notesEditor']").css("top", "10vh");
|
||||
|
||||
if (modules.editNotes) return;
|
||||
modules.editNotes = true;
|
||||
|
|
|
|||
|
|
@ -77,12 +77,15 @@ document
|
|||
// show popup with a list of Patreon supportes (updated manually)
|
||||
async function showSupporters() {
|
||||
const {supporters} = await import("../dynamic/supporters.js?v=19062022");
|
||||
const list = supporters.split("\n").sort();
|
||||
const columns = window.innerWidth < 800 ? 2 : 5;
|
||||
|
||||
alertMessage.innerHTML =
|
||||
"<ul style='column-count: 5; column-gap: 2em'>" + supporters.map(n => `<li>${n}</li>`).join("") + "</ul>";
|
||||
`<ul style='column-count: ${columns}; column-gap: 2em'>` + list.map(n => `<li>${n}</li>`).join("") + "</ul>";
|
||||
$("#alert").dialog({
|
||||
resizable: false,
|
||||
title: "Patreon Supporters",
|
||||
width: "54vw",
|
||||
width: "min-width",
|
||||
position: {my: "center", at: "center", of: "svg"}
|
||||
});
|
||||
}
|
||||
|
|
@ -157,9 +160,20 @@ optionsContent.addEventListener("click", function (event) {
|
|||
});
|
||||
|
||||
function mapSizeInputChange() {
|
||||
const $mapWidthInput = byId("mapWidthInput");
|
||||
const $mapHeightInput = byId("mapHeightInput");
|
||||
|
||||
changeMapSize();
|
||||
localStorage.setItem("mapWidth", mapWidthInput.value);
|
||||
localStorage.setItem("mapHeight", mapHeightInput.value);
|
||||
localStorage.setItem("mapWidth", $mapWidthInput.value);
|
||||
localStorage.setItem("mapHeight", $mapHeightInput.value);
|
||||
|
||||
const tooWide = +$mapWidthInput.value > window.innerWidth;
|
||||
const tooHigh = +$mapHeightInput.value > window.innerHeight;
|
||||
|
||||
if (tooWide || tooHigh) {
|
||||
const message = `Canvas size is larger than actual window size (${window.innerWidth} x ${window.innerHeight}). It can affect the performance if you are going to create a new map`;
|
||||
tip(message, false, "warn", 4000);
|
||||
}
|
||||
}
|
||||
|
||||
// change svg size on manual size change or window resize, do not change graph size
|
||||
|
|
@ -534,7 +548,7 @@ function applyStoredOptions() {
|
|||
options.stateLabelsMode = stateLabelsModeInput.value;
|
||||
}
|
||||
|
||||
// randomize options if randomization is allowed (not locked or options='default')
|
||||
// randomize options if randomization is allowed (not locked or queryParam options='default')
|
||||
function randomizeOptions() {
|
||||
const randomize = new URL(window.location.href).searchParams.get("options") === "default"; // ignore stored options
|
||||
|
||||
|
|
@ -546,7 +560,7 @@ function randomizeOptions() {
|
|||
manorsInput.value = 1000;
|
||||
manorsOutput.value = "auto";
|
||||
}
|
||||
if (randomize || !locked("religions")) religionsInput.value = religionsOutput.value = gauss(5, 2, 2, 10);
|
||||
if (randomize || !locked("religions")) religionsInput.value = religionsOutput.value = gauss(6, 3, 2, 10);
|
||||
if (randomize || !locked("power")) powerInput.value = powerOutput.value = gauss(4, 2, 0, 10, 2);
|
||||
if (randomize || !locked("neutral")) neutralInput.value = neutralOutput.value = rn(1 + Math.random(), 1);
|
||||
if (randomize || !locked("cultures")) culturesInput.value = culturesOutput.value = gauss(12, 3, 5, 30);
|
||||
|
|
@ -602,17 +616,17 @@ function randomizeCultureSet() {
|
|||
function setRendering(value) {
|
||||
viewbox.attr("shape-rendering", value);
|
||||
|
||||
if (value === "optimizeSpeed") {
|
||||
// block some styles
|
||||
coastline.select("#sea_island").style("filter", "none");
|
||||
statesHalo.style("display", "none");
|
||||
emblems.style("opacity", 1);
|
||||
} else {
|
||||
// remove style block
|
||||
coastline.select("#sea_island").style("filter", null);
|
||||
statesHalo.style("display", null);
|
||||
emblems.style("opacity", null);
|
||||
}
|
||||
// if (value === "optimizeSpeed") {
|
||||
// // block some styles
|
||||
// coastline.select("#sea_island").style("filter", "none");
|
||||
// statesHalo.style("display", "none");
|
||||
// emblems.style("opacity", 1);
|
||||
// } else {
|
||||
// // remove style block
|
||||
// coastline.select("#sea_island").style("filter", null);
|
||||
// statesHalo.style("display", null);
|
||||
// emblems.style("opacity", null);
|
||||
// }
|
||||
}
|
||||
|
||||
// generate current year and era name
|
||||
|
|
|
|||
|
|
@ -74,12 +74,13 @@ function createRiver() {
|
|||
|
||||
function addRiver() {
|
||||
const {rivers, cells} = pack;
|
||||
const {addMeandering, getApproximateLength, getWidth, getOffset, getName, getRiverPath, getBasin} = Rivers;
|
||||
const {addMeandering, getApproximateLength, getWidth, getOffset, getName, getRiverPath, getBasin, getNextId} =
|
||||
Rivers;
|
||||
|
||||
const riverCells = createRiver.cells;
|
||||
if (riverCells.length < 2) return tip("Add at least 2 cells", false, "error");
|
||||
|
||||
const riverId = rivers.length ? last(rivers).i + 1 : 1;
|
||||
const riverId = getNextId(rivers);
|
||||
const parent = cells.r[last(riverCells)] || riverId;
|
||||
|
||||
riverCells.forEach(cell => {
|
||||
|
|
@ -100,12 +101,30 @@ function createRiver() {
|
|||
const name = getName(mouth);
|
||||
const basin = getBasin(parent);
|
||||
|
||||
rivers.push({i: riverId, source, mouth, discharge, length, width, widthFactor, sourceWidth, parent, cells: riverCells, basin, name, type: "River"});
|
||||
rivers.push({
|
||||
i: riverId,
|
||||
source,
|
||||
mouth,
|
||||
discharge,
|
||||
length,
|
||||
width,
|
||||
widthFactor,
|
||||
sourceWidth,
|
||||
parent,
|
||||
cells: riverCells,
|
||||
basin,
|
||||
name,
|
||||
type: "River"
|
||||
});
|
||||
const id = "river" + riverId;
|
||||
|
||||
// render river
|
||||
lineGen.curve(d3.curveCatmullRom.alpha(0.1));
|
||||
viewbox.select("#rivers").append("path").attr("id", id).attr("d", getRiverPath(meanderedPoints, widthFactor, sourceWidth));
|
||||
viewbox
|
||||
.select("#rivers")
|
||||
.append("path")
|
||||
.attr("id", id)
|
||||
.attr("d", getRiverPath(meanderedPoints, widthFactor, sourceWidth));
|
||||
|
||||
editRiver(id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
const CONTROL_POINST_DISTANCE = 10;
|
||||
|
||||
function editRoute(onClick) {
|
||||
if (customization) return;
|
||||
if (!onClick && elSelected && d3.event.target.id === elSelected.attr("id")) return;
|
||||
|
|
@ -47,13 +50,13 @@ function editRoute(onClick) {
|
|||
}
|
||||
|
||||
function drawControlPoints(node) {
|
||||
const l = node.getTotalLength();
|
||||
const increment = l / Math.ceil(l / 4);
|
||||
for (let i = 0; i <= l; i += increment) {
|
||||
const totalLength = node.getTotalLength();
|
||||
const increment = totalLength / Math.ceil(totalLength / CONTROL_POINST_DISTANCE);
|
||||
for (let i = 0; i <= totalLength; i += increment) {
|
||||
const point = node.getPointAtLength(i);
|
||||
addControlPoint([point.x, point.y]);
|
||||
}
|
||||
routeLength.innerHTML = rn(l * distanceScaleInput.value) + " " + distanceUnitInput.value;
|
||||
routeLength.innerHTML = rn(totalLength * distanceScaleInput.value) + " " + distanceUnitInput.value;
|
||||
}
|
||||
|
||||
function addControlPoint(point, before = null) {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,27 @@
|
|||
// UI module to control the style presets
|
||||
"use strict";
|
||||
|
||||
const systemPresets = ["default", "ancient", "gloom", "light", "watercolor", "clean", "atlas", "cyberpunk", "monochrome"];
|
||||
const systemPresets = [
|
||||
"default",
|
||||
"ancient",
|
||||
"gloom",
|
||||
"pale",
|
||||
"light",
|
||||
"watercolor",
|
||||
"clean",
|
||||
"atlas",
|
||||
"cyberpunk",
|
||||
"monochrome"
|
||||
];
|
||||
const customPresetPrefix = "fmgStyle_";
|
||||
|
||||
// add style presets to list
|
||||
{
|
||||
const systemOptions = systemPresets.map(styleName => `<option value="${styleName}">${styleName}</option>`);
|
||||
const storedStyles = Object.keys(localStorage).filter(key => key.startsWith(customPresetPrefix));
|
||||
const customOptions = storedStyles.map(styleName => `<option value="${styleName}">${styleName.replace(customPresetPrefix, "")} [custom]</option>`);
|
||||
const customOptions = storedStyles.map(
|
||||
styleName => `<option value="${styleName}">${styleName.replace(customPresetPrefix, "")} [custom]</option>`
|
||||
);
|
||||
const options = systemOptions.join("") + customOptions.join("");
|
||||
document.getElementById("stylePreset").innerHTML = options;
|
||||
}
|
||||
|
|
@ -37,7 +50,8 @@ async function getStylePreset(desiredPreset) {
|
|||
const isValid = JSON.isValid(storedStyleJSON);
|
||||
if (isValid) return [desiredPreset, JSON.parse(storedStyleJSON)];
|
||||
|
||||
ERROR && console.error(`Custom style ${desiredPreset} stored in localStorage is not valid. Applying default style`);
|
||||
ERROR &&
|
||||
console.error(`Custom style ${desiredPreset} stored in localStorage is not valid. Applying default style`);
|
||||
presetToLoad = "default";
|
||||
}
|
||||
}
|
||||
|
|
@ -145,8 +159,31 @@ function addStylePreset() {
|
|||
"#stateBorders": ["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter"],
|
||||
"#provinceBorders": ["opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter"],
|
||||
"#cells": ["opacity", "stroke", "stroke-width", "filter", "mask"],
|
||||
"#gridOverlay": ["opacity", "scale", "dx", "dy", "type", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "transform", "filter", "mask"],
|
||||
"#coordinates": ["opacity", "data-size", "font-size", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter", "mask"],
|
||||
"#gridOverlay": [
|
||||
"opacity",
|
||||
"scale",
|
||||
"dx",
|
||||
"dy",
|
||||
"type",
|
||||
"stroke",
|
||||
"stroke-width",
|
||||
"stroke-dasharray",
|
||||
"stroke-linecap",
|
||||
"transform",
|
||||
"filter",
|
||||
"mask"
|
||||
],
|
||||
"#coordinates": [
|
||||
"opacity",
|
||||
"data-size",
|
||||
"font-size",
|
||||
"stroke",
|
||||
"stroke-width",
|
||||
"stroke-dasharray",
|
||||
"stroke-linecap",
|
||||
"filter",
|
||||
"mask"
|
||||
],
|
||||
"#compass": ["opacity", "transform", "filter", "mask", "shape-rendering"],
|
||||
"#rose": ["transform"],
|
||||
"#relig": ["opacity", "stroke", "stroke-width", "filter"],
|
||||
|
|
@ -174,7 +211,17 @@ function addStylePreset() {
|
|||
"#statesBody": ["opacity", "filter"],
|
||||
"#statesHalo": ["opacity", "data-width", "stroke-width", "filter"],
|
||||
"#provs": ["opacity", "fill", "font-size", "font-family", "filter"],
|
||||
"#temperature": ["opacity", "font-size", "fill", "fill-opacity", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "filter"],
|
||||
"#temperature": [
|
||||
"opacity",
|
||||
"font-size",
|
||||
"fill",
|
||||
"fill-opacity",
|
||||
"stroke",
|
||||
"stroke-width",
|
||||
"stroke-dasharray",
|
||||
"stroke-linecap",
|
||||
"filter"
|
||||
],
|
||||
"#ice": ["opacity", "fill", "stroke", "stroke-width", "filter"],
|
||||
"#emblems": ["opacity", "stroke-width", "filter"],
|
||||
"#texture": ["opacity", "filter", "mask"],
|
||||
|
|
@ -184,16 +231,65 @@ function addStylePreset() {
|
|||
"#oceanBase": ["fill"],
|
||||
"#oceanicPattern": ["href", "opacity"],
|
||||
"#terrs": ["opacity", "scheme", "terracing", "skip", "relax", "curve", "filter", "mask"],
|
||||
"#legend": ["data-size", "font-size", "font-family", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap", "data-x", "data-y", "data-columns"],
|
||||
"#legend": [
|
||||
"data-size",
|
||||
"font-size",
|
||||
"font-family",
|
||||
"stroke",
|
||||
"stroke-width",
|
||||
"stroke-dasharray",
|
||||
"stroke-linecap",
|
||||
"data-x",
|
||||
"data-y",
|
||||
"data-columns"
|
||||
],
|
||||
"#legendBox": ["fill", "fill-opacity"],
|
||||
"#burgLabels > #cities": ["opacity", "fill", "text-shadow", "data-size", "font-size", "font-family"],
|
||||
"#burgIcons > #cities": ["opacity", "fill", "fill-opacity", "size", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap"],
|
||||
"#burgIcons > #cities": [
|
||||
"opacity",
|
||||
"fill",
|
||||
"fill-opacity",
|
||||
"size",
|
||||
"stroke",
|
||||
"stroke-width",
|
||||
"stroke-dasharray",
|
||||
"stroke-linecap"
|
||||
],
|
||||
"#anchors > #cities": ["opacity", "fill", "size", "stroke", "stroke-width"],
|
||||
"#burgLabels > #towns": ["opacity", "fill", "text-shadow", "data-size", "font-size", "font-family"],
|
||||
"#burgIcons > #towns": ["opacity", "fill", "fill-opacity", "size", "stroke", "stroke-width", "stroke-dasharray", "stroke-linecap"],
|
||||
"#burgIcons > #towns": [
|
||||
"opacity",
|
||||
"fill",
|
||||
"fill-opacity",
|
||||
"size",
|
||||
"stroke",
|
||||
"stroke-width",
|
||||
"stroke-dasharray",
|
||||
"stroke-linecap"
|
||||
],
|
||||
"#anchors > #towns": ["opacity", "fill", "size", "stroke", "stroke-width"],
|
||||
"#labels > #states": ["opacity", "fill", "stroke", "stroke-width", "text-shadow", "data-size", "font-size", "font-family", "filter"],
|
||||
"#labels > #addedLabels": ["opacity", "fill", "stroke", "stroke-width", "text-shadow", "data-size", "font-size", "font-family", "filter"],
|
||||
"#labels > #states": [
|
||||
"opacity",
|
||||
"fill",
|
||||
"stroke",
|
||||
"stroke-width",
|
||||
"text-shadow",
|
||||
"data-size",
|
||||
"font-size",
|
||||
"font-family",
|
||||
"filter"
|
||||
],
|
||||
"#labels > #addedLabels": [
|
||||
"opacity",
|
||||
"fill",
|
||||
"stroke",
|
||||
"stroke-width",
|
||||
"text-shadow",
|
||||
"data-size",
|
||||
"font-size",
|
||||
"font-family",
|
||||
"filter"
|
||||
],
|
||||
"#fogging": ["opacity", "fill", "filter"]
|
||||
};
|
||||
|
||||
|
|
@ -238,7 +334,8 @@ function addStylePreset() {
|
|||
if (!styleJSON) return tip("Please provide a style JSON", false, "error");
|
||||
if (!JSON.isValid(styleJSON)) return tip("JSON string is not valid, please check the format", false, "error");
|
||||
if (!desiredName) return tip("Please provide a preset name", false, "error");
|
||||
if (styleSaverTip.innerHTML === "default") return tip("You cannot overwrite default preset, please change the name", false, "error");
|
||||
if (styleSaverTip.innerHTML === "default")
|
||||
return tip("You cannot overwrite default preset, please change the name", false, "error");
|
||||
|
||||
const presetName = customPresetPrefix + desiredName;
|
||||
applyOption(stylePreset, presetName, desiredName + " [custom]");
|
||||
|
|
|
|||
|
|
@ -74,10 +74,8 @@ toolsContent.addEventListener("click", function (event) {
|
|||
});
|
||||
|
||||
function processFeatureRegeneration(event, button) {
|
||||
if (button === "regenerateStateLabels") {
|
||||
BurgsAndStates.drawStateLabels();
|
||||
if (!layerIsOn("toggleLabels")) toggleLabels();
|
||||
} else if (button === "regenerateReliefIcons") {
|
||||
if (button === "regenerateStateLabels") BurgsAndStates.drawStateLabels();
|
||||
else if (button === "regenerateReliefIcons") {
|
||||
ReliefIcons();
|
||||
if (!layerIsOn("toggleRelief")) toggleRelief();
|
||||
} else if (button === "regenerateRoutes") {
|
||||
|
|
@ -628,10 +626,11 @@ function addRiverOnClick() {
|
|||
getType,
|
||||
getWidth,
|
||||
getOffset,
|
||||
getApproximateLength
|
||||
getApproximateLength,
|
||||
getNextId
|
||||
} = Rivers;
|
||||
const riverCells = [];
|
||||
let riverId = rivers.length ? last(rivers).i + 1 : 1;
|
||||
let riverId = getNextId(rivers);
|
||||
let parent = riverId;
|
||||
|
||||
const initialFlux = grid.cells.prec[cells.g[i]];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue