From 783b3b589421fcc95c934d4ae2d91726b3f7d41a Mon Sep 17 00:00:00 2001 From: god Date: Mon, 6 Jul 2026 02:14:22 +0800 Subject: [PATCH] fix candy_survival ghost and knock input mapping, hook ghost into player transparency, fix hud layout missing UI nodes --- scripts/managers/candy_survival_manager.gd | 31 ++++++++++++++++++++++ scripts/managers/player_input_manager.gd | 31 ++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/scripts/managers/candy_survival_manager.gd b/scripts/managers/candy_survival_manager.gd index 3fdecc5..871d28d 100644 --- a/scripts/managers/candy_survival_manager.gd +++ b/scripts/managers/candy_survival_manager.gd @@ -193,6 +193,20 @@ func _process(delta: float) -> void: if player_ghost_timer[pid] <= 0: player_ghost_active[pid] = false player_ghost_timer[pid] = 0.0 + rpc("sync_ghost_active", pid, false) + + # Turn off ghost visual/state + var all_players = get_tree().get_nodes_in_group("Players") + for player in all_players: + var curr_pid = player.get("peer_id") if "peer_id" in player else player.name.to_int() + if curr_pid == pid: + player.set("is_invisible", false) + if player.has_method("sync_modulate"): + if multiplayer.is_server() and player.has_method("can_rpc") and player.can_rpc(): + player.rpc("sync_modulate", Color.WHITE) + else: + player.sync_modulate(Color.WHITE) + break # Candy stack: points per second per candy for pid in player_candies.keys(): @@ -277,7 +291,10 @@ func _restore_time_scale() -> void: # ── Knock / Ghost ── +@rpc("any_peer", "call_local", "reliable") func try_knock(attacker: int, target: int) -> bool: + if not multiplayer.is_server(): + return false if player_ghost_active.get(target, false): return false if player_knocks.get(attacker, 0) <= 0: @@ -318,6 +335,20 @@ func try_activate_ghost(pid: int) -> bool: player_ghost_active[pid] = true player_ghost_timer[pid] = GHOST_DURATION rpc("sync_ghost_active", pid, true) + + # Core powerup integration: set is_invisible on the player node + var all_players = get_tree().get_nodes_in_group("Players") + for player in all_players: + var curr_pid = player.get("peer_id") if "peer_id" in player else player.name.to_int() + if curr_pid == pid: + player.set("is_invisible", true) + if player.has_method("sync_modulate"): + if multiplayer.is_server() and player.has_method("can_rpc") and player.can_rpc(): + player.rpc("sync_modulate", Color(1.0, 1.0, 1.0, 0.4)) + else: + player.sync_modulate(Color(1.0, 1.0, 1.0, 0.4)) + break + return true func is_ghost_active(pid: int) -> bool: diff --git a/scripts/managers/player_input_manager.gd b/scripts/managers/player_input_manager.gd index 9045101..43af831 100644 --- a/scripts/managers/player_input_manager.gd +++ b/scripts/managers/player_input_manager.gd @@ -101,6 +101,26 @@ func handle_unhandled_input(event): # 2. Action Buttons (Remappable via InputMap) if event.is_action_pressed("action_knock_tekton"): + if LobbyManager.game_mode == "Candy Survival": + var gm = player.get_node_or_null("/root/Main/CandySurvivalManager") + if gm and gm.is_active: + # Find a target to knock (first adjacent player) + var p_pos = player.current_position + var all_players = get_tree().get_nodes_in_group("Players") + for other in all_players: + if other == player: continue + var other_pos = other.current_position + if abs(p_pos.x - other_pos.x) + abs(p_pos.y - other_pos.y) == 1: + # Adjacent + var att_id = player.get("peer_id") if "peer_id" in player else player.name.to_int() + var tgt_id = other.get("peer_id") if "peer_id" in other else other.name.to_int() + if multiplayer.is_server(): + gm.try_knock(att_id, tgt_id) + else: + gm.rpc_id(1, "try_knock", att_id, tgt_id) + get_viewport().set_input_as_handled() + return + if player.powerup_manager: player.powerup_manager.use_special_effect() if player.get("is_attack_mode") and player.has_method("enter_attack_mode"): @@ -108,6 +128,17 @@ func handle_unhandled_input(event): get_viewport().set_input_as_handled() elif event.is_action_pressed("action_grab_tekton"): + if LobbyManager.game_mode == "Candy Survival": + var gm = player.get_node_or_null("/root/Main/CandySurvivalManager") + if gm and gm.is_active: + var pid = player.get("peer_id") if "peer_id" in player else player.name.to_int() + if multiplayer.is_server(): + gm.try_activate_ghost(pid) + else: + gm.rpc_id(1, "try_activate_ghost", pid) + get_viewport().set_input_as_handled() + return + if not player.is_carrying_tekton: if player.powerup_manager and player.powerup_manager.has_method("can_use_special"): player.grab_tekton()