From b9ff6a652c0edd0ef171087623a254e649964a26 Mon Sep 17 00:00:00 2001 From: Azgaar Date: Thu, 1 Sep 2022 00:22:46 +0300 Subject: [PATCH] refactor: refactor religions expand --- index.html | 2 +- src/dialogs/dialogs/states-editor.js | 4 +-- src/modules/burgs-and-states.js | 6 ++-- src/modules/ui/options.js | 2 +- src/scripts/events/index.ts | 8 +++-- src/scripts/events/onhover.ts | 5 +--- src/scripts/generation/generation.ts | 5 ++++ src/scripts/generation/pack/generateRoutes.ts | 4 +-- src/scripts/generation/pack/pack.ts | 6 ++-- .../pack/religions/expandReligions.ts | 30 ++++++++++++------- .../pack/religions/generateReligions.ts | 2 +- .../pack/religions/specifyReligions.ts | 17 ++++++----- src/utils/colorUtils.ts | 4 +-- 13 files changed, 55 insertions(+), 40 deletions(-) diff --git a/index.html b/index.html index c4280dd9..4806603e 100644 --- a/index.html +++ b/index.html @@ -1639,7 +1639,7 @@ Religions number - + diff --git a/src/dialogs/dialogs/states-editor.js b/src/dialogs/dialogs/states-editor.js index a4f96fd5..c5d797a7 100644 --- a/src/dialogs/dialogs/states-editor.js +++ b/src/dialogs/dialogs/states-editor.js @@ -1119,7 +1119,7 @@ function adjustProvinces(affectedProvinces) { // reassign province ownership to province center owner prevOwner.provinces = prevOwner.provinces.filter(province => province !== provinceId); province.state = stateId; - province.color = getMixedColor(states[stateId].color); + province.color = brighter(getMixedColor(states[stateId].color, 0.2), 0.3); states[stateId].provinces.push(provinceId); return; } @@ -1163,7 +1163,7 @@ function adjustProvinces(affectedProvinces) { const formOptions = ["Zone", "Area", "Territory", "Province"]; const formName = burgCell && oldProvince.formName ? oldProvince.formName : ra(formOptions); - const color = getMixedColor(states[stateId].color); + const color = brighter(getMixedColor(states[stateId].color, 0.2), 0.3); const kinship = nameByBurg ? 0.8 : 0.4; const type = BurgsAndStates.getType(center, burg?.port); diff --git a/src/modules/burgs-and-states.js b/src/modules/burgs-and-states.js index 5d6eb086..be4b359e 100644 --- a/src/modules/burgs-and-states.js +++ b/src/modules/burgs-and-states.js @@ -780,7 +780,7 @@ window.BurgsAndStates = (function () { const sameColored = pack.states.filter(s => s.color === c); sameColored.forEach((s, d) => { if (!d) return; - s.color = getMixedColor(s.color); + s.color = brighter(getMixedColor(s.color, 0.2), 0.3); }); }); @@ -1209,7 +1209,7 @@ window.BurgsAndStates = (function () { const formName = rw(form); form[formName] += 10; const fullName = name + " " + formName; - const color = getMixedColor(s.color); + const color = brighter(getMixedColor(s.color, 0.2), 0.3); const kinship = nameByBurg ? 0.8 : 0.4; const type = getType(center, burg.port); const coa = COA.generate(stateBurgs[i].coa, kinship, null, type); @@ -1317,7 +1317,7 @@ window.BurgsAndStates = (function () { // generate "wild" province name const cultureId = cells.culture[center]; const f = pack.features[cells.f[center]]; - const color = getMixedColor(s.color); + const color = brighter(getMixedColor(s.color, 0.2), 0.3); const provCells = stateNoProvince.filter(i => cells.province[i] === province); const singleIsle = provCells.length === f.cells && !provCells.find(i => cells.f[i] !== f.i); diff --git a/src/modules/ui/options.js b/src/modules/ui/options.js index 5c864778..fcb5dd6c 100644 --- a/src/modules/ui/options.js +++ b/src/modules/ui/options.js @@ -566,7 +566,7 @@ export function randomizeOptions() { manorsInput.value = 1000; manorsOutput.value = "auto"; } - if (randomize || !locked("religions")) religionsInput.value = religionsOutput.value = gauss(5, 2, 2, 10); + if (randomize || !locked("religions")) religionsInput.value = religionsOutput.value = gauss(6, 3, 2, 10); if (randomize || !locked("power")) powerInput.value = powerOutput.value = gauss(4, 2, 0, 10, 2); if (randomize || !locked("neutral")) neutralInput.value = neutralOutput.value = rn(1 + Math.random(), 1); if (randomize || !locked("cultures")) culturesInput.value = culturesOutput.value = gauss(12, 3, 5, 30); diff --git a/src/scripts/events/index.ts b/src/scripts/events/index.ts index 0d3d7c8c..977cfb3f 100644 --- a/src/scripts/events/index.ts +++ b/src/scripts/events/index.ts @@ -4,14 +4,16 @@ import {openDialog} from "dialogs"; import {tip} from "scripts/tooltips"; import {handleMapClick} from "./onclick"; import {onMouseMove} from "./onhover"; -// @ts-expect-error js module import {clearLegend, dragLegendBox} from "modules/legend"; export function setDefaultEventHandlers() { window.Zoom.setZoomBehavior(); - viewbox.style("cursor", "default").on(".drag", null).on("click", handleMapClick); - //.on("touchmove mousemove", onMouseMove); + viewbox + .style("cursor", "default") + .on(".drag", null) + .on("click", handleMapClick) + .on("touchmove mousemove", onMouseMove); scaleBar.on("mousemove", () => tip("Click to open Units Editor")).on("click", () => openDialog("unitsEditor")); diff --git a/src/scripts/events/onhover.ts b/src/scripts/events/onhover.ts index e0b2693c..ac1ce961 100644 --- a/src/scripts/events/onhover.ts +++ b/src/scripts/events/onhover.ts @@ -1,9 +1,6 @@ import * as d3 from "d3"; import {layerIsOn} from "layers"; -// @ts-expect-error js module -import {clearLegend, dragLegendBox} from "modules/legend"; -// @ts-expect-error js module import {updateCellInfo} from "modules/ui/cell-info"; import {debounce} from "utils/functionUtils"; import {findCell, findGridCell, isLand} from "utils/graphUtils"; @@ -78,7 +75,7 @@ const getHoveredElement = (tagName: string, group: string, subgroup: string, isL if (layerIsOn("togglePopulation")) return "populationLayer"; if (layerIsOn("toggleTemp")) return "temperatureLayer"; if (layerIsOn("toggleBiomes") && biome[cellId]) return "biomesLayer"; - if (layerIsOn("toggleReligions") && religion[cellId]) return "religionsLayer"; + if (religion[cellId]) return "religionsLayer"; // layerIsOn("toggleReligions") && if (layerIsOn("toggleProvinces") || (layerIsOn("toggleStates") && state[cellId])) return "statesLayer"; if (layerIsOn("toggleCultures") && culture[cellId]) return "culturesLayer"; if (layerIsOn("toggleHeight")) return "heightLayer"; diff --git a/src/scripts/generation/generation.ts b/src/scripts/generation/generation.ts index a6c6ef1c..614840b4 100644 --- a/src/scripts/generation/generation.ts +++ b/src/scripts/generation/generation.ts @@ -26,6 +26,7 @@ import {createGrid} from "./grid/grid"; import {createPack} from "./pack/pack"; import {getInputValue, setInputValue} from "utils/nodeUtils"; import {calculateMapCoordinates} from "modules/coordinates"; +import {drawPoint} from "utils/debugUtils"; const {Zoom, ThreeD} = window; @@ -72,6 +73,10 @@ async function generate(options?: IGenerationOptions) { // renderLayer("states"); renderLayer("religions"); + // pack.cells.route.forEach((route, index) => { + // if (route === 2) drawPoint(pack.cells.p[index], {color: "black"}); + // }); + WARN && console.warn(`TOTAL: ${rn((performance.now() - timeStart) / 1000, 2)}s`); // showStatistics(); INFO && console.groupEnd(); diff --git a/src/scripts/generation/pack/generateRoutes.ts b/src/scripts/generation/pack/generateRoutes.ts index da280f9a..b7f3e76a 100644 --- a/src/scripts/generation/pack/generateRoutes.ts +++ b/src/scripts/generation/pack/generateRoutes.ts @@ -103,7 +103,7 @@ export function generateRoutes(burgs: TBurgs, temp: Int8Array, cells: TCellsData const segments = findPathSegments({isWater: true, cellRoutes, connections, start, exit}); for (const segment of segments) { - addConnections(segment, ROUTES.MAIN_ROAD); + addConnections(segment, ROUTES.SEA_ROUTE); mainRoads.push({feature: Number(key), cells: segment}); } }); @@ -118,7 +118,7 @@ export function generateRoutes(burgs: TBurgs, temp: Int8Array, cells: TCellsData const cellId = segment[i]; const nextCellId = segment[i + 1]; if (nextCellId) connections.set(`${cellId}-${nextCellId}`, true); - cellRoutes[cellId] = roadTypeId; + if (!cellRoutes[cellId]) cellRoutes[cellId] = roadTypeId; } } diff --git a/src/scripts/generation/pack/pack.ts b/src/scripts/generation/pack/pack.ts index 915f3a63..d110e75d 100644 --- a/src/scripts/generation/pack/pack.ts +++ b/src/scripts/generation/pack/pack.ts @@ -188,11 +188,11 @@ export function createPack(grid: IGrid): IPack { burg: burgIds, state: stateIds, route: cellRoutes, - religion: religionIds - // province + religion: religionIds, + province: new Uint16Array(cells.i.length) }, features: mergedFeatures, - // rivers: rawRivers, // "name" | "basin" | "type" + rivers: rawRivers, // "name" | "basin" | "type" cultures, states, burgs, diff --git a/src/scripts/generation/pack/religions/expandReligions.ts b/src/scripts/generation/pack/religions/expandReligions.ts index 286bca0c..9b0809bf 100644 --- a/src/scripts/generation/pack/religions/expandReligions.ts +++ b/src/scripts/generation/pack/religions/expandReligions.ts @@ -1,12 +1,12 @@ import FlatQueue from "flatqueue"; -import {ROUTES} from "config/generation"; +import {MIN_LAND_HEIGHT, ROUTES} from "config/generation"; import {getInputNumber} from "utils/nodeUtils"; import {gauss} from "utils/probabilityUtils"; import {isReligion} from "utils/typeUtils"; type TReligionData = Pick; -type TCellsData = Pick; +type TCellsData = Pick; export function expandReligions(religions: TReligionData[], cells: TCellsData) { const religionIds = spreadFolkReligions(religions, cells); @@ -15,11 +15,9 @@ export function expandReligions(religions: TReligionData[], cells: TCellsData) { const cost: number[] = []; const neutralInput = getInputNumber("neutralInput"); - const maxExpansionCost = (cells.i.length / 25) * gauss(1, 0.3, 0.2, 2, 2) * neutralInput; + const maxExpansionCost = (cells.i.length / 20) * gauss(1, 0.3, 0.2, 2, 2) * neutralInput; const biomePassageCost = (cellId: number) => biomesData.cost[cells.biome[cellId]]; - const isMainRoad = (cellId: number) => cells.route[cellId] === ROUTES.MAIN_ROAD; - const isSeaRoute = (cellId: number) => cells.route[cellId] === ROUTES.SEA_ROUTE; for (const religion of religions) { if (!isReligion(religion as IReligion) || (religion as IReligion).type === "Folk") continue; @@ -32,6 +30,11 @@ export function expandReligions(religions: TReligionData[], cells: TCellsData) { const religionsMap = new Map(religions.map(religion => [religion.i, religion])); + const isMainRoad = (cellId: number) => cells.route[cellId] === ROUTES.MAIN_ROAD; + const isTrail = (cellId: number) => cells.route[cellId] === ROUTES.TRAIL; + const isSeaRoute = (cellId: number) => cells.route[cellId] === ROUTES.SEA_ROUTE; + const isWater = (cellId: number) => cells.h[cellId] < MIN_LAND_HEIGHT; + while (queue.length) { const priority = queue.peekValue()!; const {cellId, religionId} = queue.pop()!; @@ -39,16 +42,14 @@ export function expandReligions(religions: TReligionData[], cells: TCellsData) { const {culture, center, expansion, expansionism} = religionsMap.get(religionId)!; cells.c[cellId].forEach(neibCellId => { - // if (neibCellId === center && religionIds[neibCellId]) return; // do not overwrite center cells if (expansion === "culture" && culture !== cells.culture[neibCellId]) return; if (expansion === "state" && cells.state[center] !== cells.state[neibCellId]) return; - const cultureCost = culture !== cells.culture[neibCellId] ? 50 : 0; - const stateCost = cells.state[center] !== cells.state[neibCellId] ? 50 : 0; - const passageCost = isMainRoad(neibCellId) ? 1 : biomePassageCost(neibCellId); // [1, 5000] - const waterCost = isSeaRoute(neibCellId) ? 50 : 1000; + const cultureCost = culture !== cells.culture[neibCellId] ? 10 : 0; + const stateCost = cells.state[center] !== cells.state[neibCellId] ? 10 : 0; + const passageCost = getPassageCost(neibCellId); - const cellCost = Math.max(cultureCost + stateCost + passageCost + waterCost, 0); + const cellCost = cultureCost + stateCost + passageCost; const totalCost = priority + 10 + cellCost / expansionism; if (totalCost > maxExpansionCost) return; @@ -62,6 +63,13 @@ export function expandReligions(religions: TReligionData[], cells: TCellsData) { } return religionIds; + + function getPassageCost(cellId: number) { + if (isWater(cellId)) return isSeaRoute(cellId) ? 50 : 500; + if (isMainRoad(cellId)) return 1; + const biomeCost = biomePassageCost(cellId); // [1, 5000] + return isTrail(cellId) ? biomeCost / 1.5 : biomeCost; + } } // folk religions initially get all cells of their culture diff --git a/src/scripts/generation/pack/religions/generateReligions.ts b/src/scripts/generation/pack/religions/generateReligions.ts index 299d184e..83c23975 100644 --- a/src/scripts/generation/pack/religions/generateReligions.ts +++ b/src/scripts/generation/pack/religions/generateReligions.ts @@ -30,7 +30,7 @@ export function generateReligions({ cultures, states, burgs, - pick(cells, "i", "c", "biome", "culture", "burg", "state", "route") + pick(cells, "i", "c", "h", "biome", "culture", "burg", "state", "route") ); folkReligions.forEach(({center}) => drawPoint(cells.p[center], {radius: 3, color: "blue"})); diff --git a/src/scripts/generation/pack/religions/specifyReligions.ts b/src/scripts/generation/pack/religions/specifyReligions.ts index f9fa9061..937cd2b0 100644 --- a/src/scripts/generation/pack/religions/specifyReligions.ts +++ b/src/scripts/generation/pack/religions/specifyReligions.ts @@ -1,4 +1,4 @@ -import {brighter, getMixedColor} from "utils/colorUtils"; +import {brighter, darker, getMixedColor} from "utils/colorUtils"; import {each, gauss, rand} from "utils/probabilityUtils"; import {isCulture} from "utils/typeUtils"; import {expandReligions} from "./expandReligions"; @@ -7,19 +7,20 @@ import {generateReligionName} from "./generateReligionName"; const expansionismMap = { Folk: () => 0, - Organized: () => rand(3, 8), - Cult: () => gauss(1.1, 0.5, 0, 5), - Heresy: () => gauss(1.2, 0.5, 0, 5) + Organized: () => gauss(5, 3, 0, 10, 1), + Cult: () => gauss(0.5, 0.5, 0, 5, 1), + Heresy: () => gauss(1, 0.5, 0, 5, 1) }; type TReligionData = Pick; +type TCellsData = Pick; export function specifyReligions( religionsData: TReligionData[], cultures: TCultures, states: TStates, burgs: TBurgs, - cells: Pick + cells: TCellsData ): {religions: TReligions; religionIds: Uint16Array} { const rawReligions = religionsData.map(({type, form, culture: cultureId, center}, index) => { const supreme = getDeityName(cultures, cultureId); @@ -56,8 +57,10 @@ export function specifyReligions( const culture = cultures[cultureId]; if (!isCulture(culture)) throw new Error(`Culture ${cultureId} is not a valid culture`); - if (type === "Folk") return brighter(culture.color, 0.2); - return getMixedColor(culture.color, 0.2, 0); + if (type === "Folk") return culture.color; + if (type === "Heresy") return darker(getMixedColor(culture.color, 0.35), 0.3); + if (type === "Cult") return darker(getMixedColor(culture.color, 0.5), 0.8); + return brighter(getMixedColor(culture.color, 0.25), 0.3); } function combineReligionsData(): TReligions { diff --git a/src/utils/colorUtils.ts b/src/utils/colorUtils.ts index 94f5f2ff..4d1834a8 100644 --- a/src/utils/colorUtils.ts +++ b/src/utils/colorUtils.ts @@ -46,12 +46,12 @@ export function getRandomColor(): Hex { } // mix a color with a random color. TODO: refactor without interpolation -export function getMixedColor(color: Hex | CssUrl, mixation = 0.2, bright = 0.3) { +export function getMixedColor(color: Hex | CssUrl, mixation: number) { const color1 = color.startsWith("#") ? color : getRandomColor(); const color2 = getRandomColor(); const mixedColor = d3.interpolate(color1, color2)(mixation); - return d3.color(mixedColor)!.brighter(bright).formatHex() as Hex; + return d3.color(mixedColor)!.formatHex() as Hex; } export function darker(color: Hex | CssUrl, amount = 1) {