using System; using System.Collections; using System.Collections.Generic; using KTGMGemClient; using UnityEngine; using TowerDefense.UI.HUD; namespace TowerDefense.Level { /// /// PVE 无尽模式一个关卡波次管理器 /// public class EndlessWaveManager : MonoBehaviour { /// /// 当前关卡等级的所有波数据 /// public List> LevelData { get; set; } /// /// 波次时间间隔 /// public float WaveInterval { get; set; } /// /// 怪物移速缩放 /// public float SpeedScale { get; set; } = 1.0f; /// /// 当前波索引 /// public int CurrentWaveIndex { get; protected set; } /// /// 当前波数据 /// protected List waveData; /// /// 实际上就是5条兵线 /// [Tooltip("Specify list in order")] public List waves = new List(); /// /// 当前WaveManager是否开始Wave. /// protected bool isWaveStarted = false; /// /// Called when all waves are finished /// public event Action AllWaveCompleted; /// /// 当前关卡的总波数 /// public int TotalWaves { get; protected set; } /// /// 当前波的赛道总数 /// public int TotalWaveLines { get; set; } /// /// 当前波已经完成的赛道数量 /// public int CompletedWaveLine { get; protected set; } /// /// 本波次敌人总数量 /// public int TotalEnemies { get; protected set; } /// /// 本波次剩余敌人数量 /// public int RemainEnemies { get; protected set; } /// /// 当前正在进行的关卡等级 /// public int Level { get; protected set; } /// /// Starts the waves /// /// 关卡等级 /// public virtual void StartWaves(int level) { Debug.Log($"--------------------- 开始第 {level} 关 ---------------------"); Level = level; LevelData = EndlessPortData.GetLevelWaveData(level); TotalWaves = LevelData.Count; CurrentWaveIndex = 0; EndlessBossHPManager.instance.InitHP(); EndlessLevelManager.instance.DecrementEnemies -= DecrementEnemies; EndlessLevelManager.instance.DecrementEnemies += DecrementEnemies; if (LevelData.Count == 0) throw new Exception($"当前关卡:{level}, 没有关卡数据"); UpdateWave(); } /// /// 敌人数量减少 /// /// public void DecrementEnemies(int count) { RemainEnemies -= count; // 改变血条的进度 EndlessBossHPManager.instance.SetCurrentProgress(RemainEnemies * 1f / TotalEnemies); } /// /// 获取当前Wave的开始位置 /// /// /// public Vector3 GetWaveEndPos(int waveline) { return waves[waveline].StartingNode.GetNextNode().transform.position; } /// /// 更新波 /// private void UpdateWave() { if (EndlessGameUI.instance.state == EndlessGameUI.State.GameOver) return; if (CurrentWaveIndex > 0) EndlessBossHPManager.instance.SwitchHP(CurrentWaveIndex == TotalWaves -1); EndlessBossHPManager.instance.UpdateWave(TotalWaves - CurrentWaveIndex); EndlessBossHPManager.instance.ShowHP(); TotalEnemies = EndlessPortData.GetWaveEnemiesCount(Level, CurrentWaveIndex); RemainEnemies = TotalEnemies; waveData = LevelData[CurrentWaveIndex]; // 直接取第一条就行了 WaveInterval = waveData[0].Config.cooldown / 1000f; TotalWaveLines = waveData.Count; CompletedWaveLine = 0; foreach (EndlessPortConfig data in waveData) { // 兵线被摧毁了,就不再出兵了,实际上只要不是Wait状态 都应该不能出兵 if (waves[data.Config.tunel - 1].LineState == EndlessWaveLineState.Destroyed) { --TotalWaveLines; continue; } waves[data.Config.tunel - 1].WaveCompleted -= OneWaveCompleted; waves[data.Config.tunel - 1].WaveCompleted += OneWaveCompleted; waves[data.Config.tunel - 1].StartWave(data); } if (TotalWaveLines != 0) isWaveStarted = true; } /// /// 一波结束了 /// private void OneWaveCompleted() { ++CompletedWaveLine; } public void Update() { if (!isWaveStarted) return; if (CompletedWaveLine >= TotalWaveLines) { // 判断所有敌人是否全部清除 WaveLineAgentInsMgr[] waveLineAgentIns = AgentInsManager.instance.GetWaveLineList(); // 判断是否敌人数量为0 for (int i = 0; i < waveLineAgentIns.Length; ++i) { if (waveLineAgentIns[i].getAgentInsNum() != 0) return; } // 更新波索引 ++CurrentWaveIndex; EndlessBuffManager.instance.UpdateBuffList(); if (CurrentWaveIndex >= TotalWaves) // 当前关卡的所有波次全部完成 SafelyCallSpawningCompleted(); else { isWaveStarted = false; // 当前波的所有赛道都已经完成出怪 StartCoroutine(DelayToUpdateWave()); } } } /// /// 延迟去更新新的一波 /// /// private IEnumerator DelayToUpdateWave() { yield return new WaitForSeconds(WaveInterval); UpdateWave(); } /// /// Calls allWaveCompleted event /// protected virtual void SafelyCallSpawningCompleted() { isWaveStarted = false; EndlessBossHPManager.instance.UpdateWave(TotalWaves - CurrentWaveIndex); if (AllWaveCompleted != null) AllWaveCompleted(); } } }