mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
refactor: generateCoreProvinces
This commit is contained in:
parent
2b61ac6a0f
commit
fe2f8428ad
11 changed files with 129 additions and 19 deletions
|
|
@ -40,7 +40,7 @@ export function defineStateForm(
|
|||
const generic = {Monarchy: 25, Republic: 2, Union: 1};
|
||||
const naval = {Monarchy: 6, Republic: 2, Union: 1};
|
||||
|
||||
function defineForm(type: TCultureType, areaTier: AreaTiers) {
|
||||
function defineForm(type: TCultureType, areaTier: AreaTiers): TStateForm {
|
||||
const isAnarchy = P((1 - areaTier / 5) / 100); // [1% - 0.2%] chance
|
||||
if (isAnarchy) return "Anarchy";
|
||||
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ export function createPack(grid: IGrid): IPack {
|
|||
}
|
||||
});
|
||||
|
||||
const {provinceIds, provinces} = generateProvinces();
|
||||
const {provinceIds, provinces} = generateProvinces(states, burgs, cultures, {i: cells.i});
|
||||
|
||||
// BurgsAndStates.generateProvinces();
|
||||
// BurgsAndStates.defineBurgFeatures();
|
||||
|
|
|
|||
8
src/scripts/generation/pack/provinces/config.ts
Normal file
8
src/scripts/generation/pack/provinces/config.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
export const provinceForms = {
|
||||
Monarchy: {County: 22, Earldom: 6, Shire: 2, Landgrave: 2, Margrave: 2, Barony: 2, Captaincy: 1, Seneschalty: 1},
|
||||
Republic: {Province: 6, Department: 2, Governorate: 2, District: 1, Canton: 1, Prefecture: 1},
|
||||
Theocracy: {Parish: 3, Deanery: 1},
|
||||
Union: {Province: 1, State: 1, Canton: 1, Republic: 1, County: 1, Council: 1},
|
||||
Anarchy: {Council: 1, Commune: 1, Community: 1, Tribe: 1},
|
||||
Wild: {Territory: 10, Land: 5, Region: 2, Tribe: 1, Clan: 1, Dependency: 1, Area: 1}
|
||||
};
|
||||
9
src/scripts/generation/pack/provinces/expandProvinces.ts
Normal file
9
src/scripts/generation/pack/provinces/expandProvinces.ts
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import {gauss} from "utils/probabilityUtils";
|
||||
|
||||
export function expandProvinces(percentage: number, cells: Pick<IPack["cells"], "i">) {
|
||||
const provinceIds = new Uint16Array(cells.i.length);
|
||||
|
||||
const maxGrowth = percentage === 100 ? 1000 : gauss(20, 5, 5, 100) * percentage ** 0.5;
|
||||
|
||||
return provinceIds;
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
import {group} from "d3-array";
|
||||
|
||||
import {brighter, getMixedColor} from "utils/colorUtils";
|
||||
import {gauss, P, rw} from "utils/probabilityUtils";
|
||||
import {isBurg, isState} from "utils/typeUtils";
|
||||
import {provinceForms} from "./config";
|
||||
|
||||
const {COA, Names} = window;
|
||||
|
||||
export function generateCoreProvinces(states: TStates, burgs: TBurgs, cultures: TCultures, percentage: number) {
|
||||
const provinces = [] as IProvince[];
|
||||
|
||||
const validBurgs = burgs.filter(isBurg);
|
||||
const burgsToStateMap = group(validBurgs, (burg: IBurg) => burg.state);
|
||||
|
||||
states.filter(isState).forEach(state => {
|
||||
const stateBurgs = burgsToStateMap.get(state.i);
|
||||
if (!stateBurgs || stateBurgs.length < 2) return; // at least 2 provinces are required
|
||||
|
||||
stateBurgs
|
||||
.sort((a, b) => b.population * gauss(1, 0.2, 0.5, 1.5, 3) - a.population)
|
||||
.sort((a, b) => b.capital - a.capital);
|
||||
|
||||
const provincesNumber = Math.max(Math.ceil((stateBurgs.length * percentage) / 100), 2);
|
||||
const formsPool: Dict<number> = structuredClone(provinceForms[state.form]);
|
||||
|
||||
for (let i = 0; i < provincesNumber; i++) {
|
||||
const {i: burg, cell: center, culture: cultureId, coa: burgEmblem, name: burgName, type} = stateBurgs[i];
|
||||
const nameByBurg = P(0.5);
|
||||
const name = nameByBurg ? burgName : generateName(cultureId, cultures);
|
||||
3;
|
||||
const formName = rw(formsPool);
|
||||
formsPool[formName] += 10; // increase chance to get the same form again
|
||||
|
||||
const fullName = name + " " + formName;
|
||||
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});
|
||||
}
|
||||
});
|
||||
|
||||
return provinces;
|
||||
}
|
||||
|
||||
function generateName(cultureId: number, cultures: TCultures) {
|
||||
const base = cultures[cultureId].base;
|
||||
return Names.getState(Names.getBaseShort(base), base);
|
||||
}
|
||||
|
||||
function generateEmblem(
|
||||
nameByBurg: boolean,
|
||||
burgEmblem: ICoa | "string",
|
||||
type: TCultureType,
|
||||
cultures: TCultures,
|
||||
cultureId: number,
|
||||
state: IState
|
||||
) {
|
||||
const kinship = nameByBurg ? 0.8 : 0.4;
|
||||
const coa: ICoa = COA.generate(burgEmblem, kinship, null, type);
|
||||
|
||||
const cultureShield = cultures[cultureId].shield;
|
||||
const stateShield = (state.coa as ICoa)?.shield;
|
||||
coa.shield = COA.getShield(cultureShield, stateShield);
|
||||
|
||||
return coa;
|
||||
}
|
||||
|
|
@ -1,26 +1,24 @@
|
|||
import {TIME} from "config/logging";
|
||||
import {getInputNumber} from "utils/nodeUtils";
|
||||
import {gauss} from "utils/probabilityUtils";
|
||||
import {expandProvinces} from "./expandProvinces";
|
||||
import {generateCoreProvinces} from "./generateCoreProvinces";
|
||||
|
||||
const forms = {
|
||||
Monarchy: {County: 22, Earldom: 6, Shire: 2, Landgrave: 2, Margrave: 2, Barony: 2, Captaincy: 1, Seneschalty: 1},
|
||||
Republic: {Province: 6, Department: 2, Governorate: 2, District: 1, Canton: 1, Prefecture: 1},
|
||||
Theocracy: {Parish: 3, Deanery: 1},
|
||||
Union: {Province: 1, State: 1, Canton: 1, Republic: 1, County: 1, Council: 1},
|
||||
Anarchy: {Council: 1, Commune: 1, Community: 1, Tribe: 1},
|
||||
Wild: {Territory: 10, Land: 5, Region: 2, Tribe: 1, Clan: 1, Dependency: 1, Area: 1}
|
||||
};
|
||||
|
||||
export function generateProvinces(states: TStates, cells: Pick<IPack["cells"], "i">) {
|
||||
export function generateProvinces(
|
||||
states: TStates,
|
||||
burgs: TBurgs,
|
||||
cultures: TCultures,
|
||||
cells: Pick<IPack["cells"], "i">
|
||||
) {
|
||||
TIME && console.time("generateProvinces");
|
||||
|
||||
const provinceIds = new Uint16Array(cells.i.length);
|
||||
const provinces = [] as TProvinces;
|
||||
|
||||
const percentage = getInputNumber("provincesInput");
|
||||
if (states.length < 2 || percentage === 0) return {provinceIds, provinces};
|
||||
if (states.length < 2 || percentage === 0)
|
||||
return {provinceIds: new Uint16Array(cells.i.length), provinces: [] as TProvinces[]};
|
||||
|
||||
const maxGrowth = percentage === 100 ? 1000 : gauss(20, 5, 5, 100) * percentage ** 0.5;
|
||||
const coreProvinces = generateCoreProvinces(states, burgs, cultures, percentage);
|
||||
const provinceIds = expandProvinces(percentage, cells);
|
||||
|
||||
const provinces = [...coreProvinces];
|
||||
|
||||
TIME && console.timeEnd("generateProvinces");
|
||||
return {provinceIds, provinces};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue