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
{
///
/// 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 SpawnedTotalEnemies { get; protected set; }
///
/// 本波次剩余敌人数量
///
public int RemainEnemies { get; protected set; }
///
/// 当前正在进行的关卡等级
///
public int Level { get; protected set; }
///
/// 法阵
///
public List TunelList;
private string tunelMaterialPath = "UI/Endless/Tunel/tunel_";
private string faZhenPath = "UI/Endless/Tunel/EndlessFaZhen";
private Timer faZhenRefreshTimer;
private void Start()
{
HideTunel();
EventCenter.Ins.Add((int)KTGMGemClient.EventType.EndlessAgentTaskDamage, OnHit);
}
///
/// Agent掉血,不管是中毒还是乱七八糟的掉血,只要掉血就会接收到
///
///
private void OnHit(float value)
{
float nowHP = EndlessBossHPManager.instance.CurrentHP - value;
EndlessBossHPManager.instance.SetCurrentHP(nowHP);
}
///
/// 隐藏法阵,即怪出生的圈圈
///
public void HideTunel()
{
for (int i = 0; i < TunelList.Count; ++i)
{
TunelList[i].gameObject.SetActive(false);
}
}
///
/// 显示法阵
///
public void ShowTunel()
{
for (int i = 0; i < TunelList.Count; ++i)
{
TunelList[i].gameObject.SetActive(true);
}
}
///
/// Starts the waves
///
/// 关卡等级
///
public virtual void StartWaves(int level)
{
SummonFaZhen();
}
///
/// 关卡开始时首先初始化关卡信息
///
///
public void InitPort(int level)
{
EndlessBuffData.InitEndlessBuffPool(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);
}
}
///
/// 初始化关卡数据
///
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}, 没有关卡数据");
}
///
/// 召唤法阵
///
private void SummonFaZhen()
{
EventCenter.Ins.Add((int)KTGMGemClient.EventType.EndlessBossSummonEnd, OnEndlessBossSummonEnd);
EndlessBossCtrl.instance.ChangeState(EndlessBossActionState.Summon);
}
///
/// boss召唤动作结束
///
private void OnEndlessBossSummonEnd()
{
EventCenter.Ins.Remove((int)KTGMGemClient.EventType.EndlessBossSummonEnd, OnEndlessBossSummonEnd);
HideTunel();
RefreshFaZhen();
}
///
/// 刷新法阵显示
///
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;
TunelList[tunel - 1].material = Resources.Load($"{tunelMaterialPath}{tunelBgId}");
GameObject obj = Resources.Load($"{faZhenPath}{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();
ps.Play();
time = ps.main.duration * 3;
Destroy(faZhen, time);
}
if (faZhenRefreshTimer == null)
faZhenRefreshTimer = new Timer(time, UpdateWave);
}
///
/// 敌人数量减少
///
///
public void DecrementEnemies(int count)
{
RemainEnemies -= count;
}
///
/// 获取当前Wave的开始位置
///
///
///
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();
}
///
/// 初始化波次数据
///
private void InitWaveData()
{
waveData = LevelData[CurrentWaveIndex];
// 直接取第一条就行了
WaveInterval = waveData[0].Config.cooldown / 1000f;
TotalWaveLines = waveData.Count;
CompletedWaveLine = 0;
SpawnedTotalEnemies = 0;
}
///
/// 更新波
///
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);
}
}
///
/// 有新的敌人生成
///
private void SpawnNewAgent()
{
++SpawnedTotalEnemies;
if (GameConfig.IsNewbie && EndlessUIStart.instance.beginSkillStep && SpawnedTotalEnemies >= 8)
{
EndlessUIStart.instance.beginSkillStep = false;
EndlessLevelManager.instance.StopSecondWave();
}
}
///
/// 暂停所有兵线出兵
///
public void PauseAllWave()
{
foreach (EndlessPortConfig data in waveData)
{
if (waves[data.Config.tunel - 1].LineState == EndlessWaveLineState.Spawning)
waves[data.Config.tunel - 1].PauseWave();
}
}
///
/// 恢复所有兵线出兵
///
public void RestartAllWave()
{
foreach (EndlessPortConfig data in waveData)
{
if (waves[data.Config.tunel - 1].LineState == EndlessWaveLineState.Spawning)
waves[data.Config.tunel - 1].RestartWave();
}
}
///
/// 一波结束了
///
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());
}
}
}
///
/// 延迟去更新新的一波
///
///
private IEnumerator DelayToUpdateWave()
{
yield return new WaitForSeconds(WaveInterval);
InitWaveData();
RefreshBoss();
SummonFaZhen();
}
///
/// Calls allWaveCompleted event
///
protected virtual void SafelyCallSpawningCompleted()
{
isWaveStarted = false;
EndlessBossHPManager.instance.UpdateWave(TotalWaves - CurrentWaveIndex);
if (AllWaveCompleted != null)
AllWaveCompleted();
}
}
}