Refactor game scripts and update vault scene structure. Enhanced organization of game logic by separating data and rendering responsibilities across multiple scripts. Removed unused background assets and updated vault scene to include new game clock and weather system functionalities.
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
class_name GameClock
|
||||
extends Node
|
||||
## Игровые дата и время.
|
||||
##
|
||||
## Отдельная сущность, а не поле сцены: ход времени понадобится производству,
|
||||
## жителям и событиям, и сохранение обязано его восстанавливать.
|
||||
##
|
||||
## Пауза здесь своя, не движковая. `get_tree().paused` останавливает вообще всё
|
||||
## и занята меню паузы; здесь же нужно останавливать только ход партии, оставляя
|
||||
## интерфейс живым. При этом узел обычный, PAUSABLE, поэтому меню паузы
|
||||
## замораживает время само собой.
|
||||
|
||||
## Старт партии: 1 апреля 2012 года, шесть утра.
|
||||
const START := {"year": 2012, "month": 4, "day": 1, "hour": 6, "minute": 0, "second": 0}
|
||||
|
||||
## Сколько игровых минут проходит за секунду реального времени на скорости x1.
|
||||
## Сутки при этом занимают 8 минут реального времени. Множители x2…x4
|
||||
## умножают именно это значение, так что менять темп достаточно здесь.
|
||||
const MINUTES_PER_SECOND := 3.0
|
||||
|
||||
## Доступные множители скорости.
|
||||
const SPEEDS: Array[int] = [1, 2, 3, 4]
|
||||
|
||||
const MINUTES_PER_DAY := 24 * 60
|
||||
|
||||
const MONTHS: Array[String] = [
|
||||
"января", "февраля", "марта", "апреля", "мая", "июня",
|
||||
"июля", "августа", "сентября", "октября", "ноября", "декабря",
|
||||
]
|
||||
|
||||
## Прошла игровая минута — сюда подключаются HUD, производство, события.
|
||||
signal minute_passed(total_minutes: int)
|
||||
## Сменились сутки.
|
||||
signal day_passed(day_index: int)
|
||||
## Изменились скорость или состояние паузы.
|
||||
signal flow_changed
|
||||
|
||||
var running := true
|
||||
var speed := 1
|
||||
|
||||
var _start_unix := int(Time.get_unix_time_from_datetime_dict(START))
|
||||
var _elapsed_minutes := 0.0
|
||||
var _last_whole_minute := 0
|
||||
var _last_day := 0
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
if not running:
|
||||
return
|
||||
_advance(delta * MINUTES_PER_SECOND * float(speed))
|
||||
|
||||
|
||||
# --- Текущий момент ---------------------------------------------------------
|
||||
|
||||
## Момент как словарь Time: year, month, day, hour, minute, second.
|
||||
func now() -> Dictionary:
|
||||
return Time.get_datetime_dict_from_unix_time(unix_time())
|
||||
|
||||
|
||||
func unix_time() -> int:
|
||||
return _start_unix + int(_elapsed_minutes) * 60
|
||||
|
||||
|
||||
## «1 апреля 2012»
|
||||
func date_text() -> String:
|
||||
var moment := now()
|
||||
return "%d %s %d" % [
|
||||
int(moment["day"]), MONTHS[int(moment["month"]) - 1], int(moment["year"]),
|
||||
]
|
||||
|
||||
|
||||
## «06:00»
|
||||
func time_text() -> String:
|
||||
var moment := now()
|
||||
return "%02d:%02d" % [int(moment["hour"]), int(moment["minute"])]
|
||||
|
||||
|
||||
# --- Управление ходом -------------------------------------------------------
|
||||
|
||||
func set_speed(value: int) -> void:
|
||||
speed = clampi(value, SPEEDS[0], SPEEDS[SPEEDS.size() - 1])
|
||||
running = true
|
||||
flow_changed.emit()
|
||||
|
||||
|
||||
func play() -> void:
|
||||
if running:
|
||||
return
|
||||
running = true
|
||||
flow_changed.emit()
|
||||
|
||||
|
||||
func pause() -> void:
|
||||
if not running:
|
||||
return
|
||||
running = false
|
||||
flow_changed.emit()
|
||||
|
||||
|
||||
func toggle() -> void:
|
||||
running = not running
|
||||
flow_changed.emit()
|
||||
|
||||
|
||||
# --- Сохранение -------------------------------------------------------------
|
||||
|
||||
func save_data() -> Dictionary:
|
||||
return {"minutes": _elapsed_minutes, "speed": speed, "running": running}
|
||||
|
||||
|
||||
func load_data(data: Dictionary) -> void:
|
||||
_elapsed_minutes = maxf(float(data.get("minutes", 0.0)), 0.0)
|
||||
speed = clampi(int(data.get("speed", 1)), SPEEDS[0], SPEEDS[SPEEDS.size() - 1])
|
||||
running = bool(data.get("running", true))
|
||||
_last_whole_minute = int(_elapsed_minutes)
|
||||
_last_day = _day_index()
|
||||
flow_changed.emit()
|
||||
minute_passed.emit(_last_whole_minute)
|
||||
|
||||
|
||||
# --- Внутреннее -------------------------------------------------------------
|
||||
|
||||
func _advance(minutes: float) -> void:
|
||||
_elapsed_minutes += minutes
|
||||
|
||||
# Сигналим по целым минутам, а не каждый кадр: подписчикам нужен такт,
|
||||
# а не дробное значение.
|
||||
var whole := int(_elapsed_minutes)
|
||||
if whole == _last_whole_minute:
|
||||
return
|
||||
_last_whole_minute = whole
|
||||
minute_passed.emit(whole)
|
||||
|
||||
var day := _day_index()
|
||||
if day == _last_day:
|
||||
return
|
||||
_last_day = day
|
||||
day_passed.emit(day)
|
||||
|
||||
|
||||
func _day_index() -> int:
|
||||
return floori(_elapsed_minutes / float(MINUTES_PER_DAY))
|
||||
Reference in New Issue
Block a user