mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
refactor: generate historical conflicts
This commit is contained in:
parent
a2192fb984
commit
9b3a3f2e48
11 changed files with 81 additions and 28 deletions
|
|
@ -53,13 +53,14 @@ async function generate(options?: IGenerationOptions) {
|
|||
window.mapCoordinates = calculateMapCoordinates();
|
||||
|
||||
const newGrid = await createGrid(grid, precreatedGraph);
|
||||
const newPack = createPack(newGrid);
|
||||
const {pack: newPack, conflicts} = createPack(newGrid);
|
||||
|
||||
// TODO: draw default ruler
|
||||
|
||||
// redefine global grid and pack
|
||||
grid = newGrid;
|
||||
pack = newPack;
|
||||
events = {conflicts};
|
||||
|
||||
// temp rendering for debug
|
||||
// renderLayer("cells");
|
||||
|
|
|
|||
|
|
@ -113,3 +113,15 @@ export const relations = {
|
|||
farStates: {Friendly: 1, Neutral: 12, Suspicion: 2},
|
||||
navalToNaval: {Neutral: 2, Suspicion: 2, Rival: 1}
|
||||
};
|
||||
|
||||
export const conflictTypes = {
|
||||
War: 6,
|
||||
Conflict: 2,
|
||||
Campaign: 4,
|
||||
Invasion: 2,
|
||||
Rebellion: 2,
|
||||
Conquest: 2,
|
||||
Intervention: 1,
|
||||
Expedition: 1,
|
||||
Crusade: 1
|
||||
};
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ export function generateBurgsAndStates(
|
|||
rivers: Omit<IRiver, "name" | "basin" | "type">[],
|
||||
vertices: IGraphVertices,
|
||||
cells: TCellsData
|
||||
): {burgIds: Uint16Array; stateIds: Uint16Array; burgs: TBurgs; states: TStates} {
|
||||
): {burgIds: Uint16Array; stateIds: Uint16Array; burgs: TBurgs; states: TStates; conflicts: IConflict[]} {
|
||||
const cellsNumber = cells.i.length;
|
||||
|
||||
const scoredCellIds = getScoredCellIds();
|
||||
|
|
@ -31,7 +31,8 @@ export function generateBurgsAndStates(
|
|||
burgIds: new Uint16Array(cellsNumber),
|
||||
stateIds: new Uint16Array(cellsNumber),
|
||||
burgs: [NO_BURG],
|
||||
states: [NEUTRALS]
|
||||
states: [NEUTRALS],
|
||||
conflicts: []
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -69,9 +70,9 @@ export function generateBurgsAndStates(
|
|||
|
||||
const statistics = collectStatistics({...cells, state: stateIds, burg: burgIds}, burgs);
|
||||
const diplomacy = generateRelations(statesData, statistics, pick(cells, "f"));
|
||||
const states = specifyStates(statesData, statistics, diplomacy, cultures, burgs);
|
||||
const {states, conflicts} = specifyStates(statesData, statistics, diplomacy, cultures, burgs);
|
||||
|
||||
return {burgIds, stateIds, burgs, states};
|
||||
return {burgIds, stateIds, burgs, states, conflicts};
|
||||
|
||||
function getScoredCellIds() {
|
||||
const score = new Int16Array(cells.s.map(s => s * Math.random()));
|
||||
|
|
|
|||
|
|
@ -1,12 +1,22 @@
|
|||
import * as d3 from "d3";
|
||||
|
||||
import {TIME} from "config/logging";
|
||||
import {list, trimVowels} from "utils/languageUtils";
|
||||
import {gauss, ra} from "utils/probabilityUtils";
|
||||
import {getAdjective, list, trimVowels} from "utils/languageUtils";
|
||||
import {gauss, P, ra, rw} from "utils/probabilityUtils";
|
||||
import {conflictTypes} from "./config";
|
||||
|
||||
export function generateConflicts(states: IState[]) {
|
||||
const {Names} = window;
|
||||
|
||||
export function generateConflicts(states: IState[], cultures: TCultures): IConflict[] {
|
||||
TIME && console.time("generateConflicts");
|
||||
const historicalWars = generateHistoricalConflicts(states, cultures);
|
||||
const ongoingWars = generateOngoingConflicts(states);
|
||||
|
||||
TIME && console.timeEnd("generateConflicts");
|
||||
return [...historicalWars, ...ongoingWars].sort((a, b) => a.start - b.start);
|
||||
}
|
||||
|
||||
function generateOngoingConflicts(states: IState[]): IConflict[] {
|
||||
const statesMap = new Map(states.map(state => [state.i, state]));
|
||||
const wars: IConflict[] = [];
|
||||
|
||||
|
|
@ -37,7 +47,6 @@ export function generateConflicts(states: IState[]) {
|
|||
wars.push(war);
|
||||
}
|
||||
|
||||
TIME && console.timeEnd("generateConflicts");
|
||||
return wars;
|
||||
|
||||
function simulateWar(attacker: IState, defender: IState): IConflict {
|
||||
|
|
@ -134,7 +143,7 @@ export function generateConflicts(states: IState[]) {
|
|||
const name = `${attacker.name}-${trimVowels(defender.name)}ian War`;
|
||||
const parties = {attackers: attackers.map(({i}) => i), defenders: defenders.map(({i}) => i)};
|
||||
const start = options.year - gauss(2, 2, 0, 5);
|
||||
return {type: "conflict", name, start, parties, description: history.join(". ")};
|
||||
return {name, start, parties, description: history.join(". ")};
|
||||
}
|
||||
|
||||
function getStatePower(state: IState) {
|
||||
|
|
@ -156,3 +165,31 @@ export function generateConflicts(states: IState[]) {
|
|||
return "minor";
|
||||
}
|
||||
}
|
||||
|
||||
function generateHistoricalConflicts(states: IState[], cultures: TCultures): IConflict[] {
|
||||
const statesMap = new Map(states.map(state => [state.i, state]));
|
||||
const isConflict = (conflict: IConflict | null): conflict is IConflict => conflict !== null;
|
||||
const getNameBase = (cultureId: number) => cultures[cultureId].base;
|
||||
return states.map(generateConflicts).flat();
|
||||
|
||||
function generateConflicts(state: IState): IConflict[] {
|
||||
const conflicts = state.neighbors
|
||||
.map((neighbor, index) => {
|
||||
if (index && P(0.8)) return null;
|
||||
const enemy = statesMap.get(neighbor);
|
||||
if (!enemy) return null;
|
||||
|
||||
const properName = P(0.8) ? enemy.name : Names.getBaseShort(getNameBase(enemy.culture));
|
||||
const name = getAdjective(properName) + " " + rw(conflictTypes);
|
||||
const start = gauss(options.year - 100, 150, 1, options.year - 6);
|
||||
const end = start + gauss(4, 5, 1, options.year - start - 1);
|
||||
const parties = {attackers: [state.i], defenders: [enemy.i]};
|
||||
|
||||
const conflict: IConflict = {name, start, end, parties};
|
||||
return conflict;
|
||||
})
|
||||
.filter(isConflict);
|
||||
|
||||
return conflicts;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export function specifyStates(
|
|||
diplomacy: TDiplomacy,
|
||||
cultures: TCultures,
|
||||
burgs: TBurgs
|
||||
): TStates {
|
||||
): {states: TStates; conflicts: IConflict[]} {
|
||||
TIME && console.time("specifyStates");
|
||||
|
||||
const colors = defineStateColors(statistics);
|
||||
|
|
@ -56,10 +56,8 @@ export function specifyStates(
|
|||
};
|
||||
});
|
||||
|
||||
const wars = generateConflicts(states); // mutates states
|
||||
console.log(wars);
|
||||
console.log(states);
|
||||
const conflicts = generateConflicts(states, cultures); // mutates states
|
||||
|
||||
TIME && console.timeEnd("specifyStates");
|
||||
return [NEUTRALS, ...states];
|
||||
return {states: [NEUTRALS, ...states], conflicts};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import {generateReligions} from "./religions/generateReligions";
|
|||
const {LAND_COAST, WATER_COAST, DEEPER_WATER} = DISTANCE_FIELD;
|
||||
const {Biomes} = window;
|
||||
|
||||
export function createPack(grid: IGrid): IPack {
|
||||
export function createPack(grid: IGrid): {pack: IPack; conflicts: IConflict[]} {
|
||||
const {temp, prec} = grid.cells;
|
||||
const {vertices, cells} = repackGrid(grid);
|
||||
|
||||
|
|
@ -97,7 +97,7 @@ export function createPack(grid: IGrid): IPack {
|
|||
pop: population
|
||||
});
|
||||
|
||||
const {burgIds, stateIds, burgs, states} = generateBurgsAndStates(
|
||||
const {burgIds, stateIds, burgs, states, conflicts} = generateBurgsAndStates(
|
||||
cultures,
|
||||
mergedFeatures,
|
||||
temp,
|
||||
|
|
@ -199,7 +199,7 @@ export function createPack(grid: IGrid): IPack {
|
|||
religions
|
||||
};
|
||||
|
||||
return pack;
|
||||
return {pack, conflicts};
|
||||
}
|
||||
|
||||
// repack grid cells: discart deep water cells, add land cells along the coast
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue