fix(ui): address PR #115 review — 8 items
- Fix stale test path UILayer/HUD → InsertOverlay/HUD - Fix D-record citation D-051 → D-049 in main.tscn - Add null guards to hud.gd update methods (pre-_ready safety) - Minimap: dirty-flag queue_redraw instead of per-frame - Remove redundant _panel.size.x, debug print - Fix DebugOverlay/GauntletHUD positioning comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -144,12 +144,12 @@ layer = 10
|
||||
; #264: Journal panel — knowledge graph review, toggle J key, read-only (D-041)
|
||||
[node name="JournalPanel" parent="InsertOverlay" instance=ExtResource("25_journal")]
|
||||
|
||||
; HUD — implant-styled status panel (D-169, D-170). On InsertOverlay for bloom per D-051.
|
||||
; HUD — implant-styled status panel (D-169, D-170). On InsertOverlay per D-049 (z-layer 6).
|
||||
[node name="HUD" parent="InsertOverlay" instance=ExtResource("6_hud")]
|
||||
|
||||
; --- UI layer (CanvasLayer 20) ---
|
||||
; Monologue, cursor, stance — always visible, not affected by fog or camera.
|
||||
; HUD moved to InsertOverlay (layer 10) for bloom treatment per D-051.
|
||||
; HUD moved to InsertOverlay (layer 10) per D-049 (insert z-layer 6).
|
||||
[node name="UILayer" type="CanvasLayer" parent="."]
|
||||
layer = 20
|
||||
|
||||
@@ -168,7 +168,7 @@ layer = 20
|
||||
[node name="InventoryGrid" parent="UILayer" instance=ExtResource("12_inv")]
|
||||
|
||||
; #511: F3 debug overlay — real-time game state, toggled by F3
|
||||
; Position: below merged HUD status panel (starts at y:16, ~80px), 10px gap
|
||||
; Position: y:150 — below merged HUD status panel (y:16, ~80px tall), with gap
|
||||
[node name="DebugOverlay" type="Control" parent="UILayer"]
|
||||
anchors_preset = 0
|
||||
offset_left = 16
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
## D-051 (diegetic insert display)
|
||||
##
|
||||
## Implementation: client/ui/time_display.gd — draw-based Control (removed from main scene #786;
|
||||
## time display merged into HUD ImplantPanel at UILayer/HUD, see test_hud_* tests below).
|
||||
## time display merged into HUD ImplantPanel at InsertOverlay/HUD, see test_hud_* tests below).
|
||||
## Format function: Constants.format_game_time(time_of_day: int) -> String (extracted for
|
||||
## testability from time_display.gd).
|
||||
##
|
||||
## Private state access: Tests read _time_str, _phase_str, _day_str, _has_data directly
|
||||
## because time_display.gd is draw-based (no Label nodes to inspect). This is an accepted
|
||||
## test pattern for draw-based UI — the private vars ARE the rendered output contract.
|
||||
## Scene integration tests now check UILayer/HUD.get_time_text() instead.
|
||||
## Scene integration tests now check InsertOverlay/HUD.get_time_text() instead.
|
||||
class_name TestTimeDisplaySprint17
|
||||
extends GdUnitTestSuite
|
||||
|
||||
@@ -273,16 +273,16 @@ func test_sim_bridge_day_phase_is_valid() -> void:
|
||||
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Scene: HUD panel at UILayer/HUD (time row merged in, TimeDisplay removed #786)
|
||||
# Scene: HUD panel at InsertOverlay/HUD (time row merged in, TimeDisplay removed #786)
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
func test_hud_panel_exists_in_ui_layer() -> void:
|
||||
func test_hud_panel_exists_in_insert_overlay() -> void:
|
||||
var scene := MAIN_SCENE
|
||||
var instance = scene.instantiate()
|
||||
auto_free(instance)
|
||||
add_child(instance)
|
||||
|
||||
assert_that(instance.get_node_or_null("UILayer/HUD")).is_not_null()
|
||||
assert_that(instance.get_node_or_null("InsertOverlay/HUD")).is_not_null()
|
||||
|
||||
func test_hud_time_row_updates_after_process() -> void:
|
||||
var scene := MAIN_SCENE
|
||||
@@ -296,7 +296,7 @@ func test_hud_time_row_updates_after_process() -> void:
|
||||
})
|
||||
instance._process(0.016)
|
||||
|
||||
var hud = instance.get_node_or_null("UILayer/HUD")
|
||||
var hud = instance.get_node_or_null("InsertOverlay/HUD")
|
||||
assert_that(hud).is_not_null()
|
||||
assert_that(hud.get_time_text()).is_equal("12:00 · Afternoon · D1")
|
||||
|
||||
|
||||
+6
-3
@@ -21,7 +21,6 @@ func _ready() -> void:
|
||||
_panel.name = "StatusPanel"
|
||||
_panel.theme_resource = theme_res
|
||||
_panel.custom_minimum_size.x = 200.0
|
||||
_panel.size.x = 200.0
|
||||
_panel.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
_panel.position = Vector2(16, 16) # top-left; replaces standalone TimeDisplay
|
||||
add_child(_panel)
|
||||
@@ -34,10 +33,10 @@ func _ready() -> void:
|
||||
_panel.add_component(_health_row)
|
||||
_panel.add_component(_perception_row)
|
||||
|
||||
print("HUD: Initialized")
|
||||
|
||||
|
||||
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():
|
||||
@@ -47,10 +46,14 @@ func update_from_hud_data(data: Dictionary) -> void:
|
||||
|
||||
|
||||
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
|
||||
|
||||
+17
-1
@@ -38,6 +38,11 @@ var _insert_active: bool = true
|
||||
# D-169: StyleBoxFlat matching ImplantPanel aesthetic — drawn as container frame behind the circle.
|
||||
var _container_style: StyleBoxFlat = null
|
||||
|
||||
# Dirty flag — only queue_redraw() when player position or POI list changes.
|
||||
var _dirty: bool = true
|
||||
var _last_player_pos: Vector2 = Vector2(INF, INF)
|
||||
var _last_poi_count: int = -1
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
@@ -57,7 +62,16 @@ func _init_container_style() -> void:
|
||||
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if _insert_active:
|
||||
if not _insert_active:
|
||||
return
|
||||
var pos := GameState.player_position
|
||||
var poi_count := GameState.discovered_pois.size()
|
||||
if pos != _last_player_pos or poi_count != _last_poi_count:
|
||||
_last_player_pos = pos
|
||||
_last_poi_count = poi_count
|
||||
_dirty = true
|
||||
if _dirty:
|
||||
_dirty = false
|
||||
queue_redraw()
|
||||
|
||||
|
||||
@@ -66,6 +80,8 @@ func _process(_delta: float) -> void:
|
||||
func set_insert_active(active: bool) -> void:
|
||||
_insert_active = active
|
||||
visible = active
|
||||
if active:
|
||||
_dirty = true
|
||||
|
||||
|
||||
func _draw() -> void:
|
||||
|
||||
Reference in New Issue
Block a user