using KTGMGemClient; using System; using ActionGameFramework.Health; using Core.Utilities; using TowerDefense.Level; using TowerDefense.Targetting; using TowerDefense.Towers.Placement; using TowerDefense.UI.HUD; using UnityEngine; using TowerDefense.Agents; namespace TowerDefense.Towers { public enum EFeatureTower { NULL, GrowUp, CopyCat, LightTower, Skill_Fire, Skill_Bomb, END } public enum ETowerFuntion { NULL, BULLET, // 子弹塔 ENERGY, // 能量充能. FREEZE, // 水精灵充能 END } /// /// Common functionality for all types of towers /// public class Tower : Targetable { /// /// A generalised name common to a levels /// public string towerName; /// /// The size of the tower's footprint /// public IntVector2 dimensions; /// /// 是否是特色骰子,如果是,则选择一个Enum类型。 /// public EFeatureTower towerFeature = EFeatureTower.NULL; /// /// 塔防对应的充能状态. /// public ETowerFuntion eTowerFuntion = ETowerFuntion.NULL; [HideInInspector] public BulletUICtl bulletCtl = null; [HideInInspector] public EnergyUICtl energyCtl = null; [HideInInspector] public FreezeBreath FreezeBreathCtrl = null; /// /// The tower levels associated with this tower /// [SerializeField] private TowerLevel towerLevel; public TowerLevel CurrentTowerLevel { get; private set; } /// /// 精灵id,一一对应 elf_info表中的id,唯一的区分每一种精灵塔 /// public int ElfId; /// /// The physics mask the tower searches on /// public LayerMask enemyLayerMask; /// /// The current level of the tower /// public int currentLevel { get; protected set; } protected bool m_bInAttackMode = false; /// /// 攻击增加 /// public float attackRise { get; set; } /// /// 用于界面部分的数据位移 /// protected int progressOffset = 0; public int FreezeBreathProgressOffset { get; set; } public bool PlayWaveLineFlash { get; set; } = true; /// /// 是否是木属性蓄力状态 /// public bool IsWoodCharge { get; set; } /// /// 木属性蓄力瞄准的目标 /// public Agent WoodAimAgent; public int uiProOffset { get { return progressOffset; } set { progressOffset = value; } } /// /// Gets whether the tower can level up anymore /// public bool IsMaxLevel { get { return currentLevel == ElfUpgradeData.MaxTowerLevel - 1; } } /// /// 是否可以攻击 /// public bool CanAttack = true; /// /// 是否是对手塔防 /// public bool opponentSide { get; set; } /// /// 播放充能状态特效. /// /// public void PlayEnergyEffect(bool play, bool isClose = true) { if (energyCtl && isClose) energyCtl.gameObject.SetActive(!play); else if (!isClose) { } if (!opponentSide) { if (GameUI.instanceExists) ((TowerPlacementGrid)GameUI.instance.selfTowerPlaceArea).PlayEnergyEffect(gridPosition.x, play); else if (EndlessGameUI.instanceExists) ((TowerPlacementGridEndless)EndlessGameUI.instance.selfTowerPlaceArea).PlayEnergyEffect(gridPosition.x, gridPosition.y, play); } else ((TowerPlacementGrid)OpponentMgr.instance.m_CurrentArea).PlayEnergyEffect(gridPosition.x, play); } /// /// 播放水精灵充能满了特效 /// /// /// public void PlayFreezeBreathEffect(bool play, bool isClose = true) { if (FreezeBreathCtrl && isClose) FreezeBreathCtrl.gameObject.SetActive(!play); if (!opponentSide) { if (EndlessGameUI.instanceExists) ((TowerPlacementGridEndless)EndlessGameUI.instance.selfTowerPlaceArea).PlayFreezeBreathEffect(gridPosition.x, gridPosition.y, play); } } /// /// 当前是否处于攻击模式 /// public bool bInAttackMode { get { return m_bInAttackMode; } // 设置是否处于攻击状态: set { m_bInAttackMode = value; CurrentTowerLevel.SetAffectorState(m_bInAttackMode, gridPosition.x); CurrentTowerLevel.SetAttackState(value); if (value) { if (opponentSide) { OpponentMgr.instance.SetTowerAttID(gridPosition.x, ElfId, currentLevel); } else { if (LevelManager.instanceExists) { LevelManager.instance.SetTowerAttID(gridPosition.x, ElfId, currentLevel); WaveLineSelMgr.instance.attackTowerFixed(gridPosition.x); } else if (EndlessLevelManager.instanceExists) { EndlessLevelManager.instance.SetTowerAttID(gridPosition.x, ElfId, currentLevel); EndlessWaveLineManager.instance.AttackTowerFixed(gridPosition.x, PlayWaveLineFlash); } } // 处理塔位边上的界面. OnTowerUICtrl(); } } } /// /// 去掉当前Tower对应的界面数据. /// public void DisableTowerUICtrl() { // 根据是否是子弹塔防来决定是否显示相应的界面 BulletUICtl buc = placementArea.GetBulletUICtl(gridPosition.x, gridPosition.y); if ((eTowerFuntion == ETowerFuntion.BULLET) && (buc != null)) { buc.gameObject.SetActive(false); bulletCtl = null; } EnergyUICtl euc = placementArea.GetEnergyUICtl(gridPosition.x, gridPosition.y); if ((eTowerFuntion == ETowerFuntion.ENERGY) && (euc != null)) { // 设置数据 euc.gameObject.SetActive(false); energyCtl = null; } FreezeBreath ctrl = placementArea.GetFreezeBreath(gridPosition.x, gridPosition.y); if (eTowerFuntion == ETowerFuntion.FREEZE && ctrl != null) { ctrl.gameObject.SetActive(false); ctrl = null; } } public int GetTowerUICtrlProgress() { // 根据是否是子弹塔防来决定是否显示相应的界面 BulletUICtl buc = placementArea.GetBulletUICtl(gridPosition.x, gridPosition.y); if ((eTowerFuntion == ETowerFuntion.BULLET) && (buc != null)) return buc.GetCtlProgress(); EnergyUICtl euc = placementArea.GetEnergyUICtl(gridPosition.x, gridPosition.y); if ((eTowerFuntion == ETowerFuntion.ENERGY) && (euc != null)) return euc.GetCtlProgress(); FreezeBreath ctrl = placementArea.GetFreezeBreath(gridPosition.x, gridPosition.y); if (eTowerFuntion == ETowerFuntion.FREEZE && ctrl != null) return ctrl.CurrentProgress; return 0; } public void SetTowerUICtlProcess(int pro) { // 根据是否是子弹塔防来决定是否显示相应的界面 BulletUICtl buc = placementArea.GetBulletUICtl(gridPosition.x, gridPosition.y); if ((eTowerFuntion == ETowerFuntion.BULLET) && (buc != null)) { buc.SetCtlProcess(pro); progressOffset = pro; return; } EnergyUICtl euc = placementArea.GetEnergyUICtl(gridPosition.x, gridPosition.y); if ((eTowerFuntion == ETowerFuntion.ENERGY) && (euc != null)) { euc.SetCtlProcess(pro); progressOffset = pro; if (progressOffset == 10) progressOffset = 0; return; } FreezeBreath ctrl = placementArea.GetFreezeBreath(gridPosition.x, gridPosition.y); if (eTowerFuntion == ETowerFuntion.FREEZE && ctrl != null) { ctrl.SetCtrlProgress(pro); FreezeBreathProgressOffset = pro; if (FreezeBreathProgressOffset == 10) FreezeBreathProgressOffset = 0; } } /// /// 充能技能相关的代码开关。包括子弹充能和时间充能 /// protected void OnTowerUICtrl() { HandleBulletUICtrl(); HandleEnergyUICtrl(); HandleFreezeBreathCtrl(); } private void HandleBulletUICtrl() { // 根据是否是子弹塔防来决定是否显示相应的界面 BulletUICtl buc = placementArea.GetBulletUICtl(gridPosition.x, gridPosition.y); if (buc == null) return; if ((eTowerFuntion == ETowerFuntion.BULLET) && (buc != null)) { // 设置数据 buc.gameObject.SetActive(true); bulletCtl = buc; buc.ResetToMaxBullet(); } else { // 清空数据 buc.gameObject.SetActive(false); bulletCtl = null; } } private void HandleEnergyUICtrl() { // 根据是否是能量充能来决定是否显示相应的界面. EnergyUICtl euc = placementArea.GetEnergyUICtl(gridPosition.x, gridPosition.y); if ((eTowerFuntion == ETowerFuntion.ENERGY) && (euc != null)) { // 设置数据 euc.gameObject.SetActive(true); energyCtl = euc; euc.SetEnergyProgress(0); } else { // 清空数据 euc.gameObject.SetActive(false); energyCtl = null; } } private void HandleFreezeBreathCtrl() { FreezeBreath ctrl = placementArea.GetFreezeBreath(gridPosition.x, gridPosition.y); if (eTowerFuntion == ETowerFuntion.FREEZE && ctrl != null) { ctrl.gameObject.SetActive(true); FreezeBreathCtrl = ctrl; ctrl.SetProgress(0); } else { ctrl.gameObject.SetActive(false); FreezeBreathCtrl = null; } } public void CheckCtrl() { if (bulletCtl != null) { bulletCtl.gameObject.SetActive(true); } if (energyCtl != null) { energyCtl.gameObject.SetActive(true); } if (FreezeBreathCtrl != null) FreezeBreathCtrl.gameObject.SetActive(true); } /// /// This function is called when the behaviour becomes disabled or inactive. /// void OnDisable() { if (bulletCtl != null) { bulletCtl.gameObject.SetActive(false); } if (energyCtl != null) { energyCtl.gameObject.SetActive(false); } if (FreezeBreathCtrl != null) FreezeBreathCtrl.gameObject.SetActive(false); } /// /// 升级当前塔防的局内等级,需要播放相关的特效 /// public void upGradeInSceneTL() { Debug.Log("Upgrade Tower name is:" + name); // 播放相关的特效 CurrentTowerLevel.PlayUpGradeEffect(); } /// /// Gets the first level tower ghost prefab /// public TowerPlacementGhost towerGhostPrefab { get { return towerLevel.towerGhostPrefab; } } /// /// Gets the grid position for this tower on the /// public IntVector2 gridPosition { get; private set; } /// /// The placement area we've been built on /// public IPlacementArea placementArea { get; private set; } /// /// The event that fires off when a player deletes a tower /// public Action towerDeleted; /// /// The event that fires off when a tower has been destroyed /// public Action towerDestroyed; /// /// Provide the tower with data to initialize with /// /// The placement area configuration /// The destination position public virtual void Initialize(IPlacementArea targetArea, IntVector2 destination, int lvl = 0) { placementArea = targetArea; gridPosition = destination; if (targetArea != null) { transform.position = placementArea.GridToWorld(destination, dimensions); transform.rotation = placementArea.transform.rotation; targetArea.Occupy(destination, dimensions); } SetLevel(lvl); if (LevelManager.instanceExists) LevelManager.instance.levelStateChanged += OnLevelStateChanged; else if (EndlessLevelManager.instanceExists) EndlessLevelManager.instance.LevelStateChanged += OnLevelStateChanged; // 查找Targetter: Targetter target = GetComponentInChildren(); if (target) target.bOpponent = opponentSide; else Debug.Log("在当前的Tower中找不到Targetter."); } /// /// 当前的Tower是显示还是隐藏,用于减少游戏内Tower创建和删除对应的一系列数据操作 /// /// public void showTower(bool vis) { if (vis) { gameObject.SetActive(true); } else { gameObject.SetActive(false); } } /// /// Kills this tower /// public void KillTower() { // Invoke base kill method Kill(); } /// /// Used to (try to) upgrade the tower data /// public virtual bool UpgradeTower() { if (IsMaxLevel) { return false; } SetLevel(currentLevel + 1); return true; } /// /// A method for downgrading tower /// /// /// false if tower is at lowest level /// public virtual bool DowngradeTower() { if (currentLevel == 0) { return false; } SetLevel(currentLevel - 1); return true; } /// /// Used to set the tower to any valid level /// /// /// The level to upgrade the tower to /// /// /// True if successful /// public virtual bool UpgradeTowerToLevel(int level) { if (level < 0 || IsMaxLevel || level >= ElfUpgradeData.MaxTowerLevel) return false; SetLevel(level); return true; } public void Sell() { Remove(); } /// /// Removes tower from placement area and destroys it /// public override void Remove() { base.Remove(); attackRise = 0.0f; placementArea.Clear(gridPosition, dimensions); Destroy(gameObject); } /// /// unsubsribe when necessary /// protected virtual void OnDestroy() { if (LevelManager.instanceExists) { LevelManager.instance.levelStateChanged += OnLevelStateChanged; } else if (EndlessLevelManager.instanceExists) EndlessLevelManager.instance.LevelStateChanged += OnLevelStateChanged; } /// /// Cache and update oftenly used data /// protected void SetLevel(int level) { if (level < 0 || level >= ElfUpgradeData.MaxTowerLevel) return; currentLevel = level; if (CurrentTowerLevel != null) Destroy(CurrentTowerLevel.gameObject); CurrentTowerLevel = Instantiate(towerLevel, transform); CurrentTowerLevel.Initialize(this, enemyLayerMask, configuration.alignmentProvider); CurrentTowerLevel.SetShowLevel(level + 1); // disable affectors LevelState levelState = LevelState.Intro; if (LevelManager.instanceExists) levelState = LevelManager.instance.levelState; else if (EndlessLevelManager.instanceExists) levelState = EndlessLevelManager.instance.EndlessLeveltate; bool initialise = levelState == LevelState.AllEnemiesSpawned || levelState == LevelState.SpawningEnemies; initialise = false; CurrentTowerLevel.SetAffectorState(initialise, gridPosition.x); } /// /// Intiailises affectors based on the level state /// protected virtual void OnLevelStateChanged(LevelState previous, LevelState current) { bool initialise = current == LevelState.AllEnemiesSpawned || current == LevelState.SpawningEnemies; initialise = false; CurrentTowerLevel.SetAffectorState(bInAttackMode, gridPosition.x); } } }