mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
refactor: generate states cleanup
This commit is contained in:
parent
c2fc0679ad
commit
ff974a4fd0
16 changed files with 98 additions and 64 deletions
|
|
@ -4,13 +4,22 @@ import {TIME, WARN} from "config/logging";
|
|||
|
||||
const {Names} = window;
|
||||
|
||||
export function createCapitals(statesNumber: number, scoredCellIds: UintArray, burgIds: Uint16Array) {
|
||||
export function createCapitals(
|
||||
statesNumber: number,
|
||||
scoredCellIds: UintArray,
|
||||
burgIds: Uint16Array,
|
||||
cultures: TCultures,
|
||||
cells: Pick<IPack["cells"], "p" | "f" | "culture">
|
||||
) {
|
||||
TIME && console.time("createCapitals");
|
||||
|
||||
const capitals = placeCapitals(statesNumber, scoredCellIds).map((cellId, index) => {
|
||||
const capitalCells = placeCapitals(statesNumber, scoredCellIds, cells.p);
|
||||
|
||||
const capitals = capitalCells.map((cellId, index) => {
|
||||
const id = index + 1;
|
||||
const cultureId = cells.culture[cellId];
|
||||
const name: string = Names.getCultureShort(cultureId);
|
||||
const nameBase = cultures[cultureId].base;
|
||||
const name: string = Names.getBaseShort(nameBase);
|
||||
const featureId = cells.f[cellId];
|
||||
|
||||
return {i: id, cell: cellId, culture: cultureId, name, feature: featureId, capital: 1 as Logical};
|
||||
|
|
@ -24,13 +33,13 @@ export function createCapitals(statesNumber: number, scoredCellIds: UintArray, b
|
|||
return capitals;
|
||||
}
|
||||
|
||||
function placeCapitals(statesNumber: number, scoredCellIds: UintArray) {
|
||||
function placeCapitals(statesNumber: number, scoredCellIds: UintArray, points: TPoints) {
|
||||
function attemptToPlaceCapitals(spacing: number): number[] {
|
||||
const capitalCells: number[] = [];
|
||||
const capitalsQuadtree = d3.quadtree();
|
||||
|
||||
for (const cellId of scoredCellIds) {
|
||||
const [x, y] = cells.p[cellId];
|
||||
const [x, y] = points[cellId];
|
||||
|
||||
if (capitalsQuadtree.find(x, y, spacing) === undefined) {
|
||||
capitalCells.push(cellId);
|
||||
|
|
|
|||
|
|
@ -14,22 +14,17 @@ export function createStates(capitals: TCapitals, cultures: TCultures) {
|
|||
TIME && console.time("createStates");
|
||||
|
||||
const colors = getColors(capitals.length);
|
||||
const each5th = each(5); // select each 5th element
|
||||
const powerInput = getInputNumber("powerInput");
|
||||
|
||||
const states = capitals.map((capital, index) => {
|
||||
const {cell: cellId, culture: cultureId, name: capitalName, i: capitalId} = capital;
|
||||
const id = index + 1;
|
||||
|
||||
const useCapitalName = capitalName.length < 9 && each5th(cellId);
|
||||
const basename = useCapitalName ? capitalName : Names.getCultureShort(cultureId);
|
||||
const name: string = Names.getState(basename, cultureId);
|
||||
const name = getStateName(cellId, capitalName, cultureId, cultures);
|
||||
const color = colors[index];
|
||||
|
||||
const type = (cultures[cultureId] as ICulture).type;
|
||||
const expansionism = rn(Math.random() * powerInput + 1, 1);
|
||||
|
||||
const shield = COA.getShield(cultureId, null);
|
||||
const shield = COA.getShield(cultureId, null, cultures);
|
||||
const coa = {...COA.generate(null, null, null, type), shield};
|
||||
|
||||
return {i: id, center: cellId, type, name, color, expansionism, capital: capitalId, culture: cultureId, coa};
|
||||
|
|
@ -38,3 +33,11 @@ export function createStates(capitals: TCapitals, cultures: TCultures) {
|
|||
TIME && console.timeEnd("createStates");
|
||||
return [NEUTRALS, ...states];
|
||||
}
|
||||
|
||||
function getStateName(cellId: number, capitalName: string, cultureId: number, cultures: TCultures) {
|
||||
const useCapitalName = capitalName.length < 9 && each(5)(cellId);
|
||||
const nameBase = cultures[cultureId].base;
|
||||
const basename: string = useCapitalName ? capitalName : Names.getBaseShort(nameBase);
|
||||
|
||||
return Names.getState(basename, basename);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,24 +7,31 @@ import {gauss} from "utils/probabilityUtils";
|
|||
|
||||
const {Names} = window;
|
||||
|
||||
export function createTowns(scoredCellIds: UintArray, burgIds: Uint16Array) {
|
||||
export function createTowns(
|
||||
burgIds: Uint16Array,
|
||||
cultures: TCultures,
|
||||
cells: Pick<IPack["cells"], "p" | "i" | "f" | "s" | "culture">
|
||||
) {
|
||||
TIME && console.time("createTowns");
|
||||
|
||||
const townsNumber = getTownsNumber();
|
||||
if (townsNumber === 0) return [];
|
||||
|
||||
// randomize cells score a bit for more natural towns placement
|
||||
const randomizeScore = (suitability: number) => suitability * gauss(1, 3, 0, 20, 3);
|
||||
const scores = new Int16Array(cells.s.map(randomizeScore));
|
||||
|
||||
// take populated cells without capitals
|
||||
const scoredCellsIds = cells.i.filter(i => scores[i] > 0 && cells.culture[i] && !burgIds[i]);
|
||||
scoredCellsIds.sort((a, b) => scores[b] - scores[a]); // sort by randomized suitability score
|
||||
const scoredCellIds = cells.i.filter(i => scores[i] > 0 && cells.culture[i] && !burgIds[i]);
|
||||
scoredCellIds.sort((a, b) => scores[b] - scores[a]); // sort by randomized suitability score
|
||||
|
||||
const towns = placeTowns(townsNumber, scoredCellIds).map((cellId, index) => {
|
||||
const townsNumber = getTownsNumber();
|
||||
if (townsNumber === 0) return [];
|
||||
|
||||
const townCells = placeTowns(townsNumber, scoredCellIds, cells.p);
|
||||
|
||||
const towns = townCells.map((cellId, index) => {
|
||||
const id = index + 1;
|
||||
const cultureId = cells.culture[cellId];
|
||||
const name: string = Names.getCulture(cultureId);
|
||||
const namesbase = cultures[cultureId].base;
|
||||
const name: string = Names.getBase(namesbase);
|
||||
const featureId = cells.f[cellId];
|
||||
|
||||
return {i: id, cell: cellId, culture: cultureId, name, feature: featureId, capital: 0 as Logical};
|
||||
|
|
@ -40,13 +47,13 @@ export function createTowns(scoredCellIds: UintArray, burgIds: Uint16Array) {
|
|||
function getTownsNumber() {
|
||||
const inputTownsNumber = getInputNumber("manorsInput");
|
||||
const shouldAutoDefine = inputTownsNumber === 1000;
|
||||
const desiredTownsNumber = shouldAutoDefine ? rn(scoredCellsIds.length / 5 ** 0.8) : inputTownsNumber;
|
||||
const desiredTownsNumber = shouldAutoDefine ? rn(scoredCellIds.length / 5 ** 0.8) : inputTownsNumber;
|
||||
|
||||
return Math.min(desiredTownsNumber, scoredCellsIds.length);
|
||||
return Math.min(desiredTownsNumber, scoredCellIds.length);
|
||||
}
|
||||
}
|
||||
|
||||
function placeTowns(townsNumber: number, scoredCellIds: UintArray) {
|
||||
function placeTowns(townsNumber: number, scoredCellIds: UintArray, points: TPoints) {
|
||||
function attemptToPlaceTowns(spacing: number): number[] {
|
||||
const townCells: number[] = [];
|
||||
const townsQuadtree = d3.quadtree();
|
||||
|
|
@ -54,7 +61,7 @@ function placeTowns(townsNumber: number, scoredCellIds: UintArray) {
|
|||
const randomizeScaping = (spacing: number) => spacing * gauss(1, 0.3, 0.2, 2, 2);
|
||||
|
||||
for (const cellId of scoredCellIds) {
|
||||
const [x, y] = cells.p[cellId];
|
||||
const [x, y] = points[cellId];
|
||||
|
||||
// randomize min spacing a bit to make placement not that uniform
|
||||
const currentSpacing = randomizeScaping(spacing);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import {WARN} from "config/logging";
|
||||
import {pick} from "utils/functionUtils";
|
||||
import {getInputNumber} from "utils/nodeUtils";
|
||||
import {NEUTRALS, NO_BURG} from "./config";
|
||||
import {createCapitals} from "./createCapitals";
|
||||
|
|
@ -25,9 +26,9 @@ export function generateBurgsAndStates(
|
|||
const statesNumber = getStatesNumber(scoredCellIds.length);
|
||||
if (statesNumber === 0) return {burgIds, burgs: [NO_BURG], states: [NEUTRALS]};
|
||||
|
||||
const capitals = createCapitals(statesNumber, scoredCellIds, burgIds);
|
||||
const capitals = createCapitals(statesNumber, scoredCellIds, burgIds, cultures, pick(cells, "p", "f", "culture"));
|
||||
const states = createStates(capitals, cultures);
|
||||
const towns = createTowns(scoredCellIds, burgIds);
|
||||
const towns = createTowns(burgIds, cultures, pick(cells, "p", "i", "f", "s", "culture"));
|
||||
|
||||
expandStates();
|
||||
// normalizeStates();
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ export function specifyBurgs(capitals: TCapitals, towns: TTowns, roadScores: Uin
|
|||
|
||||
if (stateId === 0) {
|
||||
const baseCoa = COA.generate(null, 0, null, coaType);
|
||||
const shield = COA.getShield(cultureId, stateId);
|
||||
const shield = COA.getShield(cultureId, stateId, cultures, states);
|
||||
return {...baseCoa, shield};
|
||||
}
|
||||
|
||||
|
|
@ -111,7 +111,7 @@ export function specifyBurgs(capitals: TCapitals, towns: TTowns, roadScores: Uin
|
|||
const kinship = defineKinshipToStateEmblem();
|
||||
|
||||
const baseCoa = COA.generate(stateCOA, kinship, null, coaType);
|
||||
const shield = COA.getShield(cultureId, stateId);
|
||||
const shield = COA.getShield(cultureId, stateId, cultures, states);
|
||||
return {...baseCoa, shield};
|
||||
|
||||
function defineKinshipToStateEmblem() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue