Three architectural review comments implemented per Tyre's proposals: #3 — scene_path consumption (full, Option A) - ImplantRegistry.instantiate_all(parent) loads and instantiates all registered apps with a declared scene_path. Manifests with empty scene_path are treated as metadata-only (silently skipped). - ImplantRegistry.get_app_instance(app_path) returns the live instance. - hud.tscn no longer direct-instances AtlasApp or EconomicsApp — an AppsContainer Control holds the registry-managed children. - hud.gd._ready() calls ImplantRegistry.instantiate_all($AppsContainer). - main.gd drops @onready vars for atlas_app/economics_app; looks up both from the registry at the top of _ready(). #6c — schema_version on manifest - ImplantAppManifest: @export var schema_version: int = 1 (first field). - ImplantRegistry: const CURRENT_SCHEMA_VERSION := 1; tiered check in _scan() — older-than-current emits print_verbose, newer-than-current emits push_warning, both proceed best-effort. - apps/atlas/app.tres + apps/economics/app.tres: schema_version = 1. #10 — absorb _on_screen_changed boilerplate into ImplantApp - Base class gains _screens: Dictionary, _current_screen_id: String, register_screen(id, screen), current_screen_id(), and a real default _on_screen_changed implementation that handles leave+hide+enter+show with has_method guards and same-screen-replace detection. - atlas_app: deletes _current_screen_id, _get_screen(), _on_screen_changed() override; on_install() collapses to construct → setup → wire → register_screen(id, screen) per screen. Preserves direct screen refs for atlas-specific signal wiring and method calls. - economics_app: deletes same scaffolding; on_install() reduces to three lines (construct overview_screen, register_screen, nav.set_default). Also: replaced Resource.get(name, default) dict-style calls with direct property access on typed ImplantAppManifest reads (2-arg get() is Dictionary-only; causes "Too many arguments" parse errors on Resources). _is_valid_manifest gained a Resource type guard and a property-exists check. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
71 lines
2.1 KiB
GDScript
71 lines
2.1 KiB
GDScript
extends Control
|
|
|
|
## HUD — implant-styled status panel (D-169, D-170).
|
|
## Merged panel: Time, Health, Perception mode. Time row replaces standalone TimeDisplay (#786).
|
|
|
|
var _panel: ImplantPanel
|
|
var _time_row: ImplantDataRow
|
|
var _health_row: ImplantDataRow
|
|
var _perception_row: ImplantDataRow
|
|
|
|
|
|
func _ready() -> void:
|
|
ImplantRegistry.instantiate_all($AppsContainer)
|
|
|
|
# Remove the old raw MarginContainer/labels if present
|
|
var old := get_node_or_null("MarginContainer")
|
|
if old:
|
|
old.queue_free()
|
|
|
|
var theme_res := load("res://ui/implant/default_implant.tres") as ImplantTheme
|
|
|
|
_panel = ImplantPanel.new()
|
|
_panel.name = "StatusPanel"
|
|
_panel.theme_resource = theme_res
|
|
_panel.custom_minimum_size.x = 200.0
|
|
_panel.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
_panel.position = Vector2(16, 16) # top-left; replaces standalone TimeDisplay
|
|
add_child(_panel)
|
|
|
|
_time_row = ImplantDataRow.new("--:--")
|
|
_health_row = ImplantDataRow.new("Health: 100")
|
|
_perception_row = ImplantDataRow.new("Mode: Baseline")
|
|
|
|
_panel.add_component(_time_row)
|
|
_panel.add_component(_health_row)
|
|
_panel.add_component(_perception_row)
|
|
|
|
|
|
func update_from_hud_data(data: Dictionary) -> void:
|
|
if not _perception_row:
|
|
return
|
|
if data.has("perception_mode"):
|
|
var prefix := UIStrings.get_text("hud.perception_mode_prefix")
|
|
if prefix.is_empty():
|
|
_perception_row.text = data.perception_mode.capitalize()
|
|
else:
|
|
_perception_row.text = prefix + ": " + data.perception_mode.capitalize()
|
|
|
|
|
|
func update_health(health: int) -> void:
|
|
if not _health_row:
|
|
return
|
|
_health_row.text = UIStrings.get_text("hud.health") + ": " + str(health)
|
|
|
|
|
|
func update_from_state() -> void:
|
|
if not _time_row:
|
|
return
|
|
var gt: Dictionary = GameState.game_time
|
|
if gt.is_empty():
|
|
return
|
|
var tod: int = int(gt.get("time_of_day", 0))
|
|
var day: int = int(gt.get("day", 0))
|
|
var phase: String = str(gt.get("day_phase", ""))
|
|
_time_row.text = "%s · %s · D%d" % [Constants.format_game_time(tod), phase, day + 1]
|
|
|
|
|
|
## Returns the time row text. Used by tests after standalone TimeDisplay was removed.
|
|
func get_time_text() -> String:
|
|
return _time_row.text if _time_row else "--:--"
|