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