feat(ui): monologue display — queue, character colours, italic BBCode (#122)
- Queue management: enqueue on mid-display arrival, drain in order, MAX_QUEUE_DEPTH=8 cap, no-overwrite contract (P0 #477) - Character colours: detective=#c8e0ff (cool blue), smuggler=#f0c870 (warm amber), fallback to neutral insert text - Typography: italic via BBCode [i] tags; font size 13px (smaller than dialogue) - Positioning: bottom-left of viewport, 420×120px, 80px bottom margin above verb list - main.gd: _get_active_character_type() reads player entity kind.data.character_type; passed to show_monologue() and _on_confrontation_monologue() - gdUnit4 tests: queue order, depth cap, no-overwrite, BBCode output, colour mapping, fade timer integration Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+22
-2
@@ -288,7 +288,11 @@ func _consume_monologue() -> void:
|
||||
return
|
||||
_last_monologue_tick = GameState.current_tick
|
||||
var mono: Dictionary = GameState.current_monologue
|
||||
monologue_display.show_monologue(mono.get("text", ""), mono.get("duration_seconds", 5.0))
|
||||
monologue_display.show_monologue(
|
||||
mono.get("text", ""),
|
||||
mono.get("duration_seconds", 5.0),
|
||||
_get_active_character_type()
|
||||
)
|
||||
# #502: Amber flash on room reset
|
||||
var mono_id: String = mono.get("id", "")
|
||||
if mono_id.begins_with("room_reset"):
|
||||
@@ -296,6 +300,22 @@ func _consume_monologue() -> void:
|
||||
GameState.current_monologue = null
|
||||
|
||||
|
||||
# Derive the active character type from the player entity kind data.
|
||||
# Server populates kind.data.character_type ("detective" or "smuggler") per D-032.
|
||||
# Returns "" when the field is absent (display falls back to neutral colour).
|
||||
func _get_active_character_type() -> String:
|
||||
for entity in GameState.visible_entities:
|
||||
if not entity is Dictionary:
|
||||
continue
|
||||
var kind = entity.get("kind", {})
|
||||
if not kind is Dictionary or kind.get("variant") != "Player":
|
||||
continue
|
||||
var data = kind.get("data", {})
|
||||
if data is Dictionary:
|
||||
return data.get("character_type", "")
|
||||
return ""
|
||||
|
||||
|
||||
# Consume-once per tick with ID tracking: show dialogue, then clear.
|
||||
# Tick guard + is_dialogue_active check prevent re-triggering.
|
||||
func _consume_dialogue() -> void:
|
||||
@@ -333,7 +353,7 @@ func _on_dialogue_option_selected(response_id: String, text: String) -> void:
|
||||
# D-063: Handle confrontation beat monologue → show on monologue display (layer 7)
|
||||
func _on_confrontation_monologue(text: String, duration: float) -> void:
|
||||
if monologue_display:
|
||||
monologue_display.show_monologue(text, duration)
|
||||
monologue_display.show_monologue(text, duration, _get_active_character_type())
|
||||
|
||||
|
||||
# D-064: Handle walk-away → send WalkAway{npc_id} to server
|
||||
|
||||
Reference in New Issue
Block a user