using ActionGameFramework.Health; using TowerDefense.Agents; using TowerDefense.UI.HUD; using UnityEngine; using KTGMGemClient; namespace TowerDefense.Towers.Projectiles { [RequireComponent(typeof(Damager))] public class BallisticAttack : MonoBehaviour { /// /// 链式攻击的概率,目前只有一个链式攻击的模式,暂时不需要处理细节,先测试起来 /// public float chainAttackRate = 0; /// /// The Damager attached to the object /// protected Damager damager; /// /// 攻击增加. /// public float attackRise { get; set; } public Tower TowerPtr; /// /// 处理代理收到的伤害,这里需要判断代理的类型分别去处理 /// /// /// 子弹的属性id public void DealDamage(Targetable enemy, bool isEnhancedBullet = false) { switch ((enemy as Agent).AgentType) { case SpawnAgentType.Normal: HandleNormal(enemy, isEnhancedBullet); break; case SpawnAgentType.BubbleBomb: HandleBubbleBomb(enemy); break; case SpawnAgentType.WoodPile: HandleWoodPile(enemy); break; } } /// /// 处理木桩墙壁收到的伤害 /// /// private void HandleWoodPile(Targetable enemy) { float basicDamage = ElfInfoData.GetBasicDamage(TowerPtr.ElfId, TowerPtr.currentLevel); if (TowerPtr.ElfId == 101) basicDamage *= (enemy as WoodPileAgent).FireHurtRate; int tid = enemy.liveID; Vector3 backPos = enemy.position; // 这里也可以把碰撞点传进来 enemy.TakeDamage(basicDamage, enemy.position, damager.alignmentProvider); } /// /// 处理泡泡炸弹收到的伤害 /// /// private void HandleBubbleBomb(Targetable enemy) { // 泡泡炸弹伤害是以次数计算的 EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.EndlessBossSkillBubbleBombGetHit, (enemy as BubbleBombAgent).Id); } /// /// 判断本次伤害是否暴击 /// /// public static bool IsCrit(int elfId) { elf_info info = ElfInfoData.GetDataById(elfId); float crit = 0f; if (info != null) crit = info.b_crit / 1000f; CritProbabilityAdd critProbabilityAdd = (CritProbabilityAdd)EndlessBuffManager.instance.GetBuffInstanceByType(EndlessBuffEffectType.CritProbabilityAdd); if (critProbabilityAdd != null) crit = critProbabilityAdd.GetCrit(elfId, crit); float random = UnityEngine.Random.Range(0, 1f); return random <= crit; } /// /// 获取暴击伤害增加比率 /// /// public static float GetCritDamageRate(int elfId) { CritDamageAdd critDamageAdd = (CritDamageAdd)EndlessBuffManager.instance.GetBuffInstanceByType(EndlessBuffEffectType.CritDamageAdd); return critDamageAdd == null ? 0 : critDamageAdd.GetCritDamageRate(elfId); } /// /// 处理普通小怪和boss收到的伤害 /// /// private void HandleNormal(Targetable enemy, bool isEnhancedBullet) { // 基础伤害 = elf_info 基础攻击力 * elf_upgrade 攻击比率 / 1000f float basicDamage = ElfInfoData.GetBasicDamage(TowerPtr.ElfId, TowerPtr.currentLevel); elf_info info = ElfInfoData.GetDataById(TowerPtr.ElfId); // 处理PVE无尽模式,buff增加的伤害 if (EndlessBuffManager.instanceExists) basicDamage += EndlessBuffManager.instance.ProcessEndlessBuffAttack(basicDamage, TowerPtr.ElfId); bool crit = IsCrit(TowerPtr.ElfId); if (crit) { float basicCritDamageRate = info != null ? info.b_critdmg / 1000f : 0f; basicDamage *= 1 + basicCritDamageRate + GetCritDamageRate(TowerPtr.ElfId); } // 玉米强化子弹10倍伤害 if (isEnhancedBullet) basicDamage *= 10f; bool needFrost = HandleWaterFrost(TowerPtr.ElfId, (enemy as Agent), ref basicDamage); int deathCount = 0; // 提前处理非当前Enemy的爆炸攻击: if (chainAttackRate > 0) deathCount = AgentInsManager.instance.StartExplodeAttack((Agent)enemy, basicDamage); int tid = enemy.liveID; Vector3 backPos = enemy.position; // 这里也可以把碰撞点传进来 enemy.TakeDamage(basicDamage, enemy.position, damager.alignmentProvider, 0); if (chainAttackRate > 0) { if (enemy.isDead) ++deathCount; if (deathCount > 1) EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.EndlessOneTimeKillCount, deathCount); } // 处理塔位的技能攻击: ProcessTowerAttributeAttack(enemy, basicDamage, TowerPtr.ElfId); if (!enemy.opponentAgent) { if (GameUI.instanceExists) GameUI.instance.generateBloodText(backPos, basicDamage, crit); else if (EndlessGameUI.instanceExists && crit) { EndlessGameUI.instance.generateBloodText(backPos, basicDamage, true); EndlessGameUI.instance.FloatCritWord(backPos); } } if (!enemy.isDead && needFrost) { (enemy as Agent).IsFrost = true; (enemy as Agent).FrostRemainTime = FrostTimeAdd.DefaultFrostTime; FrostTimeAdd frostTimeAdd = (FrostTimeAdd)EndlessBuffManager.instance.GetBuffInstanceByType(EndlessBuffEffectType.FrostTimeAdd); if (frostTimeAdd != null) (enemy as Agent).FrostRemainTime = frostTimeAdd.GetFrostTime(TowerPtr.ElfId); } // 播放受击动画: if (!enemy.isDead && enemy.liveID == tid) { (enemy as Agent).PlayOnHit(); // 如果是玉米强化子弹的攻击,要处理击退的效果 if (TowerPtr != null && isEnhancedBullet) (enemy as Agent).AgentBeRepelled(); } } /// /// 处理水精灵冰冻 /// /// /// /// /// 是否需要冰冻,如果直接被打死就无所谓了,也不要飘字 public static bool HandleWaterFrost(int elfId, Agent enemy, ref float basicDamage) { bool needFrost = false; if (elfId != 201) return needFrost; // 处理冰冻状态中的额外伤害 if (enemy.IsFrost) { FrostDamageAdd frostDamageAdd = (FrostDamageAdd)EndlessBuffManager.instance.GetBuffInstanceByType(EndlessBuffEffectType.FrostDamageAdd); if (frostDamageAdd != null) basicDamage *= (1 + frostDamageAdd.GetFrostDamageAdd(elfId)); } else { FrostProbabilityAdd frostProbabilityAdd = (FrostProbabilityAdd)EndlessBuffManager.instance.GetBuffInstanceByType(EndlessBuffEffectType.FrostProbabilityAdd); if (frostProbabilityAdd != null) { float probaility = frostProbabilityAdd.GetFrostProbaility(elfId); float random = UnityEngine.Random.Range(0f, 1f); if (random <= probaility) needFrost = true; } } return needFrost; } /// /// 处理塔位的属性攻击 /// /// /// 精灵Id protected void ProcessTowerAttributeAttack(Targetable enemy, float damage, int elfId) { switch (elfId) { case 201: // 减速. SlowDown slowDown = (SlowDown)EndlessBuffManager.instance.GetBuffInstanceByType(EndlessBuffEffectType.SlowDown); (enemy as Agent).addSpeedSlowRate(0.15f + (slowDown != null ? slowDown.GetSlowDownAdd(TowerPtr.ElfId) : 0)); break; case 301: // 中毒 // enemy.poisonAgent(damage, attid); // enemy.SetTargetableMatColor(Color.green); break; } return; } /// /// Cache the damager component attached to this object /// protected virtual void Awake() { damager = GetComponent(); attackRise = 0.0f; } } }