| | |
| | | using System; |
| | | using KTGMGemClient; |
| | | using System; |
| | | using ActionGameFramework.Health; |
| | | using Core.Utilities; |
| | | using TowerDefense.Level; |
| | |
| | | using TowerDefense.Towers.Placement; |
| | | using TowerDefense.UI.HUD; |
| | | using UnityEngine; |
| | | using TowerDefense.Agents; |
| | | |
| | | namespace TowerDefense.Towers |
| | | { |
| | |
| | | NULL, |
| | | BULLET, // 子弹塔 |
| | | ENERGY, // 能量充能. |
| | | FREEZE, // 水精灵充能 |
| | | END |
| | | } |
| | | |
| | |
| | | /// </summary> |
| | | public class Tower : Targetable |
| | | { |
| | | public readonly float INSCENE_TU_DAMAGE = 30f; |
| | | public static readonly int MAX_LEVEL = 4; |
| | | |
| | | /// <summary> |
| | | /// A generalised name common to a levels |
| | | /// </summary> |
| | |
| | | public EFeatureTower towerFeature = EFeatureTower.NULL; |
| | | |
| | | /// <summary> |
| | | /// 当前塔防对应的MonsterMaterial,自身和对方显示不同的Mat. |
| | | /// </summary> |
| | | public Material materialMonsterSelf; |
| | | public Material materialMonsterOppo; |
| | | |
| | | /// <summary> |
| | | /// 当前塔防对应的攻击和等待Mat. |
| | | /// </summary> |
| | | public Material materialTowerAttackSelf; |
| | | public Material materialTowerWaitSelf; |
| | | public Material materialTowerAttackOppo; |
| | | public Material materialTowerWaitOppo; |
| | | |
| | | /// <summary> |
| | | /// 0 空状态 1 等待状态 2 攻击状态. |
| | | /// </summary> |
| | | protected int curActionState = 0; |
| | | |
| | | /// <summary> |
| | | /// 塔防对应的充能状态. |
| | | /// </summary> |
| | | public ETowerFuntion eTowerFuntion = ETowerFuntion.NULL; |
| | | |
| | | [HideInInspector] |
| | | public BulletUICtl bulletCtl = null; |
| | | |
| | | [HideInInspector] |
| | | public EnergyUICtl energyCtl = null; |
| | | |
| | | [HideInInspector] |
| | | public FreezeBreath FreezeBreathCtrl = null; |
| | | |
| | | /// <summary> |
| | | /// The tower levels associated with this tower |
| | | /// </summary> |
| | | public TowerLevel[] levels; |
| | | [SerializeField] |
| | | private TowerLevel towerLevel; |
| | | |
| | | public TowerLevel CurrentTowerLevel { get; private set; } |
| | | |
| | | /// <summary> |
| | | /// 当前塔防对应的AttributeID. |
| | | /// 精灵id,一一对应 elf_info表中的id,唯一的区分每一种精灵塔 |
| | | /// </summary> |
| | | public int attributeId; |
| | | |
| | | /// <summary> |
| | | /// 当前的Tower在游戏内UI界面上用到的Image数据,再以后应该是直接在表格内配置才合适 |
| | | /// </summary> |
| | | public Sprite uiImage; |
| | | public int ElfId; |
| | | |
| | | /// <summary> |
| | | /// The physics mask the tower searches on |
| | |
| | | protected bool m_bInAttackMode = false; |
| | | |
| | | /// <summary> |
| | | /// 精英怪和Boss双倍伤害. |
| | | /// </summary> |
| | | public bool bDoubleHitElit = false; |
| | | |
| | | /// <summary> |
| | | /// Reference to the data of the current level |
| | | /// </summary> |
| | | public TowerLevel currentTowerLevel { get; protected set; } |
| | | |
| | | /// <summary> |
| | | /// 攻击增加 |
| | | /// </summary> |
| | | public float attackRise { get; set; } |
| | |
| | | /// </summary> |
| | | protected int progressOffset = 0; |
| | | |
| | | public int FreezeBreathProgressOffset { get; set; } |
| | | |
| | | public bool PlayWaveLineFlash { get; set; } = true; |
| | | |
| | | /// <summary> |
| | | /// 塔防数据的局内升级 |
| | | /// 是否是木属性蓄力状态 |
| | | /// </summary> |
| | | public int inSceneTowerLevel |
| | | { |
| | | get; set; |
| | | } |
| | | public bool IsWoodCharge { get; set; } |
| | | |
| | | /// <summary> |
| | | /// 木属性蓄力瞄准的目标 |
| | | /// </summary> |
| | | public Agent WoodAimAgent; |
| | | |
| | | public int uiProOffset |
| | | { |
| | | get { return this.progressOffset; } |
| | | set { this.progressOffset = value; } |
| | | get { return progressOffset; } |
| | | set { progressOffset = value; } |
| | | } |
| | | |
| | | |
| | | /// <summary> |
| | | /// Gets whether the tower can level up anymore |
| | | /// </summary> |
| | | public bool isAtMaxLevel |
| | | public bool IsMaxLevel |
| | | { |
| | | get { return currentLevel == levels.Length - 1; } |
| | | get { return currentLevel == ElfUpgradeData.MaxTowerLevel - 1; } |
| | | } |
| | | |
| | | public void setTowerState(bool attack) |
| | | { |
| | | if (!materialTowerAttackSelf) return; |
| | | |
| | | if (opponentSide) |
| | | { |
| | | if (attack && (this.curActionState != 2)) |
| | | { |
| | | currentTowerLevel.SetTowerMonsterMat(materialTowerAttackOppo); |
| | | this.curActionState = 2; |
| | | } |
| | | |
| | | if ((!attack) && (this.curActionState != 1)) |
| | | { |
| | | currentTowerLevel.SetTowerMonsterMat(materialTowerWaitOppo); |
| | | this.curActionState = 1; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | if (attack && (this.curActionState != 2)) |
| | | { |
| | | currentTowerLevel.SetTowerMonsterMat(materialTowerAttackSelf); |
| | | this.curActionState = 2; |
| | | } |
| | | |
| | | if ((!attack) && (this.curActionState != 1)) |
| | | { |
| | | currentTowerLevel.SetTowerMonsterMat(materialTowerWaitSelf); |
| | | this.curActionState = 1; |
| | | } |
| | | } |
| | | } |
| | | /// <summary> |
| | | /// 是否可以攻击 |
| | | /// </summary> |
| | | public bool CanAttack = true; |
| | | |
| | | /// <summary> |
| | | /// 是否是对手塔防 |
| | |
| | | /// 播放充能状态特效. |
| | | /// </summary> |
| | | /// <param name="play"></param> |
| | | public void PlayEnergyEffect(bool play) |
| | | public void PlayEnergyEffect(bool play, bool isClose = true) |
| | | { |
| | | if (this.energyCtl) |
| | | if (energyCtl && isClose) |
| | | energyCtl.gameObject.SetActive(!play); |
| | | else if (!isClose) |
| | | { |
| | | |
| | | } |
| | | |
| | | if (!opponentSide) |
| | | { |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 播放水精灵充能满了特效 |
| | | /// </summary> |
| | | /// <param name="play"></param> |
| | | /// <param name="isClose"></param> |
| | | 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); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 当前是否处于攻击模式 |
| | | /// </summary> |
| | | public bool bInAttackMode |
| | | { |
| | | get { return this.m_bInAttackMode; } |
| | | get { return m_bInAttackMode; } |
| | | |
| | | // 设置是否处于攻击状态: |
| | | set |
| | | { |
| | | m_bInAttackMode = value; |
| | | currentTowerLevel.SetAffectorState(m_bInAttackMode, gridPosition.x); |
| | | CurrentTowerLevel.SetAffectorState(m_bInAttackMode, gridPosition.x); |
| | | CurrentTowerLevel.SetAttackState(value); |
| | | |
| | | if (value) |
| | | { |
| | | if (opponentSide) |
| | | currentTowerLevel.SetTowerMonsterMat(materialTowerWaitOppo); |
| | | else |
| | | currentTowerLevel.SetTowerMonsterMat(materialTowerWaitSelf); |
| | | |
| | | // 处理Tower |
| | | this.setTowerState(false); |
| | | |
| | | if (opponentSide) |
| | | { |
| | | OpponentMgr.instance.SetTowerAttID(gridPosition.x, attributeId, this.currentLevel); |
| | | OpponentMgr.instance.SetTowerAttID(gridPosition.x, ElfId, currentLevel); |
| | | } |
| | | else |
| | | { |
| | | if (LevelManager.instanceExists) |
| | | { |
| | | LevelManager.instance.SetTowerAttID(gridPosition.x, attributeId, this.currentLevel); |
| | | LevelManager.instance.SetTowerAttID(gridPosition.x, ElfId, currentLevel); |
| | | WaveLineSelMgr.instance.attackTowerFixed(gridPosition.x); |
| | | } |
| | | else if (EndlessLevelManager.instanceExists) |
| | | { |
| | | EndlessLevelManager.instance.SetTowerAttID(gridPosition.x, attributeId, this.currentLevel); |
| | | EndlessLevelManager.instance.SetTowerAttID(gridPosition.x, ElfId, currentLevel); |
| | | EndlessWaveLineManager.instance.AttackTowerFixed(gridPosition.x, PlayWaveLineFlash); |
| | | } |
| | | } |
| | |
| | | // 处理塔位边上的界面. |
| | | OnTowerUICtrl(); |
| | | } |
| | | |
| | | } |
| | | } |
| | | |
| | |
| | | public void DisableTowerUICtrl() |
| | | { |
| | | // 根据是否是子弹塔防来决定是否显示相应的界面 |
| | | BulletUICtl buc = this.placementArea.GetBulletUICtl(gridPosition.x, gridPosition.y); |
| | | BulletUICtl buc = placementArea.GetBulletUICtl(gridPosition.x, gridPosition.y); |
| | | |
| | | if ((this.eTowerFuntion == ETowerFuntion.BULLET) && (buc != null)) |
| | | if ((eTowerFuntion == ETowerFuntion.BULLET) && (buc != null)) |
| | | { |
| | | buc.gameObject.SetActive(false); |
| | | this.bulletCtl = null; |
| | | bulletCtl = null; |
| | | } |
| | | |
| | | EnergyUICtl euc = placementArea.GetEnergyUICtl(gridPosition.x, gridPosition.y); |
| | |
| | | { |
| | | // 设置数据 |
| | | euc.gameObject.SetActive(false); |
| | | this.energyCtl = null; |
| | | energyCtl = null; |
| | | } |
| | | |
| | | return; |
| | | 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 = this.placementArea.GetBulletUICtl(gridPosition.x, gridPosition.y); |
| | | BulletUICtl buc = placementArea.GetBulletUICtl(gridPosition.x, gridPosition.y); |
| | | |
| | | if ((this.eTowerFuntion == ETowerFuntion.BULLET) && (buc != null)) |
| | | 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 = this.placementArea.GetBulletUICtl(gridPosition.x, gridPosition.y); |
| | | BulletUICtl buc = placementArea.GetBulletUICtl(gridPosition.x, gridPosition.y); |
| | | |
| | | if ((this.eTowerFuntion == ETowerFuntion.BULLET) && (buc != null)) |
| | | if ((eTowerFuntion == ETowerFuntion.BULLET) && (buc != null)) |
| | | { |
| | | buc.SetCtlProcess(pro); |
| | | progressOffset = pro; |
| | | return; |
| | | } |
| | | |
| | | EnergyUICtl euc = placementArea.GetEnergyUICtl(gridPosition.x, gridPosition.y); |
| | |
| | | progressOffset = pro; |
| | | if (progressOffset == 10) |
| | | progressOffset = 0; |
| | | return; |
| | | } |
| | | |
| | | FreezeBreath ctrl = placementArea.GetFreezeBreath(gridPosition.x, gridPosition.y); |
| | | |
| | | |
| | | return; |
| | | if (eTowerFuntion == ETowerFuntion.FREEZE && ctrl != null) |
| | | { |
| | | ctrl.SetCtrlProgress(pro); |
| | | FreezeBreathProgressOffset = pro; |
| | | if (FreezeBreathProgressOffset == 10) |
| | | FreezeBreathProgressOffset = 0; |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | /// <summary> |
| | | /// 充能技能相关的代码开关。包括子弹充能和时间充能 |
| | | /// </summary> |
| | | protected void OnTowerUICtrl() |
| | | { |
| | | HandleBulletUICtrl(); |
| | | HandleEnergyUICtrl(); |
| | | HandleFreezeBreathCtrl(); |
| | | } |
| | | |
| | | private void HandleBulletUICtrl() |
| | | { |
| | | // 根据是否是子弹塔防来决定是否显示相应的界面 |
| | | BulletUICtl buc = this.placementArea.GetBulletUICtl(gridPosition.x, gridPosition.y); |
| | | BulletUICtl buc = placementArea.GetBulletUICtl(gridPosition.x, gridPosition.y); |
| | | |
| | | if (buc == null) return; |
| | | |
| | | if ((this.eTowerFuntion == ETowerFuntion.BULLET) && (buc != null)) |
| | | if ((eTowerFuntion == ETowerFuntion.BULLET) && (buc != null)) |
| | | { |
| | | // 设置数据 |
| | | buc.gameObject.SetActive(true); |
| | | this.bulletCtl = buc; |
| | | buc.resetToMaxBullet(); |
| | | bulletCtl = buc; |
| | | buc.ResetToMaxBullet(); |
| | | } |
| | | else |
| | | { |
| | | // 清空数据 |
| | | buc.gameObject.SetActive(false); |
| | | this.bulletCtl = null; |
| | | bulletCtl = null; |
| | | } |
| | | } |
| | | |
| | | private void HandleEnergyUICtrl() |
| | | { |
| | | // 根据是否是能量充能来决定是否显示相应的界面. |
| | | EnergyUICtl euc = placementArea.GetEnergyUICtl(gridPosition.x, gridPosition.y); |
| | | if ((eTowerFuntion == ETowerFuntion.ENERGY) && (euc != null)) |
| | | { |
| | | // 设置数据 |
| | | euc.gameObject.SetActive(true); |
| | | this.energyCtl = euc; |
| | | energyCtl = euc; |
| | | euc.SetEnergyProgress(0); |
| | | } |
| | | else |
| | | { |
| | | // 清空数据 |
| | | euc.gameObject.SetActive(false); |
| | | this.energyCtl = null; |
| | | 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); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 初始化当前塔防的局内升级,lvl从1开始. |
| | | /// This function is called when the behaviour becomes disabled or inactive. |
| | | /// </summary> |
| | | /// <param name="lvl"></param> |
| | | public void initInSceneTowerLevel(int lvl) |
| | | void OnDisable() |
| | | { |
| | | inSceneTowerLevel = lvl; |
| | | if (lvl <= 1) |
| | | if (bulletCtl != null) |
| | | { |
| | | ResetInSceneTowerLevel(); |
| | | return; |
| | | bulletCtl.gameObject.SetActive(false); |
| | | } |
| | | // 设置攻击数据的加强,暂时是测试数据,后面需要读取表格数据处理: |
| | | float damageAdd = 0; |
| | | // float damageAdd = (inSceneTowerLevel - 1) * this.INSCENE_TU_DAMAGE; |
| | | for (int ti = 0; ti < this.levels.Length; ti++) |
| | | { |
| | | if (levels[ti].levelDamager) |
| | | { |
| | | levels[ti].levelDamager.doubleHit = bDoubleHitElit; |
| | | levels[ti].levelDamager.inSceneUpGradeDamage = damageAdd; |
| | | } |
| | | } |
| | | } |
| | | |
| | | protected void ResetInSceneTowerLevel() |
| | | { |
| | | for (int ti = 0; ti < this.levels.Length; ti++) |
| | | if (energyCtl != null) |
| | | { |
| | | if (levels[ti].levelDamager) |
| | | { |
| | | levels[ti].levelDamager.inSceneUpGradeDamage = 0; |
| | | levels[ti].levelDamager.doubleHit = bDoubleHitElit; |
| | | } |
| | | energyCtl.gameObject.SetActive(false); |
| | | } |
| | | return; |
| | | |
| | | if (FreezeBreathCtrl != null) |
| | | FreezeBreathCtrl.gameObject.SetActive(false); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | /// </summary> |
| | | public void upGradeInSceneTL() |
| | | { |
| | | inSceneTowerLevel++; |
| | | |
| | | // 设置攻击数据的加强,暂时是测试数据,后面需要读取表格数据处理: |
| | | float damageAdd = inSceneTowerLevel * this.INSCENE_TU_DAMAGE; |
| | | |
| | | for (int ti = 0; ti < this.levels.Length; ti++) |
| | | { |
| | | if (levels[ti].levelDamager) |
| | | { |
| | | levels[ti].levelDamager.inSceneUpGradeDamage = damageAdd; |
| | | levels[ti].levelDamager.towerName = name; |
| | | levels[ti].levelDamager.bSet = true; |
| | | } |
| | | } |
| | | |
| | | Debug.Log("Upgrade Tower name is:" + name); |
| | | |
| | | // 播放相关的特效 |
| | | currentTowerLevel.PlayUpGradeEffect(); |
| | | CurrentTowerLevel.PlayUpGradeEffect(); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | /// </summary> |
| | | public TowerPlacementGhost towerGhostPrefab |
| | | { |
| | | get { return levels[currentLevel].towerGhostPrefab; } |
| | | get { return towerLevel.towerGhostPrefab; } |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | public IPlacementArea placementArea { get; private set; } |
| | | |
| | | /// <summary> |
| | | /// The purchase cost of the tower |
| | | /// </summary> |
| | | public int purchaseCost |
| | | { |
| | | get { return levels[0].cost; } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// The event that fires off when a player deletes a tower |
| | | /// </summary> |
| | | public Action towerDeleted; |
| | |
| | | /// The event that fires off when a tower has been destroyed |
| | | /// </summary> |
| | | public Action towerDestroyed; |
| | | |
| | | /// <summary> |
| | | /// 放置到目标位置 |
| | | /// </summary> |
| | | /// <param name="destination"></param> |
| | | public virtual void SetToDestination(IntVector2 destination) |
| | | { |
| | | gridPosition = destination; |
| | | transform.position = placementArea.GridToWorld(destination, dimensions); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// Provide the tower with data to initialize with |
| | |
| | | } |
| | | |
| | | SetLevel(lvl); |
| | | |
| | | if (LevelManager.instanceExists) |
| | | { |
| | | LevelManager.instance.levelStateChanged += OnLevelStateChanged; |
| | | } |
| | | else if (EndlessLevelManager.instanceExists) |
| | | EndlessLevelManager.instance.LevelStateChanged += OnLevelStateChanged; |
| | | |
| | | // 查找Targetter: |
| | | Targetter target = this.GetComponentInChildren<Targetter>(); |
| | | Targetter target = GetComponentInChildren<Targetter>(); |
| | | if (target) |
| | | { |
| | | target.bOpponent = this.opponentSide; |
| | | } |
| | | target.bOpponent = opponentSide; |
| | | else |
| | | Debug.Log("在当前的Tower中找不到Targetter."); |
| | | |
| | | // |
| | | // 初始化当前的局内Tower等级数据 |
| | | this.initInSceneTowerLevel(SceneTowerLvl.getInSceneTowerLvl(this.towerName)); |
| | | |
| | | if (gridPosition.y > 1) |
| | | { |
| | | currentTowerLevel.ResetScale(); |
| | | }else{ |
| | | currentTowerLevel.NormalScale(); |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// Provides information on the cost to upgrade |
| | | /// </summary> |
| | | /// <returns>Returns -1 if the towers is already at max level, other returns the cost to upgrade</returns> |
| | | public int GetCostForNextLevel() |
| | | { |
| | | if (isAtMaxLevel) |
| | | { |
| | | return -1; |
| | | } |
| | | return levels[currentLevel + 1].cost; |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | { |
| | | if (vis) |
| | | { |
| | | this.gameObject.SetActive(true); |
| | | gameObject.SetActive(true); |
| | | } |
| | | else |
| | | { |
| | | this.gameObject.SetActive(false); |
| | | gameObject.SetActive(false); |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// Provides the value recived for selling this tower |
| | | /// </summary> |
| | | /// <returns>A sell value of the tower</returns> |
| | | public int GetSellLevel() |
| | | { |
| | | return GetSellLevel(currentLevel); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// Provides the value recived for selling this tower of a particular level |
| | | /// </summary> |
| | | /// <param name="level">Level of tower</param> |
| | | /// <returns>A sell value of the tower</returns> |
| | | public int GetSellLevel(int level) |
| | | { |
| | | // sell for full price if waves haven't started yet |
| | | if (LevelManager.instanceExists && LevelManager.instance.levelState == LevelState.Building |
| | | || EndlessLevelManager.instanceExists && EndlessLevelManager.instance.EndlessLeveltate == LevelState.Building) |
| | | { |
| | | int cost = 0; |
| | | for (int i = 0; i <= level; i++) |
| | | { |
| | | cost += levels[i].cost; |
| | | } |
| | | |
| | | return cost; |
| | | } |
| | | return levels[currentLevel].sell; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// Used to (try to) upgrade the tower data |
| | | /// </summary> |
| | | public virtual bool UpgradeTower() |
| | | { |
| | | if (isAtMaxLevel) |
| | | if (IsMaxLevel) |
| | | { |
| | | return false; |
| | | } |
| | |
| | | /// </returns> |
| | | public virtual bool UpgradeTowerToLevel(int level) |
| | | { |
| | | if (level < 0 || isAtMaxLevel || level >= levels.Length) |
| | | { |
| | | return false; |
| | | } |
| | | if (level < 0 || IsMaxLevel || level >= ElfUpgradeData.MaxTowerLevel) return false; |
| | | |
| | | SetLevel(level); |
| | | return true; |
| | | } |
| | |
| | | public override void Remove() |
| | | { |
| | | base.Remove(); |
| | | |
| | | // 清空局内升级数据: |
| | | ResetInSceneTowerLevel(); |
| | | attackRise = 0.0f; |
| | | placementArea.Clear(gridPosition, dimensions); |
| | | Destroy(gameObject); |
| | |
| | | /// <summary> |
| | | /// Cache and update oftenly used data |
| | | /// </summary> |
| | | public void SetLevel(int level) |
| | | protected void SetLevel(int level) |
| | | { |
| | | if (level < 0 || level >= levels.Length) |
| | | { |
| | | return; |
| | | } |
| | | if (level < 0 || level >= ElfUpgradeData.MaxTowerLevel) return; |
| | | |
| | | currentLevel = level; |
| | | if (currentTowerLevel != null) |
| | | { |
| | | Destroy(currentTowerLevel.gameObject); |
| | | } |
| | | |
| | | // instantiate the visual representation |
| | | currentTowerLevel = Instantiate(levels[currentLevel], transform); |
| | | if (CurrentTowerLevel != null) |
| | | Destroy(CurrentTowerLevel.gameObject); |
| | | |
| | | // initialize TowerLevel |
| | | currentTowerLevel.Initialize(this, enemyLayerMask, configuration.alignmentProvider); |
| | | CurrentTowerLevel = Instantiate(towerLevel, transform); |
| | | CurrentTowerLevel.Initialize(this, enemyLayerMask, configuration.alignmentProvider); |
| | | CurrentTowerLevel.SetShowLevel(level + 1); |
| | | |
| | | // health data |
| | | ScaleHealth(); |
| | | |
| | | // |
| | | // disable affectors |
| | | LevelState levelState = LevelState.Intro; |
| | | if (LevelManager.instanceExists) |
| | |
| | | levelState = EndlessLevelManager.instance.EndlessLeveltate; |
| | | bool initialise = levelState == LevelState.AllEnemiesSpawned || levelState == LevelState.SpawningEnemies; |
| | | initialise = false; |
| | | currentTowerLevel.SetAffectorState(initialise, gridPosition.x); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// Scales the health based on the previous health |
| | | /// Requires override when the rules for scaling health on upgrade changes |
| | | /// </summary> |
| | | protected virtual void ScaleHealth() |
| | | { |
| | | configuration.SetMaxHealth(currentTowerLevel.maxHealth); |
| | | |
| | | if (currentLevel == 0) |
| | | { |
| | | configuration.SetHealth(currentTowerLevel.maxHealth); |
| | | } |
| | | else |
| | | { |
| | | int currentHealth = Mathf.FloorToInt(configuration.normalisedHealth * currentTowerLevel.maxHealth); |
| | | configuration.SetHealth(currentHealth); |
| | | } |
| | | CurrentTowerLevel.SetAffectorState(initialise, gridPosition.x); |
| | | } |
| | | |
| | | /// <summary> |
| | |
| | | { |
| | | bool initialise = current == LevelState.AllEnemiesSpawned || current == LevelState.SpawningEnemies; |
| | | initialise = false; |
| | | //currentTowerLevel.SetAffectorState(initialise); |
| | | currentTowerLevel.SetAffectorState(bInAttackMode, gridPosition.x); |
| | | CurrentTowerLevel.SetAffectorState(bInAttackMode, gridPosition.x); |
| | | } |
| | | } |
| | | } |