using ActionGameFramework.Health; using System; using TowerDefense.Agents; using TowerDefense.UI.HUD; using UnityEngine; using System.Collections.Generic; 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); } /// /// 判断本次伤害是否暴击 /// /// private bool IsCrit() { elf_info info = ElfInfoData.GetDataById(TowerPtr.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(TowerPtr.ElfId, crit); float random = UnityEngine.Random.Range(0, 1f); return random <= crit; } /// /// 获取暴击伤害增加比率 /// /// private float GetCritDamageRate() { CritDamageAdd critDamageAdd = (CritDamageAdd)EndlessBuffManager.instance.GetBuffInstanceByType(EndlessBuffEffectType.CritDamageAdd); return critDamageAdd == null ? 0 : critDamageAdd.GetCritDamageRate(TowerPtr.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增加的伤害 basicDamage += ProcessEndlessBuffAttack(basicDamage); bool crit = IsCrit(); if (crit) { float basicCritDamageRate = info != null ? info.b_critdmg / 1000f : 0f; basicDamage *= 1 + basicCritDamageRate + GetCritDamageRate(); } // 玉米强化子弹10倍伤害 if (isEnhancedBullet) basicDamage *= 10f; 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.FloatCritWord(backPos); } // 播放受击动画: if (!enemy.isDead && enemy.liveID == tid) { (enemy as Agent).PlayOnHit(); // 如果是玉米强化子弹的攻击,要处理击退的效果 if (TowerPtr != null && isEnhancedBullet) (enemy as Agent).AgentBeRepelled(); } } /// /// 处理PVE无尽模式buff增加的伤害 /// /// protected float ProcessEndlessBuffAttack(float finalDamage) { // 非无尽模式 if (!EndlessBuffManager.instanceExists) return 0; List list = EndlessBuffManager.instance.GetBuffListByEffectType(EndlessBuffEffectType.AttackAdd, TowerPtr.ElfId); if (list.Count == 0) return 0; float ratio = 0; float add = 0; for (int i = 0; i < list.Count; ++i) { ratio += list[i].Config.buff_effect[1]; add += list[i].Config.buff_effect[2]; } return finalDamage * (ratio / 100f) + add; } /// /// 处理塔位的属性攻击 /// /// /// 精灵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; } } }