tarinai/js/simulation_maintenance_system.js
2026-07-10 16:40:06 +09:00

86 lines
3.9 KiB
JavaScript

"use strict";
// Layer: simulation/system-maintenance
// Owns periodic compaction, counts refresh, grass limit enforcement,
// out-of-bounds cleanup, and draw-list invalidation.
(function (global) {
function runMaintenance(worldRef, dt, itemCountBefore) {
worldRef.compactTimer += dt;
const compactInterval = 2.5;
let itemsCompacted = false;
if (worldRef.compactTimer >= compactInterval) {
itemsCompacted = worldRef.compactItems();
worldRef.compactTarinai();
worldRef.compactAnts?.();
worldRef.compactTimer = 0;
}
worldRef.countsTimer += dt;
const countsInterval = 2.75;
const itemCountChanged = worldRef.items.length !== itemCountBefore || worldRef.items.length !== (worldRef._lastMaintenanceItemCount ?? worldRef.items.length);
const effectCountChanged = worldRef.effects.length !== (worldRef._lastMaintenanceEffectCount ?? worldRef.effects.length);
const countsDue = worldRef.countsTimer >= countsInterval;
if (countsDue || itemsCompacted || itemCountChanged || effectCountChanged || worldRef.itemBucketsDirty) {
if (countsDue || itemsCompacted || itemCountChanged || worldRef.itemBucketsDirty) worldRef.updateItemCounts();
if (countsDue || itemsCompacted || effectCountChanged) worldRef.updateEffectCounts();
worldRef._lastMaintenanceItemCount = worldRef.items.length;
worldRef._lastMaintenanceEffectCount = worldRef.effects.length;
worldRef.countsTimer = 0;
}
if ((worldRef.time || 0) >= (worldRef.nextGrassLimitCheckAt || 0)) {
worldRef.nextGrassLimitCheckAt = (worldRef.time || 0) + 3.0;
const removedGrass = worldRef.enforceGrassLimit?.("periodic-grass-limit") || 0;
if (removedGrass > 0) {
worldRef.compactItems();
worldRef.updateItemCounts();
}
}
if ((worldRef.time || 0) >= (worldRef.nextFireCompactAt || 0)) {
worldRef.nextFireCompactAt = (worldRef.time || 0) + 0.8;
const compactedFires = global.TarinaiItemDynamicToolSystem?.compactWorldFires?.(worldRef) || 0;
if (compactedFires > 0) {
itemsCompacted = true;
worldRef.updateItemCounts();
}
}
if ((worldRef.time || 0) >= (worldRef.nextGrassBedExpiryCheckAt || 0)) {
worldRef.nextGrassBedExpiryCheckAt = (worldRef.time || 0) + 5.0;
const lifespan = Math.max(1, CONFIG.dayLength || 120); // \u30B2\u30FC\u30E0\u518524\u6642\u9593
let removedBeds = 0;
const grassBeds = typeof worldRef.itemsOfType === "function" ? worldRef.itemsOfType("grass_bed") : (worldRef.items || []);
for (const it of grassBeds || []) {
if (!it || it.dead || it.type !== "grass_bed") continue;
if (!Number.isFinite(Number(it.createdAt))) it.createdAt = worldRef.time || 0;
if ((worldRef.time || 0) - Number(it.createdAt || 0) < lifespan) continue;
const removed = global.TarinaiStructureLifecycle?.deleteItem?.(worldRef, it, {
reason: "grass-bed-expired",
userReason: "\u304B\u3093\u305F\u3093\u30D9\u30C3\u30C9\u304C\u53E4\u304F\u306A\u3063\u3066\u6D88\u3048\u305F",
wake: false,
panicOwner: false,
});
if (removed) removedBeds += 1;
}
if (removedBeds > 0) {
worldRef.compactItems();
worldRef.updateItemCounts();
worldRef.markSpatialDirty?.("grass-bed-expired");
worldRef.markTerrainDirty?.("grass-bed-expired");
}
}
if ((worldRef.outOfBoundsCheckAt || -999) + 5.0 <= worldRef.time) {
worldRef.outOfBoundsCheckAt = worldRef.time;
worldRef.sanitizeOutOfBounds();
}
// Render builds the visible stack from spatial cells every frame; the old
// drawListDirty periodic invalidation is no longer a render input.
worldRef.drawSortTimer = 0;
}
global.TarinaiMaintenanceSimulationSystem = Object.freeze({
phases: Object.freeze({ runMaintenance }),
});
})(typeof window !== "undefined" ? window : globalThis);