87 lines
3.9 KiB
JavaScript
87 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) {
|
|
global.TarinaiStructureLifecycle?.maintainDependencies?.(worldRef);
|
|
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);
|