refactor: refactor religions expand

This commit is contained in:
Azgaar 2022-09-01 00:22:46 +03:00
parent 5361565cd7
commit b9ff6a652c
13 changed files with 55 additions and 40 deletions

View file

@ -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"));

View file

@ -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";

View file

@ -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();

View file

@ -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;
}
}

View file

@ -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,

View file

@ -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<IReligion, "i" | "type" | "center" | "culture" | "expansion" | "expansionism">;
type TCellsData = Pick<IPack["cells"], "i" | "c" | "biome" | "culture" | "state" | "route">;
type TCellsData = Pick<IPack["cells"], "i" | "c" | "h" | "biome" | "culture" | "state" | "route">;
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<number, TReligionData>(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

View file

@ -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"}));

View file

@ -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<IReligion, "type" | "form" | "culture" | "center">;
type TCellsData = Pick<IPack["cells"], "i" | "c" | "h" | "biome" | "culture" | "burg" | "state" | "route">;
export function specifyReligions(
religionsData: TReligionData[],
cultures: TCultures,
states: TStates,
burgs: TBurgs,
cells: Pick<IPack["cells"], "i" | "c" | "biome" | "culture" | "burg" | "state" | "route">
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 {