You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

168 lines
3.9 KiB

using ExitGames.Client.Photon;
using Photon.Pun;
using Photon.Realtime;
using System.Collections.Generic;
using UnityEngine;
public class PlayerSlotManager : MonoBehaviour {
public Room Room {
get;
set;
}
public List<PlayerSlot> playerSlots;
public GameObject colorSelector;
private List<PlayerSlot> ActiveSlots {
get => playerSlots.FindAll(p => !p.IsEmpty);
}
private List<PlayerSlot> EmptySlots {
get => playerSlots.FindAll(p => p.IsEmpty);
}
private List<Player> Players {
get => new List<Player>(Room.Players.Values);
}
public void OnJoinedRoom() {
Room = PhotonNetwork.CurrentRoom;
if (PhotonNetwork.IsMasterClient)
OnCreatedRoom();
foreach (Player player in Players)
OnPlayerEnteredRoom(player);
int colorIndex = 1;
for (int i = 1; i <= 8; i++) {
if (IsColorUsed(i, out Player player) && player != PhotonNetwork.LocalPlayer)
continue;
colorIndex = i;
break;
}
PhotonNetwork.LocalPlayer.SetCustomProperties(new Hashtable() {
["IsReady"] = false,
["ColorIndex"] = colorIndex
});
}
private bool TryGetColor(Player p, out int index) {
bool success = p.CustomProperties.TryGetValue("ColorIndex", out object objIndex);
if (success)
index = (int)objIndex;
else
index = 0;
return success;
}
private bool TryGetReady(Player p, out bool ready) {
bool success = p.CustomProperties.TryGetValue("IsReady", out object objReady);
if (success)
ready = (bool)objReady;
else
ready = false;
return success;
}
public void OnCreatedRoom() {
}
public void Clear() {
Debug.Log("Clearing player slots");
foreach (PlayerSlot playerSlot in playerSlots)
playerSlot.Player = null;
}
public void OnPlayerEnteredRoom(Player player) {
if (playerSlots.Exists(s => s.Player == player))
return;
EmptySlots[0].Player = player;
}
public void OnPlayerLeftRoom(Player player) {
PlayerSlot slot = ActiveSlots.Find(s => s.Player == player);
if (slot != null) {
slot.Player = null;
PlayerColorsUpdate();
}
}
public void OnMasterClientSwitched(Player newMaster) {
}
public void OnPlayerPropertiesUpdate(Player player, Hashtable props) {
PlayerSlot slot = ActiveSlots.Find(s => s.Player == player);
if (slot != null) {
slot.OnPropertiesUpdate(props);
PlayerColorsUpdate();
}
}
private void PlayerColorsUpdate() {
List<PlayerColor> playerColors = new List<PlayerColor>(colorSelector.GetComponentsInChildren<PlayerColor>());
foreach (PlayerColor playerColor in playerColors) {
if (IsColorUsed(playerColor.colorIndex, out Player player)) {
if (player == PhotonNetwork.LocalPlayer && !playerColor.IsSelected) {
playerColor.Select();
} else {
playerColor.Forbid();
}
} else {
playerColor.Allow();
}
}
}
public void RequestSetPlayerColor(int colorIndex) {
pv.RPC("RpcRequestSetPlayerColor", RpcTarget.MasterClient, PhotonNetwork.LocalPlayer.ActorNumber, colorIndex);
}
[PunRPC]
//Called on master client
private void RpcRequestSetPlayerColor(int actorNumber, int colorIndex) {
if (IsColorUsed(colorIndex))
return;
PlayerSlot slot = ActiveSlots.Find(s => s.Player.ActorNumber == actorNumber);
if (slot != null) {
slot.Player.SetCustomProperties(new Hashtable() { ["ColorIndex"] = colorIndex });
}
}
private bool IsColorUsed(int colorIndex) {
return Players.Exists(p => TryGetColor(p, out int index) && index == colorIndex);
}
private bool IsColorUsed(int colorIndex, out Player player) {
if (IsColorUsed(colorIndex)) {
player = Players.Find(p => TryGetColor(p, out int index) && index == colorIndex);
return true;
} else {
player = null;
return false;
}
}
public bool IsEveryoneReady() {
foreach (PlayerSlot playerSlot in playerSlots)
if (!playerSlot.IsReady && !playerSlot.IsEmpty)
return false;
return true;
}
private PhotonView pv;
public static PlayerSlotManager Instance {
get; set;
}
private void Awake() {
Instance = this;
pv = GetComponent<PhotonView>();
}
}