diff --git a/scripts/managers/candy_survival_manager.gd b/scripts/managers/candy_survival_manager.gd index 7d2c02d..ca72de2 100644 --- a/scripts/managers/candy_survival_manager.gd +++ b/scripts/managers/candy_survival_manager.gd @@ -168,6 +168,7 @@ func start_game_mode() -> void: player_sugar_rush[pid] = 0.0 player_last_knocked_by[pid] = 0 _update_candy_badge(pid) + _update_special_inventory_for_ghosts(pid) print("[CandySurvival] Started with %d players" % pids.size()) @@ -420,6 +421,8 @@ func try_activate_ghost(pid: int) -> bool: player_ghost_active[pid] = true player_ghost_timer[pid] = GHOST_DURATION rpc("sync_ghost_active", pid, true) + rpc("sync_ghost_charge_count", pid, player_ghosts[pid]) + _update_special_inventory_for_ghosts(pid) # Core powerup integration: set is_invisible on the player node var all_players = get_tree().get_nodes_in_group("Players") @@ -488,7 +491,7 @@ func setup_mission_tiles() -> void: if sticky_cells.has(Vector2i(x, y)): continue if randf() < 0.6: - var tile = tile_ids[randi() % tile_ids.size()] + var tile = 14 if randf() < 0.15 else tile_ids[randi() % tile_ids.size()] gridmap.set_cell_item(Vector3i(x, 1, y), tile) count += 1 print("[CandySurvival] Spawned %d mission tiles" % count) @@ -650,3 +653,35 @@ func sync_state_to_player(peer_id: int) -> void: if player.has_method("sync_candy_stack"): player.rpc_id(peer_id, "sync_candy_stack", colors) break + +func _update_special_inventory_for_ghosts(pid: int) -> void: + if not multiplayer.is_server(): + return + if main_scene: + var player_node = main_scene.get_node_or_null(str(pid)) + if player_node: + var st_manager = player_node.get_node_or_null("SpecialTilesManager") + if st_manager: + var has_charges = (player_ghosts.get(pid, 0) > 0) + if has_charges: + st_manager.rpc_id(pid, "sync_inventory_add", st_manager.SpecialEffect.INVISIBLE_MODE, 8) + else: + st_manager.rpc_id(pid, "sync_inventory_remove", st_manager.SpecialEffect.INVISIBLE_MODE) + +@rpc("any_peer", "call_local", "reliable") +func add_ghost_charge(pid: int) -> void: + if not multiplayer.is_server(): + return + player_ghosts[pid] = player_ghosts.get(pid, 0) + 1 + rpc("sync_ghost_charge_count", pid, player_ghosts[pid]) + _update_special_inventory_for_ghosts(pid) + +@rpc("authority", "call_local", "unreliable") +func sync_ghost_charge_count(pid: int, count: int) -> void: + if not active: + activate_client_side() + if player_ghosts.has(pid) or pid == multiplayer.get_unique_id(): + player_ghosts[pid] = count + if multiplayer.get_unique_id() == pid: + if hud_ghost_label: + hud_ghost_label.text = "👻 Ghosts: %d" % count diff --git a/scripts/managers/special_tiles_manager.gd b/scripts/managers/special_tiles_manager.gd index 76c6364..3da12fe 100644 --- a/scripts/managers/special_tiles_manager.gd +++ b/scripts/managers/special_tiles_manager.gd @@ -153,6 +153,17 @@ func add_powerup_from_item(item_id: int): var effect = get_effect_from_item(item_id) if effect == -1: return + if LobbyManager.game_mode == "Candy Survival": + if effect == SpecialEffect.INVISIBLE_MODE: + var gm = player.get_node_or_null("/root/Main/CandySurvivalManager") + if gm and gm.active: + var pid = player.get("peer_id") if "peer_id" in player else player.name.to_int() + if multiplayer.is_server(): + gm.add_ghost_charge(pid) + else: + gm.rpc_id(1, "add_ghost_charge", pid) + return + # VFX: show pickup burst on all peers (mirrors skill VFX pattern) if player.is_multiplayer_authority() and player.has_method("can_rpc") and player.can_rpc(): player.rpc("play_skill_vfx", "take_powerup") @@ -230,6 +241,17 @@ func activate_effect(effect: int, target_player: Node3D = null): NotificationManager.send_message(player, "Skill in Cooldown! (%.1fs)" % global_cooldown_timer, NotificationManager.MessageType.WARNING) return + if LobbyManager.game_mode == "Candy Survival": + if effect == SpecialEffect.INVISIBLE_MODE: + var gm = player.get_node_or_null("/root/Main/CandySurvivalManager") + if gm and gm.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) + return + # Check Attack Mode Restriction if player.get("is_attack_mode") and effect == SpecialEffect.INVISIBLE_MODE: NotificationManager.send_message(player, "Cannot enter Ghost mode while in Attack Mode!", NotificationManager.MessageType.WARNING)