using System;
using System.Collections.Generic;
using Unity.BossRoom.ConnectionManagement;
using Unity.Multiplayer.Samples.BossRoom;
using Unity.Netcode;
using UnityEngine;
namespace Unity.BossRoom.Gameplay.GameplayObjects.Character
{
///
/// Attached to the player-characters' prefab, this maintains a list of active ServerCharacter objects for players.
///
///
/// This is an optimization. In server code you can already get a list of players' ServerCharacters by
/// iterating over the active connections and calling GetComponent() on their PlayerObject. But we need
/// to iterate over all players quite often -- the monsters' IdleAIState does so in every Update() --
/// and all those GetComponent() calls add up! So this optimization lets us iterate without calling
/// GetComponent(). This will be refactored with a ScriptableObject-based approach on player collection.
///
[RequireComponent(typeof(ServerCharacter))]
public class PlayerServerCharacter : NetworkBehaviour
{
static List s_ActivePlayers = new List();
[SerializeField]
ServerCharacter m_CachedServerCharacter;
public override void OnNetworkSpawn()
{
if (IsServer)
{
s_ActivePlayers.Add(m_CachedServerCharacter);
}
else
{
enabled = false;
}
}
void OnDisable()
{
s_ActivePlayers.Remove(m_CachedServerCharacter);
}
public override void OnNetworkDespawn()
{
if (IsServer)
{
var movementTransform = m_CachedServerCharacter.Movement.transform;
SessionPlayerData? sessionPlayerData = SessionManager.Instance.GetPlayerData(OwnerClientId);
if (sessionPlayerData.HasValue)
{
var playerData = sessionPlayerData.Value;
playerData.PlayerPosition = movementTransform.position;
playerData.PlayerRotation = movementTransform.rotation;
playerData.CurrentHitPoints = m_CachedServerCharacter.HitPoints;
playerData.HasCharacterSpawned = true;
SessionManager.Instance.SetPlayerData(OwnerClientId, playerData);
}
}
}
///
/// Returns a list of all active players' ServerCharacters. Treat the list as read-only!
/// The list will be empty on the client.
///
public static List GetPlayerServerCharacters()
{
return s_ActivePlayers;
}
///
/// Returns the ServerCharacter owned by a specific client. Always returns null on the client.
///
///
/// The ServerCharacter owned by the client, or null if no ServerCharacter is found
public static ServerCharacter GetPlayerServerCharacter(ulong ownerClientId)
{
foreach (var playerServerCharacter in s_ActivePlayers)
{
if (playerServerCharacter.OwnerClientId == ownerClientId)
{
return playerServerCharacter;
}
}
return null;
}
}
}