using System; using Core.Economy; using Core.Health; using Core.Utilities; using TowerDefense.Economy; using TowerDefense.Towers.Data; using TowerDefense.Towers.Placement; using UnityEngine; using KTGMGemClient; using System.Collections; using System.Collections.Generic; using TowerDefense.Nodes; using TowerDefense.UI.HUD; namespace TowerDefense.Level { /// /// The level manager - handles the level states and tracks the player's currency /// PVE(无尽模式)关卡管理器 /// [RequireComponent(typeof(EndlessWaveManager))] public class EndlessLevelManager : Singleton { /// /// 起始关卡 /// ' /// protected int startLevel { get; set; } = 1; /// /// 当前的关卡等级 /// public int CurrentLevel { get; set; } = 1; private float dropRate; /// /// 当前金币掉率 /// /// public float DropRate { get { return dropRate; } set { dropRate = value; Debug.Log("设置了掉率" + dropRate); } } private int dropCoin; /// /// 当前金币 /// /// public int DropCoin { get { return dropCoin; } set { dropCoin = value; } } protected static readonly int MAX_TOWER = 5; /// /// The tower library for level /// public TowerLibrary TowerLibrary; /// /// The currency that the player starts with /// public int StartingCurrency; /// /// 自身所在的PlacementArea /// public TowerPlacementGridEndless SelfPlacementArea; /// /// The controller for gaining currency /// public CurrencyGainer CurrencyGainer; /// /// Configuration for if the player gains currency even in pre-build phase /// [Header("Setting will allow currency gain during the Intro and Pre-Build phase")] public bool alwaysGainCurrency; /// /// The home bases that the player must defend /// public PlayerHomeBase[] HomeBases; /// /// The attached wave manager /// public EndlessWaveManager WaveManager { get; protected set; } /// /// Number of enemies currently in the level /// public int NumberOfEnemies { get; protected set; } /// /// The current state of the level /// public LevelState EndlessLeveltate { get; protected set; } /// /// The currency controller /// public Currency Currency { get; protected set; } /// /// Number of home bases left /// public int NumberOfHomeBasesLeft { get; protected set; } /// /// Starting number of home bases /// public int NumberOfHomeBases { get; protected set; } /// /// 每一个Tower对应的AttributeID. /// protected int[] towerAttributeID = new int[5]; protected int[] towerLevel = new int[5]; /// /// An accessor for the home bases /// public PlayerHomeBase[] playerHomeBases { get { return HomeBases; } } /// /// Fired when all the waves are done and there are no more enemies left /// public event Action LevelCompleted; /// /// Fired when the level state is changed - first parameter is the old state, second parameter is the new state /// public event Action LevelStateChanged; /// /// Fired when the number of enemies has changed /// public event Action numberOfEnemiesChanged; public event Action DecrementEnemies; /// /// Event for home base being destroyed /// public event Action homeBaseDestroyed; /// /// 当前关卡的所有波次是否全部完成 /// private bool IsAllWaveCompleted; /// /// 基地起点集合 /// public List StartingNodeList; public List EndNodeList; /// /// 已经完成的关卡数量 /// public int CompletedLevels { get; protected set; } /// /// 选择buff需要通过的关卡数量,也就是,通过每通过几关然后开始选buff /// /// public int SelectBuffNeddLevels { get; set; } // cx test // public int SelectBuffNeddLevels { get; set; } = 2; /// /// buff是否选择完成 /// private bool isBuffSelectCompleted = true; /// /// 新手第一关是否完成 /// private bool isFirstLevelCompleted = false; private bool isSecondLevelCompleted = false; private bool isStopSecondWaveCompleted = false; /// /// 赛道长度 /// private float tunelLength; private List homeBasePositionList; /// /// 根据赛道id(1~5)获得基地坐标 /// /// /// public Vector3 GetHomeBasePosition(int tunelId) { return homeBasePositionList[tunelId - 1]; } /// /// 根据赛道id(1~5)和赛道类型获得世界坐标 /// /// /// public Vector3 GetTunelWorldPosition(int tunelId, EndlessBossSkillTunelType tunelType) { Vector3 startPos = StartingNodeList[tunelId - 1].transform.position; Vector3 ret = new Vector3(startPos.x, startPos.y, startPos.z); float add = 0; switch (tunelType) { case EndlessBossSkillTunelType.Top: break; case EndlessBossSkillTunelType.Center: add = -(tunelLength / 2); break; case EndlessBossSkillTunelType.Bottom: add = -tunelLength; break; } ret.z += add; return ret; } /// /// 切换基地 /// /// 列索引 public Node SwitchHomeBase(int index) { EndlessSwitchHomeBase switchHomeBase = StartingNodeList[index].GetComponent(); return switchHomeBase.SwitchHomeBase(); } /// /// 设置每一条兵线对应的AttID /// /// /// public void SetTowerAttID(int waveline, int id, int lvl) { towerAttributeID[waveline] = id; towerLevel[waveline] = lvl; } /// /// 重设当前的Currency数据 /// /// public void ResetCurrency(int curnum) { int curChg = curnum - Currency.currentCurrency; Currency.AddCurrency(curChg); } /// /// If the game is over /// public bool isGameOver { get { return EndlessLeveltate == LevelState.Win || EndlessLeveltate == LevelState.Lose; } } /// /// Increments the number of enemies. Called on Agent spawn /// public virtual void IncrementNumberOfEnemies() { NumberOfEnemies++; SafelyCallNumberOfEnemiesChanged(); } /// /// Returns the sum of all HomeBases' health /// public float GetAllHomeBasesHealth() { float health = 0.0f; foreach (PlayerHomeBase homebase in HomeBases) { health += homebase.configuration.currentHealth; } return health; } /// /// Decrements the number of enemies. Called on Agent death /// public virtual void DecrementNumberOfEnemies() { NumberOfEnemies--; CallDecrementEnemies(); SafelyCallNumberOfEnemiesChanged(); if (NumberOfEnemies < 0) { Debug.LogError("[LEVEL] There should never be a negative number of enemies. Something broke!"); NumberOfEnemies = 0; } if (NumberOfEnemies == 0 && EndlessLeveltate == LevelState.AllEnemiesSpawned) { ChangeLevelState(LevelState.Win); } } /// /// 开始关卡 /// public virtual void StartLevel() { EndlessPortData.Init(); ChangeLevelState(LevelState.SpawningEnemies); SelfPlacementArea.startCoinGenMode(); } /// /// Caches the attached wave manager and subscribes to the spawning completed event /// Sets the level state to intro and ensures that the number of enemies is set to 0 /// protected override void Awake() { base.Awake(); for (int i = 0; i < MAX_TOWER; ++i) { towerAttributeID[i] = 0; } WaveManager = GetComponent(); WaveManager.AllWaveCompleted += AllWaveCompleted; // Does not use the change state function as we don't need to broadcast the event for default value EndlessLeveltate = LevelState.Intro; NumberOfEnemies = 0; // Ensure currency change listener is assigned Currency = new Currency(StartingCurrency); CurrencyGainer.Initialize(Currency); // Iterate through home bases and subscribe NumberOfHomeBases = HomeBases.Length; NumberOfHomeBasesLeft = NumberOfHomeBases; } private void Start() { EndlessBuffSelect.instance.BuffSelectCompleted += OnBuffSelectCompleted; EndlessGameUI.instance.GameOverEvent += SafelyCallLevelCompleted; homeBasePositionList = new List(); tunelLength = Mathf.Abs(StartingNodeList[0].transform.position.z - EndNodeList[0].transform.position.z); for (int i = 0; i < StartingNodeList.Count; ++i) { Vector3 startPos = StartingNodeList[i].transform.position; Vector3 pos = new Vector3(); pos.x = startPos.x; pos.y = startPos.y; pos.z = startPos.z - tunelLength; homeBasePositionList.Add(pos); } } /// /// Updates the currency gain controller /// protected virtual void Update() { if (EndlessGameUI.instance.state == EndlessGameUI.State.GameOver) return; if (alwaysGainCurrency || !alwaysGainCurrency && EndlessLeveltate != LevelState.Building && EndlessLeveltate != LevelState.Intro) { CurrencyGainer.Tick(Time.deltaTime); } // buff选择完成,开始波次 if (!isBuffSelectCompleted) { isBuffSelectCompleted = true; if (CurrentLevel > startLevel) WaveManager.InitPort(CurrentLevel); EndlessUIStart.instance.Restart(); WaveManager.StartWaves(CurrentLevel); } // 本关卡所有波次全部生成完成 && 敌人全部被清理了,然后就去尝试进入下一关 if (EndlessLeveltate == LevelState.SpawningEnemies && IsAllWaveCompleted && NumberOfEnemies == 0) { // 新手的话,第一关完了暂停 if (!GameConfig.IsNewbie) { if (!UpdateLevel()) ChangeLevelState(LevelState.AllEnemiesSpawned); } // else if (!isFirstLevelCompleted) // { // isFirstLevelCompleted = true; // EndlessUIStart.instance.Pause(); // // 第一关的怪全部被杀光 // EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.KillDone); // } // else if (!isSecondLevelCompleted) // { // Debug.Log("开始第三关???"); // isSecondLevelCompleted = true; // //EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.CreateThirdWave); // } } } /// /// Unsubscribes from events /// protected override void OnDestroy() { base.OnDestroy(); if (WaveManager != null) WaveManager.AllWaveCompleted -= AllWaveCompleted; } /// /// Fired when the WaveManager has finished spawning enemies /// protected virtual void AllWaveCompleted() { IsAllWaveCompleted = true; int score = EndlessPortData.GetLevelScore(CurrentLevel); Debug.Log($"--------------------- 通过第{CurrentLevel}关,+{score}分 ---------------------"); // 关卡通过,加分 EndlessScoreManager.instance.AddScore(score); EndlessBossSkillManager.instance.ClearSkillList(); EndlessBossCtrl.instance.ChangeState(EndlessBossActionState.Death); if (GameConfig.IsNewbie) { if (!isFirstLevelCompleted) { isFirstLevelCompleted = true; EndlessUIStart.instance.Pause(); // 第一关的怪全部被杀光 EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.KillDone); } else if (!isSecondLevelCompleted) { //Debug.Log("开始第三关???"); isSecondLevelCompleted = true; EndlessUIStart.instance.Pause(); EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.ShowWarningTips); } } } /// /// 更新关卡 /// private bool UpdateLevel() { ++CurrentLevel; IsAllWaveCompleted = false; // 所有关卡全部结束 if (CurrentLevel > EndlessPortData.MaxLevel) return false; StartCoroutine(DelayToNextLevel()); return true; } /// /// 新手更新关卡 /// public void NewbieUpdateLevel() { ++CurrentLevel; WaveManager.InitPort(CurrentLevel); IsAllWaveCompleted = false; EndlessUIStart.instance.Restart(); WaveManager.StartWaves(CurrentLevel); } /// /// 延迟进入下一关 /// /// private IEnumerator DelayToNextLevel() { yield return new WaitForSeconds(2f); BeginLevel(); } /// /// 开始关卡,需要处理选择buff /// private void BeginLevel() { if (EndlessGameUI.instance.state == EndlessGameUI.State.GameOver) return; if (CurrentLevel == startLevel) WaveManager.InitPort(CurrentLevel); if (!GameConfig.IsNewbie) { // buff池的初始化要从正式关卡算起,不算新手关 EndlessBuffData.InitEndlessBuffPool(GameConfig.IsNewbieStart ? CurrentLevel - EndlessPortData.NewbieTotalLevel : CurrentLevel); ShowSelectBuffUI(); } else { EndlessUIStart.instance.Restart(); WaveManager.StartWaves(CurrentLevel); } } /// /// 显示选择buff界面 /// private void ShowSelectBuffUI() { // 需要随机一个buff列表出来,然后简单刷新一下界面 List list = EndlessBuffData.GetRandomBuffList(); if (list.Count == 0) { isBuffSelectCompleted = false; return; } EndlessUIStart.instance.Pause(); EndlessBuffSelect.instance.Refresh(list); EndlessBuffSelect.instance.ShowBuffUI(); } /// /// buff选择完成p /// /// public void OnBuffSelectCompleted(int index) { isBuffSelectCompleted = false; EndlessBuffManager.instance.AddBuff(EndlessBuffData.GetBuffByIndex(index)); EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.EndlessBuffRefresh); } /// /// Changes the state and broadcasts the event /// /// The new state to transitioned to protected virtual void ChangeLevelState(LevelState newState) { if (EndlessLeveltate == newState) return; LevelState oldState = EndlessLeveltate; EndlessLeveltate = newState; if (LevelStateChanged != null) LevelStateChanged(oldState, newState); switch (newState) { case LevelState.SpawningEnemies: BeginLevel(); break; case LevelState.AllEnemiesSpawned: // if (NumberOfEnemies == 0) ChangeLevelState(LevelState.Win); break; case LevelState.Lose: SafelyCallLevelCompleted(); break; case LevelState.Win: SafelyCallLevelCompleted(); Debug.Log("--------------------- you are winner !!! ---------------------"); break; } } /// /// Fired when a home base is destroyed /// protected virtual void OnHomeBaseDestroyed(DamageableBehaviour homeBase) { // Decrement the number of home bases NumberOfHomeBasesLeft--; // Call the destroyed event if (homeBaseDestroyed != null) { homeBaseDestroyed(); } // // If there are no home bases left and the level is not over then set the level to lost // if ((NumberOfHomeBasesLeft < 3) && !isGameOver) // { // ChangeLevelState(LevelState.Lose); // } } /// /// Calls the event /// protected virtual void SafelyCallLevelCompleted() { EndlessDropManager.instance.PickUpAllDrop(); if (LevelCompleted != null) LevelCompleted(); } /// /// Calls the event /// protected virtual void SafelyCallNumberOfEnemiesChanged() { if (numberOfEnemiesChanged != null) numberOfEnemiesChanged(NumberOfEnemies); } protected virtual void CallDecrementEnemies() { if (DecrementEnemies != null) DecrementEnemies(1); } /// /// 兵线的所有基地都已经被摧毁,停止某一条兵线的出兵 /// /// public void StopWaveLine(int index) { if (WaveManager.waves[index].LineState == EndlessWaveLineState.Spawning) { WaveManager.waves[index].StopWave(); WaveManager.waves[index].LineState = EndlessWaveLineState.Destroyed; --WaveManager.TotalWaveLines; } } /// /// 暂停波次,小怪停止移动,塔停止攻击 /// public void PauseWave() { EndlessUIStart.instance.Pause(); AgentInsManager.instance.SetWaveLineCanMove(-1, false, false); WaveManager.PauseAllWave(); EndlessGameUI.instance.SetAttackingTowerState(false); } /// /// 恢复波次,小怪 /// public void RestartWave() { EndlessUIStart.instance.Restart(); AgentInsManager.instance.SetWaveLineCanMove(-1, true, false); WaveManager.RestartAllWave(); EndlessGameUI.instance.SetAttackingTowerState(true); } /// /// 停止第二关波次 /// public void StopSecondWave() { if (!isStopSecondWaveCompleted) { isStopSecondWaveCompleted = true; PauseWave(); } //EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.SkillStep); EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.DragStep); } } }