Implement weather system and developer console features. Added functionality for setting weather conditions, temperature, and wind speed through a new developer console. Enhanced the vault scene to display current weather, temperature, and wind information, and updated game clock to allow time manipulation. Improved cloud rendering and introduced a new climate management system for seasonal temperature adjustments.
This commit is contained in:
+173
-1
@@ -31,7 +31,10 @@ enum Mode { SELECT, BUILD, DEMOLISH }
|
||||
@onready var _weather: WeatherSystem = $Weather
|
||||
@onready var _sky: SkyView = $Sky
|
||||
@onready var _surface: SurfaceView = $Surface
|
||||
@onready var _weather_label: Label = $Hud/Root/TopRight/Row/ClockBar/Body/Moment/WeatherLabel
|
||||
@onready var _weather_icon: WeatherIcon = $Hud/Root/TopRight/Row/ClockBar/Body/Climate/Icon
|
||||
@onready var _weather_label: Label = $Hud/Root/TopRight/Row/ClockBar/Body/Climate/WeatherLabel
|
||||
@onready var _temp_label: Label = $Hud/Root/TopRight/Row/ClockBar/Body/Climate/TempLabel
|
||||
@onready var _wind_label: Label = $Hud/Root/TopRight/Row/ClockBar/Body/Climate/WindLabel
|
||||
@onready var _stats: HBoxContainer = $Hud/Root/TopBar/Stats
|
||||
@onready var _date_label: Label = $Hud/Root/TopRight/Row/ClockBar/Body/Moment/DateLabel
|
||||
@onready var _time_label: Label = $Hud/Root/TopRight/Row/ClockBar/Body/Moment/TimeLabel
|
||||
@@ -76,6 +79,7 @@ func _ready() -> void:
|
||||
_refresh_moment()
|
||||
_refresh_flow()
|
||||
_on_weather_changed(_weather.kind)
|
||||
_register_console_commands()
|
||||
|
||||
_status.text = HINT
|
||||
|
||||
@@ -191,6 +195,163 @@ func _describe(room: Dictionary) -> String:
|
||||
return " · ".join(parts)
|
||||
|
||||
|
||||
# --- Команды консоли --------------------------------------------------------
|
||||
|
||||
## Команды живут здесь, а не в самой консоли: они управляют этой сценой и
|
||||
## умирают вместе с ней — консоль сама выбросит их, когда Callable протухнет.
|
||||
func _register_console_commands() -> void:
|
||||
var console := get_node_or_null("/root/DevConsole")
|
||||
if console == null:
|
||||
return
|
||||
|
||||
console.register("stats", "текущее состояние партии", _cmd_stats)
|
||||
console.register("time", "перевести часы", _cmd_time, "ЧЧ:ММ")
|
||||
console.register("date", "сменить дату", _cmd_date, "ДД.ММ.ГГГГ")
|
||||
console.register("speed", "скорость игры, 0 — пауза", _cmd_speed, "0..4")
|
||||
console.register(
|
||||
"weather", "поставить погоду", _cmd_weather,
|
||||
"clear|cloudy|overcast|rain|storm|fog|snow"
|
||||
)
|
||||
console.register("temp", "задать температуру", _cmd_temp, "°C")
|
||||
console.register("wind", "задать ветер", _cmd_wind, "м/с")
|
||||
console.register("build", "построить комнату", _cmd_build, "тип этаж колонка")
|
||||
console.register("wipe", "снести все комнаты", _cmd_wipe)
|
||||
|
||||
|
||||
func _cmd_stats(_arguments: Array[String]) -> String:
|
||||
var totals := _grid.totals()
|
||||
return "\n".join(PackedStringArray([
|
||||
"Время: %s, %s (%s, x%d)" % [
|
||||
_clock.date_text(), _clock.time_text(),
|
||||
"идёт" if _clock.running else "пауза", _clock.speed,
|
||||
],
|
||||
"Погода: %s, %s, ветер %s" % [
|
||||
_weather.label(),
|
||||
Climate.temperature_text(_weather.temperature),
|
||||
Climate.wind_text(_weather.wind_speed),
|
||||
],
|
||||
"Облака: %.2f · осадки %.2f · дымка %.2f" % [
|
||||
_weather.clouds, _weather.precipitation, _weather.fog,
|
||||
],
|
||||
"Комнат: %d" % _grid.rooms.size(),
|
||||
"Ресурсы: питание %+d, вода %+d, еда %+d" % [
|
||||
int(totals["power"]), int(totals["water"]), int(totals["food"]),
|
||||
],
|
||||
]))
|
||||
|
||||
|
||||
func _cmd_time(arguments: Array[String]) -> String:
|
||||
if arguments.is_empty():
|
||||
return "Нужен аргумент: time ЧЧ:ММ"
|
||||
var parts := arguments[0].split(":")
|
||||
if parts.size() != 2:
|
||||
return "Не разобрал время: %s" % arguments[0]
|
||||
|
||||
var moment := _clock.now()
|
||||
moment["hour"] = clampi(int(String(parts[0])), 0, 23)
|
||||
moment["minute"] = clampi(int(String(parts[1])), 0, 59)
|
||||
if not _clock.set_moment(moment):
|
||||
return "Этот момент раньше начала партии."
|
||||
|
||||
_refresh_all()
|
||||
return "Часы: %s" % _clock.time_text()
|
||||
|
||||
|
||||
func _cmd_date(arguments: Array[String]) -> String:
|
||||
if arguments.is_empty():
|
||||
return "Нужен аргумент: date ДД.ММ.ГГГГ"
|
||||
var parts := arguments[0].split(".")
|
||||
if parts.size() != 3:
|
||||
return "Не разобрал дату: %s" % arguments[0]
|
||||
|
||||
var moment := _clock.now()
|
||||
moment["day"] = clampi(int(String(parts[0])), 1, 31)
|
||||
moment["month"] = clampi(int(String(parts[1])), 1, 12)
|
||||
moment["year"] = int(String(parts[2]))
|
||||
if not _clock.set_moment(moment):
|
||||
return "Этот момент раньше начала партии."
|
||||
|
||||
_refresh_all()
|
||||
return "Дата: %s" % _clock.date_text()
|
||||
|
||||
|
||||
func _cmd_speed(arguments: Array[String]) -> String:
|
||||
if arguments.is_empty():
|
||||
return "Нужен аргумент: speed 0..4"
|
||||
var value := int(arguments[0])
|
||||
if value <= 0:
|
||||
_clock.pause()
|
||||
return "Пауза."
|
||||
_clock.set_speed(value)
|
||||
return "Скорость x%d" % _clock.speed
|
||||
|
||||
|
||||
func _cmd_weather(arguments: Array[String]) -> String:
|
||||
if arguments.is_empty():
|
||||
return "Нужен аргумент: weather clear|cloudy|overcast|rain|storm|fog|snow"
|
||||
|
||||
# Понимаем и латинский ключ, и русское название — как удобнее.
|
||||
var wanted := arguments[0].to_lower()
|
||||
for kind: int in WeatherSystem.KINDS:
|
||||
var entry: Dictionary = WeatherSystem.KINDS[kind]
|
||||
if String(entry["key"]) != wanted and String(entry["label"]).to_lower() != wanted:
|
||||
continue
|
||||
_weather.force_kind(kind)
|
||||
_refresh_all()
|
||||
return "Погода: %s" % _weather.label()
|
||||
return "Не знаю такой погоды: %s" % arguments[0]
|
||||
|
||||
|
||||
func _cmd_temp(arguments: Array[String]) -> String:
|
||||
if arguments.is_empty():
|
||||
return "Нужен аргумент: temp °C"
|
||||
_weather.nudge_temperature(float(arguments[0]))
|
||||
_refresh_all()
|
||||
return "Температура: %s" % Climate.temperature_text(_weather.temperature)
|
||||
|
||||
|
||||
func _cmd_wind(arguments: Array[String]) -> String:
|
||||
if arguments.is_empty():
|
||||
return "Нужен аргумент: wind м/с"
|
||||
_weather.set_wind_speed(float(arguments[0]))
|
||||
_refresh_all()
|
||||
return "Ветер: %s" % Climate.wind_text(_weather.wind_speed)
|
||||
|
||||
|
||||
func _cmd_build(arguments: Array[String]) -> String:
|
||||
if arguments.size() < 3:
|
||||
return "Нужно: build тип этаж колонка. Типы: %s" % ", ".join(VaultGrid.KINDS.keys())
|
||||
|
||||
var kind := arguments[0]
|
||||
if not VaultGrid.KINDS.has(kind):
|
||||
return "Нет такого типа: %s" % kind
|
||||
|
||||
var a_floor := int(arguments[1]) - 1
|
||||
var column := int(arguments[2])
|
||||
if not _grid.place(kind, a_floor, column):
|
||||
return "Сюда не поставить: занято или вплотную к шахте."
|
||||
|
||||
_after_change("Построено из консоли: %s" % VaultGrid.KINDS[kind]["label"])
|
||||
return "Готово: %s на этаже %d" % [VaultGrid.KINDS[kind]["label"], a_floor + 1]
|
||||
|
||||
|
||||
func _cmd_wipe(_arguments: Array[String]) -> String:
|
||||
var removed := _grid.rooms.size()
|
||||
_grid.rooms.clear()
|
||||
_after_change("Убежище очищено.")
|
||||
return "Снесено комнат: %d" % removed
|
||||
|
||||
|
||||
## После вмешательства извне проще обновить всё, чем вспоминать, что зависит
|
||||
## от чего.
|
||||
func _refresh_all() -> void:
|
||||
_refresh_moment()
|
||||
_refresh_environment()
|
||||
_refresh_weather_hud()
|
||||
_refresh_flow()
|
||||
_refresh_stats()
|
||||
|
||||
|
||||
# --- Ход времени ------------------------------------------------------------
|
||||
|
||||
func _build_flow_controls() -> void:
|
||||
@@ -249,10 +410,21 @@ func _flow_style(background: String, border: String) -> StyleBoxFlat:
|
||||
func _on_minute_passed(_total_minutes: int) -> void:
|
||||
_refresh_moment()
|
||||
_refresh_environment()
|
||||
_refresh_weather_hud()
|
||||
|
||||
|
||||
func _on_weather_changed(_kind: int) -> void:
|
||||
_refresh_weather_hud()
|
||||
|
||||
|
||||
func _refresh_weather_hud() -> void:
|
||||
var hour := SkyCycle.hour_of(_clock.now())
|
||||
var is_night := SkyCycle.sun_progress(hour) < 0.0
|
||||
|
||||
_weather_icon.set_state(_weather.kind, is_night)
|
||||
_weather_label.text = _weather.label()
|
||||
_temp_label.text = Climate.temperature_text(_weather.temperature)
|
||||
_wind_label.text = Climate.wind_text(_weather.wind_speed)
|
||||
|
||||
|
||||
func _refresh_moment() -> void:
|
||||
|
||||
Reference in New Issue
Block a user