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; }
///
/// buff是否选择完成
///
private bool isBuffSelectCompleted = true;
///
/// 新手第一关是否完成
///
private bool isFirstLevelCompleted = false;
private bool isSecondLevelCompleted = false;
private bool isThirdLevelCompleted = 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.KillSecondDone);
}
else if (isFirstLevelCompleted && isSecondLevelCompleted && !isThirdLevelCompleted)
{
isThirdLevelCompleted = true;
EndlessUIStart.instance.Pause();
EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.KillThirdDone);
}
}
}
///
/// 更新关卡
///
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);
}
}
}