"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);