From 64dc1de15a6d862edbb07381f88d441cb1304db7 Mon Sep 17 00:00:00 2001 From: Yogi Wiguna Date: Mon, 16 Mar 2026 14:45:31 +0800 Subject: [PATCH] feat: introduce special power-up manager with inventory and associated UI --- scripts/managers/special_tiles_manager.gd | 6 ++++ scripts/ui/powerup_inventory_ui.gd | 37 +++++++++++++++++++++-- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/scripts/managers/special_tiles_manager.gd b/scripts/managers/special_tiles_manager.gd index 3d45b85..cb81805 100644 --- a/scripts/managers/special_tiles_manager.gd +++ b/scripts/managers/special_tiles_manager.gd @@ -22,10 +22,12 @@ var active_buffs: Dictionary = {} # EffectEnum -> float (Duration Running) # Cooldown Constants (Level 1 / Level 8) const COOLDOWN_L1 = 15.0 const COOLDOWN_L8 = 5.0 +const GLOBAL_COOLDOWN_MAX = 5.0 const FASTER_DURATION = 5.0 const FREEZE_SLOW_DURATION = 3.0 signal cooldown_updated(effect: int, time_left: float, max_time: float) +signal global_cooldown_updated(time_left: float, max_time: float) signal powerup_unlocked(effect: int, level: int) @@ -234,6 +236,7 @@ func activate_effect(effect: int, target_player: Node3D = null): # Apply 5s cooldown globally global_cooldown_timer = 5.0 + emit_signal("global_cooldown_updated", global_cooldown_timer, GLOBAL_COOLDOWN_MAX) # Play generic cast animation or sound? if player.is_multiplayer_authority() and multiplayer.has_multiplayer_peer() and multiplayer.multiplayer_peer.get_connection_status() == MultiplayerPeer.CONNECTION_CONNECTED: @@ -552,6 +555,9 @@ func _process(delta): # Update Global Cooldown if global_cooldown_timer > 0: global_cooldown_timer -= delta + if global_cooldown_timer <= 0: + global_cooldown_timer = 0 + emit_signal("global_cooldown_updated", global_cooldown_timer, GLOBAL_COOLDOWN_MAX) # Update Active Buffs (Speed) if active_buffs.has(SpecialEffect.FASTER_SPEED): diff --git a/scripts/ui/powerup_inventory_ui.gd b/scripts/ui/powerup_inventory_ui.gd index 74c090c..a5625ad 100644 --- a/scripts/ui/powerup_inventory_ui.gd +++ b/scripts/ui/powerup_inventory_ui.gd @@ -84,6 +84,17 @@ func _setup_btn(effect_id: int, btn: Button): + # 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) # Semi-transparent black + overlay.set_anchors_preset(Control.PRESET_FULL_RECT) + overlay.anchor_top = 1.0 # Start empty at bottom + 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() @@ -148,6 +159,21 @@ func _on_player_child_entered(node: Node, player_node: Node): 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): + for effect in icon_containers: + var btn = icon_containers[effect] + var overlay = btn.get_node_or_null("CooldownOverlay") + if overlay: + if time_left > 0: + overlay.visible = true + overlay.anchor_top = 1.0 - (time_left / max_time) + btn.disabled = true + else: + overlay.visible = false + overlay.anchor_top = 1.0 + if special_manager_ref and special_manager_ref.inventory.get(effect, false): + btn.disabled = false + func _connect_special_manager(special_manager): special_manager_ref = special_manager print("[PowerUpUI] Connected to SpecialTilesManager") @@ -159,12 +185,14 @@ func _connect_special_manager(special_manager): 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 icon_containers.is_empty(): print("[PowerUpUI] Warning: Icon containers empty during setup. Attempting _ready logic now...") var container = get_node_or_null("Container") 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")) @@ -206,6 +234,11 @@ func _on_inventory_updated(inventory: Dictionary): # Single slot logic: Only the owned one is visible btn.visible = has_item if has_item: - btn.disabled = false # Individual cooldown logic might disable it later + # Check global cooldown before enabling + var is_cooling = false + if special_manager_ref and special_manager_ref.global_cooldown_timer > 0: + is_cooling = true + + btn.disabled = is_cooling btn.modulate = Color.WHITE _update_btn_shortcut(effect, btn)