extends CanvasLayer ## Top-bar HUD: speed/pause buttons and tick counter. ## ## Buttons call Sim.set_speed(); active button is yellow-tinted. ## Tick label updates on every EventBus.sim_tick signal. ## Keyboard shortcuts (pause / speed_normal / speed_fast / speed_ultra) are ## handled here so the bar is the single owner of speed-input logic. const ACTIVE_MODULATE := Color(1.2, 1.2, 0.8) const IDLE_MODULATE := Color.WHITE @onready var pause_btn : Button = $Anchor/ButtonRow/PauseBtn @onready var normal_btn : Button = $Anchor/ButtonRow/NormalBtn @onready var fast_btn : Button = $Anchor/ButtonRow/FastBtn @onready var ultra_btn : Button = $Anchor/ButtonRow/UltraBtn @onready var tick_label : Label = $Anchor/TickLabel @onready var clock_label : Label = $Anchor/ClockLabel @onready var season_label : Label = $Anchor/SeasonLabel # Maps Speed enum value → the corresponding Button node. var _speed_buttons: Dictionary = {} # Early-out cache: only set label text when the string changes. var _last_clock_text: String = "" var _last_season_text: String = "" func _ready() -> void: pause_btn.text = Strings.t(&"speed.pause") normal_btn.text = Strings.t(&"speed.normal") fast_btn.text = Strings.t(&"speed.fast") ultra_btn.text = Strings.t(&"speed.ultra") tick_label.text = "(boot)" clock_label.text = Strings.t(&"clock.format").format({"d": 1, "t": "06:00"}) season_label.text = Strings.t(&"season.format").format({"s": Strings.t(&"season.spring"), "d": 1}) _speed_buttons = { Sim.Speed.PAUSE: pause_btn, Sim.Speed.NORMAL: normal_btn, Sim.Speed.FAST: fast_btn, Sim.Speed.ULTRA: ultra_btn, } pause_btn.pressed.connect(func() -> void: Sim.set_speed(Sim.Speed.PAUSE)) normal_btn.pressed.connect(func() -> void: Sim.set_speed(Sim.Speed.NORMAL)) fast_btn.pressed.connect(func() -> void: Sim.set_speed(Sim.Speed.FAST)) ultra_btn.pressed.connect(func() -> void: Sim.set_speed(Sim.Speed.ULTRA)) EventBus.speed_changed.connect(_on_speed_changed) EventBus.sim_tick.connect(_on_sim_tick) EventBus.sim_tick.connect(_on_clock_refresh) EventBus.sim_tick.connect(_on_season_refresh) # Reflect the initial speed state without emitting a signal. _apply_highlight(Sim.current_speed) func _unhandled_input(event: InputEvent) -> void: if event.is_action_pressed("pause"): Sim.set_speed(Sim.Speed.PAUSE) elif event.is_action_pressed("speed_normal"): Sim.set_speed(Sim.Speed.NORMAL) elif event.is_action_pressed("speed_fast"): Sim.set_speed(Sim.Speed.FAST) elif event.is_action_pressed("speed_ultra"): Sim.set_speed(Sim.Speed.ULTRA) func _on_speed_changed(new_speed: int) -> void: _apply_highlight(new_speed as Sim.Speed) func _on_sim_tick(tick_number: int) -> void: tick_label.text = Strings.t(&"hud.tick").format({"n": tick_number}) func _on_clock_refresh(_n: int) -> void: var t: String = Strings.t(&"clock.format").format({"d": Clock.current_day(), "t": Clock.time_string()}) if t != _last_clock_text: _last_clock_text = t clock_label.text = t func _on_season_refresh(_n: int) -> void: var season_key: StringName = &"season." + String(Clock.current_season()) var t: String = Strings.t(&"season.format").format({ "s": Strings.t(season_key), "d": Clock.day_of_season() + 1, # display as 1-indexed }) if t != _last_season_text: _last_season_text = t season_label.text = t func _apply_highlight(speed: Sim.Speed) -> void: for s: int in _speed_buttons: _speed_buttons[s].modulate = ACTIVE_MODULATE if s == speed else IDLE_MODULATE