Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 56 additions & 22 deletions public/modules/dynamic/editors/cultures-editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@ let culturesManualHistory = [];

const cultureTypes = ["Generic", "River", "Lake", "Naval", "Nomadic", "Hunting", "Highland"];

const culturesPage = {page: 1};
const CULTURES_SORT_ACCESSORS = {
name: c => c.name,
type: c => c.type || "",
base: c => c.base,
cells: c => c.cells,
expansionism: c => c.expansionism || 0,
area: c => c.area,
population: c => c.rural * populationRate + c.urban * populationRate * urbanization,
emblems: c => c.shield
};

export function open() {
closeDialogs("#culturesEditor, .stable");
if (!layerIsOn("toggleCultures")) toggleCultures();
Expand All @@ -12,6 +24,7 @@ export function open() {
if (layerIsOn("toggleReligions")) toggleReligions();
if (layerIsOn("toggleProvinces")) toggleProvinces();

culturesPage.page = 1;
refreshCulturesEditor();

$("#culturesEditor").dialog({
Expand Down Expand Up @@ -77,6 +90,10 @@ function insertEditorHtml() {

function addListeners() {
applySortingByHeader("culturesHeader");
bindEditorSortReset(ensureEl("culturesHeader"), () => {
culturesPage.page = 1;
culturesEditorAddLines();
});

ensureEl("culturesEditorRefresh").on("click", refreshCulturesEditor);
ensureEl("culturesEditStyle").on("click", () => editStyle("cults"));
Expand Down Expand Up @@ -120,24 +137,32 @@ function culturesCollectStatistics() {

function culturesEditorAddLines() {
const unit = getAreaUnit();
let lines = "";
let totalArea = 0;
let totalPopulation = 0;

const emblemShapeGroup = ensureEl("emblemShape").selectedOptions[0]?.parentNode?.label;
const selectShape = emblemShapeGroup === "Diversiform";

for (const c of pack.cultures) {
if (c.removed) continue;
const allCultures = pack.cultures.filter(c => !c.removed);
sortDataByActiveHeader(ensureEl("culturesHeader"), allCultures, CULTURES_SORT_ACCESSORS);

// footer totals over the full set
let totalArea = 0;
let totalPopulation = 0;
for (const c of allCultures) {
totalArea += getArea(c.area);
totalPopulation += rn(c.rural * populationRate + c.urban * populationRate * urbanization);
}

const pageInfo = getEditorPage(allCultures, culturesPage);
let lines = "";

for (const c of pageInfo.items) {
const area = getArea(c.area);
const rural = c.rural * populationRate;
const urban = c.urban * populationRate * urbanization;
const population = rn(rural + urban);
const populationTip = `Total population: ${si(population)}. Rural population: ${si(rural)}. Urban population: ${si(
urban
)}. Click to edit`;
totalArea += area;
totalPopulation += population;

if (!c.i) {
// Uncultured (neutral) line
Expand Down Expand Up @@ -231,6 +256,11 @@ function culturesEditorAddLines() {
ensureEl("culturesFooterArea").dataset.area = totalArea;
ensureEl("culturesFooterPopulation").dataset.population = totalPopulation;

renderEditorPagination(ensureEl("culturesFooter"), pageInfo, page => {
culturesPage.page = page;
culturesEditorAddLines();
});

// add listeners
$body.querySelectorAll(":scope > div").forEach($line => {
$line.on("mouseenter", cultureHighlightOn);
Expand Down Expand Up @@ -258,7 +288,6 @@ function culturesEditorAddLines() {
$body.dataset.type = "absolute";
togglePercentageMode();
}
applySorting($culturesHeader);
$("#culturesEditor").dialog({ width: fitContent() });
}

Expand Down Expand Up @@ -578,12 +607,12 @@ function drawCultureCenters() {
.attr("cy", d => pack.cells.p[d.center][1])
.on("mouseenter", d => {
tip(tooltip, true);
$body.querySelector(`div[data-id='${d.i}']`).classList.add("selected");
$body.querySelector(`div[data-id='${d.i}']`)?.classList.add("selected");
cultureHighlightOn(event);
})
.on("mouseleave", d => {
tip("", true);
$body.querySelector(`div[data-id='${d.i}']`).classList.remove("selected");
$body.querySelector(`div[data-id='${d.i}']`)?.classList.remove("selected");
cultureHighlightOff(event);
})
.call(d3.drag().on("start", cultureCenterDrag));
Expand Down Expand Up @@ -682,6 +711,8 @@ function recalculateCultures(force) {
function enterCultureManualAssignent() {
if (!layerIsOn("toggleCultures")) toggleCultures();
customization = 4;
culturesPage.page = 1;
culturesEditorAddLines();
cults.append("g").attr("id", "temp");
document.querySelectorAll("#culturesBottom > *").forEach(el => (el.style.display = "none"));
ensureEl("culturesManuallyButtons").style.display = "inline-block";
Expand Down Expand Up @@ -718,8 +749,10 @@ function selectCultureOnMapClick() {
const assigned = cults.select("#temp").select("polygon[data-cell='" + i + "']");
const culture = assigned.size() ? +assigned.attr("data-culture") : pack.cells.culture[i];

$body.querySelector("div.selected").classList.remove("selected");
$body.querySelector("div[data-id='" + culture + "']").classList.add("selected");
const $row = $body.querySelector("div[data-id='" + culture + "']");
if (!$row) return; // clicked culture's row is on another page; ignore to avoid a crash
$body.querySelector("div.selected")?.classList.remove("selected");
$row.classList.add("selected");
}

function dragCultureBrush() {
Expand Down Expand Up @@ -794,7 +827,7 @@ function exitCulturesManualAssignment(close) {
ensureEl("culturesManuallyButtons").style.display = "none";

culturesEditor.querySelectorAll(".hide").forEach(el => el.classList.remove("hidden"));
culturesFooter.style.display = "block";
culturesFooter.style.display = "flex";
$body.querySelectorAll("div > input, select, span, svg").forEach(e => (e.style.pointerEvents = "all"));
if (!close) $("#culturesEditor").dialog({ position: { my: "right top", at: "right-10 top+10", of: "svg" } });

Expand Down Expand Up @@ -858,15 +891,16 @@ function addCulture() {
function downloadCulturesCsv() {
const unit = getAreaUnit("2");
const headers = `Id,Name,Color,Cells,Expansionism,Type,Area ${unit},Population,Namesbase,Emblems Shape,Origins`;
const lines = Array.from($body.querySelectorAll(":scope > div"));
const data = lines.map($line => {
const { id, name, color, cells, expansionism, type, area, population, emblems, base } = $line.dataset;
const namesbase = nameBases[+base].name;
const { origins } = pack.cultures[+id];
const originList = origins.filter(origin => origin).map(origin => pack.cultures[origin].name);
const originText = '"' + originList.join(", ") + '"';
return [id, name, color, cells, expansionism, type, area, population, namesbase, emblems, originText].join(",");
});
const data = pack.cultures
.filter(c => !c.removed)
.map(c => {
const area = getArea(c.area);
const population = rn(c.rural * populationRate + c.urban * populationRate * urbanization);
const namesbase = nameBases[c.base].name;
const originList = (c.origins || []).filter(origin => origin).map(origin => pack.cultures[origin].name);
const originText = '"' + originList.join(", ") + '"';
return [c.i, c.name, c.color || "", c.cells, c.i ? (c.expansionism ?? "") : "", c.type || "", area, population, namesbase, c.shield, originText].join(",");
});
const csvData = [headers].concat(data).join("\n");

const name = getFileName("Cultures") + ".csv";
Expand Down
87 changes: 67 additions & 20 deletions public/modules/dynamic/editors/religions-editor.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
const $body = insertEditorHtml();
addListeners();

const religionsPage = {page: 1};
const RELIGIONS_SORT_ACCESSORS = {
name: r => r.name,
type: r => r.type || "",
form: r => r.form || "",
deity: r => r.deity || "",
area: r => r.area,
population: r => r.rural * populationRate + r.urban * populationRate * urbanization,
expansion: r => r.expansion || "",
expansionism: r => r.expansionism || 0
};

export function open() {
closeDialogs("#religionsEditor, .stable");
if (!layerIsOn("toggleReligions")) toggleReligions();
Expand All @@ -9,6 +21,7 @@ export function open() {
if (layerIsOn("toggleCultures")) toggleCultures();
if (layerIsOn("toggleProvinces")) toggleProvinces();

religionsPage.page = 1;
refreshReligionsEditor();
drawReligionCenters();

Expand Down Expand Up @@ -92,6 +105,10 @@ function insertEditorHtml() {

function addListeners() {
applySortingByHeader("religionsHeader");
bindEditorSortReset(ensureEl("religionsHeader"), () => {
religionsPage.page = 1;
religionsEditorAddLines();
});

ensureEl("religionsEditorRefresh").on("click", refreshReligionsEditor);
ensureEl("religionsEditStyle").on("click", () => editStyle("relig"));
Expand Down Expand Up @@ -129,26 +146,34 @@ function religionsCollectStatistics() {
}
}

// add line for each religion
// add line for each religion (current page only; sort + totals span all religions)
function religionsEditorAddLines() {
const unit = " " + getAreaUnit();
let lines = "";

const allReligions = pack.religions.filter(
r => !r.removed && !(r.i && !r.cells && $body.dataset.extinct !== "show")
);
sortDataByActiveHeader(ensureEl("religionsHeader"), allReligions, RELIGIONS_SORT_ACCESSORS);

// footer totals over the full (visible) set
let totalArea = 0;
let totalPopulation = 0;
for (const r of allReligions) {
totalArea += getArea(r.area);
totalPopulation += rn(r.rural * populationRate + r.urban * populationRate * urbanization);
}

for (const r of pack.religions) {
if (r.removed) continue;
if (r.i && !r.cells && $body.dataset.extinct !== "show") continue; // hide extinct religions
const pageInfo = getEditorPage(allReligions, religionsPage);
let lines = "";

for (const r of pageInfo.items) {
const area = getArea(r.area);
const rural = r.rural * populationRate;
const urban = r.urban * populationRate * urbanization;
const population = rn(rural + urban);
const populationTip = `Believers: ${si(population)}; Rural areas: ${si(rural)}; Urban areas: ${si(
urban
)}. Click to change`;
totalArea += area;
totalPopulation += population;

if (!r.i) {
// No religion (neutral) line
Expand Down Expand Up @@ -233,6 +258,11 @@ function religionsEditorAddLines() {
ensureEl("religionsFooterArea").dataset.area = totalArea;
ensureEl("religionsFooterPopulation").dataset.population = totalPopulation;

renderEditorPagination(ensureEl("religionsFooter"), pageInfo, page => {
religionsPage.page = page;
religionsEditorAddLines();
});

// add listeners
$body.querySelectorAll(":scope > div").forEach($line => {
$line.on("mouseenter", religionHighlightOn);
Expand All @@ -258,7 +288,6 @@ function religionsEditorAddLines() {
togglePercentageMode();
}

applySorting(religionsHeader);
$("#religionsEditor").dialog({ width: fitContent() });
}

Expand Down Expand Up @@ -640,6 +669,7 @@ async function showHierarchy() {
}

function toggleExtinct() {
religionsPage.page = 1;
$body.dataset.extinct = $body.dataset.extinct !== "show" ? "show" : "hide";
religionsEditorAddLines();
drawReligionCenters();
Expand All @@ -648,6 +678,8 @@ function toggleExtinct() {
function enterReligionsManualAssignent() {
if (!layerIsOn("toggleReligions")) toggleReligions();
customization = 7;
religionsPage.page = 1;
religionsEditorAddLines();
relig.append("g").attr("id", "temp");
document.querySelectorAll("#religionsBottom > *").forEach(el => (el.style.display = "none"));
ensureEl("religionsManuallyButtons").style.display = "inline-block";
Expand Down Expand Up @@ -683,8 +715,10 @@ function selectReligionOnMapClick() {
const assigned = relig.select("#temp").select("polygon[data-cell='" + i + "']");
const religion = assigned.size() ? +assigned.attr("data-religion") : pack.cells.religion[i];

$body.querySelector("div.selected").classList.remove("selected");
$body.querySelector("div[data-id='" + religion + "']").classList.add("selected");
const $row = $body.querySelector("div[data-id='" + religion + "']");
if (!$row) return; // clicked religion's row is on another page; ignore to avoid a crash
$body.querySelector("div.selected")?.classList.remove("selected");
$row.classList.add("selected");
}

function dragReligionBrush() {
Expand Down Expand Up @@ -760,7 +794,7 @@ function exitReligionsManualAssignment(close) {
ensureEl("religionsEditor")
.querySelectorAll(".hide")
.forEach(el => el.classList.remove("hidden"));
ensureEl("religionsFooter").style.display = "block";
ensureEl("religionsFooter").style.display = "flex";
$body.querySelectorAll("div > input, select, span, svg").forEach(e => (e.style.pointerEvents = "all"));
if (!close) $("#religionsEditor").dialog({ position: { my: "right top", at: "right-10 top+10", of: "svg" } });

Expand Down Expand Up @@ -809,15 +843,28 @@ function addReligion() {
function downloadReligionsCsv() {
const unit = getAreaUnit("2");
const headers = `Id,Name,Color,Type,Form,Supreme Deity,Area ${unit},Believers,Origins,Potential,Expansionism`;
const lines = Array.from($body.querySelectorAll(":scope > div"));
const data = lines.map($line => {
const { id, name, color, type, form, deity, area, population, expansion, expansionism } = $line.dataset;
const deityText = '"' + deity + '"';
const { origins } = pack.religions[+id];
const originList = (origins || []).filter(origin => origin).map(origin => pack.religions[origin].name);
const originText = '"' + originList.join(", ") + '"';
return [id, name, color, type, form, deityText, area, population, originText, expansion, expansionism].join(",");
});
const data = pack.religions
.filter(r => !r.removed && !(r.i && !r.cells && $body.dataset.extinct !== "show"))
.map(r => {
const area = getArea(r.area);
const population = rn(r.rural * populationRate + r.urban * populationRate * urbanization);
const deityText = '"' + (r.deity || "") + '"';
const originList = (r.origins || []).filter(origin => origin).map(origin => pack.religions[origin].name);
const originText = '"' + originList.join(", ") + '"';
return [
r.i,
r.name,
r.color || "",
r.type || "",
r.form || "",
deityText,
area,
population,
originText,
r.expansion || "",
r.i ? (r.expansionism ?? "") : ""
].join(",");
});
const csvData = [headers].concat(data).join("\n");

const name = getFileName("Religions") + ".csv";
Expand Down
Loading
Loading