import { type SchedulePhase } from "../time/stateSchedule.js"; import type { WindField, WindVector } from "./wind.js"; export interface WindZoneState { direction: WindVector; speed: number; /** Announcement label for HUD countdowns ("gale", "calm", "tailwind"). */ label?: string; } export interface WindZoneConfig { id: string; center: readonly [number, number]; radius: number; /** The zone's scheduled wind states; a single phase makes a static zone. */ phases: readonly SchedulePhase[]; /** Staggers this zone's schedule against identical ones. */ offsetSeconds?: number; } export interface WindZonesConfig { zones: readonly WindZoneConfig[]; /** Wind outside every zone; omit for dead air. */ ambient?: WindField; } export interface WindShiftForecast { zoneId: string; /** Absolute time the zone's next state begins. */ at: number; /** Seconds from the queried time until the shift. */ inSeconds: number; next: WindZoneState; } /** * Named, discrete wind zones over an ambient field — each zone runs a deterministic * `StateSchedule` of wind states, so games get scheduled shifts with advance announcement * (`forecastShift` drives the "gale in 12s" countdown) instead of one continuous field. */ export interface WindZones { zoneIds(): readonly string[]; /** Innermost zone containing the point (later declarations win ties); `null` in open air. */ zoneAt(x: number, z: number): string | null; /** The wind vector at a point and time: the containing zone's scheduled state, else ambient. */ windAt(x: number, z: number, t: number): WindVector; /** A zone's live state; `null` for an unknown zone. */ stateAt(zoneId: string, t: number): WindZoneState | null; /** The zone's next scheduled shift after `t`; `null` for unknown or single-phase zones. */ forecastShift(zoneId: string, t: number): WindShiftForecast | null; } export declare function createWindZones(config: WindZonesConfig): WindZones;