using ActionGameFramework.Health; using System; using TowerDefense.Agents; using TowerDefense.UI.HUD; using UnityEngine; using TowerDefense.Level; using System.Collections.Generic; using KTGMGemClient; namespace TowerDefense.Towers.Projectiles { [RequireComponent(typeof(Damager))] public class BallisticAttack : MonoBehaviour { /// /// 链式攻击的概率,目前只有一个链式攻击的模式,暂时不需要处理细节,先测试起来 /// public float chainAttackRate = 0; /// /// 当前攻击塔位对应的属性ID /// public int attributeId = 0; /// /// The Damager attached to the object /// protected Damager damager; /// /// 攻击增加. /// public float attackRise { get; set; } /// /// 基础增加暴击伤害率 /// private float baseCritDamageRate = 0.5f; public Tower TowerPtr; /// /// 处理代理收到的伤害,这里需要判断代理的类型分别去处理 /// /// /// 子弹的属性id public void DealDamage(Targetable enemy, int attributeId = -1) { switch ((enemy as Agent).AgentType) { case SpawnAgentType.Normal: HandleNormal(enemy); break; case SpawnAgentType.BubbleBomb: HandleBubbleBomb(enemy); break; case SpawnAgentType.WoodPile: HandleWoodPile(enemy, attributeId); break; } } /// /// 处理木桩墙壁收到的伤害 /// /// private void HandleWoodPile(Targetable enemy, int id) { float finalDamage = damager.finalDamage; if (id == 10101) finalDamage *= (enemy as WoodPileAgent).FireHurtRate; int tid = enemy.liveID; Vector3 backPos = enemy.position; // 这里也可以把碰撞点传进来 enemy.TakeDamage(finalDamage, enemy.position, damager.alignmentProvider); EndlessGameUI.instance.generateBloodText(backPos, finalDamage); } /// /// 处理泡泡炸弹收到的伤害 /// /// private void HandleBubbleBomb(Targetable enemy) { // 泡泡炸弹伤害是以次数计算的 EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.EndlessBossSkillBubbleBombGetHit, (enemy as BubbleBombAgent).Id); } /// /// 判断本次伤害是否暴击 /// /// private bool IsCrit() { CritProbabilityAdd critProbabilityAdd = (CritProbabilityAdd)EndlessBuffManager.instance.GetBuffInstanceByType(EndlessBuffEffectType.CritProbabilityAdd); float crit = critProbabilityAdd.GetCrit(TowerPtr.attributeId); float random = UnityEngine.Random.Range(0, 1f); return random <= crit; } /// /// 获取暴击伤害增加比率 /// /// private float GetCritDamageRate() { CritDamageAdd critDamageAdd = (CritDamageAdd)EndlessBuffManager.instance.GetBuffInstanceByType(EndlessBuffEffectType.CritDamageAdd); return critDamageAdd.GetCritDamageRate(TowerPtr.attributeId); } /// /// 处理普通小怪和boss收到的伤害 /// /// private void HandleNormal(Targetable enemy) { float finalDamage = damager.finalDamage; bool crit = IsCrit(); // 处理PVE无尽模式,buff增加的伤害 finalDamage += ProcessEndlessBuffAttack(finalDamage); if (crit) finalDamage *= 1 + baseCritDamageRate + GetCritDamageRate(); int deathCount = 0; // 提前处理非当前Enemy的爆炸攻击: if (chainAttackRate > 0) deathCount = AgentInsManager.instance.StartExplodeAttack((Agent)enemy, finalDamage); int tid = enemy.liveID; Vector3 backPos = enemy.position; // 这里也可以把碰撞点传进来 enemy.TakeDamage(finalDamage, 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, finalDamage, attributeId); if (!enemy.opponentAgent) { if (GameUI.instanceExists) GameUI.instance.generateBloodText(backPos, finalDamage, crit); else if (EndlessGameUI.instanceExists) EndlessGameUI.instance.generateBloodText(backPos, finalDamage, crit); } // 播放受击动画: if ((!enemy.isDead) && (enemy.liveID == tid)) (enemy as Agent).PlayOnHit(); } /// /// 处理PVE无尽模式buff增加的伤害 /// /// protected float ProcessEndlessBuffAttack(float finalDamage) { // 非无尽模式 if (!EndlessBuffManager.instanceExists) return 0; List list = EndlessBuffManager.instance.GetBuffListByEffectType(EndlessBuffEffectType.AttackAdd, attributeId); 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; } /// /// 处理塔位的属性攻击 /// /// /// protected void ProcessTowerAttributeAttack(Targetable enemy, float damage, int attid) { int id = (int)Math.Floor(attid / 10000.0f); switch (id) { case 2: // 减速. SlowDown slowDown = (SlowDown)EndlessBuffManager.instance.GetBuffInstanceByType(EndlessBuffEffectType.SlowDown); enemy.addSpeedSlowRate(0.25f + slowDown.GetSlowDownAdd(TowerPtr.attributeId)); enemy.SetTargetableMatColor(Color.blue); break; case 3: // 中毒 // enemy.poisonAgent(damage, attid); // enemy.SetTargetableMatColor(Color.green); break; case 5: // 破甲 enemy.bShieldBreak = true; break; } return; } /// /// Cache the damager component attached to this object /// protected virtual void Awake() { damager = GetComponent(); attackRise = 0.0f; } } }