|
|
|
|
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>();
|
|
|
|
|
}
|
|
|
|
|
}
|