You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
307 lines
8.9 KiB
C#
307 lines
8.9 KiB
C#
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<ServerCharacter> players = new List<ServerCharacter>();
|
|
|
|
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();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Populates the players list from active ServerCharacters in the scene.
|
|
/// </summary>
|
|
private void PopulatePlayersList()
|
|
{
|
|
players.Clear();
|
|
players = FindObjectsOfType<ServerCharacter>().ToList();
|
|
Debug.Log("CrowManager: Players list populated.");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Determines which player should be the crow.
|
|
/// </summary>
|
|
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();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Assigns a player as the Crow.
|
|
/// </summary>
|
|
/// <param name="player">The ServerCharacter to assign as Crow.</param>
|
|
private void AssignCrow(ServerCharacter player)
|
|
{
|
|
if (currentCrow == player) return;
|
|
|
|
if (currentCrow != null)
|
|
{
|
|
currentCrow.Movement.SetSpeedModifier(1f);
|
|
var foresightPrefab = FindObjectOfType<CrowsForesightPrefab>();
|
|
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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clears the current Crow if no player is unoccupied.
|
|
/// </summary>
|
|
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();
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// RPC to notify clients about the Crow change.
|
|
/// </summary>
|
|
/// <param name="crowClientId">The Client ID of the new crow, or 0 if no crow.</param>
|
|
[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<CrowsForesightPrefab>();
|
|
// if (foresightPrefab)
|
|
// {
|
|
// foresightPrefab.DespawnForesight();
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
player.SetAsCrow(false);
|
|
player.SwitchToPlayerModel();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Adds a character to the players list.
|
|
/// </summary>
|
|
/// <param name="character">The ServerCharacter to add.</param>
|
|
public void AddCharacterToList(ServerCharacter character)
|
|
{
|
|
if (!players.Contains(character))
|
|
{
|
|
players.Add(character);
|
|
Debug.Log($"Player {character.name} added to CrowManager.");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes a character from the players list.
|
|
/// </summary>
|
|
/// <param name="character">The ServerCharacter to remove.</param>
|
|
public void RemoveCharacterFromList(ServerCharacter character)
|
|
{
|
|
if (players.Contains(character))
|
|
{
|
|
players.Remove(character);
|
|
Debug.Log($"Player {character.name} removed from CrowManager.");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ensures the players list is updated when a player is spawned or despawned.
|
|
/// </summary>
|
|
/// <param name="character">The ServerCharacter to track.</param>
|
|
public void OnPlayerSpawned(ServerCharacter character)
|
|
{
|
|
AddCharacterToList(character);
|
|
}
|
|
|
|
public void OnPlayerDespawned(ServerCharacter character)
|
|
{
|
|
RemoveCharacterFromList(character);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves the current Crow.
|
|
/// </summary>
|
|
/// <returns>The current Crow player.</returns>
|
|
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<CrowsForesightPrefab>();
|
|
|
|
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<CrowsForesightPrefab>();
|
|
|
|
if (foresightPrefab == null)
|
|
{
|
|
Debug.LogError("[CrowManager] Error: CrowsForesightPrefab not found on Crow!");
|
|
return;
|
|
}
|
|
|
|
foresightPrefab.OnSwapRequested(senderId, receiverId, senderPos, receiverPos);
|
|
}
|
|
|
|
|
|
|
|
}
|