extends Control # PowerUpInventoryUI - Displays stored powerups and handles selection # UI References # UI References var power_up_button: Button var effect_textures: Dictionary = { 0: preload("res://assets/graphics/touch_control/speed.png"), 1: preload("res://assets/graphics/touch_control/freeze_area.png"), 2: preload("res://assets/graphics/touch_control/wall.png"), 3: preload("res://assets/graphics/touch_control/ghost.png") } # Local State var current_effect: int = -1 var special_manager_ref: Node = null # Reference to SpecialTilesManager @onready var SettingsManager = get_node_or_null("/root/SettingsManager") signal effect_selected(effect: int) func _ready(): print("[PowerUpUI] _ready called") # Connect to SettingsManager to update labels on rebind OR controller toggle if SettingsManager: if not SettingsManager.control_remapped.is_connected(_on_control_remapped): SettingsManager.control_remapped.connect(_on_control_remapped) if not SettingsManager.settings_applied.is_connected(_on_control_remapped_refresh): SettingsManager.settings_applied.connect(_on_control_remapped_refresh) # New Single Button UI (moved to InteractionBtn) power_up_button = get_node_or_null("../InteractionBtn/PowerUpBtn") if not power_up_button: # Fallback just in case power_up_button = get_node_or_null("PowerUpBtn") if not power_up_button: print("[PowerUpUI] ERROR: PowerUpBtn not found") return # Helper to setup the single button _setup_powerup_btn(power_up_button) # Start hidden until player has a powerup power_up_button.visible = false print("[PowerUpUI] UI Initialization Complete (Single Button Mode).") func _on_control_remapped(_action: String, _key: int): # Refresh all labels _update_shortcuts_for_mode(LobbyManager.is_game_mode(GameMode.Mode.STOP_N_GO)) func _on_control_remapped_refresh(): """Called when settings_applied fires (e.g. use_controller toggled).""" _update_shortcuts_for_mode(LobbyManager.is_game_mode(GameMode.Mode.STOP_N_GO)) func _setup_powerup_btn(btn: Button): # Start DISABLED btn.disabled = true btn.modulate = Color(0.5, 0.5, 0.5, 0.5) btn.focus_mode = Control.FOCUS_NONE # Add Cooldown Overlay if not btn.has_node("CooldownOverlay"): var overlay = ColorRect.new() overlay.name = "CooldownOverlay" overlay.mouse_filter = Control.MOUSE_FILTER_IGNORE overlay.color = Color(0, 0, 0, 0.6) overlay.set_anchors_preset(Control.PRESET_FULL_RECT) overlay.anchor_top = 1.0 overlay.grow_vertical = Control.GROW_DIRECTION_BEGIN btn.add_child(overlay) # Add Keyboard Shortcut Label if not btn.has_node("ShortcutLabel"): var sc_lbl = Label.new() sc_lbl.name = "ShortcutLabel" sc_lbl.mouse_filter = Control.MOUSE_FILTER_IGNORE sc_lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT sc_lbl.vertical_alignment = VERTICAL_ALIGNMENT_TOP sc_lbl.set_anchors_preset(Control.PRESET_TOP_RIGHT) sc_lbl.offset_left = -60 # Width of label roughly sc_lbl.offset_right = 6 sc_lbl.offset_top = -4 sc_lbl.offset_bottom = 12 sc_lbl.add_theme_font_size_override("font_size", 16) sc_lbl.add_theme_color_override("font_outline_color", Color.BLACK) sc_lbl.add_theme_constant_override("outline_size", 4) sc_lbl.add_theme_color_override("font_color", Color(0.9, 0.9, 0.9)) btn.add_child(sc_lbl) _update_btn_shortcut(btn) # Connect click if not btn.pressed.is_connected(_on_btn_pressed): btn.pressed.connect(_on_btn_pressed) func _update_shortcuts_for_mode(_is_restricted: bool): if power_up_button: _update_btn_shortcut(power_up_button) func _update_btn_shortcut(btn: Button): var sc_lbl = btn.get_node_or_null("ShortcutLabel") if not sc_lbl: return if not SettingsManager: sc_lbl.text = "" return # Show universal powerup shortcut sc_lbl.text = " %s " % SettingsManager.get_action_display("use_powerup") func _on_btn_pressed(effect_id: int = -1): var target_effect = effect_id if effect_id != -1 else current_effect if target_effect == -1: return print("[PowerUpUI] Activating effect: %d" % target_effect) if special_manager_ref: special_manager_ref.activate_effect(target_effect) func setup(player_node): print("[PowerUpUI] Setup called for player: ", player_node.name) var special_manager = player_node.get_node_or_null("SpecialTilesManager") if special_manager: _connect_special_manager(special_manager) else: print("[PowerUpUI] SpecialTilesManager not found on %s. Waiting for it..." % player_node.name) if not player_node.child_entered_tree.is_connected(_on_player_child_entered): player_node.child_entered_tree.connect(_on_player_child_entered.bind(player_node)) func _on_player_child_entered(node: Node, player_node: Node): if node.name == "SpecialTilesManager": print("[PowerUpUI] SpecialTilesManager appeared on %s!" % player_node.name) _connect_special_manager(node) # Disconnect to avoid checking every child forever if player_node.child_entered_tree.is_connected(_on_player_child_entered): player_node.child_entered_tree.disconnect(_on_player_child_entered) func _on_global_cooldown_updated(time_left: float, max_time: float): if not power_up_button: return var overlay = power_up_button.get_node_or_null("CooldownOverlay") if overlay: if time_left > 0: overlay.visible = true overlay.anchor_top = 1.0 - (time_left / max_time) power_up_button.disabled = true else: overlay.visible = false overlay.anchor_top = 1.0 if current_effect != -1: power_up_button.disabled = false func _connect_special_manager(special_manager): special_manager_ref = special_manager print("[PowerUpUI] Connected to SpecialTilesManager") # Connect signals if not already connected if not special_manager.is_connected("inventory_updated", _on_inventory_updated): special_manager.connect("inventory_updated", _on_inventory_updated) if not special_manager.is_connected("global_cooldown_updated", _on_global_cooldown_updated): special_manager.connect("global_cooldown_updated", _on_global_cooldown_updated) # Initial State Sync if not power_up_button: _ready() # Sync Inventory _on_inventory_updated(special_manager.inventory) func _on_inventory_updated(inventory: Dictionary): if not power_up_button: return # Update UI icon (Single slot logic) var active_effect: int = -1 for effect in inventory: if inventory[effect] == true: active_effect = effect break current_effect = active_effect if active_effect != -1: power_up_button.visible = true power_up_button.icon = effect_textures.get(active_effect) # Check global cooldown var is_cooling = false if special_manager_ref and special_manager_ref.global_cooldown_timer > 0: is_cooling = true power_up_button.disabled = is_cooling power_up_button.modulate = Color.WHITE _update_btn_shortcut(power_up_button) else: power_up_button.visible = false power_up_button.disabled = true