mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 17:51:24 +01:00
refactor: markupPackFeatures
This commit is contained in:
parent
87d8c1024d
commit
f82fcbae0f
8 changed files with 271 additions and 178 deletions
|
|
@ -3,10 +3,9 @@ import * as d3 from "d3";
|
|||
import {ERROR, INFO, WARN} from "config/logging";
|
||||
import {closeDialogs} from "dialogs/utils";
|
||||
import {openDialog} from "dialogs";
|
||||
import {initLayers, renderLayer, restoreLayers} from "layers";
|
||||
import {initLayers, restoreLayers} from "layers";
|
||||
// @ts-expect-error js module
|
||||
import {drawCoastline} from "modules/coastline";
|
||||
import {reMarkFeatures} from "modules/markup";
|
||||
// @ts-expect-error js module
|
||||
import {drawScaleBar, Rulers} from "modules/measurers";
|
||||
// @ts-expect-error js module
|
||||
|
|
@ -26,26 +25,12 @@ import {debounce} from "utils/functionUtils";
|
|||
import {rn} from "utils/numberUtils";
|
||||
import {generateSeed} from "utils/probabilityUtils";
|
||||
import {byId} from "utils/shorthands";
|
||||
import {rankCells} from "../rankCells";
|
||||
import {showStatistics} from "../statistics";
|
||||
import {createGrid} from "./grid";
|
||||
import {reGraph} from "./reGraph";
|
||||
import {createPack} from "./pack";
|
||||
import {getInputValue, setInputValue} from "utils/nodeUtils";
|
||||
|
||||
const {
|
||||
Zoom,
|
||||
Lakes,
|
||||
OceanLayers,
|
||||
Rivers,
|
||||
Biomes,
|
||||
Cultures,
|
||||
BurgsAndStates,
|
||||
Religions,
|
||||
Military,
|
||||
Markers,
|
||||
Names,
|
||||
ThreeD
|
||||
} = window;
|
||||
const {Zoom, ThreeD} = window;
|
||||
|
||||
interface IGenerationOptions {
|
||||
seed: string;
|
||||
|
|
@ -66,42 +51,10 @@ async function generate(options?: IGenerationOptions) {
|
|||
randomizeOptions();
|
||||
|
||||
const newGrid = await createGrid(grid, precreatedGraph);
|
||||
const newPack = reGraph(newGrid);
|
||||
const newPack = createPack(newGrid);
|
||||
|
||||
reMarkFeatures(newPack, newGrid);
|
||||
drawCoastline(newPack);
|
||||
|
||||
Rivers.generate(newPack, newGrid);
|
||||
renderLayer("rivers", newPack);
|
||||
Lakes.defineGroup(newPack);
|
||||
Biomes.define(newPack, newGrid);
|
||||
|
||||
rankCells(newPack);
|
||||
Cultures.generate();
|
||||
Cultures.expand();
|
||||
BurgsAndStates.generate();
|
||||
Religions.generate();
|
||||
BurgsAndStates.defineStateForms();
|
||||
BurgsAndStates.generateProvinces();
|
||||
BurgsAndStates.defineBurgFeatures();
|
||||
|
||||
renderLayer("states");
|
||||
renderLayer("borders");
|
||||
BurgsAndStates.drawStateLabels();
|
||||
|
||||
Rivers.specify();
|
||||
Lakes.generateName();
|
||||
|
||||
Military.generate();
|
||||
Markers.generate();
|
||||
addZones();
|
||||
|
||||
OceanLayers(newGrid);
|
||||
|
||||
drawScaleBar(window.scale);
|
||||
Names.getMapName();
|
||||
|
||||
// @ts-expect-error redefine global
|
||||
// redefine global grid and pack
|
||||
grid = newGrid;
|
||||
pack = newPack;
|
||||
|
||||
WARN && console.warn(`TOTAL: ${rn((performance.now() - timeStart) / 1000, 2)}s`);
|
||||
|
|
|
|||
|
|
@ -1,17 +1,75 @@
|
|||
import * as d3 from "d3";
|
||||
|
||||
import {renderLayer} from "layers";
|
||||
// @ts-expect-error js module
|
||||
import {drawCoastline} from "modules/coastline";
|
||||
import {markupPackFeatures} from "modules/markup";
|
||||
// @ts-expect-error js module
|
||||
import {drawScaleBar} from "modules/measurers";
|
||||
// @ts-expect-error js module
|
||||
import {addZones} from "modules/zones";
|
||||
import {DISTANCE_FIELD, MIN_LAND_HEIGHT} from "config/generation";
|
||||
import {TIME} from "config/logging";
|
||||
import {UINT16_MAX} from "constants";
|
||||
import {createTypedArray} from "utils/arrayUtils";
|
||||
import {calculateVoronoi} from "scripts/generation/graph";
|
||||
import {createTypedArray} from "utils/arrayUtils";
|
||||
import {pick} from "utils/functionUtils";
|
||||
import {rn} from "utils/numberUtils";
|
||||
import {DISTANCE_FIELD, MIN_LAND_HEIGHT} from "config/generation";
|
||||
import {rankCells} from "../rankCells";
|
||||
|
||||
const {LAND_COAST, WATER_COAST, DEEPER_WATER} = DISTANCE_FIELD;
|
||||
const {Lakes, OceanLayers, Rivers, Biomes, Cultures, BurgsAndStates, Religions, Military, Markers, Names} = window;
|
||||
|
||||
// recalculate Voronoi Graph to pack cells
|
||||
export function reGraph(grid: IGrid): IPackBase {
|
||||
TIME && console.time("reGraph");
|
||||
export function createPack(grid: IGrid): IPack {
|
||||
const {vertices, cells} = repackGrid(grid);
|
||||
|
||||
const markup = markupPackFeatures(grid, pick(cells, "c", "b", "p", "h"));
|
||||
|
||||
drawCoastline({vertices, cells}); // split into vertices definition and rendering
|
||||
|
||||
// Rivers.generate(newPack, grid);
|
||||
// renderLayer("rivers", newPack);
|
||||
// Lakes.defineGroup(newPack);
|
||||
// Biomes.define(newPack, grid);
|
||||
|
||||
// const rankCellsData = pick(newPack.cells, "i", "f", "fl", "conf", "r", "h", "area", "biome", "haven", "harbor");
|
||||
// rankCells(newPack.features!, rankCellsData);
|
||||
|
||||
Cultures.generate();
|
||||
Cultures.expand();
|
||||
BurgsAndStates.generate();
|
||||
Religions.generate();
|
||||
BurgsAndStates.defineStateForms();
|
||||
BurgsAndStates.generateProvinces();
|
||||
BurgsAndStates.defineBurgFeatures();
|
||||
|
||||
renderLayer("states");
|
||||
renderLayer("borders");
|
||||
BurgsAndStates.drawStateLabels();
|
||||
|
||||
Rivers.specify();
|
||||
Lakes.generateName();
|
||||
|
||||
Military.generate();
|
||||
Markers.generate();
|
||||
addZones();
|
||||
|
||||
OceanLayers(newGrid);
|
||||
|
||||
drawScaleBar(window.scale);
|
||||
Names.getMapName();
|
||||
|
||||
const pack = {
|
||||
vertices,
|
||||
cells
|
||||
};
|
||||
|
||||
return pack as IPack;
|
||||
}
|
||||
|
||||
// repack grid cells: discart deep water cells, add land cells along the coast
|
||||
function repackGrid(grid: IGrid) {
|
||||
TIME && console.time("repackGrid");
|
||||
const {cells: gridCells, points, features} = grid;
|
||||
const newCells: {p: TPoints; g: number[]; h: number[]} = {p: [], g: [], h: []}; // store new data
|
||||
const spacing2 = grid.spacing ** 2;
|
||||
|
|
@ -59,7 +117,7 @@ export function reGraph(grid: IGrid): IPackBase {
|
|||
return Math.min(area, UINT16_MAX);
|
||||
}
|
||||
|
||||
const pack: IPackBase = {
|
||||
const pack = {
|
||||
vertices,
|
||||
cells: {
|
||||
...cells,
|
||||
|
|
@ -71,6 +129,6 @@ export function reGraph(grid: IGrid): IPackBase {
|
|||
}
|
||||
};
|
||||
|
||||
TIME && console.timeEnd("reGraph");
|
||||
TIME && console.timeEnd("repackGrid");
|
||||
return pack;
|
||||
}
|
||||
|
|
@ -8,12 +8,14 @@ const FLUX_MAX_BONUS = 250;
|
|||
const SUITABILITY_FACTOR = 5;
|
||||
|
||||
// assess cells suitability for population and rank cells for culture centers and burgs placement
|
||||
export function rankCells(pack: IPack) {
|
||||
export function rankCells(
|
||||
features: TPackFeatures,
|
||||
cells: Pick<IPack["cells"], "i" | "f" | "fl" | "conf" | "r" | "h" | "area" | "biome" | "haven" | "harbor">
|
||||
) {
|
||||
TIME && console.time("rankCells");
|
||||
const {cells, features} = pack;
|
||||
|
||||
cells.s = new Int16Array(cells.i.length); // cell suitability array
|
||||
cells.pop = new Float32Array(cells.i.length); // cell population array
|
||||
const suitability = new Int16Array(cells.i.length); // cell suitability array
|
||||
const population = new Float32Array(cells.i.length); // cell population array
|
||||
|
||||
const meanFlux = d3.median(cells.fl.filter(f => f)) || 0;
|
||||
const maxFlux = (d3.max(cells.fl) || 0) + (d3.max(cells.conf) || 0); // to normalize flux
|
||||
|
|
@ -30,14 +32,12 @@ export function rankCells(pack: IPack) {
|
|||
const coastBonus = getCoastBonus(cellId); // [-30, 30]
|
||||
const estuaryBonus = getEstuaryBonus(cellId); // [0, 15]
|
||||
|
||||
const suitability =
|
||||
(habitabilityBonus + riverBonus + elevationBonus + coastBonus + estuaryBonus) / SUITABILITY_FACTOR; // [-30, 311]
|
||||
const bonuses = [habitabilityBonus, riverBonus, elevationBonus, coastBonus, estuaryBonus];
|
||||
const total = d3.sum(bonuses) / SUITABILITY_FACTOR; // [-30, 311]
|
||||
suitability[cellId] = total;
|
||||
|
||||
// cell rural population is suitability adjusted by cell area
|
||||
const population = suitability > 0 ? suitability * (cells.area[cellId] / meanArea) : 0;
|
||||
|
||||
cells.pop[cellId] = population;
|
||||
cells.s[cellId] = suitability;
|
||||
population[cellId] = total > 0 ? total * (cells.area[cellId] / meanArea) : 0;
|
||||
}
|
||||
|
||||
function getHabitabilityBonus(cellId: number) {
|
||||
|
|
@ -57,7 +57,10 @@ export function rankCells(pack: IPack) {
|
|||
if (!isCoastal(cellId)) return 0;
|
||||
|
||||
const havenCell = cells.haven[cellId];
|
||||
const {group} = features[cells.f[havenCell]];
|
||||
const feature = features[cells.f[havenCell]];
|
||||
if (!feature) return 0;
|
||||
|
||||
const {group} = feature;
|
||||
|
||||
// lake coast
|
||||
if (group === "freshwater") return 30;
|
||||
|
|
@ -78,4 +81,6 @@ export function rankCells(pack: IPack) {
|
|||
}
|
||||
|
||||
TIME && console.timeEnd("rankCells");
|
||||
|
||||
return {s: suitability, pop: population};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue