tarinai/js/simulation_item_ant_system.js
2026-06-26 12:46:32 +09:00

63 lines
3.1 KiB
JavaScript

"use strict";
// Layer: simulation/system-items-ants
// Owns scheduled item updates, random grass growth, ball/ant spatial refresh,
// and item/ant spatial post-processing.
(function (global) {
const helpers = () => global.TarinaiSimulationRuntime?.helpers || {};
function updateRandomGrassGrowth(worldRef, dt) {
if (!worldRef || !global.TarinaiGrass) return false;
if ((worldRef.groundGrassMultiplier?.() ?? 1) <= 0) return false;
const groundGrowthMul = Math.max(0, Number(global.TarinaiGround?.grassGrowthMultiplier?.(worldRef.groundType || "soil") ?? (worldRef.groundGrassMultiplier?.() ?? 1)) || 0);
if (groundGrowthMul <= 0) return false;
worldRef.grassGrowthTimer = (worldRef.grassGrowthTimer || 0) + dt;
const field = worldRef.fieldType || "garden";
const growthSpeedMul = 6.0 * groundGrowthMul;
const interval = (field === "park" ? 1.8 : (field === "cage" ? 3.2 : 2.4)) / Math.max(0.1, growthSpeedMul);
if (worldRef.grassGrowthTimer < interval) return false;
worldRef.grassGrowthTimer = 0;
const grasses = worldRef.itemsOfType ? worldRef.itemsOfType("grass") : (worldRef.items || []).filter(it => it && it.type === "grass");
if (!grasses || !grasses.length) return false;
const tries = Math.min(12, grasses.length);
for (let i = 0; i < tries; i++) {
const it = grasses[Math.floor(Math.random() * grasses.length)];
if (!it || it.dead || (it.amount || 0) <= 0) continue;
if (worldRef.grassBlockedAt?.(it.x, it.y, it)) {
if (global.TarinaiGrass.regress(it, 1) > 0) {
worldRef.markTerrainDirtyAt?.(it.x, it.y, Math.max(it.r || 24, 36), "random-grass-blocked") || worldRef.markTerrainDirty?.("random-grass-blocked");
worldRef.markItemBucketsDirty?.("random-grass-blocked");
return true;
}
continue;
}
if (global.TarinaiGrass.advance(it, 1)) {
worldRef.markTerrainDirtyAt?.(it.x, it.y, Math.max(it.r || 24, 36), "random-grass-grow") || worldRef.markTerrainDirty?.("random-grass-grow");
return true;
}
}
return false;
}
function updateItemsAndAnts(worldRef, dt) {
const h = helpers();
const itemCountBefore = worldRef.items.length;
h.updateItemsScheduled?.(worldRef, dt);
updateRandomGrassGrowth(worldRef, dt);
const itemsMoved = h.markScheduledItemsMoved?.(worldRef, "items-moved", 0.25) || false;
if (worldRef.itemCounts?.ball) {
worldRef.ensureSpatial?.("ball-ball-collisions");
worldRef.resolveBallBallCollisions(dt);
worldRef.markSpatialDirty?.("ball-ball-collisions");
}
worldRef.updateAnts?.(dt);
const antsMoved = h.markSpatialDirtyIfMoved?.(worldRef, worldRef.ants || [], "ants-moved", 0.25) || false;
if (itemsMoved || antsMoved || worldRef.spatialDirty) worldRef.ensureSpatial?.("post-mobile-item-update");
return { itemCountBefore, itemsMoved, antsMoved };
}
const phases = Object.freeze({ updateItemsAndAnts });
const helpersApi = Object.freeze({ updateRandomGrassGrowth });
global.TarinaiItemAntSimulationSystem = Object.freeze({ phases, helpers: helpersApi });
})(typeof window !== "undefined" ? window : globalThis);