From 452c75675679c44cc39b04bdb7d330d7c5c14d5c Mon Sep 17 00:00:00 2001
From: wangguan <wangguan@kt007.com>
Date: Tue, 29 Dec 2020 10:48:06 +0800
Subject: [PATCH] 增加多SDK支持。常规使用SDKChannel.KTGM 偶哈游的是空SDK

---
 Assets/Scripts/TowerDefense/Affectors/AttackAffector.cs |  974 ++++++++++++++++++++++++++++++++++++--------------------
 1 files changed, 620 insertions(+), 354 deletions(-)

diff --git a/Assets/Scripts/TowerDefense/Affectors/AttackAffector.cs b/Assets/Scripts/TowerDefense/Affectors/AttackAffector.cs
index a8b13a7..bdad9c7 100644
--- a/Assets/Scripts/TowerDefense/Affectors/AttackAffector.cs
+++ b/Assets/Scripts/TowerDefense/Affectors/AttackAffector.cs
@@ -3,410 +3,676 @@
 using ActionGameFramework.Audio;
 using ActionGameFramework.Health;
 using Core.Health;
-using TowerDefense.Agents;
 using TowerDefense.Targetting;
 using TowerDefense.Towers;
 using TowerDefense.Towers.Projectiles;
 using UnityEngine;
 using KTGMGemClient;
+using TowerDefense.Agents;
+using TowerDefense.Level;
 
 namespace TowerDefense.Affectors
 {
-	/// <summary>
-	/// The common effect for handling firing projectiles to attack
-	/// 
-	/// Requires an ILauncher but it is not automatically added
-	/// Add an ILauncher implementation to this GameObject before you add this script
-	/// </summary>
-	[RequireComponent(typeof(ILauncher))]
-	public class AttackAffector : Affector, ITowerRadiusProvider
-	{
-		/// <summary>
-		/// The projectile used to attack
-		/// </summary>
-		public GameObject projectile;
-
-		// 
-		protected GameObject projectile1;
-		protected GameObject projectile2;
-
-		/// <summary>
-		/// The list of points to launch the projectiles from
-		/// </summary>
-		public Transform[] projectilePoints;
-
-		/// <summary>
-		/// The reference to the center point where the tower will search from
-		/// </summary>
-		public Transform epicenter;
-
-		/// <summary>
-		/// Configuration for when the tower does splash damage
-		/// </summary>
-		public bool isMultiAttack;
-
-		/// <summary>
-		/// 如果是多目标攻击,最多攻击目标
-		/// </summary>
-		public int maxAttackNum = 1;
-
-
+    /// <summary>
+    /// The common effect for handling firing projectiles to attack
+    /// 
+    /// Requires an ILauncher but it is not automatically added
+    /// Add an ILauncher implementation to this GameObject before you add this script
+    /// </summary>
+    [RequireComponent(typeof(ILauncher))]
+    public class AttackAffector : Affector, ITowerRadiusProvider
+    {
         /// <summary>
-        /// The fire rate in fires-per-second
+        /// The projectile used to attack
         /// </summary>
-        public float fireRate;
-
-
-		/// <summary>
-		/// 是否木属性数据
-		/// </summary>
-		public bool bWoodAffector = false;
-
-		/// <summary>
-		/// The audio source to play when firing
-		/// </summary>
-		public RandomAudioSource randomAudioSource;
-
-		/// <summary>
-		/// Gets the targetter
-		/// </summary>
-		public Targetter towerTargetter;
-
-		/// <summary>
-		/// Color of effect radius visualization
-		/// </summary>
-		public Color radiusEffectColor;
-
-		/// <summary>
-		/// Search condition
-		/// </summary>
-		public Filter searchCondition;
-
-		/// <summary>
-		/// Fire condition
-		/// </summary>
-		public Filter fireCondition;
-
-		/// <summary>
-		/// The reference to the attached launcher
-		/// </summary>
-		protected ILauncher m_Launcher;
-
-		/// <summary>
-		/// The time before firing is possible
-		/// </summary>
-		protected float m_FireTimer;
-
-		/// <summary>
-		/// Reference to the current tracked enemy
-		/// </summary>
-		protected Targetable m_TrackingEnemy;
-
-		/// <summary>
-		/// 处理装弹时间.
-		/// </summary>
-		protected float fillBulletTime = 0.0f;
+        public GameObject projectile;
 
         /// <summary>
-        /// 充能时间
+        /// 木塔最后一击是特殊攻击,需要替换projectile
+        /// </summary>
+        public GameObject woodProjectile_SP;
+
+        /// <summary>
+        /// The list of points to launch the projectiles from
+        /// </summary>
+        public Transform[] projectilePoints;
+
+        /// <summary>
+        /// The reference to the center point where the tower will search from
+        /// </summary>
+        public Transform epicenter;
+
+        /// <summary>
+        /// 如果是多目标攻击,最多攻击目标
+        /// </summary>
+        public int maxAttackNum = 1;
+
+        /// <summary>
+        /// 是否木属性数据
+        /// </summary>
+        public bool bWoodAffector = false;
+
+        /// <summary>
+        /// The audio source to play when firing
+        /// </summary>
+        public RandomAudioSource randomAudioSource;
+
+        /// <summary>
+        /// Gets the targetter
+        /// </summary>
+        public Targetter towerTargetter;
+
+        /// <summary>
+        /// Color of effect radius visualization
+        /// </summary>
+        public Color radiusEffectColor;
+
+        /// <summary>
+        /// Search condition
+        /// </summary>
+        public Filter searchCondition;
+
+        /// <summary>
+        /// Fire condition
+        /// </summary>
+        public Filter fireCondition;
+
+        /// <summary>
+        /// The reference to the attached launcher
+        /// </summary>
+        protected ILauncher m_Launcher;
+
+        /// <summary>
+        /// The time before firing is possible
+        /// </summary>
+        protected float m_FireTimer;
+
+        protected float freezeBreathTimer;
+
+        /// <summary>
+        /// Reference to the current tracked enemy
+        /// </summary>
+        protected Targetable m_TrackingEnemy;
+
+        public TowerLevel towerLevel;
+
+        /// <summary>
+        /// 处理装弹时间.
+        /// </summary>
+        protected float fillBulletTime = 0.0f;
+
+        /// <summary>
+        /// 火精灵充能时间
         /// </summary>
         protected float energyCalTime = 0;
-		protected float fInEnergy = 0;
-		protected float fBackupTimer = 0.0f;
-		/// <summary>
-		/// Gets the search rate from the targetter
-		/// </summary>
-		public float searchRate
-		{
-			get { return towerTargetter.searchRate; }
-			set { towerTargetter.searchRate = value; }
-		}
 
-		/// <summary>
-		/// Gets the targetable
-		/// </summary>
-		public Targetable trackingEnemy
-		{
-			get { return m_TrackingEnemy; }
-		}
+        protected float fInEnergy = 0;
 
-		/// <summary>
-		/// Gets or sets the attack radius
-		/// </summary>
-		public float effectRadius
-		{
-			get { return towerTargetter.effectRadius; }
-		}
+        protected float fBackupTimer = 0.0f;
 
-		public Color effectColor 
-		{
-			get { return radiusEffectColor; }
-		}
+        /// <summary>
+        /// 水精灵的充能时间
+        /// </summary>
+        protected float freezeBreathCallTime = 0;
 
-		public Targetter targetter 
-		{
-			get { return towerTargetter; }
-		}
+        protected float inFreezeBreath;
 
-		/// <summary>
-		/// Initializes the attack affector
-		/// </summary>
-		public override void Initialize(IAlignmentProvider affectorAlignment)
-		{
-			Initialize(affectorAlignment, -1);
-		}
+        protected float freezeBreathBackTimer = 0;
 
-		/// <summary>
-		/// 返回可能存在的Targetter.
-		/// </summary>
-		/// <returns></returns>
-		public override TowerDefense.Targetting.Targetter GetTargetter()
-		{
-			return targetter;
-		}
+        private int towerAttributeId;
 
-		/// <summary>
-		/// Initialises the  attack affector with a layer mask
-		/// </summary>
-		public override void Initialize(IAlignmentProvider affectorAlignment, LayerMask mask)
-		{
-			base.Initialize(affectorAlignment, mask);
-			SetUpTimers();
+        /// <summary>
+        /// 火精灵技能固定攻击倍速
+        /// </summary>
+        /// <value></value>
+        protected float fireSpeed { get; set; } = 5f;
 
-			towerTargetter.ResetTargetter();
-			towerTargetter.alignment = affectorAlignment;
-			towerTargetter.acquiredTarget += OnAcquiredTarget;
-			towerTargetter.lostTarget += OnLostTarget;
-		}
+        /// <summary>
+        /// 木属性精灵蓄力时间
+        /// </summary>
+        protected float woodChargeTime { get; set; } = 1.5f;
 
-		void OnDestroy()
-		{
-			towerTargetter.acquiredTarget -= OnAcquiredTarget;
-			towerTargetter.lostTarget -= OnLostTarget;
-		}
+        protected float woodRemainChargeTime { get; set; }
 
-		void OnLostTarget()
-		{
-			m_TrackingEnemy = null;
-		}
+        /// <summary>
+        /// 蓄力特效时间
+        /// </summary>
+        protected float woodChargeEffectTime { get; set; }
 
-		void OnAcquiredTarget(Targetable acquiredTarget)
-		{
-			m_TrackingEnemy = acquiredTarget;
-		}
+        /// <summary>
+        /// 木属性精灵蓄力特效
+        /// </summary>
+        public ParticleSystem WoodChargeEffect;
 
-		public Damager damagerProjectile
-		{
-			get { return projectile == null ? null : projectile.GetComponent<Damager>(); }
-		}
+        public Transform WoodChargeTransform;
 
-		public Damager damagerProjectile1
-		{
-			get { return projectile == null ? null : projectile.GetComponent<Damager>(); }
-		}
+        /// <summary>
+        /// 木属性正在瞄准的Agent
+        /// </summary>
+        protected Agent woodAimAgent;
 
-		public Damager damagerProjectile2
-		{
-			get { return projectile == null ? null : projectile.GetComponent<Damager>(); }
-		}
-
-
-		/// <summary>
-		/// Returns the total projectile damage 
-		/// </summary>
-		public float GetProjectileDamage()
-		{
-			var splash = projectile.GetComponent<SplashDamager>();
-			float splashDamage = splash != null ? splash.damage : 0;
-			return damagerProjectile.finalDamage + splashDamage;
-		}
-
-		/// <summary>
-		/// Initialise the RepeatingTimer
-		/// </summary>
-		protected virtual void SetUpTimers()
-		{
-			m_FireTimer = 1 / fireRate;
-			m_Launcher = GetComponent<ILauncher>();
-		}
-
-
-		protected void updateTowerSkillData()
+        /// <summary>
+        /// 火精灵攻击最终攻击倍速,里面计算了buff增加的倍速
+        /// </summary>
+        /// <value></value>
+        public float finalFireSpeed
         {
-			// 
-			// 预留出来装填子弹的时间.
-			if (fillBulletTime > 0)
-			{
-				fillBulletTime -= Time.deltaTime;
-				if (fillBulletTime <= 0.3f)
-				{
-					if (towerPtr && towerPtr.bulletCtl)
-						towerPtr.bulletCtl.resetToMaxBullet();
-				}
-
-				if (fillBulletTime <= 0)
-				{
-					fillBulletTime = 0;
-				}
-			}
-
-			// 
-			// 充能时间的处理
-			if( towerPtr && towerPtr.energyCtl)
+            get
             {
-				if( this.fInEnergy <= 0)
+                FireRateAdd fireRateAdd = (FireRateAdd)EndlessBuffManager.instance.GetBuffInstanceByType(EndlessBuffEffectType.FireRateAdd);
+                float rateAdd = 0;
+
+                if (fireRateAdd != null)
+                    rateAdd = fireRateAdd.GetFireSpeedAdd(towerPtr.ElfId);
+                return rateAdd > 1 ? rateAdd : fireSpeed;
+            }
+        }
+
+        /// <summary>
+        /// Gets the search rate from the targetter
+        /// </summary>
+        public float searchRate
+        {
+            get { return towerTargetter.searchRate; }
+            set { towerTargetter.searchRate = value; }
+        }
+
+        /// <summary>
+        /// Gets the targetable
+        /// </summary>
+        public Targetable trackingEnemy
+        {
+            get { return m_TrackingEnemy; }
+        }
+
+        /// <summary>
+        /// Gets or sets the attack radius
+        /// </summary>
+        public float effectRadius
+        {
+            get { return towerTargetter.effectRadius; }
+        }
+
+        public Color effectColor
+        {
+            get { return radiusEffectColor; }
+        }
+
+        public Targetter targetter
+        {
+            get { return towerTargetter; }
+        }
+
+        /// <summary>
+        /// Initializes the attack affector
+        /// </summary>
+        public override void Initialize(IAlignmentProvider affectorAlignment)
+        {
+            Initialize(affectorAlignment, -1);
+        }
+
+        /// <summary>
+        /// 返回可能存在的Targetter.
+        /// </summary>
+        /// <returns></returns>
+        public override TowerDefense.Targetting.Targetter GetTargetter()
+        {
+            return targetter;
+        }
+
+        /// <summary>
+        /// Initialises the  attack affector with a layer mask
+        /// </summary>
+        public override void Initialize(IAlignmentProvider affectorAlignment, LayerMask mask)
+        {
+            base.Initialize(affectorAlignment, mask);
+            SetUpTimers();
+
+            towerTargetter.ResetTargetter();
+            towerTargetter.alignment = affectorAlignment;
+            towerTargetter.acquiredTarget += OnAcquiredTarget;
+            // towerTargetter.lostTarget += OnLostTarget;
+
+            myTower = transform.parent.GetComponent<TowerLevel>();
+            GetAudioEnum();
+
+        }
+        private AudioEnum audioEnum;//当前音乐的种类
+        bool isWoodAudio;
+
+        void GetAudioEnum()
+        {
+            //小怪身上也有这个脚本,塔的名字做了更改,所以判断条件需要变成transform.parent.parent
+            if (transform.parent.parent != null)
+            {
+                if (transform.parent.parent.name.StartsWith("GrowUpTower"))
                 {
-					this.energyCalTime += Time.deltaTime;
-					float process = energyCalTime % 11.0f;
-					int proint = (int)Math.Floor(process);
-					proint += towerPtr.uiProOffset;
-					towerPtr.energyCtl.SetEnergyProcessFloat( process );
-					if (proint == 10)
-					{
-						fInEnergy = 5.0f;
+                    //火元素
+                    audioEnum = AudioEnum.FireTAttack;
+                }
+                else if (transform.parent.parent.name.StartsWith("BlinkTower"))
+                {
+                    //木元素
+                    audioEnum = AudioEnum.WoodTAttack;
+                }
+                else if (transform.parent.parent.name.StartsWith("CopyCatTower"))
+                {
+                    //水元素
+                    audioEnum = AudioEnum.WaterTAttack;
+                }
+            }
 
-						// 设置多倍攻击速度
-						fBackupTimer = m_FireTimer;
-						m_FireTimer = m_FireTimer / 3.0f;
+        }
 
-						towerPtr.uiProOffset = 0;
-						towerPtr.PlayEnergyEffect(true);
-					}
+        void OnDestroy()
+        {
+            // towerTargetter.acquiredTarget -= OnAcquiredTarget;
+            // towerTargetter.lostTarget -= OnLostTarget;
+        }
+
+        void OnAcquiredTarget(Targetable acquiredTarget)
+        {
+            // m_TrackingEnemy = acquiredTarget;
+        }
+
+        public Damager damagerProjectile
+        {
+            get { return projectile == null ? null : projectile.GetComponent<Damager>(); }
+        }
+
+        public Damager damagerProjectile1
+        {
+            get { return projectile == null ? null : projectile.GetComponent<Damager>(); }
+        }
+
+        public Damager damagerProjectile2
+        {
+            get { return projectile == null ? null : projectile.GetComponent<Damager>(); }
+        }
+
+        /// <summary>
+        /// Initialise the RepeatingTimer
+        /// </summary>
+        protected virtual void SetUpTimers()
+        {
+            m_Launcher = GetComponent<ILauncher>();
+        }
+
+        TowerLevel myTower;
+        bool fireState = false;
+        protected void updateTowerSkillData()
+        {
+            if (towerLevel != null && towerLevel.ParentTower != null && towerLevel.ParentTower.ElfId == 301)
+                HandleBullet();
+            if (towerLevel != null && towerLevel.ParentTower != null && towerLevel.ParentTower.ElfId == 101)
+                HandleEnergy();
+            if (towerLevel != null && towerLevel.ParentTower != null && towerLevel.ParentTower.ElfId == 201)
+                HandleFreezeBreath();
+        }
+
+        // 处理木精灵装填子弹
+        private void HandleBullet()
+        {
+            if (woodRemainChargeTime > 0f)
+                woodRemainChargeTime -= Time.deltaTime;
+
+            if (woodChargeEffectTime > 0f)
+            {
+                woodChargeEffectTime -= Time.deltaTime;
+                UpdateWoodAim();
+
+                if (woodChargeEffectTime <= 0)
+                {
+                    towerPtr.IsWoodCharge = false;
+                    CancelWoodAim();
+                    WoodChargeEffect.Stop();
+                }
+            }
+
+            // 预留出来装填子弹的时间.
+            if (fillBulletTime > 0)
+            {
+                fillBulletTime -= Time.deltaTime;
+                if (fillBulletTime <= 0.3f)
+                {
+                    if (towerPtr && towerPtr.bulletCtl)
+                        towerPtr.bulletCtl.ResetToMaxBullet();
+                }
+
+                if (fillBulletTime <= 0)
+                {
+                    fillBulletTime = 0;
+                }
+            }
+        }
+
+        /// <summary>
+        /// 更新木属性瞄准
+        /// </summary>
+        private void UpdateWoodAim()
+        {
+            // 离得最近的 Agent
+            Agent agent = AgentInsManager.instance.GetMinDisAgent(waveLineID, false);
+
+            if (agent != null)
+            {
+                // 还没有瞄准目标,直接分配
+                if (woodAimAgent == null)
+                {
+                    woodAimAgent = agent;
+                    towerPtr.WoodAimAgent = agent;
+
+                    if (agent.WoodAimCount == 0)
+                        agent.PlayWoodAimEffect();
+
+                    ++agent.WoodAimCount;
+                }
+                // 有小怪走到之前瞄准目标的前面 或者 之前瞄准的目标死亡,切换瞄准目标
+                else if (woodAimAgent.Id != agent.Id)
+                {
+                    if (woodAimAgent.WoodAimCount > 0)
+                    {
+                        --woodAimAgent.WoodAimCount;
+
+                        if (woodAimAgent.WoodAimCount == 0)
+                            woodAimAgent.StopWoodAimEffect();
+                    }
+
+                    woodAimAgent = agent;
+                    towerPtr.WoodAimAgent = agent;
+
+                    if (agent.WoodAimCount == 0)
+                        agent.PlayWoodAimEffect();
+
+                    ++agent.WoodAimCount;
+                }
+            }
+        }
+
+        /// <summary>
+        /// 取消木属性瞄准
+        /// </summary>
+        private void CancelWoodAim()
+        {
+            if (woodAimAgent != null)
+            {
+                if (woodAimAgent.WoodAimCount > 0)
+                {
+                    --woodAimAgent.WoodAimCount;
+
+                    if (woodAimAgent.WoodAimCount == 0)
+                        woodAimAgent.StopWoodAimEffect();
+                }
+            }
+
+            woodAimAgent = null;
+        }
+
+        // 处理火精灵充能
+        private void HandleEnergy()
+        {
+            // 充能时间的处理
+            if (towerPtr && towerPtr.energyCtl)
+            {
+                if (fInEnergy <= 0)
+                {
+                    energyCalTime += Time.deltaTime;
+                    float process = energyCalTime % 11.0f;
+                    int proint = (int)Math.Floor(process);
+                    proint += towerPtr.uiProOffset;
+                    towerPtr.energyCtl.SetEnergyProcessFloat(process);
+                    if (proint == 10)
+                    {
+                        fireState = true;
+                        fInEnergy = finalFireSpeed;
+                        // 设置多倍攻击速度
+                        fBackupTimer = m_FireTimer;
+                        m_FireTimer = m_FireTimer / finalFireSpeed;
+
+                        towerPtr.uiProOffset = 0;
+                        towerPtr.PlayEnergyEffect(true);
+                    }
                 }
                 else
                 {
-					fInEnergy -= Time.deltaTime;
-					if( fInEnergy <= 0)
+                    fInEnergy -= Time.deltaTime;
+                    if (fInEnergy <= 0)
                     {
-                        EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.FireTowerChargeEnd);
-						fInEnergy = 0.0f;
-						this.energyCalTime = 0.0f;	
-						towerPtr.energyCtl.SetEnergyProgress(0);
+                        fireState = false;
+                        //EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.FireTowerChargeEnd);
+                        fInEnergy = 0.0f;
+                        energyCalTime = 0.0f;
+                        towerPtr.energyCtl.SetEnergyProgress(0);
 
-						// 恢复正常攻击速度 
-						m_FireTimer = fBackupTimer;
+                        // 恢复正常攻击速度 
+                        m_FireTimer = fBackupTimer;
 
-						towerPtr.PlayEnergyEffect(false);
+                        towerPtr.PlayEnergyEffect(false);
 
-					}
-				}
+                    }
+                }
+            }
+        }
 
-			}
-		}
-
-		/// <summary>
-		/// Update the timers
-		/// </summary>
-		protected virtual void Update()
-		{
-			// 处理当前Affector所在Tower对应的技能
-			updateTowerSkillData();
-
-			m_FireTimer -= Time.deltaTime;
-			if( trackingEnemy == null )
-				m_TrackingEnemy = targetter.GetTarget(waveLineID, bWoodAffector);
-			if (trackingEnemy != null && m_FireTimer <= 0.0f)
-			{
-				OnFireTimer();
-				m_FireTimer = 1 / fireRate;
-
-				// 多倍攻速:
-				if (fInEnergy > 0.0f)
-					m_FireTimer = m_FireTimer / 3.0f;
-			}
-		}
-
-		/// <summary>
-		/// Fired at every poll of the fire rate timer
-		/// </summary>
-		protected virtual void OnFireTimer()
-		{
-			if (fireCondition != null)
-			{
-				if (!fireCondition())
-				{
-					return;
-				}
-			}
-			FireProjectile();
-		}
-
-		/// <summary>
-		/// Common logic when attacking
-		/// 调用攻击的核心函数,由这个函数发起真正的攻击,多目标或者单目标
-		/// </summary>
-		protected virtual void FireProjectile()
-		{
-			// 不再处理多子弹攻击,确保只有一个弹道
-			isMultiAttack = false; 
-			m_TrackingEnemy = targetter.GetTarget( waveLineID, bWoodAffector );
-			if ( (m_TrackingEnemy == null) || (fillBulletTime>0) )
-			{
-				if (this.towerPtr) 
-					towerPtr.setTowerState(false);
-				return;
-			}else
+        // 处理水精灵的充能
+        private void HandleFreezeBreath()
+        {
+            if (towerPtr && towerPtr.FreezeBreathCtrl)
             {
-				if (this.towerPtr) 
-					towerPtr.setTowerState(true);
+                Damager damager = projectile.gameObject.GetComponent<Damager>();
+
+                if (inFreezeBreath <= 0)
+                {
+                    freezeBreathCallTime += Time.deltaTime;
+                    float process = freezeBreathCallTime % (FreezeBreath.ChargeTime + 1);
+                    int processInt = (int)Mathf.Floor(process);
+                    processInt += towerPtr.FreezeBreathProgressOffset;
+                    towerPtr.FreezeBreathCtrl.SetProgress(process);
+
+                    if (processInt == (int)Mathf.Floor(FreezeBreath.ChargeTime))
+                    {
+                        inFreezeBreath = towerPtr.FreezeBreathCtrl.SkillTime;
+                        towerPtr.FreezeBreathProgressOffset = 0;
+                        towerPtr.PlayFreezeBreathEffect(true);
+                        towerPtr.FreezeBreathCtrl.ReleaseCount = 1;
+                        towerPtr.FreezeBreathCtrl.PlayFreezeEffect(waveLineID);
+                        towerPtr.FreezeBreathCtrl.ReleaseFreeze(waveLineID, towerPtr, damager.alignmentProvider);
+                    }
+                }
+                else
+                {
+                    inFreezeBreath -= Time.deltaTime;
+                    int time = Mathf.FloorToInt(towerPtr.FreezeBreathCtrl.EffectTime / (towerPtr.FreezeBreathCtrl.DamageCount - 1) * 10);
+                    int interval = Mathf.FloorToInt(inFreezeBreath * 10);
+                    int offset = Mathf.FloorToInt(towerPtr.FreezeBreathCtrl.SkillTime * 10) - Mathf.FloorToInt(towerPtr.FreezeBreathCtrl.EffectTime * 10);
+
+                    if (interval == time * (towerPtr.FreezeBreathCtrl.DamageCount - towerPtr.FreezeBreathCtrl.ReleaseCount - 1) + offset && towerPtr.FreezeBreathCtrl.ReleaseCount < towerPtr.FreezeBreathCtrl.DamageCount)
+                    {
+                        ++towerPtr.FreezeBreathCtrl.ReleaseCount;
+                        towerPtr.FreezeBreathCtrl.ReleaseFreeze(waveLineID, towerPtr, damager.alignmentProvider);
+                    }
+
+                    if (inFreezeBreath <= 0)
+                    {
+                        inFreezeBreath = 0;
+                        freezeBreathCallTime = 0;
+                        towerPtr.FreezeBreathCtrl.SetProgress(0);
+                        towerPtr.PlayFreezeBreathEffect(false);
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// This function is called when the object becomes enabled and active.
+        /// </summary>
+        void OnEnable()
+        {
+            if (towerPtr && towerPtr.energyCtl)
+            {
+                if (fireState)
+                {
+                    towerPtr.PlayEnergyEffect(true);
+                }
             }
 
-			// 
-			// 处理子弹充能相关的内容
-			if( towerPtr && (towerPtr.bulletCtl != null))
+            // 如果在木属性蓄力期间,让瞄准动画播放
+            if (towerPtr && towerPtr.IsWoodCharge && woodAimAgent != null)
+                woodAimAgent.PlayWoodAimEffect();
+        }
+
+        /// <summary>
+        /// This function is called when the behaviour becomes disabled or inactive.
+        /// </summary>
+        void OnDisable()
+        {
+            if (towerPtr && towerPtr.energyCtl)
             {
-				int bnum = towerPtr.bulletCtl.decBullet();
-				// 
-				if (bnum == 0)
-				{
-					damagerProjectile.damageMulti = 2.0f;	
-					fillBulletTime = 2.0f;
-				}
+                towerPtr.PlayEnergyEffect(false, false);
             }
 
-			if (isMultiAttack)
-			{
-				List<Targetable> enemies = towerTargetter.GetAllTargets();
-				if( (enemies != null)&&(Targetter.bSearchTarget) )
-					m_Launcher.Launch(enemies, projectile, projectilePoints,this.maxAttackNum);
-			}
-			else
-			{
-				if(Targetter.bSearchTarget )
-					m_Launcher.Launch(m_TrackingEnemy, damagerProjectile.gameObject, projectilePoints);
-			}
-			if (randomAudioSource != null)
-			{
-				if( Targetter.bSearchTarget )
-					randomAudioSource.PlayRandomClip();
-			}
-		}
+            if (towerPtr && towerPtr.FreezeBreathCtrl)
+                towerPtr.PlayFreezeBreathEffect(false, false);
+        }
 
-		/// <summary>
-		/// A delegate to compare distances of components
-		/// </summary>
-		/// <param name="first"></param>
-		/// <param name="second"></param>
-		protected virtual int ByDistance(Targetable first, Targetable second)
-		{
-			float firstSqrMagnitude = Vector3.SqrMagnitude(first.position - epicenter.position);
-			float secondSqrMagnitude = Vector3.SqrMagnitude(second.position - epicenter.position);
-			return firstSqrMagnitude.CompareTo(secondSqrMagnitude);
-		}
+        /// <summary>
+        /// Update the timers
+        /// </summary>
+        protected virtual void Update()
+        {
+            if (m_Launcher == null || towerPtr != null && !towerPtr.CanAttack) return;
+
+            // 处理当前Affector所在Tower对应的技能
+            updateTowerSkillData();
+
+            m_FireTimer -= Time.deltaTime;
+            m_TrackingEnemy = targetter.GetTarget(waveLineID, bWoodAffector);
+
+            if (m_TrackingEnemy != null && m_FireTimer < 0)
+            {
+                m_FireTimer = towerLevel.GetFireRate();
+
+                if (fInEnergy > 0)
+                    m_FireTimer /= finalFireSpeed;
+
+                towerLevel.FireSpeed = fInEnergy > 0 ? finalFireSpeed : 1f;
+
+                if (towerPtr && towerPtr.bulletCtl != null)
+                {
+                    int bnum = towerPtr.bulletCtl.GetCtlProgress();
+
+                    // 蓄力时间内不攻击
+                    if (bnum == 0 || woodRemainChargeTime > 0f) return;
+                }
+
+                if (towerPtr && towerPtr.FreezeBreathCtrl != null)
+                {
+                    // 冷冻气息期间不攻击
+                    if (inFreezeBreath > 0.0001f) return;
+                }
+
+                towerLevel.ChangeState(TowerActionState.Attack);
+            }
+        }
+
+        /// <summary>
+        /// Common logic when attacking
+        /// 调用攻击的核心函数,由这个函数发起真正的攻击,多目标或者单目标
+        /// </summary>
+        public virtual void FireProjectile()
+        {
+            m_TrackingEnemy = targetter.GetTarget(waveLineID, bWoodAffector);
+            GameObject go = projectile;
+
+            if (m_TrackingEnemy == null || fillBulletTime > 0) return;
+
+            Damager goDamager = go.GetComponent<Damager>();
+            goDamager.IsEnhancedBullet = false;
+            goDamager.TowerPtr = towerPtr;
+
+            // 处理子弹充能相关的内容
+            if (towerPtr && towerPtr.bulletCtl != null)
+            {
+                int bnum = towerPtr.bulletCtl.decBullet();
+                // 暴击子弹的数量,如果获得相应buff可能会修改暴击子弹数量
+                int critBulletNum = towerPtr.bulletCtl.CritBulletNum;
+
+                if (bnum < critBulletNum)
+                {
+                    if (bnum == 0)
+                        // 不需要装填时间
+                        fillBulletTime = 0.1f;
+
+                    //这里需要替换特效
+                    var poolable = Core.Utilities.Poolable.TryGetPoolable<Core.Utilities.Poolable>(woodProjectile_SP);
+                    go = poolable.gameObject;
+                    //go = Instantiate(woodProjectile_SP);
+                    Damager tmpDamager = go.GetComponent<Damager>();
+                    tmpDamager.damageMulti = 10.0f;
+                    tmpDamager.damage = damagerProjectile.damage;
+                    tmpDamager.IsEnhancedBullet = true;
+                    tmpDamager.TowerPtr = towerPtr;
+                    isWoodAudio = true;
+                }
+
+                // 下一颗子弹是强化子弹,然后直接蓄力
+                if (bnum - 1 >= 0 && bnum - 1 < critBulletNum)
+                {
+                    woodRemainChargeTime = woodChargeTime;
+                    towerPtr.IsWoodCharge = true;
+                    DecreaseWoodChargeTime decreaseWoodChargeTime = (DecreaseWoodChargeTime)EndlessBuffManager.instance.GetBuffInstanceByType(EndlessBuffEffectType.DecreaseWoodChargeTime);
+
+                    if (decreaseWoodChargeTime != null)
+                        woodRemainChargeTime = decreaseWoodChargeTime.GetWoodChargeTime(woodChargeTime);
+
+                    woodChargeEffectTime = woodRemainChargeTime + 0.5f / towerLevel.ActionAnimator.speed;
+                    WoodChargeEffect.Play();
+                }
+            }
+
+            if (Targetter.bSearchTarget)
+            {
+                m_Launcher.Launch(m_TrackingEnemy, go, projectilePoints);
+                if (AudioSourceManager.Ins)
+                {
+                    if (isWoodAudio)
+                    {
+                        isWoodAudio = false;
+                        AudioSourceManager.Ins.Play(AudioEnum.WoodSkill);
+                    }
+                    else
+                    {
+                        AudioSourceManager.Ins.Play(audioEnum);
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// A delegate to compare distances of components
+        /// </summary>
+        /// <param name="first"></param>
+        /// <param name="second"></param>
+        protected virtual int ByDistance(Targetable first, Targetable second)
+        {
+            float firstSqrMagnitude = Vector3.SqrMagnitude(first.position - epicenter.position);
+            float secondSqrMagnitude = Vector3.SqrMagnitude(second.position - epicenter.position);
+            return firstSqrMagnitude.CompareTo(secondSqrMagnitude);
+        }
 
 #if UNITY_EDITOR
-		/// <summary>
-		/// Draws the search area
-		/// </summary>
-		void OnDrawGizmosSelected()
-		{
-			Gizmos.DrawWireSphere(epicenter.position, towerTargetter.effectRadius);
-		}
+        /// <summary>
+        /// Draws the search area
+        /// </summary>
+        void OnDrawGizmosSelected()
+        {
+            Gizmos.DrawWireSphere(epicenter.position, towerTargetter.effectRadius);
+        }
 #endif
-	}
+    }
 
-	/// <summary>
-	/// A delegate for boolean calculation logic
-	/// </summary>
-	public delegate bool Filter();
+    /// <summary>
+    /// A delegate for boolean calculation logic
+    /// </summary>
+    public delegate bool Filter();
 }
\ No newline at end of file

--
Gitblit v1.9.1