using System.Collections.Generic; using System.Linq; using Unity.BossRoom.Gameplay.GameplayObjects.Character; using UnityEngine; using Unity.Netcode; public class CrowManager : NetworkBehaviour { public static CrowManager Instance { get; private set; } public List players = new List(); private ServerCharacter currentCrow; public Transform mapCenter; private void Awake() { if (Instance != null && Instance != this) { Destroy(this); return; } Instance = this; } public override void OnNetworkSpawn() { if (!IsServer) { enabled = false; // Disable CrowManager on clients return; } } private void Update() { if (!IsServer) return; // Ensure logic only runs on the server DetermineCrow(); } /// /// Populates the players list from active ServerCharacters in the scene. /// private void PopulatePlayersList() { players.Clear(); players = FindObjectsOfType().ToList(); Debug.Log("CrowManager: Players list populated."); } /// /// Determines which player should be the crow. /// int unoccupiedPlayers = 0; private void DetermineCrow() { unoccupiedPlayers = 0; ServerCharacter potentialCrow = null; foreach (var player in players) { if (!player.IsOnAPlatform) { unoccupiedPlayers++; potentialCrow = player; } } if (unoccupiedPlayers == 1) { AssignCrow(potentialCrow); } else if (unoccupiedPlayers == 0 && currentCrow != null) { ClearCrow(); } } /// /// Assigns a player as the Crow. /// /// The ServerCharacter to assign as Crow. private void AssignCrow(ServerCharacter player) { if (currentCrow == player) return; if (currentCrow != null) { currentCrow.Movement.SetSpeedModifier(1f); var foresightPrefab = FindObjectOfType(); if (foresightPrefab) { foresightPrefab.DespawnForesight(); } currentCrow.SetAsCrow(false); // Clear old crow } currentCrow = player; currentCrow.SetAsCrow(true); Debug.Log($"{currentCrow.name} is now the Crow."); currentCrow.Movement.SetSpeedModifier(1.5f); // Notify all clients about the new crow NotifyCrowChangeClientRpc(currentCrow.OwnerClientId); } /// /// Clears the current Crow if no player is unoccupied. /// public void ClearCrow() { if (currentCrow != null) { Debug.Log($"[CrowManager] {currentCrow.name} landed on a platform. Removing crow status."); currentCrow.SetAsCrow(false); currentCrow = null; // Notify all clients that the crow role is cleared NotifyCrowChangeClientRpc(0); // 0 means no crow } // Recalculate crow status after removing the old crow DetermineCrow(); } /// /// RPC to notify clients about the Crow change. /// /// The Client ID of the new crow, or 0 if no crow. [Rpc(SendTo.Everyone)] private void NotifyCrowChangeClientRpc(ulong crowClientId) { foreach (var player in players) { if (player.OwnerClientId == crowClientId) { player.SetAsCrow(true); player.SwitchToCrowModel(); currentCrow = player; Debug.Log($"Client: {player.name} is the new Crow."); } else { // // If a player was the crow but is now losing it, request foresight removal // if (player.IsCrow) // { // Debug.Log($"[CrowManager] {player.name} is no longer the Crow. Requesting foresight removal."); // if (IsServer) // { // var foresightPrefab = FindObjectOfType(); // if (foresightPrefab) // { // foresightPrefab.DespawnForesight(); // } // } // } player.SetAsCrow(false); player.SwitchToPlayerModel(); } } } /// /// Adds a character to the players list. /// /// The ServerCharacter to add. public void AddCharacterToList(ServerCharacter character) { if (!players.Contains(character)) { players.Add(character); Debug.Log($"Player {character.name} added to CrowManager."); } } /// /// Removes a character from the players list. /// /// The ServerCharacter to remove. public void RemoveCharacterFromList(ServerCharacter character) { if (players.Contains(character)) { players.Remove(character); Debug.Log($"Player {character.name} removed from CrowManager."); } } /// /// Ensures the players list is updated when a player is spawned or despawned. /// /// The ServerCharacter to track. public void OnPlayerSpawned(ServerCharacter character) { AddCharacterToList(character); } public void OnPlayerDespawned(ServerCharacter character) { RemoveCharacterFromList(character); } /// /// Retrieves the current Crow. /// /// The current Crow player. public ServerCharacter GetCurrentCrow() { return currentCrow; } public void NotifyForesightSwap(ulong senderId, ulong receiverId, Vector3 senderPos, Vector3 receiverPos) { Debug.Log($"[CrowManager] NotifyForesightSwap called - Sender: {senderId}, Receiver: {receiverId}, SenderPos: {senderPos}, ReceiverPos: {receiverPos}"); if (currentCrow) { Debug.Log($"[CrowManager] Sending foresight swap notification to the Crow: {currentCrow.OwnerClientId}"); NotifySwapForesightClientRpc(senderId, receiverId, senderPos, receiverPos); } else { Debug.LogWarning("[CrowManager] No current crow found to receive the foresight swap update."); } } public void NotifyForesightSwapDecision(ulong senderId, Vector3 receiverPos, bool isAccepted) { if (currentCrow) { NotifySwapForesightDecisionClientRpc(senderId, receiverPos, isAccepted); } } [Rpc(SendTo.Everyone)] private void NotifySwapForesightDecisionClientRpc(ulong senderId, Vector3 receiverPos, bool isAccepted) { if (currentCrow == null) { Debug.LogError("[CrowManager] Error: currentCrow is null!"); return; } if (currentCrow.clientCharacter == null) { Debug.LogError("[CrowManager] Error: currentCrow.clientCharacter is null!"); return; } var foresightPrefab = FindObjectOfType(); if (foresightPrefab == null) { Debug.LogError("[CrowManager] Error: CrowsForesightPrefab not found!"); return; } if (isAccepted) { foresightPrefab.OnSwapAccepted(senderId, receiverPos); } else { foresightPrefab.OnSwapRejected(senderId, receiverPos); } } [Rpc(SendTo.Everyone)] private void NotifySwapForesightClientRpc(ulong senderId, ulong receiverId, Vector3 senderPos, Vector3 receiverPos) { Debug.Log($"[CrowManager] NotifySwapForesightClientRpc received - Sender: {senderId}, Receiver: {receiverId}, SenderPos: {senderPos}, ReceiverPos: {receiverPos}"); if (currentCrow == null) { Debug.LogError("[CrowManager] Error: Current Crow is null!"); return; } if (currentCrow.clientCharacter == null) { Debug.LogError("[CrowManager] Error: Current Crow clientCharacter is null!"); return; } var foresightPrefab = FindObjectOfType(); if (foresightPrefab == null) { Debug.LogError("[CrowManager] Error: CrowsForesightPrefab not found on Crow!"); return; } foresightPrefab.OnSwapRequested(senderId, receiverId, senderPos, receiverPos); } }