wangguan
2020-12-11 58cb0692ed67a4108b51e31b765db4c3483e3df7
Assets/Scripts/TowerDefense/Towers/Tower.cs
@@ -8,6 +8,8 @@
using TowerDefense.UI.HUD;
using UnityEngine;
using TowerDefense.Agents;
using System.Collections;
using System.Collections.Generic;
namespace TowerDefense.Towers
{
@@ -36,10 +38,6 @@
    /// </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>
@@ -54,13 +52,6 @@
        /// 是否是特色骰子,如果是,则选择一个Enum类型。
        /// </summary>
        public EFeatureTower towerFeature = EFeatureTower.NULL;
        /// <summary>
        /// 当前塔防对应的MonsterMaterial,自身和对方显示不同的Mat.
        /// </summary>
        public Material materialMonsterSelf;
        public Material materialMonsterOppo;
        /// <summary>
        /// 塔防对应的充能状态.
@@ -79,17 +70,15 @@
        /// <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
@@ -99,19 +88,9 @@
        /// <summary>
        /// The current level of the tower
        /// </summary>
        public int currentLevel { get; protected set; }
        public int currentLevel { get; set; }
        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>
        /// 攻击增加
@@ -127,6 +106,38 @@
        public bool PlayWaveLineFlash { get; set; } = true;
        private bool isBondage;
        /// <summary>
        /// 是否是泡泡禁锢状态
        /// </summary>
        /// <value></value>
        public bool IsBondage
        {
            get { return isBondage; }
            set
            {
                isBondage = value;
                CanAttack = !value;
            }
        }
        /// <summary>
        /// 禁锢时间
        /// </summary>
        public float BondageTime { get; set; }
        /// <summary>
        /// 禁锢警告时间
        /// </summary>
        /// <value></value>
        public float BondageWarningTime { get; set; }
        /// <summary>
        /// 泡泡禁锢期间,点击一次减少的时间
        /// </summary>
        public float BondageClickDecreaseTime { get; set; } = 1f;
        /// <summary>
        /// 是否是木属性蓄力状态
        /// </summary>
@@ -137,14 +148,6 @@
        /// </summary>
        public Agent WoodAimAgent;
        /// <summary>
        /// 塔防数据的局内升级
        /// </summary>
        public int inSceneTowerLevel
        {
            get; set;
        }
        public int uiProOffset
        {
            get { return progressOffset; }
@@ -154,9 +157,9 @@
        /// <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; }
        }
        /// <summary>
@@ -168,6 +171,248 @@
        /// 是否是对手塔防
        /// </summary>
        public bool opponentSide { get; set; }
        /// <summary>
        /// 禁锢警告
        /// </summary>
        protected GameObject bondageWarningObj;
        /// <summary>
        /// 禁锢泡泡
        /// </summary>
        protected GameObject bondageObj;
        private GameObject tapObj;
        /// <summary>
        /// 精灵被禁锢时点击次数
        /// </summary>
        public int BondageTapCount { get; private set; }
        /// <summary>
        /// 泡泡上升高度
        /// </summary>
        private float yAdd = 10f;
        /// <summary>
        /// 原始y值
        /// </summary>
        private float originY;
        /// <summary>
        /// 是否开始禁锢
        /// </summary>
        public bool IsStartBondage { get; set; }
        private float bombDuration = 0.7f;
        private float bombTime;
        /// <summary>
        /// 爆炸是否结束
        /// </summary>
        private bool isBombCompleted;
        private void Start()
        {
            originY = transform.position.y;
            promptDic = new Dictionary<string, bool>();
        }
        private void Update()
        {
            HandleBondageBubble();
        }
        private static Dictionary<string, bool> promptDic;
        /// <summary>
        /// 处理禁锢泡泡技能
        /// </summary>
        private void HandleBondageBubble()
        {
            if (IsStartBondage)
            {
                if (isBondage)
                {
                    if (transform.position.y < yAdd + originY && bondageObj != null)
                    {
                        // 上升状态
                        Vector3 pos = transform.position;
                        pos.y += 28f * Time.deltaTime;
                        transform.position = pos;
                        pos = bondageObj.transform.position;
                        pos.y += 28f * Time.deltaTime;
                        bondageObj.transform.position = pos;
                    }
                }
                else
                {
                    if (!isBombCompleted)
                    {
                        bombTime += Time.deltaTime;
                        if (bombTime > bombDuration)
                        {
                            // 爆炸结束开始下降
                            isBombCompleted = true;
                        }
                    }
                    else
                    {
                        if (transform.position.y > originY)
                        {
                            // 下降状态
                            Vector3 pos = transform.position;
                            pos.y -= 55f * Time.deltaTime;
                            transform.position = pos;
                        }
                        else
                        {
                            // 下降结束
                            IsStartBondage = false;
                        }
                    }
                }
            }
            if (!IsBondage) return;
            if (BondageWarningTime > 0)
            {
                BondageWarningTime -= Time.deltaTime;
                if (BondageWarningTime <= 0)
                {
                    DestroyBondageWarningObj();
                    StartBondage();
                    ShowTapPrompt();
                }
            }
            else
            {
                BondageTime -= Time.deltaTime;
                if (BondageTime <= 0)
                {
                    DestroyBondageWarningObj();
                    HideTapPrompt();
                    IsBondage = false;
                    Destroy(bondageObj);
                    bondageObj = null;
                    BondageBubbleBomb();
                }
            }
        }
        private void DestroyBondageWarningObj()
        {
            if (bondageWarningObj == null) return;
            ParticleSystem ps = bondageWarningObj.transform.GetChild(0).GetComponent<ParticleSystem>();
            ps.Stop();
            ps.Clear();
            Destroy(bondageWarningObj);
            bondageWarningObj = null;
        }
        /// <summary>
        /// 展示连续点击提示
        /// </summary>
        private void ShowTapPrompt()
        {
            string key = $"{gridPosition.x}";
            if (promptDic.ContainsKey(key)) return;
            promptDic.Add(key, true);
            GameObject prefab = Resources.Load<GameObject>("Prefabs/Endless/BondageBubbleTap");
            tapObj = Instantiate(prefab);
            tapObj.transform.SetParent(TowerPlacementGridEndless.instance.GridContainer.transform, false);
            Vector3 worldPos = TowerPlacementGridEndless.instance.GetGridWorldPos(gridPosition.x, 3);
            ParticleSystem ps = tapObj.transform.GetChild(0).GetComponent<ParticleSystem>();
            tapObj.transform.position = worldPos;
            Vector3 pos = tapObj.transform.position;
            pos.x += 5.8f;
            pos.z += 3f;
            pos.y = 20f;
            tapObj.transform.position = pos;
            ps?.Play();
        }
        private void HideTapPrompt()
        {
            if (tapObj != null)
            {
                ParticleSystem ps = tapObj.transform.GetChild(0).GetComponent<ParticleSystem>();
                ps?.Stop();
                Destroy(tapObj);
                tapObj = null;
                string key = $"{gridPosition.x}";
                if (promptDic.ContainsKey(key))
                    promptDic.Remove(key);
            }
        }
        public void OnPressed()
        {
            if (!IsStartBondage || BondageWarningTime > 0) return;
            ++BondageTapCount;
            if (BondageTapCount >= 3)
                HideTapPrompt();
            BondageTime -= BondageClickDecreaseTime;
        }
        /// <summary>
        /// 禁锢泡泡爆炸
        /// </summary>
        private void BondageBubbleBomb()
        {
            GameObject prefab = Resources.Load<GameObject>("Prefabs/Endless/BondageBubbleBomb");
            GameObject obj = Instantiate(prefab);
            obj.transform.SetParent(TowerPlacementGridEndless.instance.GridContainer.transform, false);
            obj.transform.position = transform.position;
            obj.transform.GetChild(0).GetComponent<ParticleSystem>().Play();
            Destroy(obj, 1.2f);
            AudioSourceManager.Ins.StopBossWaterSkill();
        }
        /// <summary>
        /// 开始泡泡禁锢
        /// </summary>
        private void StartBondage()
        {
            bombTime = 0;
            BondageTapCount = 0;
            isBombCompleted = false;
            GameObject prefab = Resources.Load<GameObject>("Prefabs/Endless/BondageBubble");
            bondageObj = Instantiate(prefab);
            bondageObj.transform.SetParent(TowerPlacementGridEndless.instance.GridContainer.transform, false);
            bondageObj.transform.position = transform.position;
            Vector3 pos = bondageObj.transform.position;
            pos.y += gridPosition.y == 3 ? 2f : 1f;
            bondageObj.transform.position = pos;
            bondageObj.transform.GetChild(0).GetComponent<ParticleSystem>().Play();
            AudioSourceManager.Ins.Play(AudioEnum.BossWaterSkill);
        }
        /// <summary>
        /// 禁锢警告
        /// </summary>
        /// <param name="tower"></param>
        public void BondageWarning()
        {
            GameObject prefab = Resources.Load<GameObject>("Prefabs/Endless/BondageBubbleWarning");
            bondageWarningObj = Instantiate(prefab);
            bondageWarningObj.transform.SetParent(TowerPlacementGridEndless.instance.GridContainer.transform, false);
            bondageWarningObj.transform.position = TowerPlacementGridEndless.instance.GetGridWorldPos(gridPosition.x, gridPosition.y);
            bondageWarningObj.transform.GetChild(0).GetComponent<ParticleSystem>().Play();
        }
        /// <summary>
        /// 播放充能状态特效.
@@ -221,25 +466,25 @@
            set
            {
                m_bInAttackMode = value;
                currentTowerLevel.SetAffectorState(m_bInAttackMode, gridPosition.x);
                currentTowerLevel.SetAttackState(value);
                CurrentTowerLevel.SetAffectorState(m_bInAttackMode, gridPosition.x);
                CurrentTowerLevel.SetAttackState(value);
                if (value)
                {
                    if (opponentSide)
                    {
                        OpponentMgr.instance.SetTowerAttID(gridPosition.x, attributeId, currentLevel);
                        OpponentMgr.instance.SetTowerAttID(gridPosition.x, ElfId, currentLevel);
                    }
                    else
                    {
                        if (LevelManager.instanceExists)
                        {
                            LevelManager.instance.SetTowerAttID(gridPosition.x, attributeId, currentLevel);
                            LevelManager.instance.SetTowerAttID(gridPosition.x, ElfId, currentLevel);
                            WaveLineSelMgr.instance.attackTowerFixed(gridPosition.x);
                        }
                        else if (EndlessLevelManager.instanceExists)
                        {
                            EndlessLevelManager.instance.SetTowerAttID(gridPosition.x, attributeId, currentLevel);
                            EndlessLevelManager.instance.SetTowerAttID(gridPosition.x, ElfId, currentLevel);
                            EndlessWaveLineManager.instance.AttackTowerFixed(gridPosition.x, PlayWaveLineFlash);
                        }
                    }
@@ -441,15 +686,10 @@
        /// </summary>
        public void upGradeInSceneTL()
        {
            inSceneTowerLevel++;
            // 设置攻击数据的加强,暂时是测试数据,后面需要读取表格数据处理:
            float damageAdd = inSceneTowerLevel * INSCENE_TU_DAMAGE;
            Debug.Log("Upgrade Tower name is:" + name);
            // 播放相关的特效
            currentTowerLevel.PlayUpGradeEffect();
            CurrentTowerLevel.PlayUpGradeEffect();
        }
        /// <summary>
@@ -457,7 +697,7 @@
        /// </summary>
        public TowerPlacementGhost towerGhostPrefab
        {
            get { return levels[currentLevel].towerGhostPrefab; }
            get { return towerLevel.towerGhostPrefab; }
        }
        /// <summary>
@@ -536,13 +776,13 @@
            // Invoke base kill method
            Kill();
        }
        /// <summary>
        /// Used to (try to) upgrade the tower data
        /// </summary>
        public virtual bool UpgradeTower()
        {
            if (isAtMaxLevel)
            if (IsMaxLevel)
            {
                return false;
            }
@@ -577,10 +817,8 @@
        /// </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;
        }
@@ -617,23 +855,24 @@
        /// <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)
            if (CurrentTowerLevel != null)
                Destroy(CurrentTowerLevel.gameObject);
            CurrentTowerLevel = Instantiate(towerLevel, transform);
            CurrentTowerLevel.Initialize(this, enemyLayerMask, configuration.alignmentProvider);
            CurrentTowerLevel.SetShowLevel(level + 1);
            //if(gridPosition.y>=2)
            {
                Destroy(currentTowerLevel.gameObject);
                //Debug.Log("上阵状态,设置缩放");
                CurrentTowerLevel.SetScale(level + 1);
            }
            // instantiate the visual representation
            currentTowerLevel = Instantiate(levels[currentLevel], transform);
            // initialize TowerLevel
            currentTowerLevel.Initialize(this, enemyLayerMask, configuration.alignmentProvider);
            // disable affectors
            LevelState levelState = LevelState.Intro;
@@ -643,7 +882,7 @@
                levelState = EndlessLevelManager.instance.EndlessLeveltate;
            bool initialise = levelState == LevelState.AllEnemiesSpawned || levelState == LevelState.SpawningEnemies;
            initialise = false;
            currentTowerLevel.SetAffectorState(initialise, gridPosition.x);
            CurrentTowerLevel.SetAffectorState(initialise, gridPosition.x);
        }
        /// <summary>
@@ -653,8 +892,7 @@
        {
            bool initialise = current == LevelState.AllEnemiesSpawned || current == LevelState.SpawningEnemies;
            initialise = false;
            //currentTowerLevel.SetAffectorState(initialise);
            currentTowerLevel.SetAffectorState(bInAttackMode, gridPosition.x);
            CurrentTowerLevel.SetAffectorState(bInAttackMode, gridPosition.x);
        }
    }
}