using System;
|
using System.Collections;
|
using System.Collections.Generic;
|
using KTGMGemClient;
|
using UnityEngine;
|
using TowerDefense.UI.HUD;
|
using Core.Utilities;
|
using Core.Health;
|
|
namespace TowerDefense.Level
|
{
|
/// <summary>
|
/// PVE 无尽模式一个关卡波次管理器
|
/// </summary>
|
public class EndlessWaveManager : MonoBehaviour
|
{
|
/// <summary>
|
/// 当前关卡等级的所有波数据
|
/// </summary>
|
public List<List<EndlessPortConfig>> LevelData { get; set; }
|
|
/// <summary>
|
/// 波次时间间隔
|
/// </summary>
|
public float WaveInterval { get; set; }
|
|
/// <summary>
|
/// 怪物移速缩放
|
/// </summary>
|
public float SpeedScale { get; set; } = 1.0f;
|
|
/// <summary>
|
/// 当前波索引
|
/// </summary>
|
public int CurrentWaveIndex { get; protected set; }
|
|
/// <summary>
|
/// 当前波数据
|
/// </summary>
|
protected List<EndlessPortConfig> waveData;
|
|
/// <summary>
|
/// 实际上就是5条兵线
|
/// </summary>
|
[Tooltip("Specify list in order")]
|
public List<EndlessWave> waves = new List<EndlessWave>();
|
|
/// <summary>
|
/// 当前WaveManager是否开始Wave.
|
/// </summary>
|
protected bool isWaveStarted = false;
|
|
/// <summary>
|
/// Called when all waves are finished
|
/// </summary>
|
public event Action AllWaveCompleted;
|
|
/// <summary>
|
/// 当前关卡的总波数
|
/// </summary>
|
public int TotalWaves { get; protected set; }
|
|
/// <summary>
|
/// 当前波的赛道总数
|
/// </summary>
|
public int TotalWaveLines { get; set; }
|
|
/// <summary>
|
/// 当前波已经完成的赛道数量
|
/// </summary>
|
public int CompletedWaveLine { get; protected set; }
|
|
/// <summary>
|
/// 本波次敌人总数量
|
/// </summary>
|
public int TotalEnemies { get; protected set; }
|
|
/// <summary>
|
/// 所有兵线已经生成的敌人总数量
|
/// </summary>
|
/// <value></value>
|
public int SpawnedTotalEnemies { get; protected set; }
|
|
/// <summary>
|
/// 本波次剩余敌人数量
|
/// </summary>
|
public int RemainEnemies { get; protected set; }
|
|
/// <summary>
|
/// 当前正在进行的关卡等级
|
/// </summary>
|
public int Level { get; protected set; }
|
|
/// <summary>
|
/// 法阵
|
/// </summary>
|
public List<MeshRenderer> TunelList;
|
|
private string tunelMaterialPath = "UI/Endless/Tunel/tunel_";
|
|
private string faZhenPath = "UI/Endless/Tunel/EndlessFaZhen";
|
|
private Timer faZhenRefreshTimer;
|
|
|
/// <summary>
|
/// 管理法阵的对象池
|
/// </summary>
|
/// <returns></returns>
|
private Dictionary<string, List<GameObject>> faZhenDic = new Dictionary<string, List<GameObject>>();
|
private void Start()
|
{
|
faZhenDic = new Dictionary<string, List<GameObject>>();
|
HideTunel();
|
EventCenter.Ins.Add<float>((int)KTGMGemClient.EventType.EndlessAgentTaskDamage, OnHit);
|
EventCenter.Ins.Add<int>((int)KTGMGemClient.EventType.WaveLineFinish, WaveLineFinish);
|
|
}
|
|
/// <summary>
|
/// Agent掉血,不管是中毒还是乱七八糟的掉血,只要掉血就会接收到
|
/// </summary>
|
/// <param name="value"></param>
|
private void OnHit(float value)
|
{
|
float nowHP = EndlessBossHPManager.instance.CurrentHP - value;
|
EndlessBossHPManager.instance.SetCurrentHP(nowHP);
|
}
|
|
/// <summary>
|
/// 隐藏法阵,即怪出生的圈圈
|
/// </summary>
|
public void HideTunel()
|
{
|
for (int i = 0; i < TunelList.Count; ++i)
|
{
|
TunelList[i].gameObject.SetActive(false);
|
}
|
}
|
|
/// <summary>
|
/// 显示法阵
|
/// </summary>
|
public void ShowTunel()
|
{
|
for (int i = 0; i < TunelList.Count; ++i)
|
{
|
TunelList[i].gameObject.SetActive(true);
|
}
|
}
|
|
/// <summary>
|
/// Starts the waves
|
/// </summary>
|
/// <param name="level">关卡等级</param>
|
///
|
public virtual void StartWaves(int level)
|
{
|
SummonFaZhen();
|
}
|
|
/// <summary>
|
/// 关卡开始时首先初始化关卡信息
|
/// </summary>
|
/// <param name="level"></param>
|
public void InitPort(int level)
|
{
|
InitPortData(level);
|
InitWaveData();
|
RefreshBoss();
|
|
if (!GameConfig.IsNewbie)
|
{
|
endless_boss bossData = EndlessBossData.GetDataById(waveData[0].Config.resource);
|
|
if (bossData != null)
|
EndlessBossSkillManager.instance.Init(bossData.skill);
|
}
|
}
|
|
/// <summary>
|
/// 初始化关卡数据
|
/// </summary>
|
private void InitPortData(int level)
|
{
|
Debug.Log($"--------------------- 开始第 {level} 关 ---------------------");
|
Level = level;
|
LevelData = EndlessPortData.GetLevelWaveData(level);
|
TotalWaves = LevelData.Count;
|
CurrentWaveIndex = 0;
|
EndlessBossHPManager.instance.Init();
|
EndlessLevelManager.instance.DecrementEnemies -= DecrementEnemies;
|
EndlessLevelManager.instance.DecrementEnemies += DecrementEnemies;
|
|
if (LevelData.Count == 0)
|
throw new Exception($"当前关卡:{level}, 没有关卡数据");
|
}
|
|
/// <summary>
|
/// 召唤法阵
|
/// </summary>
|
private void SummonFaZhen()
|
{
|
EventCenter.Ins.Add((int)KTGMGemClient.EventType.EndlessBossSummonEnd, OnEndlessBossSummonEnd);
|
EndlessBossCtrl.instance.ChangeState(EndlessBossActionState.Summon);
|
}
|
|
/// <summary>
|
/// boss召唤动作结束
|
/// </summary>
|
private void OnEndlessBossSummonEnd()
|
{
|
EventCenter.Ins.Remove((int)KTGMGemClient.EventType.EndlessBossSummonEnd, OnEndlessBossSummonEnd);
|
HideTunel();
|
RefreshFaZhen();
|
}
|
|
/// <summary>
|
/// 刷新法阵显示
|
/// </summary>
|
private void RefreshFaZhen()
|
{
|
float time = 0;
|
|
// 刷新法阵的显示
|
for (int i = 0; i < waveData.Count; ++i)
|
{
|
int tunel = waveData[i].Config.tunel;
|
int tunelBgId = waveData[i].Config.tunel_bg;
|
|
// string key = $"{faZhenPath}{tunelBgId}{tunelBgId}";
|
// List<GameObject> allPS;
|
// GameObject tmpPSObj = null;
|
// if (faZhenDic.ContainsKey(key))
|
// {
|
// allPS = faZhenDic[key];
|
// foreach (GameObject item in allPS)
|
// {
|
// if (item.activeSelf)
|
// {
|
// tmpPSObj = item;
|
// break;
|
// }
|
// }
|
// }
|
|
// if (tmpPSObj == null)
|
// {
|
// allPS = new List<GameObject>();
|
// GameObject obj = Resources.Load<GameObject>($"{faZhenPath}{tunelBgId}{tunelBgId}");
|
// GameObject faZhen = Instantiate(obj);
|
// tmpPSObj = faZhen;
|
// allPS.Add(faZhen);
|
// faZhenDic.Add(key, allPS);
|
// }
|
|
// tmpPSObj.transform.SetParent(TunelList[tunel - 1].gameObject.transform);
|
// tmpPSObj.transform.localPosition = new Vector3(0, 1, 0);
|
// tmpPSObj.transform.localScale = new Vector3(2, 2, 2);
|
// TunelList[tunel - 1].gameObject.SetActive(true);
|
TunelList[tunel - 1].material = Resources.Load<Material>($"{tunelMaterialPath}{tunelBgId}");
|
GameObject obj = Resources.Load<GameObject>($"{faZhenPath}{tunelBgId}{tunelBgId}");
|
GameObject faZhen = Instantiate(obj);
|
|
faZhen.transform.SetParent(TunelList[tunel - 1].gameObject.transform);
|
faZhen.transform.localPosition = new Vector3(0, 1, 0);
|
faZhen.transform.localScale = new Vector3(2, 2, 2);
|
TunelList[tunel - 1].gameObject.SetActive(true);
|
|
ParticleSystem ps = faZhen.transform.GetChild(0).GetComponent<ParticleSystem>();
|
ps.Play();
|
time = ps.main.duration * 3;
|
Destroy(faZhen, time);
|
}
|
|
if (faZhenRefreshTimer == null)
|
faZhenRefreshTimer = new Timer(time, UpdateWave);
|
}
|
|
/// <summary>
|
/// 延迟关闭法阵
|
/// </summary>
|
/// <param name="WaveLineId"></param>
|
private void WaveLineFinish(int WaveLineId)
|
{
|
//StartCoroutine(CloseFaZhen(WaveLineId));
|
}
|
|
IEnumerator CloseFaZhen(int WaveLineId)
|
{
|
yield return new WaitForSeconds(1.0f);
|
Debug.Log("当前列出怪完成,WaveLineId:" + WaveLineId);
|
|
TunelList[WaveLineId - 1].gameObject.SetActive(false);
|
}
|
|
/// <summary>
|
/// 敌人数量减少
|
/// </summary>
|
/// <param name="count"></param>
|
public void DecrementEnemies(int count)
|
{
|
RemainEnemies -= count;
|
}
|
|
/// <summary>
|
/// 获取当前Wave的开始位置
|
/// </summary>
|
/// <param name="waveline"></param>
|
/// <returns></returns>
|
public Vector3 GetWaveEndPos(int waveline)
|
{
|
return waves[waveline].StartingNode.GetNextNode().transform.position;
|
}
|
|
|
private void RefreshBoss()
|
{
|
if (CurrentWaveIndex > 0 || TotalWaves == 1)
|
EndlessBossHPManager.instance.SwitchHP(CurrentWaveIndex == TotalWaves - 1);
|
EndlessBossHPManager.instance.InitHP(EndlessPortData.GetWaveEnemiesTotalHP(Level, CurrentWaveIndex));
|
EndlessBossHPManager.instance.SetBossInfo($"第{Level}关 {waveData[0].Config.boss_name}");
|
EndlessBossHPManager.instance.UpdateWave(TotalWaves - CurrentWaveIndex);
|
EndlessBossHPManager.instance.ShowHP();
|
EndlessScoreManager.instance.ShowScore();
|
EndlessLevelManager.instance.DropRate = EndlessPortData.GetDropRate(Level, CurrentWaveIndex);
|
reward tmpData = EndlessPortData.GetDropReward(Level, CurrentWaveIndex);
|
//if(tmpData!=null && tmpData.type == Protobuf.CURRENCY.Arenaexp)//暂时没法判断,需要新加字段
|
if (tmpData != null)
|
EndlessLevelManager.instance.DropCoin = tmpData != null ? tmpData.count : 0;
|
|
}
|
|
/// <summary>
|
/// 初始化波次数据
|
/// </summary>
|
private void InitWaveData()
|
{
|
waveData = LevelData[CurrentWaveIndex];
|
// 直接取第一条就行了
|
WaveInterval = waveData[0].Config.cooldown / 1000f;
|
TotalWaveLines = waveData.Count;
|
CompletedWaveLine = 0;
|
SpawnedTotalEnemies = 0;
|
}
|
|
/// <summary>
|
/// 更新波
|
/// </summary>
|
private void UpdateWave()
|
{
|
if (EndlessGameUI.instance.state == EndlessGameUI.State.GameOver) return;
|
|
TotalEnemies = EndlessPortData.GetWaveEnemiesCount(Level, CurrentWaveIndex);
|
RemainEnemies = TotalEnemies;
|
|
foreach (EndlessPortConfig data in waveData)
|
{
|
// 兵线被摧毁了,就不再出兵了,实际上只要不是Wait状态 都应该不能出兵
|
if (waves[data.Config.tunel - 1].LineState == EndlessWaveLineState.Destroyed)
|
{
|
--TotalWaveLines;
|
continue;
|
}
|
|
int tunelIndex = data.Config.tunel - 1;
|
waves[tunelIndex].WaveCompleted -= OneWaveCompleted;
|
waves[tunelIndex].WaveCompleted += OneWaveCompleted;
|
waves[tunelIndex].SpawnNewAgent -= SpawnNewAgent;
|
waves[tunelIndex].SpawnNewAgent += SpawnNewAgent;
|
waves[data.Config.tunel - 1].StartWave(data);
|
}
|
|
if (TotalWaveLines != 0)
|
{
|
isWaveStarted = true;
|
EndlessBossSkillManager.instance.Restart();
|
EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.EndlessBeginWave);
|
}
|
}
|
|
/// <summary>
|
/// 有新的敌人生成
|
/// </summary>
|
private void SpawnNewAgent()
|
{
|
++SpawnedTotalEnemies;
|
|
if (GameConfig.IsNewbie)
|
{
|
if (EndlessUIStart.instance.beginDragStep && SpawnedTotalEnemies >= 3)
|
{
|
EndlessUIStart.instance.beginDragStep = false;
|
EndlessLevelManager.instance.StopSecondWave();
|
}
|
else if (EndlessUIStart.instance.guideThirdWaveStep)
|
{
|
//Debug.Log($"当前波次是木属性的 总怪物数量:{TotalEnemies} 当前已经生成了:{SpawnedTotalEnemies * 2}");
|
if (TotalEnemies - (SpawnedTotalEnemies * 2) <= 0)
|
{
|
Debug.Log("延迟第三波生成完毕");
|
StartCoroutine(BroadCastCreateThirdWaveDone());
|
}
|
}
|
}
|
}
|
|
IEnumerator BroadCastCreateThirdWaveDone()
|
{
|
yield return new WaitForSeconds(0.5f);
|
EndlessUIStart.instance.guideThirdWaveStep = false;
|
EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.CreateThirdWaveDone);
|
}
|
|
/// <summary>
|
/// 暂停所有兵线出兵
|
/// </summary>
|
public void PauseAllWave()
|
{
|
foreach (EndlessPortConfig data in waveData)
|
{
|
waves[data.Config.tunel - 1].PauseWave();
|
}
|
}
|
|
/// <summary>
|
/// 恢复所有兵线出兵
|
/// </summary>
|
public void RestartAllWave()
|
{
|
foreach (EndlessPortConfig data in waveData)
|
{
|
waves[data.Config.tunel - 1].RestartWave();
|
}
|
}
|
|
/// <summary>
|
/// 一波结束了
|
/// </summary>
|
private void OneWaveCompleted()
|
{
|
++CompletedWaveLine;
|
}
|
|
public void Update()
|
{
|
if (faZhenRefreshTimer != null)
|
{
|
if (faZhenRefreshTimer.Tick(Time.deltaTime))
|
faZhenRefreshTimer = null;
|
}
|
|
if (!isWaveStarted || EndlessGameUI.instance.state == EndlessGameUI.State.GameOver) 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();
|
EndlessBossSkillManager.instance.Reset();
|
EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.EndlessCompletedPort, Level, CurrentWaveIndex);
|
|
if (CurrentWaveIndex >= TotalWaves)
|
// 当前关卡的所有波次全部完成
|
SafelyCallSpawningCompleted();
|
else
|
{
|
isWaveStarted = false;
|
// 当前波的所有赛道都已经完成出怪
|
StartCoroutine(DelayToUpdateWave());
|
}
|
}
|
}
|
|
/// <summary>
|
/// 延迟去更新新的一波
|
/// </summary>
|
/// <returns></returns>
|
private IEnumerator DelayToUpdateWave()
|
{
|
yield return new WaitForSeconds(WaveInterval);
|
InitWaveData();
|
RefreshBoss();
|
SummonFaZhen();
|
}
|
|
/// <summary>
|
/// Calls allWaveCompleted event
|
/// </summary>
|
protected virtual void SafelyCallSpawningCompleted()
|
{
|
isWaveStarted = false;
|
EndlessBossHPManager.instance.UpdateWave(TotalWaves - CurrentWaveIndex);
|
|
if (AllWaveCompleted != null)
|
AllWaveCompleted();
|
}
|
}
|
}
|