mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 17:51:24 +01:00
refactor: grid generation
This commit is contained in:
parent
d18636eb8f
commit
e59b536e83
15 changed files with 157 additions and 105 deletions
|
|
@ -3,16 +3,24 @@ import * as d3 from "d3";
|
|||
import {ERROR, INFO, WARN} from "config/logging";
|
||||
import {closeDialogs} from "dialogs/utils";
|
||||
import {initLayers, renderLayer, restoreLayers} from "layers";
|
||||
// @ts-expect-error js module
|
||||
import {drawCoastline} from "modules/coastline";
|
||||
import {calculateMapCoordinates, defineMapSize} from "modules/coordinates";
|
||||
import {markupGridFeatures, markupGridOcean} from "modules/markup";
|
||||
import {markupGridFeatures} from "modules/markup";
|
||||
// @ts-expect-error js module
|
||||
import {drawScaleBar, Rulers} from "modules/measurers";
|
||||
// @ts-expect-error js module
|
||||
import {generatePrecipitation} from "modules/precipitation";
|
||||
import {calculateTemperatures} from "modules/temperature";
|
||||
// @ts-expect-error js module
|
||||
import {unfog} from "modules/ui/editors";
|
||||
// @ts-expect-error js module
|
||||
import {applyMapSize, randomizeOptions} from "modules/ui/options";
|
||||
// @ts-expect-error js module
|
||||
import {applyStyleOnLoad} from "modules/ui/stylePresets";
|
||||
// @ts-expect-error js module
|
||||
import {addZones} from "modules/zones";
|
||||
// @ts-expect-error js module
|
||||
import {aleaPRNG} from "scripts/aleaPRNG";
|
||||
import {hideLoading, showLoading} from "scripts/loading";
|
||||
import {clearMainTip, tip} from "scripts/tooltips";
|
||||
|
|
@ -45,9 +53,9 @@ export async function generate(options?: IGenerationOptions) {
|
|||
applyMapSize();
|
||||
randomizeOptions();
|
||||
|
||||
const updatedGrid = await updateGrid(precreatedGraph);
|
||||
const updatedGrid = await updateGrid(grid, precreatedGraph);
|
||||
|
||||
reGraph();
|
||||
reGraph(updatedGrid);
|
||||
drawCoastline();
|
||||
|
||||
Rivers.generate();
|
||||
|
|
@ -75,6 +83,8 @@ export async function generate(options?: IGenerationOptions) {
|
|||
Markers.generate();
|
||||
addZones();
|
||||
|
||||
OceanLayers(updatedGrid);
|
||||
|
||||
drawScaleBar(scale);
|
||||
Names.getMapName();
|
||||
|
||||
|
|
@ -110,35 +120,33 @@ export async function generate(options?: IGenerationOptions) {
|
|||
}
|
||||
}
|
||||
|
||||
async function updateGrid(precreatedGraph?: IGrid) {
|
||||
const globalGrid = grid;
|
||||
|
||||
const updatedGrid: IGraph & Partial<IGrid> = shouldRegenerateGridPoints(globalGrid)
|
||||
async function updateGrid(globalGrid: IGrid, precreatedGraph?: IGrid): Promise<IGrid> {
|
||||
const baseGrid: IGridBase = shouldRegenerateGridPoints(globalGrid)
|
||||
? (precreatedGraph && undressGrid(precreatedGraph)) || generateGrid()
|
||||
: undressGrid(globalGrid);
|
||||
|
||||
const heights = await HeightmapGenerator.generate(updatedGrid);
|
||||
updatedGrid.cells.h = heights;
|
||||
const heights: Uint8Array = await HeightmapGenerator.generate(baseGrid);
|
||||
if (!heights) throw new Error("Heightmap generation failed");
|
||||
const heightsGrid = {...baseGrid, cells: {...baseGrid.cells, h: heights}};
|
||||
|
||||
const {featureIds, distanceField, features} = markupGridFeatures(updatedGrid);
|
||||
updatedGrid.cells.f = featureIds;
|
||||
updatedGrid.cells.t = distanceField;
|
||||
updatedGrid.features = features;
|
||||
const {featureIds, distanceField, features} = markupGridFeatures(heightsGrid);
|
||||
const markedGrid = {...heightsGrid, features, cells: {...heightsGrid.cells, f: featureIds, t: distanceField}};
|
||||
|
||||
const touchesEdges = features.some(feature => feature && feature.land && feature.border);
|
||||
defineMapSize(touchesEdges);
|
||||
|
||||
Lakes.addLakesInDeepDepressions(updatedGrid);
|
||||
Lakes.openNearSeaLakes(updatedGrid);
|
||||
|
||||
OceanLayers(updatedGrid);
|
||||
|
||||
window.mapCoordinates = calculateMapCoordinates();
|
||||
calculateTemperatures();
|
||||
generatePrecipitation();
|
||||
|
||||
Lakes.addLakesInDeepDepressions(markedGrid);
|
||||
Lakes.openNearSeaLakes(markedGrid);
|
||||
|
||||
const temperature = calculateTemperatures(markedGrid);
|
||||
const temperatureGrid = {...markedGrid, cells: {...markedGrid.cells, temp: temperature}};
|
||||
|
||||
const prec = generatePrecipitation(temperatureGrid);
|
||||
return {...temperatureGrid, cells: {...temperatureGrid.cells, prec}};
|
||||
}
|
||||
|
||||
function undressGrid(extendedGrid: IGrid) {
|
||||
function undressGrid(extendedGrid: IGrid): IGridBase {
|
||||
const {spacing, cellsDesired, boundary, points, cellsX, cellsY, cells, vertices} = extendedGrid;
|
||||
const {i, b, c, v} = cells;
|
||||
return {spacing, cellsDesired, boundary, points, cellsX, cellsY, cells: {i, b, c, v}, vertices};
|
||||
|
|
@ -154,12 +162,17 @@ export async function generateMapOnLoad() {
|
|||
// clear the map
|
||||
export function undraw() {
|
||||
viewbox.selectAll("path, circle, polygon, line, text, use, #zones > g, #armies > g, #ruler > g").remove();
|
||||
|
||||
byId("deftemp")
|
||||
.querySelectorAll("path, clipPath, svg")
|
||||
?.querySelectorAll("path, clipPath, svg")
|
||||
.forEach(el => el.remove());
|
||||
byId("coas").innerHTML = ""; // remove auto-generated emblems
|
||||
|
||||
// remove auto-generated emblems
|
||||
if (byId("coas")) byId("coas")!.innerHTML = "";
|
||||
|
||||
notes = [];
|
||||
rulers = new Rulers();
|
||||
|
||||
unfog();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,9 +5,12 @@ import {UINT16_MAX} from "constants";
|
|||
import {createTypedArray} from "utils/arrayUtils";
|
||||
import {calculateVoronoi, getPackPolygon} from "utils/graphUtils";
|
||||
import {rn} from "utils/numberUtils";
|
||||
import {DISTANCE_FIELD, MIN_LAND_HEIGHT} from "config/generation";
|
||||
|
||||
const {LAND_COAST, WATER_COAST, DEEPER_WATER} = DISTANCE_FIELD;
|
||||
|
||||
// recalculate Voronoi Graph to pack cells
|
||||
export function reGraph() {
|
||||
export function reGraph(grid: IGrid) {
|
||||
TIME && console.time("reGraph");
|
||||
const {cells: gridCells, points, features} = grid;
|
||||
const newCells: {p: TPoints; g: number[]; h: number[]} = {p: [], g: [], h: []}; // store new data
|
||||
|
|
@ -16,14 +19,18 @@ export function reGraph() {
|
|||
for (const i of gridCells.i) {
|
||||
const height = gridCells.h[i];
|
||||
const type = gridCells.t[i];
|
||||
if (height < 20 && type !== -1 && type !== -2) continue; // exclude all deep ocean points
|
||||
if (type === -2 && (i % 4 === 0 || features[gridCells.f[i]].type === "lake")) continue; // exclude non-coastal lake points
|
||||
if (height < MIN_LAND_HEIGHT && type !== WATER_COAST && type !== DEEPER_WATER) continue; // exclude all deep ocean points
|
||||
|
||||
const feature = features[gridCells.f[i]];
|
||||
const isLake = feature && feature.type === "lake";
|
||||
|
||||
if (type === DEEPER_WATER && (i % 4 === 0 || isLake)) continue; // exclude non-coastal lake points
|
||||
const [x, y] = points[i];
|
||||
|
||||
addNewPoint(i, x, y, height);
|
||||
|
||||
// add additional points for cells along coast
|
||||
if (type === 1 || type === -1) {
|
||||
if (type === LAND_COAST || type === WATER_COAST) {
|
||||
if (gridCells.b[i]) continue; // not for near-border cells
|
||||
gridCells.c[i].forEach(e => {
|
||||
if (i > e) return;
|
||||
|
|
@ -55,7 +62,7 @@ export function reGraph() {
|
|||
pack.cells.p = newCells.p;
|
||||
pack.cells.g = createTypedArray({maxValue: grid.points.length, from: newCells.g});
|
||||
pack.cells.q = d3.quadtree(newCells.p.map(([x, y], i) => [x, y, i]));
|
||||
pack.cells.h = createTypedArray({maxValue: 100, from: newCells.h});
|
||||
pack.cells.h = new Uint8Array(newCells.h);
|
||||
pack.cells.area = createTypedArray({maxValue: UINT16_MAX, from: pack.cells.i}).map(getCellArea);
|
||||
|
||||
TIME && console.timeEnd("reGraph");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue