y
This commit is contained in:
parent
61718e2981
commit
f657b6a4a4
94 changed files with 3970 additions and 1241 deletions
|
|
@ -18,30 +18,73 @@ function colonyChartObjectKeys() {
|
|||
return ["grass", "zunchi", "trace", "grass_bed", "water"];
|
||||
}
|
||||
|
||||
function renderStats() {
|
||||
const alive = world.tarinai;
|
||||
const isDiseased = (t) => Boolean(t?.zunchiDisease || t?.sleepDisease || t?.explosionDisease || t?.fightDisease);
|
||||
const lifeRatio = (t) => Math.max(0, Math.min(1, (Number(t?.age || 0) || 0) / Math.max(1, Number(t?.lifeSpan || 1) || 1)));
|
||||
const sickCount = alive.reduce((n, t) => n + (isDiseased(t) ? 1 : 0), 0);
|
||||
const juvenileCount = alive.reduce((n, t) => n + (lifeRatio(t) <= 0.10 ? 1 : 0), 0);
|
||||
const elderCount = alive.reduce((n, t) => n + (lifeRatio(t) >= 0.80 ? 1 : 0), 0);
|
||||
const avg = (fn) => alive.length ? alive.reduce((a, t) => a + fn(t), 0) / alive.length : 0;
|
||||
function colonyStatsUiVisible() {
|
||||
if (typeof document !== "undefined" && document.hidden) return false;
|
||||
const card = ui?.colonyChart?.closest?.(".colony-card") || null;
|
||||
if (!card) return Boolean(ui?.colonyChart);
|
||||
if (card.classList?.contains?.("hidden") || card.classList?.contains?.("collapsed")) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function collectDynamicColonyStats() {
|
||||
const needKeys = typeof TARINAI_NEED_KEYS !== "undefined" ? TARINAI_NEED_KEYS : ["food", "sleep", "health", "safety", "social", "fulfill"];
|
||||
const needAverages = Object.fromEntries(needKeys.map(key => [`need_${key}`, avg(t => Number(t.needs?.[key] || 0) || 0)]));
|
||||
const temp = world.updateTemperature?.(0) ?? world.currentTemperature ?? (CONFIG.standardTemperature ?? 15);
|
||||
const values = {
|
||||
pop: alive.length,
|
||||
const needSums = Object.fromEntries(needKeys.map(key => [key, 0]));
|
||||
let liveCount = 0;
|
||||
let sickCount = 0;
|
||||
let juvenileCount = 0;
|
||||
let elderCount = 0;
|
||||
let stressSum = 0;
|
||||
for (const t of world.tarinai || []) {
|
||||
if (!t || t.dead) continue;
|
||||
liveCount += 1;
|
||||
if (t.zunchiDisease || t.sleepDisease || t.explosionDisease || t.fightDisease) sickCount += 1;
|
||||
const ratio = Math.max(0, Math.min(1, (Number(t.age || 0) || 0) / Math.max(1, Number(t.lifeSpan || 1) || 1)));
|
||||
if (ratio <= 0.10) juvenileCount += 1;
|
||||
if (ratio >= 0.80) elderCount += 1;
|
||||
stressSum += Number(t.stress || 0) || 0;
|
||||
for (const key of needKeys) needSums[key] += Number(t.needs?.[key] || 0) || 0;
|
||||
}
|
||||
const divisor = Math.max(1, liveCount);
|
||||
const dynamic = {
|
||||
sick: sickCount,
|
||||
juvenile: juvenileCount,
|
||||
elder: elderCount,
|
||||
stress: liveCount ? stressSum / divisor : 0,
|
||||
ants: (world.ants || []).reduce((n, ant) => n + (ant && !ant.dead ? 1 : 0), 0),
|
||||
...Object.fromEntries(needKeys.map(key => [`need_${key}`, liveCount ? needSums[key] / divisor : 0])),
|
||||
};
|
||||
world._colonyStatsDynamicCache = dynamic;
|
||||
return dynamic;
|
||||
}
|
||||
|
||||
function renderStats(options = {}) {
|
||||
const colonyVisible = options.force === true || colonyStatsUiVisible();
|
||||
// Selected-data and family views are separate surfaces. Keep them fresh
|
||||
// without paying for colony aggregation while the colony card is hidden.
|
||||
if (!colonyVisible) {
|
||||
if (ui?.selectedCard && !ui.selectedCard.classList.contains("hidden")) renderSelected();
|
||||
return;
|
||||
}
|
||||
|
||||
const counts = world.tarinaiCounts?.() || world.rebuildTarinaiCountCache?.("stats") || { alive: 0, zunchiSlaves: 0, tarinaiKings: 0 };
|
||||
const liveCount = Math.max(0, Number(counts.alive || 0) || 0);
|
||||
const temp = world.currentTemperature ?? world.updateTemperature?.(0) ?? (CONFIG.standardTemperature ?? 15);
|
||||
const dynamic = collectDynamicColonyStats();
|
||||
const values = {
|
||||
pop: liveCount,
|
||||
zunchiSlaves: Math.max(0, Number(counts.zunchiSlaves || 0) || 0),
|
||||
tarinaiKings: Math.max(0, Number(counts.tarinaiKings || 0) || 0),
|
||||
sick: dynamic.sick || 0,
|
||||
juvenile: dynamic.juvenile || 0,
|
||||
elder: dynamic.elder || 0,
|
||||
dead: world.deadCount,
|
||||
birthEvents: Math.max(0, Number(world.birthEventCount || 0) || 0),
|
||||
deathEvents: Math.max(0, Number(world.deadCount || 0) || 0),
|
||||
stress: avg(t => t.stress),
|
||||
stress: dynamic.stress || 0,
|
||||
temperature: Number(temp) || 0,
|
||||
ants: (world.ants || []).reduce((n, ant) => n + (ant && !ant.dead ? 1 : 0), 0),
|
||||
...needAverages,
|
||||
objects: { ...(world.itemCounts || {}) },
|
||||
ants: dynamic.ants || 0,
|
||||
...dynamic,
|
||||
objects: world.itemCounts || {},
|
||||
};
|
||||
setTextIfChanged(ui.statSick, "sick", values.sick);
|
||||
setTextIfChanged(ui.statJuvenile, "juvenile", values.juvenile);
|
||||
|
|
@ -58,7 +101,7 @@ function renderStats() {
|
|||
if (ui.temperatureAutoToggle) ui.temperatureAutoToggle.checked = world.temperatureAuto !== false;
|
||||
const tarinaiLimit = Math.max(0, Number(world.tarinaiPopulationLimit) || 0);
|
||||
const objectLimit = Math.max(0, Number(world.objectLimit) || 0);
|
||||
const objectCount = world.activeObjectCount?.() ?? (world.items || []).filter(item => item && !item.dead).length;
|
||||
const objectCount = world.activeObjectCount?.() ?? 0;
|
||||
if (typeof window.syncColonyLimitControls === "function") {
|
||||
window.syncColonyLimitControls("tarinai", tarinaiLimit);
|
||||
window.syncColonyLimitControls("object", objectLimit);
|
||||
|
|
@ -72,7 +115,7 @@ function renderStats() {
|
|||
window.TarinaiGroundUI.update(world);
|
||||
updateColonyHistory(values);
|
||||
drawColonyChart(values);
|
||||
renderSelected();
|
||||
if (ui?.selectedCard && !ui.selectedCard.classList.contains("hidden")) renderSelected();
|
||||
if (world.familyTreeDirty) scheduleArchiveWindowRender();
|
||||
}
|
||||
|
||||
|
|
@ -102,6 +145,8 @@ function updateColonyHistory(values) {
|
|||
count: 0,
|
||||
sums: {
|
||||
pop: 0,
|
||||
zunchiSlaves: 0,
|
||||
tarinaiKings: 0,
|
||||
sick: 0,
|
||||
juvenile: 0,
|
||||
elder: 0,
|
||||
|
|
@ -124,6 +169,8 @@ function updateColonyHistory(values) {
|
|||
const row = {
|
||||
t: bucket.end,
|
||||
pop: bucket.sums.pop / bucket.count,
|
||||
zunchiSlaves: bucket.sums.zunchiSlaves / bucket.count,
|
||||
tarinaiKings: bucket.sums.tarinaiKings / bucket.count,
|
||||
sick: bucket.sums.sick / bucket.count,
|
||||
juvenile: bucket.sums.juvenile / bucket.count,
|
||||
elder: bucket.sums.elder / bucket.count,
|
||||
|
|
@ -154,6 +201,8 @@ function updateColonyHistory(values) {
|
|||
uiCache.chartDeathEventSeen = currentDeathEvents;
|
||||
bucket.count += 1;
|
||||
bucket.sums.pop += values.pop || 0;
|
||||
bucket.sums.zunchiSlaves += values.zunchiSlaves || 0;
|
||||
bucket.sums.tarinaiKings += values.tarinaiKings || 0;
|
||||
bucket.sums.sick += values.sick || 0;
|
||||
bucket.sums.juvenile += values.juvenile || 0;
|
||||
bucket.sums.elder += values.elder || 0;
|
||||
|
|
@ -174,6 +223,8 @@ function chartRows(values) {
|
|||
return [{
|
||||
t: Math.max(0, Number(uiCache.chartBucketStart || 0) || 0),
|
||||
pop: 0,
|
||||
zunchiSlaves: 0,
|
||||
tarinaiKings: 0,
|
||||
sick: 0,
|
||||
juvenile: 0,
|
||||
elder: 0,
|
||||
|
|
@ -320,6 +371,8 @@ function chartSeries(mode = "population") {
|
|||
{ key: "elder", label: "\u8001\u4f53", color: "#8a7054" },
|
||||
{ key: "births", label: "\u8a95\u751f\u6570", color: "#d48ac2" },
|
||||
{ key: "deaths", label: "\u6b7b\u4ea1\u6570", color: "#4d4d56" },
|
||||
{ key: "zunchiSlaves", label: "\u305a\u3093\u3061\u3069\u308c\u3044", color: "#8f6a44" },
|
||||
{ key: "tarinaiKings", label: "\u305f\u308a\u306a\u3044\u738b", color: "#d4a62a" },
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue