refactor: split to several files

This commit is contained in:
max 2022-08-25 00:20:43 +03:00
parent cce374da24
commit 17e96524fb
5 changed files with 158 additions and 142 deletions

View file

@ -309,7 +309,7 @@ const methods = {
"Culture + type": 4
};
export const types = {
const types = {
Shamanism: {Beliefs: 3, Shamanism: 2, Spirits: 1},
Animism: {Spirits: 1, Beliefs: 1},
"Ancestor worship": {Beliefs: 1, Forefathers: 2, Ancestors: 2},

View file

@ -0,0 +1,38 @@
import {religionsData} from "config/religionsData";
import {ra} from "utils/probabilityUtils";
const {Names} = window;
const {base, approaches} = religionsData;
export function getDeityName(cultures: TCultures, cultureId: number) {
if (cultureId === undefined) throw "CultureId is undefined";
const meaning = generateMeaning();
const base = cultures[cultureId].base;
const cultureName = Names.getBase(base);
return cultureName + ", The " + meaning;
}
function generateMeaning() {
const approach = ra(approaches);
if (approach === "Number") return ra(base.number);
if (approach === "Being") return ra(base.being);
if (approach === "Adjective") return ra(base.adjective);
if (approach === "Color + Animal") return `${ra(base.color)} ${ra(base.animal)}`;
if (approach === "Adjective + Animal") return `${ra(base.adjective)} ${ra(base.animal)}`;
if (approach === "Adjective + Being") return `${ra(base.adjective)} ${ra(base.being)}`;
if (approach === "Adjective + Genitive") return `${ra(base.adjective)} ${ra(base.genitive)}`;
if (approach === "Color + Being") return `${ra(base.color)} ${ra(base.being)}`;
if (approach === "Color + Genitive") return `${ra(base.color)} ${ra(base.genitive)}`;
if (approach === "Being + of + Genitive") return `${ra(base.being)} of ${ra(base.genitive)}`;
if (approach === "Being + of the + Genitive") return `${ra(base.being)} of the ${ra(base.theGenitive)}`;
if (approach === "Animal + of + Genitive") return `${ra(base.animal)} of ${ra(base.genitive)}`;
if (approach === "Adjective + Being + of + Genitive")
return `${ra(base.adjective)} ${ra(base.being)} of ${ra(base.genitive)}`;
if (approach === "Adjective + Animal + of + Genitive")
return `${ra(base.adjective)} ${ra(base.animal)} of ${ra(base.genitive)}`;
throw "Unknown generation approach";
}

View file

@ -0,0 +1,22 @@
import {religionsData} from "config/religionsData";
import {getMixedColor} from "utils/colorUtils";
import {rw} from "utils/probabilityUtils";
import {getDeityName} from "./generateDeityName";
const {forms, types} = religionsData;
export function generateFolkReligions(cultures: TCultures) {
const isValidCulture = (culture: TWilderness | ICulture): culture is ICulture =>
culture.i !== 0 && !(culture as ICulture).removed;
return cultures.filter(isValidCulture).map(culture => {
const {i: cultureId, name: cultureName, center} = culture;
const form = rw(forms.Folk);
const type: {[key: string]: number} = types[form];
const name = cultureName + " " + rw(type);
const deity = form === "Animism" ? null : getDeityName(cultures, cultureId);
const color = getMixedColor(culture.color, 0.1, 0);
return {name, type: "Folk", form, deity, color, culture: cultureId, center, origins: [0]};
});
}

View file

@ -0,0 +1,94 @@
import * as d3 from "d3";
import {WARN} from "config/logging";
import {religionsData} from "config/religionsData";
import {getRandomColor, getMixedColor} from "utils/colorUtils";
import {getInputNumber} from "utils/nodeUtils";
import {rand, rw} from "utils/probabilityUtils";
import {isBurg} from "utils/typeUtils";
import {getDeityName} from "./generateDeityName";
import {generateFolkReligions} from "./generateFolkReligions";
import {generateReligionName} from "./generateReligionName";
const {forms, types} = religionsData;
export function generateOrganizedReligionsAndCults(
states: TStates,
cultures: TCultures,
burgs: TBurgs,
cultureIds: Uint16Array,
stateIds: Uint16Array,
burgIds: Uint16Array,
folkReligions: ReturnType<typeof generateFolkReligions>,
cells: Pick<IPack["cells"], "i" | "p" | "pop">
) {
const religionsNumber = getInputNumber("religionsInput");
if (religionsNumber === 0) return [];
const cultsNumber = Math.floor((rand(1, 4) / 10) * religionsNumber); // 10-40%
const organizedNumber = religionsNumber - cultsNumber;
const canditateCells = getCandidateCells();
const religionCells = placeReligions();
return religionCells.map((cellId, index) => {
const cultureId = cultureIds[cellId];
const stateId = stateIds[cellId];
const burgId = burgIds[cellId];
const type = index < organizedNumber ? "Organized" : "Cult";
const form = rw(forms[type] as {[key in keyof typeof types]: number});
const deityName = getDeityName(cultures, cultureId);
const deity = form === "Non-theism" ? null : deityName;
const {name, expansion, center} = generateReligionName({
cultureId,
stateId,
burgId,
cultures,
states,
burgs,
center: cellId,
form,
deity: deityName
});
const folkReligion = folkReligions.find(({culture}) => culture === cultureId);
const baseColor = folkReligion?.color || getRandomColor();
const color = getMixedColor(baseColor, 0.3, 0);
return {name, type, form, deity, color, culture: cultureId, center, expansion};
});
function placeReligions() {
const religionCells = [];
const religionsTree = d3.quadtree();
// initial min distance between religions
let spacing = (graphWidth + graphHeight) / 4 / religionsNumber;
for (const cellId of canditateCells) {
const [x, y] = cells.p[cellId];
if (religionsTree.find(x, y, spacing) === undefined) {
religionCells.push(cellId);
religionsTree.add([x, y]);
if (religionCells.length === religionsNumber) return religionCells;
}
}
WARN && console.warn(`Placed only ${religionCells.length} of ${religionsNumber} religions`);
return religionCells;
}
function getCandidateCells() {
const validBurgs = burgs.filter(isBurg);
if (validBurgs.length >= religionsNumber)
return validBurgs.sort((a, b) => b.population - a.population).map(burg => burg.cell);
return cells.i.filter(i => cells.pop[i] > 2).sort((a, b) => cells.pop[b] - cells.pop[a]);
}
}

View file

@ -1,17 +1,8 @@
import * as d3 from "d3";
import {TIME, WARN} from "config/logging";
import {religionsData} from "config/religionsData";
import {TIME} from "config/logging";
import {unique} from "utils/arrayUtils";
import {getMixedColor, getRandomColor} from "utils/colorUtils";
import {findAll} from "utils/graphUtils";
import {getInputNumber} from "utils/nodeUtils";
import {ra, rand, rw} from "utils/probabilityUtils";
import {isBurg} from "utils/typeUtils";
import {generateReligionName} from "./generateReligionName";
const {Names} = window;
const {approaches, base, forms, types} = religionsData;
import {generateFolkReligions} from "./generateFolkReligions";
import {generateOrganizedReligionsAndCults} from "./generateOrganizedReligionsAndCults";
type TCellsData = Pick<IPack["cells"], "i" | "c" | "p" | "g" | "h" | "t" | "biome" | "pop" | "burg">;
@ -58,135 +49,6 @@ export function generateReligions({
return {religionIds};
}
function generateFolkReligions(cultures: TCultures) {
const isValidCulture = (culture: TWilderness | ICulture): culture is ICulture =>
culture.i !== 0 && !(culture as ICulture).removed;
return cultures.filter(isValidCulture).map(culture => {
const {i: cultureId, name: cultureName, center} = culture;
const form = rw(forms.Folk);
const type: {[key: string]: number} = types[form];
const name = cultureName + " " + rw(type);
const deity = form === "Animism" ? null : getDeityName(cultures, cultureId);
const color = getMixedColor(culture.color, 0.1, 0);
return {name, type: "Folk", form, deity, color, culture: cultureId, center, origins: [0]};
});
}
function generateOrganizedReligionsAndCults(
states: TStates,
cultures: TCultures,
burgs: TBurgs,
cultureIds: Uint16Array,
stateIds: Uint16Array,
burgIds: Uint16Array,
folkReligions: ReturnType<typeof generateFolkReligions>,
cells: Pick<IPack["cells"], "i" | "p" | "pop">
) {
const religionsNumber = getInputNumber("religionsInput");
if (religionsNumber === 0) return [];
const cultsNumber = Math.floor((rand(1, 4) / 10) * religionsNumber); // 10-40%
const organizedNumber = religionsNumber - cultsNumber;
const canditateCells = getCandidateCells();
const religionCells = placeReligions();
return religionCells.map((cellId, index) => {
const cultureId = cultureIds[cellId];
const stateId = stateIds[cellId];
const burgId = burgIds[cellId];
const type = index < organizedNumber ? "Organized" : "Cult";
const form = rw(forms[type] as {[key in keyof typeof types]: number});
const deityName = getDeityName(cultures, cultureId);
const deity = form === "Non-theism" ? null : deityName;
const {name, expansion, center} = generateReligionName({
cultureId,
stateId,
burgId,
cultures,
states,
burgs,
center: cellId,
form,
deity: deityName
});
const folkReligion = folkReligions.find(({culture}) => culture === cultureId);
const baseColor = folkReligion?.color || getRandomColor();
const color = getMixedColor(baseColor, 0.3, 0);
return {name, type, form, deity, color, culture: cultureId, center, expansion};
});
function placeReligions() {
const religionCells = [];
const religionsTree = d3.quadtree();
// initial min distance between religions
let spacing = (graphWidth + graphHeight) / 4 / religionsNumber;
for (const cellId of canditateCells) {
const [x, y] = cells.p[cellId];
if (religionsTree.find(x, y, spacing) === undefined) {
religionCells.push(cellId);
religionsTree.add([x, y]);
if (religionCells.length === religionsNumber) return religionCells;
}
}
WARN && console.warn(`Placed only ${religionCells.length} of ${religionsNumber} religions`);
return religionCells;
}
function getCandidateCells() {
const validBurgs = burgs.filter(isBurg);
if (validBurgs.length >= religionsNumber)
return validBurgs.sort((a, b) => b.population - a.population).map(burg => burg.cell);
return cells.i.filter(i => cells.pop[i] > 2).sort((a, b) => cells.pop[b] - cells.pop[a]);
}
}
function getDeityName(cultures: TCultures, cultureId: number) {
if (cultureId === undefined) throw "CultureId is undefined";
const meaning = generateMeaning();
const base = cultures[cultureId].base;
const cultureName = Names.getBase(base);
return cultureName + ", The " + meaning;
}
function generateMeaning() {
const approach = ra(approaches);
if (approach === "Number") return ra(base.number);
if (approach === "Being") return ra(base.being);
if (approach === "Adjective") return ra(base.adjective);
if (approach === "Color + Animal") return `${ra(base.color)} ${ra(base.animal)}`;
if (approach === "Adjective + Animal") return `${ra(base.adjective)} ${ra(base.animal)}`;
if (approach === "Adjective + Being") return `${ra(base.adjective)} ${ra(base.being)}`;
if (approach === "Adjective + Genitive") return `${ra(base.adjective)} ${ra(base.genitive)}`;
if (approach === "Color + Being") return `${ra(base.color)} ${ra(base.being)}`;
if (approach === "Color + Genitive") return `${ra(base.color)} ${ra(base.genitive)}`;
if (approach === "Being + of + Genitive") return `${ra(base.being)} of ${ra(base.genitive)}`;
if (approach === "Being + of the + Genitive") return `${ra(base.being)} of the ${ra(base.theGenitive)}`;
if (approach === "Animal + of + Genitive") return `${ra(base.animal)} of ${ra(base.genitive)}`;
if (approach === "Adjective + Being + of + Genitive")
return `${ra(base.adjective)} ${ra(base.being)} of ${ra(base.genitive)}`;
if (approach === "Adjective + Animal + of + Genitive")
return `${ra(base.adjective)} ${ra(base.animal)} of ${ra(base.genitive)}`;
throw "Unknown generation approach";
}
function getReligionsInRadius(
religionIds: Uint16Array,
{x, y, r, max}: {x: number; y: number; r: number; max: number}