using Photon.Pun; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; public class Rift : MonoBehaviour, IPunObservable { [Header("Listeners:")] [SerializeField] private GameEventListener_Float experienceOnDeath; [Header("Visual Components:")] [SerializeField] private GameObject openning; [SerializeField] private GameObject maintain; [SerializeField] private GameObject closing; [Header("Enemies:")] [SerializeField] private List enemyPrefabs = new List(); [Header("Boss Prefabs:")] [SerializeField] private List bossPrefabs = new List(); [Header("Spawnpoint Variations:")] [SerializeField] private List spawnpoints = new List(); private Dictionary enemyType_Quantity; PhotonView photonView; WaitForSeconds delayBetweenSpawns = new WaitForSeconds(GameConstants.GameBalancing.RiftDelayBetweenSpawns); WaitForSeconds delayToClose = new WaitForSeconds(1f); UnitDifficultySettings unitDifficultySettings; UnitDifficultySetter unitDifficultySetter; GameObject spawnedEnemy; RiftSettings settings; RiftSpawner riftSpawner; int spawnpointIndex; int totalEnemiesPerWave; int totalWavesToDefeat = 0; bool bossSpawned = false; private List keyValuePairs = new List(); private void Awake() { photonView = GetComponent(); experienceOnDeath.Response.AddListener((x) => CountTowardsBossSpawn()); } public void InitializeRift(RiftSettings settings, RiftSpawner riftSpawner) { this.settings = settings; this.riftSpawner = riftSpawner; totalEnemiesPerWave = 0; totalWavesToDefeat = settings.numberOfWaves; bossSpawned = false; enemyType_Quantity = settings.enemyIndexes_Quantity.ToDictionary(entry => entry.Key, entry => entry.Value); Debug.Log("Total Types of enemies: " + enemyType_Quantity.Keys.Count); unitDifficultySettings = GameDifficultyController.Instance.GetCurrentDifficultySettings(); } public void StartSpawning() { if (PhotonNetwork.IsMasterClient) StartCoroutine(SpawnEnemiesOverTime()); } IEnumerator SpawnEnemiesOverTime() { SetVisual(0); keyValuePairs.Clear(); foreach (KeyValuePair entry in enemyType_Quantity) { keyValuePairs.Add(new int[] { entry.Key, entry.Value }); totalEnemiesPerWave += entry.Value; } yield return new WaitForSeconds(0.8f); SetVisual(1); for (int i = 0; i < keyValuePairs.Count; i++) { for (int j = 0; j < keyValuePairs[i][1]; j++) { spawnedEnemy = PhotonNetwork.Instantiate("Enemies/" + enemyPrefabs[keyValuePairs[i][0]].name, spawnpoints[Random.Range(0, spawnpoints.Count)].position, this.transform.rotation); unitDifficultySetter = spawnedEnemy.GetComponentInChildren(true); unitDifficultySetter.InitializeUnitDifficulty(unitDifficultySettings); yield return delayBetweenSpawns; } } SetVisual(2); yield return delayToClose; SetVisual(-1); //yield return delayBetweenSpawns; //DestroyAfterSpawn(); } IEnumerator SpawnBoss() { yield return delayToClose; UpdateScaleForBossSpawn(); SetVisual(0); yield return new WaitForSeconds(0.8f); SetVisual(1); spawnedEnemy = PhotonNetwork.Instantiate("Bosses/" + bossPrefabs[settings.bossIndex].name, this.transform.position, this.transform.rotation); unitDifficultySetter = spawnedEnemy.GetComponentInChildren(true); unitDifficultySetter.InitializeUnitDifficulty(unitDifficultySettings); yield return delayBetweenSpawns; SetVisual(2); yield return delayToClose; SetVisual(-1); yield return delayBetweenSpawns; DestroyAfterSpawn(); } private void CountTowardsBossSpawn() { if (!PhotonNetwork.IsMasterClient) return; totalEnemiesPerWave--; if (totalEnemiesPerWave > 0) return; if (bossSpawned) return; totalWavesToDefeat--; Debug.Log("All enemies dead, waves defeated decreased to = " + totalWavesToDefeat); if (totalWavesToDefeat > 0) { StartCoroutine(DelayedChangeLocation()); return; } Debug.Log("Spawning boss"); bossSpawned = true; StartCoroutine(SpawnBoss()); } private void DestroyAfterSpawn() { if (PhotonNetwork.LocalPlayer.IsMasterClient) PhotonNetwork.Destroy(this.gameObject); } private IEnumerator DelayedChangeLocation() { yield return delayToClose; ChangeLocation(); } private void ChangeLocation() { Debug.Log("Changing location and spawning new wave"); spawnpointIndex = Random.Range(0, settings.zoneData.spawnPoints.Count); this.transform.position = settings.zoneData.spawnPoints[spawnpointIndex].position; riftSpawner.lastUsedSpawnpoint = spawnpointIndex; StartSpawning(); } private void SetVisual(int index) { switch (index) { case -1: openning.SetActive(false); maintain.SetActive(false); closing.SetActive(false); break; case 0: openning.SetActive(true); maintain.SetActive(false); closing.SetActive(false); break; case 1: openning.SetActive(false); maintain.SetActive(true); closing.SetActive(false); break; case 2: openning.SetActive(false); maintain.SetActive(false); closing.SetActive(true); break; default: break; } } private void UpdateScaleForBossSpawn() { openning.transform.localScale = Vector3.one * 2f; maintain.transform.localScale = Vector3.one * 2f; closing.transform.localScale = Vector3.one * 2f; photonView.RPC(nameof(RPC_ScaleForBoss), RpcTarget.Others); } [PunRPC] private void RPC_ScaleForBoss() { openning.transform.localScale = Vector3.one * 2f; maintain.transform.localScale = Vector3.one * 2f; closing.transform.localScale = Vector3.one * 2f; } public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info) { if (stream.IsWriting) { stream.SendNext(openning.activeSelf); stream.SendNext(maintain.activeSelf); stream.SendNext(closing.activeSelf); } if (stream.IsReading) { openning.SetActive((bool)stream.ReceiveNext()); maintain.SetActive((bool)stream.ReceiveNext()); closing.SetActive((bool)stream.ReceiveNext()); } } }