"use strict"; (function (global) { const DomainIds = global.TarinaiDomainIds; if (!DomainIds) throw new Error("TarinaiDomainIds must be loaded before weather_system.js"); const WEATHER_IDS = DomainIds.WEATHER_IDS; function canonicalWeather(value = "sunny") { return DomainIds.canonicalWeatherId(value); } function chooseNext(current = "sunny") { const id = canonicalWeather(current); const choices = id === "light_rain" ? WEATHER_IDS.filter(weather => weather !== "light_rain") : WEATHER_IDS; return pick(choices); } function resetTimer() { return rand(CONFIG.weatherChangeMin, CONFIG.weatherChangeMax); } function fixedWeatherFor(worldRef) { const fixed = global.TarinaiGround.fixedWeather(worldRef?.groundType || "soil") || ""; return fixed || null; } function enforceFixedWeather(worldRef) { const fixed = fixedWeatherFor(worldRef); if (!fixed || !worldRef) return false; const previous = canonicalWeather(worldRef.weather || "sunny"); worldRef.weather = canonicalWeather(fixed); worldRef.nextWeatherChange = resetTimer(); if (previous !== worldRef.weather) { worldRef.log?.(`\u5929\u6C17: ${weatherLabel(worldRef.weather)}`); } return true; } function shouldDropRainWater(worldRef, dt = 0) { return Boolean( worldRef?.weather === "light_rain" && Math.random() < Math.max(0, Number(dt) || 0) * 0.24 ); } function createRainWaterItem(worldRef, opts = {}) { const px = Number(opts?.x); const py = Number(opts?.y); const hasX = Number.isFinite(px); const hasY = Number.isFinite(py); const x = hasX ? px : rand(58, worldRef.w - 58); const y = hasY ? py : rand(58, worldRef.h - 58); const drop = new Item("water", x, y); drop.rainDrop = opts?.rainDrop === true || (!hasX && !hasY); const amount = Number(opts?.amount); drop.amount = Number.isFinite(amount) ? amount : rand(24, 58); // Rain drops, placed water drops, and water-balloon splashes all use the // same Item("water") object. Optional velocity only gives that same water // item a short ballistic motion; it is not a separate splash item type. const vx = Number(opts?.vx); const vy = Number(opts?.vy); if (Number.isFinite(vx) || Number.isFinite(vy)) { drop.prevX = drop.x; drop.prevY = drop.y; drop.vx = Number.isFinite(vx) ? vx : 0; drop.vy = Number.isFinite(vy) ? vy : 0; } const flight = Number(opts?.splashFlightTimer ?? opts?.flightTimer); if (Number.isFinite(flight) && flight > 0) drop.splashFlightTimer = flight; return drop; } function applyNextWeather(worldRef) { if (!worldRef) return null; if (enforceFixedWeather(worldRef)) return worldRef.weather || "sunny"; const previous = canonicalWeather(worldRef.weather || "sunny"); const next = chooseNext(previous); worldRef.weather = canonicalWeather(next); worldRef.nextWeatherChange = resetTimer(); if (next !== previous) { worldRef.log?.(`\u5929\u6C17: ${weatherLabel(next)}`); } return next; } global.TarinaiWeatherSystem = Object.freeze({ enforceFixedWeather, shouldDropRainWater, createRainWaterItem, applyNextWeather, }); })(typeof window !== "undefined" ? window : globalThis);