66 lines
2.7 KiB
GDScript
66 lines
2.7 KiB
GDScript
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)
|