class_name Climate extends RefCounted ## Климатическая норма: какой температуры и ветра ждать в это время года. ## ## Средняя полоса Европы — ориентир, а не точная модель. Только вычисления: ## погода (weather_system.gd) берёт отсюда цель и плавно к ней идёт. ## Среднемесячная температура, °C, с января по декабрь. const MONTHLY_MEAN: Array[float] = [ 0.5, 1.5, 5.0, 9.5, 14.0, 17.0, 19.0, 18.5, 14.5, 9.5, 4.5, 1.5, ] ## Суточный размах по месяцам: зимой день и ночь ближе друг к другу, чем летом. const MONTHLY_SWING: Array[float] = [ 4.0, 5.0, 7.0, 9.0, 10.0, 11.0, 11.0, 10.5, 9.0, 7.0, 4.5, 3.5, ] ## Самый тёплый час суток; самый холодный — через двенадцать часов от него. const WARMEST_HOUR := 15.0 ## Поправка к температуре по типу погоды, °C. Индекс — WeatherSystem.Kind; ## перечисление сюда не тянем, иначе получится циклическая ссылка между ## классами: погода уже зависит от климата. const WEATHER_OFFSET: Array[float] = [1.5, 0.0, -1.0, -2.0, -3.0, -1.5, -3.0] ## Характерная скорость ветра по тем же типам, м/с. const WEATHER_WIND: Array[float] = [2.5, 4.0, 5.5, 7.5, 15.0, 1.0, 5.0] ## Выше этого осадки идут дождём, ниже — снегом. const SNOW_THRESHOLD := 0.5 ## Ветер сильнее этого считаем предельным для визуализации. const WIND_REFERENCE := 18.0 ## Норма для месяца (1..12) и часа суток, без учёта погоды. static func base_temperature(month: int, hour: float) -> float: var index := clampi(month - 1, 0, 11) var mean := MONTHLY_MEAN[index] var swing := MONTHLY_SWING[index] # Суточный ход — косинус с максимумом в WARMEST_HOUR. var phase := (hour - WARMEST_HOUR) / 24.0 * TAU return mean + swing * 0.5 * cos(phase) static func weather_offset(kind: int) -> float: if kind < 0 or kind >= WEATHER_OFFSET.size(): return 0.0 return WEATHER_OFFSET[kind] static func base_wind(kind: int) -> float: if kind < 0 or kind >= WEATHER_WIND.size(): return 3.0 return WEATHER_WIND[kind] ## «12°C» — для HUD. static func temperature_text(celsius: float) -> String: return "%d°C" % roundi(celsius) ## «4 м/с» — для HUD. static func wind_text(speed: float) -> String: return "%d м/с" % roundi(speed)