using ExitGames.Client.Photon; using Photon.Pun; using Photon.Realtime; using System.Collections; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.UI; public class NetworkManager : MonoBehaviourPunCallbacks, IOnEventCallback { [SerializeField] private GameEvent_RiftSettings onSpawnRiftRequest; [SerializeField] private StringSharedField charSelected; [SerializeField] private GameEvent_Player onPlayerJoinedParty; [SerializeField] private GameEvent_Player onPlayerLeftParty; [SerializeField] private GameEvent_Player onPlayerVoted; [SerializeField] private GameEvent_Player onPlayerVoteCanceled; [SerializeField] private GameEvent onLoadLevelStarting; [SerializeField] private GameEvent onJoinedRoom; [SerializeField] private GameEventListener_ZoneData onGameSceneLoaded; [SerializeField] private GameEventListener_JobInstance onJobSelected; [SerializeField] private GameEventListener_PhotonView onPlayerSpawned; [SerializeField] private GameEventListener onInfoPanelClosed; [SerializeField] private TMP_Text changeLevelVoteText; private int count = 0; private bool changeLevelVoted = false; private Button voteButton; //private object inProgress = false; private Dictionary playerVoted = new Dictionary(); public List party = new List(); private string votedZone; private void Awake() { DontDestroyOnLoad(this); onGameSceneLoaded.Response.AddListener(OnGameSceneLoaded); onPlayerSpawned.Response.AddListener(OnPlayerSpawned); onInfoPanelClosed.Response.AddListener(() => { CancelChangeLevelVote(); }); onJobSelected.Response.AddListener((x) => votedZone = x.zoneName); } // Start is called before the first frame update void Start() { PhotonNetwork.AutomaticallySyncScene = true; PhotonNetwork.ConnectUsingSettings(); Debug.Log("Connecting.."); } public override void OnConnectedToMaster() { Debug.Log("Connected."); PhotonNetwork.JoinLobby(); Debug.Log("Joining Lobby.."); } public override void OnJoinedLobby() { Debug.Log("Lobby joined."); //PhotonNetwork.JoinOrCreateRoom("Sprint_01", new RoomOptions { MaxPlayers = 0, EmptyRoomTtl = 0 }, TypedLobby.Default); //Debug.Log("Joining Game.."); } public override void OnJoinedRoom() { Debug.Log("Party \"" + PhotonNetwork.CurrentRoom.Name + "\" joined."); ClearVotes(); if (!SceneManager.GetActiveScene().name.Contains(GameConstants.Scenes.HuntersInn)) { if (PhotonNetwork.IsMasterClient) { PhotonNetwork.LoadLevel(GameConstants.Scenes.HuntersInn); } } onJoinedRoom.Raise(); } public void OnGameSceneLoaded(ZoneData zoneData) { ClearVotes(); StartCoroutine(SpawnCharacterWithDelay()); if (PhotonNetwork.LocalPlayer.IsMasterClient && zoneData.isHostileZone) StartCoroutine(SpawnEnemiesWithDelay(zoneData)); } public IEnumerator SpawnCharacterWithDelay() { yield return new WaitUntil(() => PhotonNetwork.InRoom); PhotonNetwork.Instantiate("PlayableCharacters/" + charSelected.Value, Vector3.zero + new Vector3(3 * PhotonNetwork.LocalPlayer.ActorNumber, 0, 0), Quaternion.identity); } /* private void Update() { if (!PhotonNetwork.LocalPlayer.IsMasterClient) return; if (Input.GetKeyDown(KeyCode.S)) { onSpawnRiftRequest.Raise(new RiftSettings() { zoneData = rift, riftIndex = Random.Range(0, 5), enemyIndexes_Quantity = new Dictionary() { { 0, Random.Range(2, 6) }, { 1, Random.Range(2, 6) } } }); //PhotonNetwork.InstantiateRoomObject("AngrySkellyPrefab", new Vector3(-10, 0, 10), Quaternion.identity); } if (Input.GetKeyDown(KeyCode.F1)) { PhotonNetwork.LoadLevel(huntersInn); } if (Input.GetKeyDown(KeyCode.F2)) { PhotonNetwork.LoadLevel(skellyard); } }*/ public IEnumerator SpawnEnemiesWithDelay(ZoneData zoneData) { yield return new WaitForSeconds(1f); onSpawnRiftRequest.Raise(new RiftSettings() { zoneData = zoneData, numberOfWaves = Random.Range(GameConstants.GameBalancing.MinimumNumberOfWavesPerRift, GameConstants.GameBalancing.MaximumNumberOfWavesPerRift), riftIndex = Random.Range(0, 5), enemyIndexes_Quantity = new Dictionary() { { (int)GameConstants.EnemySpawning.EnemyID.AngrySkelly, Random.Range(GameConstants.GameBalancing.MinimumQuantityAngrySkelly, GameConstants.GameBalancing.MaximumQuantityAngrySkelly) }, { (int)GameConstants.EnemySpawning.EnemyID.SkellyMage, Random.Range(GameConstants.GameBalancing.MinimumQuantitySkellyMage, GameConstants.GameBalancing.MaximumQuantitySkellyMage) }, { (int)GameConstants.EnemySpawning.EnemyID.VineGolem, Random.Range(GameConstants.GameBalancing.MinimumQuantityVineGolem, GameConstants.GameBalancing.MaximumQuantityVineGolem) }, { (int)GameConstants.EnemySpawning.EnemyID.PolygonGolem, Random.Range(GameConstants.GameBalancing.MinimumQuantityPolygonGolem, GameConstants.GameBalancing.MaximumQuantityPolygonGolem) }, { (int)GameConstants.EnemySpawning.EnemyID.Lich, Random.Range(GameConstants.GameBalancing.MinimumQuantityLich, GameConstants.GameBalancing.MaximumQuantityLich) }, }, bossIndex = Random.Range(0, (int)GameConstants.EnemySpawning.EnemyID.Count) }); ; } public override void OnPlayerEnteredRoom(Player newPlayer) { Debug.Log("New player joined: " + newPlayer.NickName); playerVoted.Add(newPlayer, false); changeLevelVoteText.text = $"Votes: {count}/{PhotonNetwork.PlayerList.Length}"; //party.Add(newPlayer); //onPlayerJoinedParty.Raise(newPlayer); } public override void OnPlayerLeftRoom(Player otherPlayer) { if (playerVoted.ContainsKey(otherPlayer)) { if (playerVoted[otherPlayer]) count--; playerVoted.Remove(otherPlayer); } if (party.Contains(otherPlayer)) { party.Remove(otherPlayer); onPlayerLeftParty.Raise(otherPlayer); } changeLevelVoteText.text = $"Votes: {count}/{PhotonNetwork.PlayerList.Length}"; Debug.Log("Player left: " + otherPlayer.NickName); } public void OnPlayerSpawned(PhotonView photonView) { party.Add(photonView.Owner); onPlayerJoinedParty.Raise(photonView.Owner); } public void ChangeLevelVote(Button button) { if (!PhotonNetwork.IsConnected) return; if (changeLevelVoted) return; voteButton = button; changeLevelVoted = true; voteButton.interactable = false; if (PhotonNetwork.CurrentRoom.PlayerCount == 1) { CountVote(PhotonNetwork.LocalPlayer); Send_All_OnLoadLevelStarting(); } else { CountVote(PhotonNetwork.LocalPlayer); RaiseEventOptions raiseEventOptions = new RaiseEventOptions { Receivers = ReceiverGroup.Others }; object[] content = new object[] { PhotonNetwork.LocalPlayer, votedZone }; PhotonNetwork.RaiseEvent(GameConstants.NetworkEventCodes.ChangeLevelVoted, content, raiseEventOptions, SendOptions.SendReliable); if (PhotonNetwork.IsMasterClient) { if (count >= PhotonNetwork.CurrentRoom.PlayerCount) { Send_All_OnLoadLevelStarting(); } } } } public void CancelChangeLevelVote() { if (!PhotonNetwork.IsConnected) return; changeLevelVoted = false; if (voteButton != null) voteButton.interactable = true; RemoveVote(PhotonNetwork.LocalPlayer); ClearVotes(); RaiseEventOptions raiseEventOptions = new RaiseEventOptions { Receivers = ReceiverGroup.Others }; PhotonNetwork.RaiseEvent(GameConstants.NetworkEventCodes.CancelChangeLevelVoted, PhotonNetwork.LocalPlayer, raiseEventOptions, SendOptions.SendReliable); } public void Send_All_OnLoadLevelStarting() { RaiseEventOptions raiseEventOptions = new RaiseEventOptions { Receivers = ReceiverGroup.All }; PhotonNetwork.RaiseEvent(GameConstants.NetworkEventCodes.LoadLevelStarting, 0, raiseEventOptions, SendOptions.SendReliable); } public void OnEvent(EventData photonEvent) { if (photonEvent.Code == GameConstants.NetworkEventCodes.JobSelection) { string jsonJobData = (string)photonEvent.CustomData; Debug.Log("Job selected: " + jsonJobData); JobInstance selectedJob = JsonUtility.FromJson(jsonJobData); votedZone = selectedJob.zoneName; } if (photonEvent.Code == GameConstants.NetworkEventCodes.ChangeLevelVoted) { object[] content = (object[])photonEvent.CustomData; Player player = (Player)content[0]; votedZone = (string)content[1]; Debug.Log(player); Debug.Log(player.ActorNumber); Debug.Log(player.NickName); if (PhotonNetwork.IsMasterClient) { CountVote(player); if (count >= PhotonNetwork.CurrentRoom.PlayerCount) { Send_All_OnLoadLevelStarting(); } } else { CountVote(player); } } if (photonEvent.Code == GameConstants.NetworkEventCodes.CancelChangeLevelVoted) { Player player = (Player)photonEvent.CustomData; Debug.Log(player); Debug.Log(player.ActorNumber); Debug.Log(player.NickName); RemoveVote(player); ClearVotes(); onPlayerVoteCanceled.Raise(player); } if (photonEvent.Code == GameConstants.NetworkEventCodes.LoadLevelStarting) { Debug.Log("loadlevelStarting"); UpdateGameStateOnLoadLevelStarting(); if (PhotonNetwork.IsMasterClient) NetworkLoadVotedLevel(); } } private void CountVote(Player player) { playerVoted[player] = true; count++; changeLevelVoteText.text = $"Votes: {count}/{PhotonNetwork.PlayerList.Length}"; onPlayerVoted.Raise(player); } private void RemoveVote(Player player) { playerVoted[player] = false; count--; if (count < 0) count = 0; changeLevelVoteText.text = $"Votes: {count}/{PhotonNetwork.PlayerList.Length}"; onPlayerVoteCanceled.Raise(player); } private void ClearVotes() { List keys = new List(playerVoted.Keys); for (int i = 0; i < keys.Count; i++) { playerVoted[keys[i]] = false; } count = 0; if (voteButton != null) voteButton.interactable = true; changeLevelVoted = false; changeLevelVoteText.text = $"Votes: {count}/{PhotonNetwork.PlayerList.Length}"; } private void NetworkLoadVotedLevel() { UpdateRoomPropertiesInProgress(false); StartCoroutine(NetworkLoadRestartWithDelay()); } private IEnumerator NetworkLoadRestartWithDelay() { yield return new WaitForSeconds(1.5f); PhotonNetwork.LoadLevel(GameConstants.Scenes.GetSceneNameByZoneName(votedZone)); } private void UpdateGameStateOnLoadLevelStarting() { onLoadLevelStarting.Raise(); } private void CheckRoomProperties() { //if (PhotonNetwork.CurrentRoom.CustomProperties.TryGetValue("inProgress", out inProgress)) //{ // Debug.Log("Got inProgress from properties: " + (bool)inProgress + " "); //} PhotonNetwork.Instantiate(charSelected.Value, Vector3.zero + new Vector3(3 * PhotonNetwork.LocalPlayer.ActorNumber, 0, 0), Quaternion.identity); } public override void OnRoomPropertiesUpdate(ExitGames.Client.Photon.Hashtable propertiesThatChanged) { } public void UpdateRoomPropertiesInProgress(bool inProgress) { ExitGames.Client.Photon.Hashtable ht = new ExitGames.Client.Photon.Hashtable { { "inProgress", inProgress } }; PhotonNetwork.CurrentRoom.SetCustomProperties(ht); } }