extends PanelContainer class_name AbilityButton ## Individual ability/action button for the action bar ## Shows icon, keybind, cooldown overlay, and tooltip signal pressed() signal hovered() # References @onready var icon: TextureRect = $MarginContainer/VBoxContainer/Icon @onready var keybind_label: Label = $MarginContainer/VBoxContainer/KeybindLabel @onready var cooldown_overlay: ColorRect = $MarginContainer/VBoxContainer/Icon/CooldownOverlay @onready var cooldown_label: Label = $MarginContainer/VBoxContainer/Icon/CooldownLabel # Data var ability_icon: Texture2D = null var keybind_text: String = "" var ability_name: String = "" var ability_description: String = "" # Cooldown tracking var is_on_cooldown: bool = false var cooldown_remaining: float = 0.0 var cooldown_total: float = 0.0 # Colors const COOLDOWN_COLOR = Color(0.0, 0.0, 0.0, 0.7) # Dark overlay during cooldown const EMPTY_SLOT_COLOR = Color(0.3, 0.3, 0.3, 0.5) # Gray for empty slots func _ready(): # Setup default appearance cooldown_overlay.visible = false cooldown_label.visible = false # Connect mouse events for tooltip mouse_entered.connect(_on_mouse_entered) mouse_exited.connect(_on_mouse_exited) _update_appearance() func _process(delta): if is_on_cooldown: cooldown_remaining -= delta if cooldown_remaining <= 0: cooldown_remaining = 0 is_on_cooldown = false _update_cooldown_display() else: _update_cooldown_display() ## Set the ability data func set_ability(ability_texture: Texture2D, keybind: String, name: String = "", description: String = ""): ability_icon = ability_texture keybind_text = keybind ability_name = name ability_description = description _update_appearance() ## Clear the ability (make slot empty) func clear_ability(): ability_icon = null ability_name = "" ability_description = "" _update_appearance() ## Set only the keybind (for empty slots) func set_keybind(keybind: String): keybind_text = keybind _update_appearance() ## Start a cooldown animation func start_cooldown(remaining: float, total: float = -1): # If total is provided, use it; otherwise use remaining as both if total > 0: cooldown_total = total else: # Only set cooldown_total if we're starting a new cooldown if not is_on_cooldown: cooldown_total = remaining is_on_cooldown = true cooldown_remaining = remaining _update_cooldown_display() ## Update visual appearance based on current state func _update_appearance(): if not is_node_ready(): return # Update icon if ability_icon: icon.texture = ability_icon icon.modulate = Color.WHITE else: icon.texture = null icon.modulate = EMPTY_SLOT_COLOR # Update keybind label if keybind_label: keybind_label.text = keybind_text ## Update cooldown overlay and label func _update_cooldown_display(): if not is_node_ready(): return if is_on_cooldown: cooldown_overlay.visible = true cooldown_overlay.color = COOLDOWN_COLOR # Show timer for cooldowns > 1 second if cooldown_total > 1.0: cooldown_label.visible = true cooldown_label.text = str(ceil(cooldown_remaining)) else: cooldown_label.visible = false # Animate overlay height based on remaining cooldown var percent_remaining = cooldown_remaining / cooldown_total cooldown_overlay.size.y = icon.size.y * percent_remaining else: cooldown_overlay.visible = false cooldown_label.visible = false ## Mouse hover handlers for tooltip func _on_mouse_entered(): hovered.emit() # Tooltip will be implemented later func _on_mouse_exited(): # Hide tooltip pass ## Handle button press func _gui_input(event): if event is InputEventMouseButton: if event.pressed and event.button_index == MOUSE_BUTTON_LEFT: if not is_on_cooldown and ability_icon != null: pressed.emit()