mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 17:51:24 +01:00
refactor: roads generation - define by distance to make route less curvy
This commit is contained in:
parent
2c3cdad59d
commit
1dd185354b
2 changed files with 34 additions and 17 deletions
|
|
@ -2,11 +2,14 @@ import Delaunator from "delaunator";
|
||||||
import FlatQueue from "flatqueue";
|
import FlatQueue from "flatqueue";
|
||||||
|
|
||||||
import {TIME} from "config/logging";
|
import {TIME} from "config/logging";
|
||||||
import {ROUTES} from "config/generation";
|
import {ELEVATION, MIN_LAND_HEIGHT, ROUTES} from "config/generation";
|
||||||
import {dist2} from "utils/functionUtils";
|
import {dist2} from "utils/functionUtils";
|
||||||
import {drawLine} from "utils/debugUtils";
|
import {drawLine} from "utils/debugUtils";
|
||||||
|
|
||||||
export function generateRoutes(burgs: TBurgs, cells: Pick<IPack["cells"], "c" | "h" | "biome" | "state" | "burg">) {
|
export function generateRoutes(
|
||||||
|
burgs: TBurgs,
|
||||||
|
cells: Pick<IPack["cells"], "c" | "p" | "h" | "biome" | "state" | "burg">
|
||||||
|
) {
|
||||||
const cellRoutes = new Uint8Array(cells.h.length);
|
const cellRoutes = new Uint8Array(cells.h.length);
|
||||||
const validBurgs = burgs.filter(burg => burg.i && !(burg as IBurg).removed) as IBurg[];
|
const validBurgs = burgs.filter(burg => burg.i && !(burg as IBurg).removed) as IBurg[];
|
||||||
const mainRoads = generateMainRoads();
|
const mainRoads = generateMainRoads();
|
||||||
|
|
@ -108,15 +111,20 @@ export function generateRoutes(burgs: TBurgs, cells: Pick<IPack["cells"], "c" |
|
||||||
const next = queue.pop()!;
|
const next = queue.pop()!;
|
||||||
|
|
||||||
for (const neibCellId of cells.c[next]) {
|
for (const neibCellId of cells.c[next]) {
|
||||||
if (cells.h[neibCellId] < 20) continue; // ignore water cells
|
if (cells.h[neibCellId] < MIN_LAND_HEIGHT) continue; // ignore water cells
|
||||||
const stateChangeCost = cells.state && cells.state[neibCellId] !== cells.state[next] ? 400 : 0; // prefer to lay within the same state
|
|
||||||
const habitability = biomesData.habitability[cells.biome[neibCellId]];
|
const habitability = biomesData.habitability[cells.biome[neibCellId]];
|
||||||
if (!habitability) continue; // avoid inhabitable cells (eg. lava, glacier)
|
if (!habitability) continue; // inhabitable cells are not passable (eg. lava, glacier)
|
||||||
const habitedCost = habitability ? Math.max(100 - habitability, 0) : 400; // routes tend to lay within populated areas
|
|
||||||
const heightChangeCost = Math.abs(cells.h[neibCellId] - cells.h[next]) * 10; // routes tend to avoid elevation changes
|
const distanceCost = dist2(cells.p[next], cells.p[neibCellId]);
|
||||||
const heightCost = cells.h[neibCellId] > 80 ? cells.h[neibCellId] : 0; // routes tend to avoid mountainous areas
|
|
||||||
const cellCoast = 10 + stateChangeCost + habitedCost + heightChangeCost + heightCost;
|
const habitabilityModifier = 1 + Math.max(100 - habitability, 0) / 1000; // [1, 1.1];
|
||||||
const totalCost = priority + (cellRoutes[neibCellId] || cells.burg[neibCellId] ? cellCoast / 3 : cellCoast);
|
const heightModifier = 1 + Math.max(cells.h[neibCellId] - ELEVATION.HILLS, 0) / 500; // [1, 1.1];
|
||||||
|
const roadModifier = cellRoutes[neibCellId] ? 0.5 : 1;
|
||||||
|
const burgModifier = cells.burg[neibCellId] ? 0.5 : 1;
|
||||||
|
|
||||||
|
const cellsCost = distanceCost * habitabilityModifier * heightModifier * roadModifier * burgModifier;
|
||||||
|
const totalCost = priority + cellsCost;
|
||||||
|
|
||||||
if (from[neibCellId] || totalCost >= cost[neibCellId]) continue;
|
if (from[neibCellId] || totalCost >= cost[neibCellId]) continue;
|
||||||
from[neibCellId] = next;
|
from[neibCellId] = next;
|
||||||
|
|
@ -168,12 +176,6 @@ function getRouteSegments(pathCells: number[], cellRoutes: Uint8Array) {
|
||||||
const hasRoute = (cellId: number) => cellRoutes[cellId] !== 0;
|
const hasRoute = (cellId: number) => cellRoutes[cellId] !== 0;
|
||||||
const noRoute = (cellId: number) => cellRoutes[cellId] === 0;
|
const noRoute = (cellId: number) => cellRoutes[cellId] === 0;
|
||||||
|
|
||||||
const segments: number[][] = [];
|
|
||||||
let segment: number[] = [];
|
|
||||||
|
|
||||||
// UC: complitely new route
|
|
||||||
if (pathCells.every(noRoute)) return [pathCells];
|
|
||||||
|
|
||||||
// UC: only first and/or last cell have route
|
// UC: only first and/or last cell have route
|
||||||
if (pathCells.slice(1, -1).every(noRoute)) return [pathCells];
|
if (pathCells.slice(1, -1).every(noRoute)) return [pathCells];
|
||||||
|
|
||||||
|
|
@ -181,6 +183,9 @@ function getRouteSegments(pathCells: number[], cellRoutes: Uint8Array) {
|
||||||
if (pathCells.every(hasRoute)) return [];
|
if (pathCells.every(hasRoute)) return [];
|
||||||
|
|
||||||
// UC: discontinuous route
|
// UC: discontinuous route
|
||||||
|
const segments: number[][] = [];
|
||||||
|
let segment: number[] = [];
|
||||||
|
|
||||||
for (let i = 0; i < pathCells.length; i++) {
|
for (let i = 0; i < pathCells.length; i++) {
|
||||||
const cellId = pathCells[i];
|
const cellId = pathCells[i];
|
||||||
const nextCellId = pathCells[i + 1];
|
const nextCellId = pathCells[i + 1];
|
||||||
|
|
@ -190,6 +195,11 @@ function getRouteSegments(pathCells: number[], cellRoutes: Uint8Array) {
|
||||||
|
|
||||||
const noConnection = !hasRoute || !nextHasRoute;
|
const noConnection = !hasRoute || !nextHasRoute;
|
||||||
if (noConnection) segment.push(cellId);
|
if (noConnection) segment.push(cellId);
|
||||||
|
|
||||||
|
if (nextHasRoute) {
|
||||||
|
if (segment.length) segments.push(segment);
|
||||||
|
segment = [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return segments;
|
return segments;
|
||||||
|
|
|
||||||
|
|
@ -117,7 +117,14 @@ export function createPack(grid: IGrid): IPack {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const {cellRoutes, routes} = generateRoutes(burgs, {c: cells.c, h: heights, biome, state: stateIds, burg: burgIds});
|
const {cellRoutes, routes} = generateRoutes(burgs, {
|
||||||
|
c: cells.c,
|
||||||
|
p: cells.p,
|
||||||
|
h: heights,
|
||||||
|
biome,
|
||||||
|
state: stateIds,
|
||||||
|
burg: burgIds
|
||||||
|
});
|
||||||
|
|
||||||
// Religions.generate();
|
// Religions.generate();
|
||||||
// BurgsAndStates.defineStateForms();
|
// BurgsAndStates.defineStateForms();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue