mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-16 17:31:24 +01:00
refactor: generateCoreProvinces
This commit is contained in:
parent
2b61ac6a0f
commit
fe2f8428ad
11 changed files with 129 additions and 19 deletions
|
|
@ -15,6 +15,7 @@
|
|||
"@rollup/plugin-node-resolve": "^13.3.0",
|
||||
"@rollup/plugin-replace": "^4.0.0",
|
||||
"@types/d3": "^5.9.0",
|
||||
"@types/d3-array": "^3.0.3",
|
||||
"@types/delaunator": "^5.0.0",
|
||||
"@types/jquery": "^3.5.14",
|
||||
"@types/jqueryui": "^1.12.16",
|
||||
|
|
@ -35,6 +36,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"d3": "5.8.0",
|
||||
"d3-array": "^3.2.0",
|
||||
"delaunator": "^5.0.0",
|
||||
"flatqueue": "^2.0.3",
|
||||
"lineclip": "^1.1.5",
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
|
|||
1
src/types/pack/burgs.d.ts
vendored
1
src/types/pack/burgs.d.ts
vendored
|
|
@ -3,6 +3,7 @@ interface IBurg {
|
|||
name: string;
|
||||
feature: number;
|
||||
state: number;
|
||||
culture: number;
|
||||
cell: number;
|
||||
x: number;
|
||||
y: number;
|
||||
|
|
|
|||
6
src/types/pack/provinces.d.ts
vendored
6
src/types/pack/provinces.d.ts
vendored
|
|
@ -1,7 +1,13 @@
|
|||
interface IProvince {
|
||||
i: number;
|
||||
name: string;
|
||||
burg: number;
|
||||
formName: string;
|
||||
fullName: string;
|
||||
color: Hex | CssUrls;
|
||||
state: number;
|
||||
center: number;
|
||||
coa: ICoa | string;
|
||||
removed?: boolean;
|
||||
}
|
||||
|
||||
|
|
|
|||
4
src/types/pack/states.d.ts
vendored
4
src/types/pack/states.d.ts
vendored
|
|
@ -7,7 +7,7 @@ interface IState {
|
|||
type: TCultureType;
|
||||
culture: number;
|
||||
expansionism: number;
|
||||
form: string;
|
||||
form: TStateForm;
|
||||
formName: string;
|
||||
fullName: string;
|
||||
coa: ICoa | string;
|
||||
|
|
@ -38,6 +38,8 @@ interface ICoa {
|
|||
t1: string;
|
||||
}
|
||||
|
||||
type TStateForm = "Monarchy" | "Republic" | "Theocracy" | "Union" | "Anarchy";
|
||||
|
||||
type TRelation =
|
||||
| "Ally"
|
||||
| "Friendly"
|
||||
|
|
|
|||
17
yarn.lock
17
yarn.lock
|
|
@ -155,6 +155,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-1.2.9.tgz#c7dc78992cd8ca5c850243a265fd257ea56df1fa"
|
||||
integrity sha512-E/7RgPr2ylT5dWG0CswMi9NpFcjIEDqLcUSBgNHe/EMahfqYaTx4zhcggG3khqoEB/leY4Vl6nTSbwLUPjXceA==
|
||||
|
||||
"@types/d3-array@^3.0.3":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.0.3.tgz#87d990bf504d14ad6b16766979d04e943c046dac"
|
||||
integrity sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ==
|
||||
|
||||
"@types/d3-axis@^1":
|
||||
version "1.0.16"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-axis/-/d3-axis-1.0.16.tgz#93d7a28795c2f8b0e2fd550fcc4d29b7f174e693"
|
||||
|
|
@ -738,6 +743,13 @@ d3-array@1, d3-array@^1.1.1, d3-array@^1.2.0:
|
|||
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f"
|
||||
integrity sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==
|
||||
|
||||
d3-array@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.0.tgz#15bf96cd9b7333e02eb8de8053d78962eafcff14"
|
||||
integrity sha512-3yXFQo0oG3QCxbF06rMPFyGRMGJNS7NvsV1+2joOjbBE+9xvWQ8+GcMJAjRCzw06zQ3/arXeJgbPYcjUCuC+3g==
|
||||
dependencies:
|
||||
internmap "1 - 2"
|
||||
|
||||
d3-axis@1:
|
||||
version "1.0.12"
|
||||
resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-1.0.12.tgz#cdf20ba210cfbb43795af33756886fb3638daac9"
|
||||
|
|
@ -1469,6 +1481,11 @@ inherits@2, inherits@^2.0.3, inherits@~2.0.3:
|
|||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
"internmap@1 - 2":
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009"
|
||||
integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==
|
||||
|
||||
is-builtin-module@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.1.0.tgz#6fdb24313b1c03b75f8b9711c0feb8c30b903b00"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue