mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 17:51:24 +01:00
refactor: refactor religions expand
This commit is contained in:
parent
5361565cd7
commit
b9ff6a652c
13 changed files with 55 additions and 40 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"}));
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue