mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-22 03:51:23 +01:00
Complete locked religions functionality
This commit is contained in:
parent
85f639954e
commit
3b90b62219
1 changed files with 26 additions and 68 deletions
|
|
@ -371,9 +371,10 @@ window.Religions = (function () {
|
||||||
TIME && console.time("generateReligions");
|
TIME && console.time("generateReligions");
|
||||||
// const {cells, states, cultures, burgs} = pack;
|
// const {cells, states, cultures, burgs} = pack;
|
||||||
|
|
||||||
|
const lockedReligions = pack.religions?.filter(religion => religion.locked && !religion.removed) || [];
|
||||||
|
|
||||||
const folkReligions = generateFolkReligions();
|
const folkReligions = generateFolkReligions();
|
||||||
const {lockedReligions, lockedReligionCount} = saveLockedReligions();
|
const basicReligions = generateOrganizedReligions(+religionsInput.value, lockedReligions);
|
||||||
const basicReligions = generateOrganizedReligions(+religionsInput.value, lockedReligionCount);
|
|
||||||
|
|
||||||
const namedReligions = specifyReligions([...folkReligions, ...basicReligions]);
|
const namedReligions = specifyReligions([...folkReligions, ...basicReligions]);
|
||||||
const indexedReligions = combineReligions(namedReligions, lockedReligions);
|
const indexedReligions = combineReligions(namedReligions, lockedReligions);
|
||||||
|
|
@ -395,13 +396,8 @@ window.Religions = (function () {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveLockedReligions() {
|
function generateOrganizedReligions(desiredReligionNumber, lockedReligions) {
|
||||||
const lockedReligions = pack.religions?.filter(religion => religion.locked && !religion.removed) || [];
|
|
||||||
const lockedReligionCount = lockedReligions.filter(({type}) => type !== "Folk").length || 0;
|
const lockedReligionCount = lockedReligions.filter(({type}) => type !== "Folk").length || 0;
|
||||||
return {lockedReligions, lockedReligionCount};
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateOrganizedReligions(desiredReligionNumber, lockedReligionCount) {
|
|
||||||
const requiredReligionsNumber = desiredReligionNumber - lockedReligionCount;
|
const requiredReligionsNumber = desiredReligionNumber - lockedReligionCount;
|
||||||
if (requiredReligionsNumber < 1) return [];
|
if (requiredReligionsNumber < 1) return [];
|
||||||
|
|
||||||
|
|
@ -431,7 +427,7 @@ window.Religions = (function () {
|
||||||
const religionsTree = d3.quadtree();
|
const religionsTree = d3.quadtree();
|
||||||
|
|
||||||
// pre-populate with locked centers
|
// pre-populate with locked centers
|
||||||
// TODO
|
lockedReligions.forEach(({center}) => religionsTree.add(cells.p[center]));
|
||||||
|
|
||||||
// min distance between religion inceptions
|
// min distance between religion inceptions
|
||||||
const spacing = (graphWidth + graphHeight) / 2 / desiredReligionNumber; // was major gauss(1,0.3, 0.2,2, 2) / 6; cult gauss(2,0.3, 1,3, 2) /6; heresy /60
|
const spacing = (graphWidth + graphHeight) / 2 / desiredReligionNumber; // was major gauss(1,0.3, 0.2,2, 2) / 6; cult gauss(2,0.3, 1,3, 2) /6; heresy /60
|
||||||
|
|
@ -481,12 +477,6 @@ window.Religions = (function () {
|
||||||
|
|
||||||
return rawReligions;
|
return rawReligions;
|
||||||
|
|
||||||
// const religionIds = expandReligions(rawReligions);
|
|
||||||
// const names = renameOldReligions(rawReligions);
|
|
||||||
// const origins = defineOrigins(religionIds, rawReligions, cells.c);
|
|
||||||
|
|
||||||
// return {religions: combineReligionsData(), religionIds};
|
|
||||||
|
|
||||||
function getReligionColor(culture, type) {
|
function getReligionColor(culture, type) {
|
||||||
if (!culture.i) ERROR && console.error(`Culture ${culture.i} is not a valid culture`);
|
if (!culture.i) ERROR && console.error(`Culture ${culture.i} is not a valid culture`);
|
||||||
|
|
||||||
|
|
@ -504,12 +494,15 @@ window.Religions = (function () {
|
||||||
|
|
||||||
const {lockedReligionQueue, highestLockedIndex, codes} = parseLockedReligions();
|
const {lockedReligionQueue, highestLockedIndex, codes} = parseLockedReligions();
|
||||||
const maxIndex = Math.max(highestLockedIndex, namedReligions.length + lockedReligions.length + 1);
|
const maxIndex = Math.max(highestLockedIndex, namedReligions.length + lockedReligions.length + 1);
|
||||||
|
|
||||||
for (let index = 1, progress = 0; index < maxIndex; index++) {
|
for (let index = 1, progress = 0; index < maxIndex; index++) {
|
||||||
|
// place locked religion back at its old index
|
||||||
if (index === lockedReligionQueue[0]?.i) {
|
if (index === lockedReligionQueue[0]?.i) {
|
||||||
const nextReligion = lockedReligionQueue.shift();
|
const nextReligion = lockedReligionQueue.shift();
|
||||||
indexedReligions.push(nextReligion);
|
indexedReligions.push(nextReligion);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// slot the new religions
|
||||||
if (progress < namedReligions.length) {
|
if (progress < namedReligions.length) {
|
||||||
const nextReligion = namedReligions[progress];
|
const nextReligion = namedReligions[progress];
|
||||||
progress++;
|
progress++;
|
||||||
|
|
@ -529,7 +522,7 @@ window.Religions = (function () {
|
||||||
|
|
||||||
function parseLockedReligions() {
|
function parseLockedReligions() {
|
||||||
const lockedReligionQueue = lockedReligions.map(r => r).sort((a, b) => a.i - b.i);
|
const lockedReligionQueue = lockedReligions.map(r => r).sort((a, b) => a.i - b.i);
|
||||||
const highestLockedIndex = lockedReligionQueue[-1]?.i;
|
const highestLockedIndex = Math.max(lockedReligions.map(r => r.i));
|
||||||
|
|
||||||
const codes = lockedReligions.length > 0 ? lockedReligions.map(r => r.code) : [];
|
const codes = lockedReligions.length > 0 ? lockedReligions.map(r => r.code) : [];
|
||||||
|
|
||||||
|
|
@ -548,7 +541,7 @@ window.Religions = (function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// finally generate origins tree
|
// finally generate and stores origins trees
|
||||||
function defineOrigins(religionIds, indexedReligions) {
|
function defineOrigins(religionIds, indexedReligions) {
|
||||||
const religionOriginsParamsMap = {
|
const religionOriginsParamsMap = {
|
||||||
Organized: {clusterSize: 100, maxReligions: 2}, // was 150/count, 2
|
Organized: {clusterSize: 100, maxReligions: 2}, // was 150/count, 2
|
||||||
|
|
@ -569,6 +562,7 @@ window.Religions = (function () {
|
||||||
|
|
||||||
const {clusterSize, maxReligions} = religionOriginsParamsMap[type];
|
const {clusterSize, maxReligions} = religionOriginsParamsMap[type];
|
||||||
const origins = getReligionsInRadius(pack.cells.c, center, religionIds, i, clusterSize, maxReligions);
|
const origins = getReligionsInRadius(pack.cells.c, center, religionIds, i, clusterSize, maxReligions);
|
||||||
|
|
||||||
if (origins === [0]) return [folkReligion.i]; // hegemony has local roots
|
if (origins === [0]) return [folkReligion.i]; // hegemony has local roots
|
||||||
return origins;
|
return origins;
|
||||||
});
|
});
|
||||||
|
|
@ -601,58 +595,20 @@ window.Religions = (function () {
|
||||||
return foundReligions.size ? [...foundReligions].slice(0, maxReligions) : [0];
|
return foundReligions.size ? [...foundReligions].slice(0, maxReligions) : [0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// add folk religions
|
|
||||||
cultures.forEach(c => {
|
|
||||||
if (!c.i) return religions.push({i: 0, name: "No religion"});
|
|
||||||
|
|
||||||
if (pack.religions) {
|
|
||||||
const lockedFolkReligion = pack.religions.find(
|
|
||||||
r => r.culture === c.i && !r.removed && r.lock && r.type === "Folk"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (lockedFolkReligion) {
|
|
||||||
for (const i of cells.i) {
|
|
||||||
if (cells.religion[i] === lockedFolkReligion.i) religionIds[i] = newId;
|
|
||||||
}
|
|
||||||
|
|
||||||
lockedFolkReligion.i = newId;
|
|
||||||
religions.push(lockedFolkReligion);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
// restore locked non-folk religions
|
|
||||||
if (pack.religions) {
|
|
||||||
const lockedNonFolkReligions = pack.religions.filter(r => r.lock && !r.removed && r.type !== "Folk");
|
|
||||||
for (const religion of lockedNonFolkReligions) {
|
|
||||||
const newId = religions.length;
|
|
||||||
for (const i of cells.i) {
|
|
||||||
if (cells.religion[i] === religion.i) religionIds[i] = newId;
|
|
||||||
}
|
|
||||||
|
|
||||||
religion.i = newId;
|
|
||||||
religion.origins = religion.origins.filter(origin => origin < newId);
|
|
||||||
religionsTree.add(cells.p[religion.center]);
|
|
||||||
religions.push(religion);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
// growth algorithm to assign cells to religions
|
// growth algorithm to assign cells to religions
|
||||||
function expandReligions(religions) {
|
function expandReligions(religions) {
|
||||||
|
const cells = pack.cells;
|
||||||
const religionIds = spreadFolkReligions(religions);
|
const religionIds = spreadFolkReligions(religions);
|
||||||
|
|
||||||
const queue = new PriorityQueue({comparator: (a, b) => a.p - b.p});
|
const queue = new PriorityQueue({comparator: (a, b) => a.p - b.p});
|
||||||
const cost = [];
|
const cost = [];
|
||||||
|
|
||||||
const maxExpansionCost = (cells.i.length / 20) * gauss(1, 0.3, 0.2, 2, 2) * neutralInput.value; // limit cost for organized religions growth (was /25)
|
const maxExpansionCost = (cells.i.length / 20) * gauss(1, 0.3, 0.2, 2, 2) * neutralInput.value; // limit cost for organized religions growth (was /25, heresy /10)
|
||||||
|
|
||||||
const biomePassageCost = (cellId) => biomesData.cost[cells.biome[cellId]];
|
const biomePassageCost = (cellId) => biomesData.cost[cells.biome[cellId]];
|
||||||
|
|
||||||
religions
|
religions
|
||||||
.filter(r => r.i && !r.lock && r.type !== "Folk")
|
.filter(r => r.i && !r.lock && r.type !== "Folk" && !r.removed)
|
||||||
.forEach(r => {
|
.forEach(r => {
|
||||||
religionIds[r.center] = r.i;
|
religionIds[r.center] = r.i;
|
||||||
queue.queue({e: r.center, p: 0, r: r.i, s: cells.state[r.center]});
|
queue.queue({e: r.center, p: 0, r: r.i, s: cells.state[r.center]});
|
||||||
|
|
@ -662,9 +618,9 @@ window.Religions = (function () {
|
||||||
const religionsMap = new Map(religions.map(r => [r.i, r]));
|
const religionsMap = new Map(religions.map(r => [r.i, r]));
|
||||||
|
|
||||||
const isMainRoad = (cellId) => (cells.road[cellId] - cells.crossroad[cellId]) > 4;
|
const isMainRoad = (cellId) => (cells.road[cellId] - cells.crossroad[cellId]) > 4;
|
||||||
const isTrail = (cellId) => cells.h > 19 && (cells.road[cellId] - cells.crossroad[cellId]) === 1;
|
const isTrail = (cellId) => cells.h[cellId] > 19 && (cells.road[cellId] - cells.crossroad[cellId]) === 1;
|
||||||
const isSeaRoute = (cellId) => cells.h < 20 && cells.road;
|
const isSeaRoute = (cellId) => cells.h[cellId] < 20 && cells.road[cellId];
|
||||||
const isWater = (cellId) => cells.h < 20;
|
const isWater = (cellId) => cells.h[cellId] < 20;
|
||||||
// const popCost = d3.max(cells.pop) / 3; // enougth population to spered religion without penalty
|
// const popCost = d3.max(cells.pop) / 3; // enougth population to spered religion without penalty
|
||||||
|
|
||||||
while (queue.length) {
|
while (queue.length) {
|
||||||
|
|
@ -705,16 +661,19 @@ window.Religions = (function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// folk religions initially get all cells of their culture
|
// folk religions initially get all cells of their culture, and locked religions are retained
|
||||||
function spreadFolkReligions(religions) {
|
function spreadFolkReligions(religions) {
|
||||||
const religionIds = new Uint16Array(cells.i.length);
|
const religionIds = new Uint16Array(cells.i.length);
|
||||||
|
|
||||||
const folkReligions = religions.filter(({type}) => type === "Folk");
|
const folkReligions = religions.filter(religion => religion.type === "Folk" && !religion.removed);
|
||||||
const cultureToReligionMap = new Map(folkReligions.map(({i, culture}) => [culture, i]));
|
const cultureToReligionMap = new Map(folkReligions.map(({i, culture}) => [culture, i]));
|
||||||
|
|
||||||
for (const cellId of cells.i) {
|
for (const cellId of cells.i) {
|
||||||
const oldId = cells.religion[cellId];
|
const oldId = cells.religion[cellId] || 0;
|
||||||
// TODO locked
|
if (oldId && religions[oldId]?.lock && !religions[oldId]?.removed) {
|
||||||
|
religionIds[cellId] = oldId;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const cultureId = cells.culture[cellId];
|
const cultureId = cells.culture[cellId];
|
||||||
religionIds[cellId] = cultureToReligionMap.get(cultureId) || 0;
|
religionIds[cellId] = cultureToReligionMap.get(cultureId) || 0;
|
||||||
}
|
}
|
||||||
|
|
@ -723,15 +682,14 @@ window.Religions = (function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkCenters() {
|
function checkCenters() {
|
||||||
const codes = religions.map(r => r.code);
|
|
||||||
religions.forEach(r => {
|
religions.forEach(r => {
|
||||||
if (!r.i) return;
|
if (!r.i) return;
|
||||||
r.code = abbreviate(r.name, codes);
|
|
||||||
|
|
||||||
// move religion center if it's not within religion area after expansion
|
// move religion center if it's not within religion area after expansion
|
||||||
if (religionIds[r.center] === r.i) return; // in area
|
if (religionIds[r.center] === r.i) return; // in area
|
||||||
const firstCell = cells.i.find(i => religionIds[i] === r.i);
|
const firstCell = cells.i.find(i => religionIds[i] === r.i);
|
||||||
|
const cultureHome = pack.cultures[r.culture]?.center;
|
||||||
if (firstCell) r.center = firstCell; // move center, othervise it's an extinct religion
|
if (firstCell) r.center = firstCell; // move center, othervise it's an extinct religion
|
||||||
|
else if (type === "Folk" && cultureHome) r.center = cultureHome;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue