From ff974a4fd044b9069c3ec5a04ed74a3872f2aab4 Mon Sep 17 00:00:00 2001 From: max Date: Sat, 6 Aug 2022 00:02:35 +0300 Subject: [PATCH] refactor: generate states cleanup --- src/dialogs/dialogs/label-editor.js | 5 +-- src/dialogs/dialogs/states-editor.js | 15 +++++---- src/modules/burgs-and-states.js | 21 ++++++++----- src/modules/coa-generator.js | 9 +++--- src/modules/define-svg.js | 2 +- src/modules/heightmap-generator.js | 8 ++--- src/modules/names-generator.js | 5 ++- src/modules/submap.js | 2 +- src/modules/ui/provinces-editor.js | 13 +++++--- src/modules/ui/tools.js | 4 ++- .../pack/burgsAndStates/createCapitals.ts | 19 +++++++++--- .../pack/burgsAndStates/createStates.ts | 17 +++++----- .../pack/burgsAndStates/createTowns.ts | 31 ++++++++++++------- .../burgsAndStates/generateBurgsAndStates.ts | 5 +-- .../pack/burgsAndStates/specifyBurgs.ts | 4 +-- src/types/globals.d.ts | 2 +- 16 files changed, 98 insertions(+), 64 deletions(-) diff --git a/src/dialogs/dialogs/label-editor.js b/src/dialogs/dialogs/label-editor.js index 791c6cd7..6c7aaf10 100644 --- a/src/dialogs/dialogs/label-editor.js +++ b/src/dialogs/dialogs/label-editor.js @@ -337,8 +337,9 @@ export function open({el}) { let name = ""; if (elSelected.attr("id").slice(0, 10) === "stateLabel") { const id = +elSelected.attr("id").slice(10); - const culture = pack.states[id].culture; - name = Names.getState(Names.getCulture(culture, 4, 7, ""), culture); + const cultureId = pack.states[id].culture; + const base = pack.cultures[cultureId].base; + name = Names.getState(Names.getBase(base, 4, 7, ""), base); } else { const box = elSelected.node().getBBox(); const cell = findCell((box.x + box.width) / 2, (box.y + box.height) / 2); diff --git a/src/dialogs/dialogs/states-editor.js b/src/dialogs/dialogs/states-editor.js index ac964b66..144edf6a 100644 --- a/src/dialogs/dialogs/states-editor.js +++ b/src/dialogs/dialogs/states-editor.js @@ -464,14 +464,15 @@ function editStateName(state) { function regenerateShortNameCuture() { const state = +stateNameEditor.dataset.state; - const culture = pack.states[state].culture; - const name = Names.getState(Names.getCultureShort(culture), culture); + const cultureId = pack.states[state].culture; + const base = pack.cultures[cultureId].base; + const name = Names.getState(Names.getBaseShort(base), base); byId("stateNameEditorShort").value = name; } function regenerateShortNameRandom() { const base = rand(nameBases.length - 1); - const name = Names.getState(Names.getBase(base), undefined, base); + const name = Names.getState(Names.getBase(base), base); byId("stateNameEditorShort").value = name; } @@ -1156,7 +1157,8 @@ function adjustProvinces(affectedProvinces) { const culture = cells.culture[center]; const nameByBurg = burgCell && P(0.5); - const name = nameByBurg ? burg.name : oldProvince.name || Names.getState(Names.getCultureShort(culture), culture); + const base = pack.cultures[culture].base; + const name = nameByBurg ? burg.name : oldProvince.name || Names.getState(Names.getBaseShort(base), base); const formOptions = ["Zone", "Area", "Territory", "Province"]; const formName = burgCell && oldProvince.formName ? oldProvince.formName : ra(formOptions); @@ -1259,8 +1261,9 @@ function addState() { if (d3.event.shiftKey === false) exitAddStateMode(); const culture = cells.culture[center]; - const basename = center % 5 === 0 ? burgs[burg].name : Names.getCulture(culture); - const name = Names.getState(basename, culture); + const base = pack.cultures[culture].base; + const basename = center % 5 === 0 ? burgs[burg].name : Names.getBase(culture); + const name = Names.getState(basename, base); const color = getRandomColor(); const pole = cells.p[center]; diff --git a/src/modules/burgs-and-states.js b/src/modules/burgs-and-states.js index be862dec..90e97dc3 100644 --- a/src/modules/burgs-and-states.js +++ b/src/modules/burgs-and-states.js @@ -106,8 +106,9 @@ window.BurgsAndStates = (function () { // states data const expansionism = rn(Math.random() * powerInput.value + 1, 1); - const basename = b.name.length < 9 && each5th(b.cell) ? b.name : Names.getCultureShort(b.culture); - const name = Names.getState(basename, b.culture); + const base = pack.cultures[b.culture].base; + const basename = b.name.length < 9 && each5th(b.cell) ? b.name : Names.getBaseShort(base); + const name = Names.getState(basename, base); const type = cultures[b.culture].type; const coa = COA.generate(null, null, null, type); @@ -1200,9 +1201,11 @@ window.BurgsAndStates = (function () { s.provinces.push(province); const center = stateBurgs[i].cell; const burg = stateBurgs[i].i; - const c = stateBurgs[i].culture; + const cultureId = stateBurgs[i].culture; const nameByBurg = P(0.5); - const name = nameByBurg ? stateBurgs[i].name : Names.getState(Names.getCultureShort(c), c); + + const base = pack.cultures[cultureId].base; + const name = nameByBurg ? stateBurgs[i].name : Names.getState(Names.getBaseShort(base), base); const formName = rw(form); form[formName] += 10; const fullName = name + " " + formName; @@ -1210,7 +1213,7 @@ window.BurgsAndStates = (function () { const kinship = nameByBurg ? 0.8 : 0.4; const type = getType(center, burg.port); const coa = COA.generate(stateBurgs[i].coa, kinship, null, type); - coa.shield = COA.getShield(c, s.i); + coa.shield = COA.getShield(cultureId, s.i); provinces.push({i: province, state: s.i, center, burg, name, formName, fullName, color, coa}); } }); @@ -1312,7 +1315,7 @@ window.BurgsAndStates = (function () { } // generate "wild" province name - const c = cells.culture[center]; + const cultureId = cells.culture[center]; const f = pack.features[cells.f[center]]; const color = getMixedColor(s.color); @@ -1325,7 +1328,9 @@ window.BurgsAndStates = (function () { const colonyName = colony && P(0.8) && getColonyName(); if (colonyName) return colonyName; if (burgCell && P(0.5)) return burgs[burg].name; - return Names.getState(Names.getCultureShort(c), c); + const base = pack.cultures[cultureId].base; + + return Names.getState(Names.getBaseShort(base), base); })(); const formName = (function () { @@ -1341,7 +1346,7 @@ window.BurgsAndStates = (function () { const kinship = dominion ? 0 : 0.4; const type = getType(center, burgs[burg]?.port); const coa = COA.generate(s.coa, kinship, dominion, type); - coa.shield = COA.getShield(c, s.i); + coa.shield = COA.getShield(cultureId, s.i); provinces.push({i: province, state: s.i, center, burg, name, formName, fullName, color, coa}); s.provinces.push(province); diff --git a/src/modules/coa-generator.js b/src/modules/coa-generator.js index 363c30dd..8c83f689 100644 --- a/src/modules/coa-generator.js +++ b/src/modules/coa-generator.js @@ -1,3 +1,4 @@ +import {pack} from "d3"; import {P, rw} from "utils/probabilityUtils"; window.COA = (function () { @@ -1038,14 +1039,14 @@ window.COA = (function () { return coa; }; - const getShield = function (culture, state) { + const getShield = function (cultureId, stateId, cultures = pack.cultures, states = pack.states) { const emblemShape = document.getElementById("emblemShape"); const shapeGroup = emblemShape.selectedOptions[0]?.parentNode.label || "Diversiform"; if (shapeGroup !== "Diversiform") return emblemShape.value; - if (emblemShape.value === "state" && state && pack.states[state].coa) return pack.states[state].coa.shield; - if (pack.cultures[culture].shield) return pack.cultures[culture].shield; - ERROR && console.error("Shield shape is not defined on culture level", pack.cultures[culture]); + if (emblemShape.value === "state" && stateId && states[stateId].coa) return states[stateId].coa.shield; + if (cultures[cultureId].shield) return cultures[cultureId].shield; + ERROR && console.error("Shield shape is not defined on culture level", cultures[cultureId]); return "heater"; }; diff --git a/src/modules/define-svg.js b/src/modules/define-svg.js index cea8ed4c..29dc267b 100644 --- a/src/modules/define-svg.js +++ b/src/modules/define-svg.js @@ -15,7 +15,7 @@ export function defineSvg(width, height) { texture = viewbox.append("g").attr("id", "texture"); terrs = viewbox.append("g").attr("id", "terrs"); biomes = viewbox.append("g").attr("id", "biomes"); - cells = viewbox.append("g").attr("id", "cells"); + // cells = viewbox.append("g").attr("id", "cells"); gridOverlay = viewbox.append("g").attr("id", "gridOverlay"); coordinates = viewbox.append("g").attr("id", "coordinates"); compass = viewbox.append("g").attr("id", "compass"); diff --git a/src/modules/heightmap-generator.js b/src/modules/heightmap-generator.js index ba0ecbd6..7e4195de 100644 --- a/src/modules/heightmap-generator.js +++ b/src/modules/heightmap-generator.js @@ -99,7 +99,7 @@ window.HeightmapGenerator = (function () { if (tool === "Smooth") return smooth(a2); } - function getBlobPower(cells) { + function getBlobPower(cellsNumber) { const blobPowerMap = { 1000: 0.93, 2000: 0.95, @@ -115,10 +115,10 @@ window.HeightmapGenerator = (function () { 90000: 0.9964, 100000: 0.9973 }; - return blobPowerMap[cells] || 0.98; + return blobPowerMap[cellsNumber] || 0.98; } - function getLinePower() { + function getLinePower(cellsNumber) { const linePowerMap = { 1000: 0.75, 2000: 0.77, @@ -135,7 +135,7 @@ window.HeightmapGenerator = (function () { 100000: 0.93 }; - return linePowerMap[cells] || 0.81; + return linePowerMap[cellsNumber] || 0.81; } const addHill = (count, height, rangeX, rangeY) => { diff --git a/src/modules/names-generator.js b/src/modules/names-generator.js index 02f3f976..34b07901 100644 --- a/src/modules/names-generator.js +++ b/src/modules/names-generator.js @@ -162,10 +162,9 @@ window.Names = (function () { }; // generate state name based on capital or random name and culture-specific suffix - const getState = function (name, culture, base) { + const getState = function (name, base) { if (name === undefined) return ERROR && console.error("Please define a base name"); - if (culture === undefined && base === undefined) return ERROR && console.error("Please define a culture"); - if (base === undefined) base = pack.cultures[culture].base; + if (base === undefined) return ERROR && console.error("Please define a namesbase"); // exclude endings inappropriate for states name if (name.includes(" ")) name = capitalize(name.replace(/ /g, "").toLowerCase()); // don't allow multiword state names diff --git a/src/modules/submap.js b/src/modules/submap.js index a31d6dc8..850f07c0 100644 --- a/src/modules/submap.js +++ b/src/modules/submap.js @@ -2,7 +2,7 @@ import * as d3 from "d3"; import {INFO} from "config/logging"; import {findCell} from "utils/graphUtils"; -import {getMiddlePoint} from "utils/lineUtils"; +import {getCommonEdgePoint} from "utils/lineUtils"; import {rn} from "utils/numberUtils"; import {aleaPRNG} from "scripts/aleaPRNG"; import {renderLayer} from "layers"; diff --git a/src/modules/ui/provinces-editor.js b/src/modules/ui/provinces-editor.js index d8ba38f9..f1097256 100644 --- a/src/modules/ui/provinces-editor.js +++ b/src/modules/ui/provinces-editor.js @@ -552,13 +552,15 @@ export function editProvinces() { function regenerateShortNameCuture() { const province = +provinceNameEditor.dataset.province; const culture = pack.cells.culture[pack.provinces[province].center]; - const name = Names.getState(Names.getCultureShort(culture), culture); + const base = pack.cultures[culture].base; + + const name = Names.getState(Names.getBaseShort(base), base); byId("provinceNameEditorShort").value = name; } function regenerateShortNameRandom() { const base = rand(nameBases.length - 1); - const name = Names.getState(Names.getBase(base), undefined, base); + const name = Names.getState(Names.getBase(base), base); byId("provinceNameEditorShort").value = name; } @@ -1033,8 +1035,9 @@ export function editProvinces() { const province = provinces.length; pack.states[state].provinces.push(province); const burg = cells.burg[center]; - const c = cells.culture[center]; - const name = burg ? pack.burgs[burg].name : Names.getState(Names.getCultureShort(c), c); + const cultureId = cells.culture[center]; + const base = pack.cultures[cultureId].base; + const name = burg ? pack.burgs[burg].name : Names.getState(Names.getBaseShort(base), base); const formName = oldProvince ? provinces[oldProvince].formName : "Province"; const fullName = name + " " + formName; const stateColor = pack.states[state].color; @@ -1046,7 +1049,7 @@ export function editProvinces() { const parent = burg ? pack.burgs[burg].coa : pack.states[state].coa; const type = BurgsAndStates.getType(center, parent.port); const coa = COA.generate(parent, kinship, P(0.1), type); - coa.shield = COA.getShield(c, state); + coa.shield = COA.getShield(cultureId, state); COArenderer.add("province", province, coa, point[0], point[1]); provinces.push({i: province, state, center, burg, name, formName, fullName, color, coa}); diff --git a/src/modules/ui/tools.js b/src/modules/ui/tools.js index e91fa041..ac833fcb 100644 --- a/src/modules/ui/tools.js +++ b/src/modules/ui/tools.js @@ -221,9 +221,11 @@ function regenerateStates() { } const culture = capital.culture; + const base = pack.cultures[culture].base; + const basename = capital.name.length < 9 && capital.cell % 5 === 0 ? capital.name : Names.getCulture(culture, 3, 6, "", 0); - const name = Names.getState(basename, culture); + const name = Names.getState(basename, base); const nomadic = [1, 2, 3, 4].includes(pack.cells.biome[capital.cell]); const type = nomadic ? "Nomadic" diff --git a/src/scripts/generation/pack/burgsAndStates/createCapitals.ts b/src/scripts/generation/pack/burgsAndStates/createCapitals.ts index 9688a478..c43553f0 100644 --- a/src/scripts/generation/pack/burgsAndStates/createCapitals.ts +++ b/src/scripts/generation/pack/burgsAndStates/createCapitals.ts @@ -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 +) { 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); diff --git a/src/scripts/generation/pack/burgsAndStates/createStates.ts b/src/scripts/generation/pack/burgsAndStates/createStates.ts index b96c3dcf..5a78aac7 100644 --- a/src/scripts/generation/pack/burgsAndStates/createStates.ts +++ b/src/scripts/generation/pack/burgsAndStates/createStates.ts @@ -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); +} diff --git a/src/scripts/generation/pack/burgsAndStates/createTowns.ts b/src/scripts/generation/pack/burgsAndStates/createTowns.ts index 0e33a34e..9a93374d 100644 --- a/src/scripts/generation/pack/burgsAndStates/createTowns.ts +++ b/src/scripts/generation/pack/burgsAndStates/createTowns.ts @@ -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 +) { 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); diff --git a/src/scripts/generation/pack/burgsAndStates/generateBurgsAndStates.ts b/src/scripts/generation/pack/burgsAndStates/generateBurgsAndStates.ts index 2976cd73..157eb705 100644 --- a/src/scripts/generation/pack/burgsAndStates/generateBurgsAndStates.ts +++ b/src/scripts/generation/pack/burgsAndStates/generateBurgsAndStates.ts @@ -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(); diff --git a/src/scripts/generation/pack/burgsAndStates/specifyBurgs.ts b/src/scripts/generation/pack/burgsAndStates/specifyBurgs.ts index 5882f331..bc1fe2b5 100644 --- a/src/scripts/generation/pack/burgsAndStates/specifyBurgs.ts +++ b/src/scripts/generation/pack/burgsAndStates/specifyBurgs.ts @@ -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() { diff --git a/src/types/globals.d.ts b/src/types/globals.d.ts index f9888c46..17a1e3f2 100644 --- a/src/types/globals.d.ts +++ b/src/types/globals.d.ts @@ -49,7 +49,7 @@ let landmass: Selection; let texture: Selection; let terrs: Selection; let biomes: Selection; -let cells: Selection; +// let cells: Selection; let gridOverlay: Selection; let coordinates: Selection; let compass: Selection;