tarinai/js/simulation_ambient_system.js
2026-07-11 21:13:39 +09:00

56 lines
2.6 KiB
JavaScript

"use strict";
// Layer: simulation/system-ambient-spawn
// Owns low-frequency ambient Tarinai/grass/rain-water creation.
(function (global) {
function spawnAmbientTarinai(worldRef, dt) {
if ((worldRef.canAddTarinai?.(1) ?? true) && worldRef.tarinai.length > 0 && worldRef.tarinai.length <= 10 && worldRef.time - (worldRef.lastBirthAt || -999) > 12 && Math.random() < dt * 0.022) {
const spot = worldRef.edgeSpawnPoint(null, null, 42, true);
const t = worldRef.addTarinai({ x: spot.x, y: spot.y, vx: spot.vx, vy: spot.vy, entryTimer: 2.0 });
if (!t) return;
t.wanderAngle = spot.angle;
t.surpriseTimer = Math.max(t.surpriseTimer || 0, 0.35);
worldRef.log(`${t.name}\u304c\u753b\u9762\u5916\u304b\u3089\u8ff7\u3044\u8fbc\u3093\u3067\u304d\u305f\u3002`);
}
}
function spawnAmbientGrass(worldRef, dt) {
if ((worldRef.groundGrassMultiplier?.() ?? 1) <= 0) return;
const groundGrowthMul = Math.max(0, Number(global.TarinaiGround.grassGrowthMultiplier(worldRef.groundType || "soil") ?? (worldRef.groundGrassMultiplier?.() ?? 1)) || 0);
if (groundGrowthMul <= 0) return;
if ((worldRef.canAddGrass?.(1) ?? true) && Math.random() < dt * 0.070 * groundGrowthMul) {
const spot = worldRef.findGrassPlantingSpot(rand(60, worldRef.w - 60), rand(60, worldRef.h - 60), {
allowOriginal: true,
minRadius: 28,
maxRadius: 140,
attempts: 18,
});
if (spot) {
const sprout = new Item("grass", spot.x, spot.y);
global.TarinaiGrass.setStage(sprout, 0, { force: true });
worldRef.addItem?.(sprout, "grass-spawn");
}
}
}
function spawnRainWater(worldRef, dt) {
// Rain visuals are diagonal line streaks in render.js. This branch creates
// horizontal oval water items spawned by rain; it intentionally does not
// share the rain overlay renderer.
if (global.TarinaiWeatherSystem.shouldDropRainWater(worldRef, dt)) {
const drop = global.TarinaiWeatherSystem.createRainWaterItem(worldRef, { rainDrop: true });
const sand = worldRef.toiletSandAt?.(drop.x, drop.y) || null;
if (sand) {
sand.toiletFlash = 1;
sand.awakeUntil = Math.max(sand.awakeUntil || 0, (worldRef.time || 0) + 0.8);
worldRef.markTerrainDirtyAt?.(sand.x, sand.y, Math.max(64, (sand.r || 48) * 1.72), "toilet-sand-rain-absorb");
return;
}
worldRef.addItem?.(drop, "rain-water");
}
}
global.TarinaiAmbientSimulationSystem = Object.freeze({
phases: Object.freeze({ spawnAmbientTarinai, spawnAmbientGrass, spawnRainWater }),
});
})(typeof window !== "undefined" ? window : globalThis);