233 lines
8.4 KiB
GDScript
233 lines
8.4 KiB
GDScript
extends Control
|
|
|
|
# PowerUpInventoryUI - Displays stored powerups and handles selection
|
|
|
|
# UI References
|
|
var icon_containers: Dictionary = {} # { EffectEnum: Button }
|
|
|
|
# Local State
|
|
var selected_effect: int = -1
|
|
var special_manager_ref: Node = null # Reference to SpecialTilesManager
|
|
|
|
signal effect_selected(effect: int)
|
|
|
|
func _ready():
|
|
print("[PowerUpUI] _ready called")
|
|
# Map Effect Enum to UI Nodes (Assumes specific names in main.tscn)
|
|
# We try to get them immediately. If they are children, they should be accessible.
|
|
var container = get_node_or_null("Container")
|
|
if not container:
|
|
print("[PowerUpUI] ERROR: HBoxContainer not found in ", get_path())
|
|
return
|
|
|
|
# Mapping based on User Request
|
|
# 11: FASTER_SPEED (0) -> SpeedBtn
|
|
# 12: AREA_FREEZE (1) -> FreezeAreaBtn
|
|
# 13: BLOCK_FLOOR (2) -> WallBtn
|
|
# 14: INVISIBLE_MODE (3) -> GhostBtn
|
|
|
|
# We use 0, 1, 2, 3 to match SpecialTilesManager.SpecialEffect enum
|
|
_setup_btn(0, container.get_node_or_null("SpeedBtn"))
|
|
_setup_btn(1, container.get_node_or_null("FreezeAreaBtn"))
|
|
var wall_btn = container.get_node_or_null("WallBtn")
|
|
_setup_btn(2, wall_btn)
|
|
|
|
var mode = LobbyManager.get_game_mode()
|
|
var is_restricted = GameMode.is_restricted(mode)
|
|
if wall_btn and is_restricted:
|
|
wall_btn.visible = false # Hide Wall Power-up in restricted modes
|
|
_setup_btn(3, container.get_node_or_null("GhostBtn"))
|
|
|
|
print("[PowerUpUI] UI Initialization Complete. Mapped %d buttons." % icon_containers.size())
|
|
|
|
func _setup_btn(effect_id: int, btn: Button):
|
|
if not btn:
|
|
print("[PowerUpUI] Warning: Button for effect %d is null" % effect_id)
|
|
return
|
|
|
|
icon_containers[effect_id] = btn
|
|
|
|
# Start DISABLED
|
|
btn.disabled = true
|
|
btn.modulate = Color(0.5, 0.5, 0.5, 0.5) # Grayed out
|
|
btn.focus_mode = Control.FOCUS_NONE
|
|
|
|
# Add Level Label
|
|
if not btn.has_node("LevelLabel"):
|
|
var lvl_lbl = Label.new()
|
|
lvl_lbl.name = "LevelLabel"
|
|
lvl_lbl.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
lvl_lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT
|
|
lvl_lbl.vertical_alignment = VERTICAL_ALIGNMENT_BOTTOM
|
|
lvl_lbl.set_anchors_preset(Control.PRESET_FULL_RECT)
|
|
lvl_lbl.add_theme_font_size_override("font_size", 16)
|
|
lvl_lbl.add_theme_color_override("font_outline_color", Color.BLACK)
|
|
lvl_lbl.add_theme_constant_override("outline_size", 4)
|
|
lvl_lbl.text = "" # Hidden initially
|
|
btn.add_child(lvl_lbl)
|
|
|
|
# Add Cooldown Label
|
|
if not btn.has_node("CooldownLabel"):
|
|
var cd_lbl = Label.new()
|
|
cd_lbl.name = "CooldownLabel"
|
|
cd_lbl.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
cd_lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|
cd_lbl.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
|
cd_lbl.set_anchors_preset(Control.PRESET_FULL_RECT)
|
|
cd_lbl.add_theme_font_size_override("font_size", 20)
|
|
cd_lbl.add_theme_color_override("font_outline_color", Color.BLACK)
|
|
cd_lbl.add_theme_constant_override("outline_size", 4)
|
|
cd_lbl.text = ""
|
|
btn.add_child(cd_lbl)
|
|
|
|
# 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
|
|
|
|
# Position: Top Left of the button
|
|
sc_lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_LEFT
|
|
sc_lbl.vertical_alignment = VERTICAL_ALIGNMENT_TOP
|
|
|
|
# Anchor to top left
|
|
sc_lbl.set_anchors_preset(Control.PRESET_TOP_LEFT)
|
|
|
|
# Offset to be close to the corner
|
|
sc_lbl.offset_left = 0
|
|
sc_lbl.offset_top = -5 # Close to the button top
|
|
|
|
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)
|
|
# Add color override to make it distinct (optional, but good for visibility)
|
|
sc_lbl.add_theme_color_override("font_color", Color(0.9, 0.9, 0.9))
|
|
|
|
# Determine Label Text based on Effect ID
|
|
var key_text = ""
|
|
var mode = LobbyManager.get_game_mode()
|
|
var is_restricted = GameMode.is_restricted(mode)
|
|
if is_restricted:
|
|
# Restricted Mapping: 1, 2, 3 (No Wall)
|
|
match effect_id:
|
|
0: key_text = "1"
|
|
1: key_text = "2" # Freeze is now 2
|
|
3: key_text = "3" # Ghost is now 3
|
|
else:
|
|
# Free Mode Mapping: 1, 2, 3, 4 (Original)
|
|
match effect_id:
|
|
0: key_text = "1"
|
|
2: key_text = "2"
|
|
1: key_text = "3"
|
|
3: key_text = "4"
|
|
|
|
sc_lbl.text = key_text
|
|
btn.add_child(sc_lbl)
|
|
|
|
# Connect click
|
|
if not btn.pressed.is_connected(_on_btn_pressed):
|
|
btn.pressed.connect(_on_btn_pressed.bind(effect_id))
|
|
|
|
func _on_btn_pressed(effect_id: int):
|
|
print("[PowerUpUI] Clicked Button %d" % effect_id)
|
|
if special_manager_ref:
|
|
special_manager_ref.activate_effect(effect_id)
|
|
else:
|
|
print("[PowerUpUI] ERROR: special_manager_ref is null during click")
|
|
|
|
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 _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("powerup_unlocked", _on_powerup_unlocked):
|
|
special_manager.connect("powerup_unlocked", _on_powerup_unlocked)
|
|
|
|
if not special_manager.is_connected("cooldown_updated", _on_cooldown_updated):
|
|
special_manager.connect("cooldown_updated", _on_cooldown_updated)
|
|
|
|
if not special_manager.is_connected("inventory_updated", _on_inventory_updated):
|
|
special_manager.connect("inventory_updated", _on_inventory_updated)
|
|
|
|
# Initial State Sync
|
|
if icon_containers.is_empty():
|
|
print("[PowerUpUI] Warning: Icon containers empty during setup. Attempting _ready logic now...")
|
|
var container = get_node_or_null("HBoxContainer")
|
|
if container:
|
|
# Fix: Use correct IDs 0-3 here too
|
|
_setup_btn(0, container.get_node_or_null("SpeedBtn"))
|
|
_setup_btn(1, container.get_node_or_null("FreezeAreaBtn"))
|
|
_setup_btn(2, container.get_node_or_null("WallBtn"))
|
|
_setup_btn(3, container.get_node_or_null("GhostBtn"))
|
|
|
|
# Sync Inventory
|
|
_on_inventory_updated(special_manager.inventory)
|
|
|
|
# Sync Levels for owned items
|
|
for effect in special_manager.inventory:
|
|
if special_manager.inventory[effect]:
|
|
var lvl = special_manager.powerup_levels.get(effect, 1)
|
|
_on_powerup_unlocked(effect, lvl)
|
|
|
|
func _on_powerup_unlocked(effect: int, level: int):
|
|
# Enable button and set level
|
|
if icon_containers.has(effect):
|
|
var btn = icon_containers[effect]
|
|
print("[PowerUpUI] Enabling button for Effect %d (Node: %s)" % [effect, btn.name])
|
|
btn.disabled = false
|
|
btn.modulate = Color.WHITE # Restore color
|
|
btn.visible = true # Ensure visible
|
|
|
|
# Update Level
|
|
var lvl_lbl = btn.get_node_or_null("LevelLabel")
|
|
if lvl_lbl:
|
|
lvl_lbl.text = "Lvl %d" % level
|
|
else:
|
|
print("[PowerUpUI] ERROR: Unlocked Effect %d but no UI button found! Keys: %s" % [effect, icon_containers.keys()])
|
|
|
|
func _on_cooldown_updated(effect: int, time_left: float, max_time: float):
|
|
if icon_containers.has(effect):
|
|
var btn = icon_containers[effect]
|
|
var cd_lbl = btn.get_node_or_null("CooldownLabel")
|
|
if cd_lbl:
|
|
if time_left > 0:
|
|
cd_lbl.text = "%d" % int(time_left)
|
|
btn.disabled = true
|
|
btn.modulate = Color(0.7, 0.7, 0.7, 0.8)
|
|
else:
|
|
cd_lbl.text = ""
|
|
# Re-enable if we own it
|
|
if special_manager_ref and special_manager_ref.inventory.get(effect, false):
|
|
btn.disabled = false
|
|
btn.modulate = Color.WHITE
|
|
|
|
func _on_inventory_updated(inventory: Dictionary):
|
|
# Update UI icons (Dimmed vs Lit) and Enablement
|
|
print("[PowerUpUI] Inventory Updated: ", inventory)
|
|
for effect in icon_containers:
|
|
if inventory.has(effect):
|
|
var has_item = inventory[effect]
|
|
var btn = icon_containers[effect]
|
|
|
|
btn.modulate = Color.WHITE if has_item else Color(0.5, 0.5, 0.5, 0.5)
|
|
btn.disabled = !has_item
|