mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
refactor: render provinces
This commit is contained in:
parent
4dc5648310
commit
b2ab699843
12 changed files with 136 additions and 127 deletions
|
|
@ -143,9 +143,10 @@ export function createPack(grid: IGrid): IPack {
|
|||
}
|
||||
});
|
||||
|
||||
const {provinceIds, provinces} = generateProvinces(states, burgs, cultures, mergedFeatures, {
|
||||
const {provinceIds, provinces} = generateProvinces(states, burgs, cultures, mergedFeatures, vertices, {
|
||||
i: cells.i,
|
||||
c: cells.c,
|
||||
v: cells.v,
|
||||
h: heights,
|
||||
t: distanceField,
|
||||
f: featureIds,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import {brighter, getMixedColor} from "utils/colorUtils";
|
|||
import {gauss, P, rw} from "utils/probabilityUtils";
|
||||
import {isBurg, isState} from "utils/typeUtils";
|
||||
import {provinceForms} from "./config";
|
||||
import {generateProvinceName, generateProvinceEmblem} from "./utils";
|
||||
|
||||
const {COA, Names} = window;
|
||||
|
||||
|
|
@ -37,7 +36,7 @@ export function generateCoreProvinces(states: TStates, burgs: TBurgs, cultures:
|
|||
const color = brighter(getMixedColor(state.color, 0.2), 0.3);
|
||||
const coa = generateEmblem(nameByBurg, burgEmblem, type, cultures, cultureId, state);
|
||||
|
||||
provinces.push({i: provinces.length, name, formName, center, burg, state: state.i, fullName, color, coa});
|
||||
provinces.push({i: provinces.length + 1, name, formName, center, burg, state: state.i, fullName, color, coa});
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -3,13 +3,15 @@ import {getInputNumber} from "utils/nodeUtils";
|
|||
import {expandProvinces} from "./expandProvinces";
|
||||
import {generateCoreProvinces} from "./generateCoreProvinces";
|
||||
import {generateWildProvinces} from "./generateWildProvinces";
|
||||
import {specifyProvinces} from "./specifyProvinces";
|
||||
|
||||
export function generateProvinces(
|
||||
states: TStates,
|
||||
burgs: TBurgs,
|
||||
cultures: TCultures,
|
||||
features: TPackFeatures,
|
||||
cells: Pick<IPack["cells"], "i" | "c" | "h" | "t" | "f" | "culture" | "state" | "burg">
|
||||
vertices: IGraphVertices,
|
||||
cells: Pick<IPack["cells"], "i" | "c" | "v" | "h" | "t" | "f" | "culture" | "state" | "burg">
|
||||
): {provinceIds: Uint16Array; provinces: TProvinces} {
|
||||
TIME && console.time("generateProvinces");
|
||||
|
||||
|
|
@ -30,7 +32,7 @@ export function generateProvinces(
|
|||
cells
|
||||
}); // mutates provinceIds
|
||||
|
||||
const provinces: TProvinces = [0, ...coreProvinces, ...wildProvinces];
|
||||
const provinces = specifyProvinces(provinceIds, coreProvinces, wildProvinces, vertices, cells.c, cells.v);
|
||||
|
||||
TIME && console.timeEnd("generateProvinces");
|
||||
return {provinceIds, provinces};
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ export function generateWildProvinces({
|
|||
|
||||
let noProvinceCellsInState = noProvinceCells.filter(i => cells.state[i] === state.i);
|
||||
while (noProvinceCellsInState.length) {
|
||||
const provinceId = coreProvinces.length + wildProvinces.length;
|
||||
const provinceId = coreProvinces.length + wildProvinces.length + 1;
|
||||
const burgCell = noProvinceCellsInState.find(i => cells.burg[i]);
|
||||
const center = burgCell || noProvinceCellsInState[0];
|
||||
const cultureId = cells.culture[center];
|
||||
|
|
|
|||
20
src/scripts/generation/pack/provinces/specifyProvinces.ts
Normal file
20
src/scripts/generation/pack/provinces/specifyProvinces.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import {getPolesOfInaccessibility} from "scripts/getPolesOfInaccessibility";
|
||||
|
||||
export function specifyProvinces(
|
||||
provinceIds: Uint16Array,
|
||||
coreProvinces: IProvince[],
|
||||
wildProvinces: IProvince[],
|
||||
vertices: IGraphVertices,
|
||||
cellNeighbors: number[][],
|
||||
cellVertices: number[][]
|
||||
): TProvinces {
|
||||
const getType = (cellId: number) => provinceIds[cellId];
|
||||
const poles = getPolesOfInaccessibility({vertices, getType, cellNeighbors, cellVertices});
|
||||
|
||||
const provinces = [...coreProvinces, ...wildProvinces].map(province => {
|
||||
const pole = poles[province.i];
|
||||
return {...province, pole};
|
||||
});
|
||||
|
||||
return [0, ...provinces];
|
||||
}
|
||||
64
src/scripts/getPolesOfInaccessibility.ts
Normal file
64
src/scripts/getPolesOfInaccessibility.ts
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
import polylabel from "polylabel";
|
||||
|
||||
import {TIME} from "config/logging";
|
||||
import {connectVertices} from "./connectVertices";
|
||||
|
||||
interface IGetPolesProps {
|
||||
vertices: IGraphVertices;
|
||||
cellNeighbors: number[][];
|
||||
cellVertices: number[][];
|
||||
getType: (cellId: number) => number;
|
||||
}
|
||||
|
||||
export function getPolesOfInaccessibility(props: IGetPolesProps) {
|
||||
TIME && console.time("getPolesOfInaccessibility");
|
||||
const multiPolygons = getMultiPolygons(props);
|
||||
|
||||
const poles: Dict<TPoint> = Object.fromEntries(
|
||||
Object.entries(multiPolygons).map(([id, multiPolygon]) => {
|
||||
const [x, y] = polylabel(multiPolygon, 20);
|
||||
return [id, [x, y]];
|
||||
})
|
||||
);
|
||||
|
||||
TIME && console.timeEnd("getPolesOfInaccessibility");
|
||||
return poles;
|
||||
}
|
||||
|
||||
function getMultiPolygons({vertices, getType, cellNeighbors, cellVertices}: IGetPolesProps) {
|
||||
const multiPolygons: Dict<number[][][]> = {};
|
||||
|
||||
const checkedCells = new Uint8Array(cellNeighbors.length);
|
||||
const addToChecked = (cellId: number) => {
|
||||
checkedCells[cellId] = 1;
|
||||
};
|
||||
const isChecked = (cellId: number) => checkedCells[cellId] === 1;
|
||||
|
||||
for (let cellId = 0; cellId < cellNeighbors.length; cellId++) {
|
||||
if (isChecked(cellId) || getType(cellId) === 0) continue;
|
||||
addToChecked(cellId);
|
||||
|
||||
const type = getType(cellId);
|
||||
const ofSameType = (cellId: number) => getType(cellId) === type;
|
||||
const ofDifferentType = (cellId: number) => getType(cellId) !== type;
|
||||
|
||||
const onborderCell = cellNeighbors[cellId].find(ofDifferentType);
|
||||
if (onborderCell === undefined) continue;
|
||||
|
||||
const startingVertex = cellVertices[cellId].find(v => vertices.c[v].some(ofDifferentType));
|
||||
if (startingVertex === undefined) throw new Error(`Starting vertex for cell ${cellId} is not found`);
|
||||
|
||||
const vertexChain = connectVertices({vertices, startingVertex, ofSameType, addToChecked, closeRing: true});
|
||||
if (vertexChain.length < 3) continue;
|
||||
|
||||
addPolygon(type, vertexChain);
|
||||
}
|
||||
|
||||
return multiPolygons;
|
||||
|
||||
function addPolygon(id: number, vertexChain: number[]) {
|
||||
if (!multiPolygons[id]) multiPolygons[id] = [];
|
||||
const polygon = vertexChain.map(vertex => vertices.p[vertex]);
|
||||
multiPolygons[id].push(polygon);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue