feat(ui): bind dialogue speaker colors to entity identity (#573)

Maintains Dict[entity_id → Color] in dialogue_box for player conversations.
On first encounter, assigns a round-robin palette color; reuses on subsequent lines.
Eliminates position-based name-hash coloring for player dialogue.

Changes:
- Add _npc_entity_colors dict, _npc_entity_id, _next_npc_color fields
- Add _assign_npc_color(entity_id) — registers palette color on first encounter
- show_dialogue: accept npc_entity_id param, register entity color
- append_line: optional speaker_entity_id/target_entity_id stored in log entries
- append_player_line: pass _npc_entity_id as target_entity_id
- append_dialogue_response: accept entity_id, register, pass to append_line
- _format_entry else branch: look up _npc_entity_colors before name-hash fallback
- main.gd: pass _last_dialogue_npc_id to show_dialogue, speaker_entity_id to append_dialogue_response

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-04 02:05:15 +01:00
co-authored by Claude Sonnet 4.6
parent 87b5cbb6c2
commit 974bb2b28e
2 changed files with 56 additions and 12 deletions
+3 -2
View File
@@ -351,7 +351,8 @@ func _consume_dialogue() -> void:
dialogue_box.show_dialogue(
dlg.get("npc_name", ""),
dlg.get("speech", ""),
dlg.get("options", [])
dlg.get("options", []),
_last_dialogue_npc_id
)
GameState.current_dialogue = null
@@ -385,7 +386,7 @@ func _consume_dialogue_response() -> void:
var speaker_color_index: int = dr.get("speaker_color_index", -1)
var speaker_name: String = dr.get("speaker_name", _last_dialogue_npc_name)
dialogue_box.update_entity_display(speaker_entity_id, speaker_name, speaker_color_index)
dialogue_box.append_dialogue_response(speaker_name, dr.get("text", ""))
dialogue_box.append_dialogue_response(speaker_name, dr.get("text", ""), speaker_entity_id)
GameState.dialogue_response = null