mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-22 03:51:23 +01:00
Prepare to lock - Further refactor
This commit is contained in:
parent
cbb36a4875
commit
85f639954e
1 changed files with 122 additions and 83 deletions
|
|
@ -360,16 +360,25 @@ window.Religions = (function () {
|
||||||
Society: 1
|
Society: 1
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const expansionismMap = {
|
||||||
|
Folk: () => 0,
|
||||||
|
Organized: () => gauss(5, 3, 0, 10, 1), // was rand(3, 8)
|
||||||
|
Cult: () => gauss(0.5, 0.5, 0, 5, 1), // was gauss(1.1, 0.5, 0, 5)
|
||||||
|
Heresy: () => gauss(1, 0.5, 0, 5, 1) // was gauss(1.2, 0.5, 0, 5)
|
||||||
|
};
|
||||||
|
|
||||||
function generate() {
|
function generate() {
|
||||||
TIME && console.time("generateReligions");
|
TIME && console.time("generateReligions");
|
||||||
// const {cells, states, cultures, burgs} = pack;
|
// const {cells, states, cultures, burgs} = pack;
|
||||||
|
|
||||||
const folkReligions = generateFolkReligions();
|
const folkReligions = generateFolkReligions();
|
||||||
const {lockedReligions, lockedReligionCount} = restoreLockedReligions();
|
const {lockedReligions, lockedReligionCount} = saveLockedReligions();
|
||||||
const basicReligions = generateOrganizedReligions(+religionsInput.value, lockedReligionCount);
|
const basicReligions = generateOrganizedReligions(+religionsInput.value, lockedReligionCount);
|
||||||
|
|
||||||
const {religions, religionIds} = specifyReligions([...folkReligions, ...basicReligions], lockedReligions);
|
const namedReligions = specifyReligions([...folkReligions, ...basicReligions]);
|
||||||
|
const indexedReligions = combineReligions(namedReligions, lockedReligions);
|
||||||
|
const religionIds = expandReligions(indexedReligions);
|
||||||
|
const religions = defineOrigins(religionIds, indexedReligions);
|
||||||
|
|
||||||
pack.religions = religions;
|
pack.religions = religions;
|
||||||
pack.cells.religion = religionIds;
|
pack.cells.religion = religionIds;
|
||||||
|
|
@ -386,9 +395,10 @@ window.Religions = (function () {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function restoreLockedReligions() {
|
function saveLockedReligions() {
|
||||||
//TODO
|
const lockedReligions = pack.religions?.filter(religion => religion.locked && !religion.removed) || [];
|
||||||
return {lockedReligions: [], lockedReligionCount: 0};
|
const lockedReligionCount = lockedReligions.filter(({type}) => type !== "Folk").length || 0;
|
||||||
|
return {lockedReligions, lockedReligionCount};
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateOrganizedReligions(desiredReligionNumber, lockedReligionCount) {
|
function generateOrganizedReligions(desiredReligionNumber, lockedReligionCount) {
|
||||||
|
|
@ -450,113 +460,145 @@ window.Religions = (function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function specifyReligions(newReligions, lockedReligions) {
|
function specifyReligions(newReligions) {
|
||||||
const {cells, cultures} = pack;
|
const {cells, cultures} = pack;
|
||||||
|
|
||||||
const expansionismMap = {
|
const rawReligions = newReligions.map(({type, form, culture: cultureId, center}) => {
|
||||||
Folk: () => 0,
|
const supreme = getDeityName(cultures[cultureId]);
|
||||||
Organized: () => gauss(5, 3, 0, 10, 1), // was rand(3, 8)
|
|
||||||
Cult: () => gauss(0.5, 0.5, 0, 5, 1), // was gauss(1.1, 0.5, 0, 5)
|
|
||||||
Heresy: () => gauss(1, 0.5, 0, 5, 1) // was gauss(1.2, 0.5, 0, 5)
|
|
||||||
};
|
|
||||||
const religionOriginsParamsMap = {
|
|
||||||
Organized: {clusterSize: 100, maxReligions: 2}, // was 150/count, 2
|
|
||||||
Cult: {clusterSize: 50, maxReligions: 3}, // was 300/count, rand(0,4)
|
|
||||||
Heresy: {clusterSize: 50, maxReligions: 4}
|
|
||||||
};
|
|
||||||
|
|
||||||
const rawReligions = newReligions.map(({type, form, culture: cultureId, center}, index) => {
|
|
||||||
const supreme = generateDeityName(cultures[cultureId]);
|
|
||||||
const deity = form === "Non-theism" || form === "Animism" ? null : supreme;
|
const deity = form === "Non-theism" || form === "Animism" ? null : supreme;
|
||||||
|
|
||||||
const stateId = cells.state[center];
|
const stateId = cells.state[center];
|
||||||
|
|
||||||
let {name, expansion} = generateReligionName(form, supreme, center);
|
let {name, expansion} = generateReligionName(type, form, supreme, center);
|
||||||
if (expansion === "state" && !stateId) expansion = "global";
|
if (expansion === "state" && !stateId) expansion = "global";
|
||||||
|
|
||||||
const expansionism = expansionismMap[type]();
|
const expansionism = expansionismMap[type]();
|
||||||
|
|
||||||
const color = getReligionColor(cultures[cultureId], type);
|
const color = getReligionColor(cultures[cultureId], type);
|
||||||
|
|
||||||
return {i: index + 1, name, type, form, culture: cultureId, center, deity, expansion, expansionism, color};
|
return {name, type, form, culture: cultureId, center, deity, expansion, expansionism, color};
|
||||||
});
|
});
|
||||||
|
|
||||||
const religionIds = expandReligions(rawReligions);
|
return rawReligions;
|
||||||
const names = renameOldReligions(rawReligions);
|
|
||||||
const origins = defineOrigins(religionIds, rawReligions, cells.c);
|
|
||||||
|
|
||||||
return {religions: combineReligionsData(), religionIds};
|
// 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) throw new Error(`Culture ${culture.i} is not a valid culture`);
|
if (!culture.i) ERROR && console.error(`Culture ${culture.i} is not a valid culture`);
|
||||||
|
|
||||||
if (type === "Folk") return culture.color;
|
if (type === "Folk") return culture.color;
|
||||||
if (type === "Heresy") return getMixedColor(culture.color, 0.35, 0.2);
|
if (type === "Heresy") return getMixedColor(culture.color, 0.35, 0.2);
|
||||||
if (type === "Cult") return getMixedColor(culture.color, 0.5, 0);
|
if (type === "Cult") return getMixedColor(culture.color, 0.5, 0);
|
||||||
return getMixedColor(culture.color, 0.25, 0.4);
|
return getMixedColor(culture.color, 0.25, 0.4);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function combineReligionsData() {
|
// indexes, conditionally renames, and abbreviates religions
|
||||||
const noReligion = {i: 0, name: "No religion"};
|
function combineReligions(namedReligions, lockedReligions) {
|
||||||
|
const noReligion = {i: 0, name: "No religion"};
|
||||||
|
const indexedReligions = [noReligion];
|
||||||
|
|
||||||
const religions = rawReligions.map((religion, index) => ({
|
const {lockedReligionQueue, highestLockedIndex, codes} = parseLockedReligions();
|
||||||
...religion,
|
const maxIndex = Math.max(highestLockedIndex, namedReligions.length + lockedReligions.length + 1);
|
||||||
name: names[index],
|
for (let index = 1, progress = 0; index < maxIndex; index++) {
|
||||||
origins: origins[index]
|
if (index === lockedReligionQueue[0]?.i) {
|
||||||
}));
|
const nextReligion = lockedReligionQueue.shift();
|
||||||
|
indexedReligions.push(nextReligion);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (progress < namedReligions.length) {
|
||||||
|
const nextReligion = namedReligions[progress];
|
||||||
|
progress++;
|
||||||
|
if (nextReligion.type === "Folk" && lockedReligions.some(
|
||||||
|
({type, culture}) => type === "Folk" && culture === nextReligion.culture
|
||||||
|
)) continue; // when there is a locked Folk religion for this culture discard duplicate
|
||||||
|
|
||||||
return [noReligion, ...religions];
|
const newName = renameOld(nextReligion);
|
||||||
|
const code = abbreviate(newName, codes);
|
||||||
|
codes.push(code);
|
||||||
|
indexedReligions.push({...nextReligion, i: index, name: newName, code});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
indexedReligions.push({i: index, name: "Padding", removed: true});
|
||||||
|
}
|
||||||
|
return indexedReligions;
|
||||||
|
|
||||||
|
function parseLockedReligions() {
|
||||||
|
const lockedReligionQueue = lockedReligions.map(r => r).sort((a, b) => a.i - b.i);
|
||||||
|
const highestLockedIndex = lockedReligionQueue[-1]?.i;
|
||||||
|
|
||||||
|
const codes = lockedReligions.length > 0 ? lockedReligions.map(r => r.code) : [];
|
||||||
|
|
||||||
|
return {lockedReligionQueue, highestLockedIndex, codes};
|
||||||
}
|
}
|
||||||
|
|
||||||
// prepend 'Old' to names of folk religions which have organized competitors
|
// prepend 'Old' to names of folk religions which have organized competitors
|
||||||
function renameOldReligions(rawReligions) {
|
function renameOld({name, type, culture: cultureId}) {
|
||||||
return rawReligions.map(({name, type, culture: cultureId}) => {
|
if (type !== "Folk") return name;
|
||||||
if (type !== "Folk") return name;
|
|
||||||
|
|
||||||
const haveOrganized = rawReligions.some(({type, culture, expansion}) => culture === cultureId && type === "Organized" && expansion === "culture");
|
const haveOrganized = namedReligions.some(
|
||||||
if (haveOrganized && name.slice(0, 3) !== "Old") return `Old ${name}`;
|
({type, culture, expansion}) => culture === cultureId && type === "Organized" && expansion === "culture")
|
||||||
return name;
|
|| lockedReligions.some(({type, culture, expansion}) => culture === cultureId && type === "Organized" && expansion === "culture");
|
||||||
});
|
if (haveOrganized && name.slice(0, 3) !== "Old") return `Old ${name}`;
|
||||||
|
return name;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function defineOrigins(religionIds, rawReligions, neighbors) {
|
// finally generate origins tree
|
||||||
return rawReligions.map(religion => {
|
function defineOrigins(religionIds, indexedReligions) {
|
||||||
if (religion.type === "Folk") return [0];
|
const religionOriginsParamsMap = {
|
||||||
|
Organized: {clusterSize: 100, maxReligions: 2}, // was 150/count, 2
|
||||||
|
Cult: {clusterSize: 50, maxReligions: 3}, // was 300/count, rand(0,4)
|
||||||
|
Heresy: {clusterSize: 50, maxReligions: 4}
|
||||||
|
};
|
||||||
|
|
||||||
const {i, type, culture: cultureId, expansion, center} = religion;
|
const origins = indexedReligions.map((religion, index) => {
|
||||||
|
if (religion.type === "Folk") return [0];
|
||||||
|
if (index === 0) return null;
|
||||||
|
|
||||||
const folkReligion = rawReligions.find(({culture, type}) => type === "Folk" && culture === cultureId);
|
const {i, type, culture: cultureId, expansion, center} = religion;
|
||||||
const isFolkBased = folkReligion && cultureId && expansion === "culture" && each(2)(center); // P(0.5) -> isEven cellId
|
|
||||||
|
|
||||||
if (isFolkBased) return [folkReligion.i];
|
const folkReligion = indexedReligions.find(({culture, type}) => type === "Folk" && culture === cultureId);
|
||||||
|
const isFolkBased = folkReligion && cultureId && expansion === "culture" && each(2)(center); // P(0.5) -> isEven cellId
|
||||||
|
|
||||||
const {clusterSize, maxReligions} = religionOriginsParamsMap[type];
|
if (isFolkBased) return [folkReligion.i];
|
||||||
const origins = getReligionsInRadius(neighbors, center, religionIds, i, clusterSize, maxReligions);
|
|
||||||
return origins;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getReligionsInRadius(neighbors, center, religionIds, religionId, clusterSize, maxReligions) {
|
const {clusterSize, maxReligions} = religionOriginsParamsMap[type];
|
||||||
const foundReligions = new Set();
|
const origins = getReligionsInRadius(pack.cells.c, center, religionIds, i, clusterSize, maxReligions);
|
||||||
const queue = [center];
|
if (origins === [0]) return [folkReligion.i]; // hegemony has local roots
|
||||||
const checked = {};
|
return origins;
|
||||||
|
});
|
||||||
|
|
||||||
for (let size = 0; queue.length && size < clusterSize; size++) {
|
return indexedReligions.map((religion, index) => ({
|
||||||
const cellId = queue.pop();
|
...religion,
|
||||||
checked[cellId] = true;
|
origins: origins[index]
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
for (const neibId of neighbors[cellId]) {
|
function getReligionsInRadius(neighbors, center, religionIds, religionId, clusterSize, maxReligions) {
|
||||||
if (checked[neibId]) continue;
|
const foundReligions = new Set();
|
||||||
checked[neibId] = true;
|
const queue = [center];
|
||||||
|
const checked = {};
|
||||||
|
|
||||||
const neibReligion = religionIds[neibId];
|
for (let size = 0; queue.length && size < clusterSize; size++) {
|
||||||
if (neibReligion && neibReligion !== religionId) foundReligions.add(neibReligion);
|
const cellId = queue.shift();
|
||||||
queue.push(neibId);
|
checked[cellId] = true;
|
||||||
}
|
|
||||||
|
for (const neibId of neighbors[cellId]) {
|
||||||
|
if (checked[neibId]) continue;
|
||||||
|
checked[neibId] = true;
|
||||||
|
|
||||||
|
const neibReligion = religionIds[neibId];
|
||||||
|
if (neibReligion && neibReligion !== religionId) foundReligions.add(neibReligion);
|
||||||
|
queue.push(neibId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return foundReligions.size ? [...foundReligions].slice(0, maxReligions) : [0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return foundReligions.size ? [...foundReligions].slice(0, maxReligions) : [0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -671,6 +713,8 @@ window.Religions = (function () {
|
||||||
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];
|
||||||
|
// TODO locked
|
||||||
const cultureId = cells.culture[cellId];
|
const cultureId = cells.culture[cellId];
|
||||||
religionIds[cellId] = cultureToReligionMap.get(cultureId) || 0;
|
religionIds[cellId] = cultureToReligionMap.get(cultureId) || 0;
|
||||||
}
|
}
|
||||||
|
|
@ -702,14 +746,9 @@ window.Religions = (function () {
|
||||||
religions[religionId].type === "Organized" ? rw({Organized: 4, Cult: 1, Heresy: 2}) : rw({Organized: 5, Cult: 2});
|
religions[religionId].type === "Organized" ? rw({Organized: 4, Cult: 1, Heresy: 2}) : rw({Organized: 5, Cult: 2});
|
||||||
const form = rw(forms[type]);
|
const form = rw(forms[type]);
|
||||||
const deity =
|
const deity =
|
||||||
type === "Heresy" ? religions[religionId].deity : form === "Non-theism" ? null : generateDeityName(culture);
|
type === "Heresy" ? religions[religionId].deity : form === "Non-theism" ? null : getDeityName(culture);
|
||||||
|
|
||||||
let name, expansion;
|
const {name, expansion} = generateReligionName(type, form, deity, center);
|
||||||
if (type === "Organized") [name, expansion] = generateReligionName(form, deity, center);
|
|
||||||
else {
|
|
||||||
name = getCultName(form, center);
|
|
||||||
expansion = "global";
|
|
||||||
}
|
|
||||||
|
|
||||||
const formName = type === "Heresy" ? religions[religionId].form : form;
|
const formName = type === "Heresy" ? religions[religionId].form : form;
|
||||||
const code = abbreviate(
|
const code = abbreviate(
|
||||||
|
|
@ -727,7 +766,7 @@ window.Religions = (function () {
|
||||||
form: formName,
|
form: formName,
|
||||||
deity,
|
deity,
|
||||||
expansion,
|
expansion,
|
||||||
expansionism: 0,
|
expansionism: expansionismMap[type](),
|
||||||
center,
|
center,
|
||||||
cells: 0,
|
cells: 0,
|
||||||
area: 0,
|
area: 0,
|
||||||
|
|
@ -747,7 +786,7 @@ window.Religions = (function () {
|
||||||
}
|
}
|
||||||
|
|
||||||
// get supreme deity name
|
// get supreme deity name
|
||||||
const generateDeityName = function (culture) {
|
const getDeityName = function (culture) {
|
||||||
if (culture === undefined) {
|
if (culture === undefined) {
|
||||||
ERROR && console.error("Please define a culture");
|
ERROR && console.error("Please define a culture");
|
||||||
return;
|
return;
|
||||||
|
|
@ -779,7 +818,7 @@ window.Religions = (function () {
|
||||||
ERROR && console.error("Unkown generation approach");
|
ERROR && console.error("Unkown generation approach");
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateReligionName(form, deity, center) {
|
function generateReligionName(variety, form, deity, center) {
|
||||||
const {cells, cultures, burgs, states} = pack;
|
const {cells, cultures, burgs, states} = pack;
|
||||||
|
|
||||||
const random = () => Names.getCulture(cells.culture[center], null, null, "", 0);
|
const random = () => Names.getCulture(cells.culture[center], null, null, "", 0);
|
||||||
|
|
@ -795,7 +834,7 @@ window.Religions = (function () {
|
||||||
return adj ? getAdjective(name) : name;
|
return adj ? getAdjective(name) : name;
|
||||||
};
|
};
|
||||||
|
|
||||||
const m = rw(namingMethods);
|
const m = rw(namingMethods[variety]);
|
||||||
if (m === "Random + type") return [random() + " " + type(), "global"];
|
if (m === "Random + type") return [random() + " " + type(), "global"];
|
||||||
if (m === "Random + ism") return [trimVowels(random()) + "ism", "global"];
|
if (m === "Random + ism") return [trimVowels(random()) + "ism", "global"];
|
||||||
if (m === "Supreme + ism" && deity) return [trimVowels(supreme()) + "ism", "global"];
|
if (m === "Supreme + ism" && deity) return [trimVowels(supreme()) + "ism", "global"];
|
||||||
|
|
@ -811,5 +850,5 @@ window.Religions = (function () {
|
||||||
return [trimVowels(random()) + "ism", "global"]; // else
|
return [trimVowels(random()) + "ism", "global"]; // else
|
||||||
}
|
}
|
||||||
|
|
||||||
return {generate, add, getDeityName: generateDeityName, updateCultures};
|
return {generate, add, getDeityName, updateCultures};
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue