extends PanelContainer # Interaction prompt — displays available interaction verb for nearby entity. # Server-driven: shows when GameState.nearby_interactions is non-empty, # hides when empty. No game logic — pure display layer. # # v0.1: Single-line "E - Talk" (first verb on nearest entity) # v0.2: Will be replaced/extended with radial verb menu. # Public interface: get_interaction_target(), get_selected_verb() @onready var prompt_label: Label = $MarginContainer/PromptLabel var _is_showing: bool = false var _active_tween: Tween = null var _current_target_id: int = -1 const FADE_IN: float = 0.15 const FADE_OUT: float = 0.15 func _ready() -> void: modulate.a = 0.0 visible = false _is_showing = false func _process(_delta: float) -> void: var interactions: Array = GameState.nearby_interactions if interactions.size() > 0: _show_prompt(interactions[0]) elif _is_showing: _hide_prompt() func _show_prompt(interaction: Dictionary) -> void: var target_id: int = interaction.get("entity_id", -1) var verbs: Array = interaction.get("verbs", []) if verbs.is_empty(): if _is_showing: _hide_prompt() return # v0.1: pick first verb (sorted by priority from server) var verb_label: String = verbs[0].get("label", "") var display_text: String = "E - %s" % verb_label if _current_target_id != target_id or prompt_label.text != display_text: prompt_label.text = display_text _current_target_id = target_id if not _is_showing: visible = true _is_showing = true if _active_tween and _active_tween.is_valid(): _active_tween.kill() _active_tween = create_tween() _active_tween.tween_property(self, "modulate:a", 1.0, FADE_IN) func _hide_prompt() -> void: if not _is_showing: return _is_showing = false _current_target_id = -1 if _active_tween and _active_tween.is_valid(): _active_tween.kill() _active_tween = create_tween() _active_tween.tween_property(self, "modulate:a", 0.0, FADE_OUT) _active_tween.tween_callback(func(): visible = false) ## Returns the current interaction target entity ID, or -1 if no interaction. func get_interaction_target() -> int: return _current_target_id ## Returns the selected verb kind (v0.1: first verb on nearest, v0.2: radial selection). func get_selected_verb() -> String: var interactions: Array = GameState.nearby_interactions if interactions.is_empty(): return "" var verbs: Array = interactions[0].get("verbs", []) if verbs.is_empty(): return "" return verbs[0].get("kind", "")