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
|
{
|
/// <summary>
|
/// 链式攻击的概率,目前只有一个链式攻击的模式,暂时不需要处理细节,先测试起来
|
/// </summary>
|
public float chainAttackRate = 0;
|
|
/// <summary>
|
/// 当前攻击塔位对应的属性ID
|
/// </summary>
|
public int attributeId = 0;
|
|
/// <summary>
|
/// The Damager attached to the object
|
/// </summary>
|
protected Damager damager;
|
|
/// <summary>
|
/// 攻击增加.
|
/// </summary>
|
public float attackRise { get; set; }
|
|
/// <summary>
|
/// 处理代理收到的伤害,这里需要判断代理的类型分别去处理
|
/// </summary>
|
/// <param name="enemy"></param>
|
/// <param name="attributeId">子弹的属性id</param>
|
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;
|
}
|
}
|
|
/// <summary>
|
/// 处理木桩墙壁收到的伤害
|
/// </summary>
|
/// <param name="enemy"></param>
|
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);
|
}
|
|
/// <summary>
|
/// 处理泡泡炸弹收到的伤害
|
/// </summary>
|
/// <param name="enemy"></param>
|
private void HandleBubbleBomb(Targetable enemy)
|
{
|
// 泡泡炸弹伤害是以次数计算的
|
EventCenter.Ins.BroadCast((int)KTGMGemClient.EventType.EndlessBossSkillBubbleBombGetHit, (enemy as BubbleBombAgent).Id);
|
}
|
|
/// <summary>
|
/// 判断本次伤害是否暴击
|
/// </summary>
|
/// <returns></returns>
|
private bool IsCrit()
|
{
|
CritProbabilityAdd critProbabilityAdd = (CritProbabilityAdd)EndlessBuffManager.instance.GetBuffInstanceByType(EndlessBuffEffectType.CritProbabilityAdd);
|
float crit = critProbabilityAdd.GetCrit(damager.TowerAttributeId);
|
float random = UnityEngine.Random.Range(0, 1f);
|
|
return random <= crit;
|
}
|
|
/// <summary>
|
/// 获取暴击伤害增加比率
|
/// </summary>
|
/// <returns></returns>
|
private float GetCritDamageRate()
|
{
|
CritDamageAdd critDamageAdd = (CritDamageAdd)EndlessBuffManager.instance.GetBuffInstanceByType(EndlessBuffEffectType.CritDamageAdd);
|
return critDamageAdd.GetCritDamageRate(damager.TowerAttributeId);
|
}
|
|
/// <summary>
|
/// 处理普通小怪和boss收到的伤害
|
/// </summary>
|
/// <param name="enemy"></param>
|
private void HandleNormal(Targetable enemy)
|
{
|
float finalDamage = damager.finalDamage;
|
bool crit = IsCrit();
|
|
// 处理PVE无尽模式,buff增加的伤害
|
finalDamage += ProcessEndlessBuffAttack(finalDamage);
|
|
if (crit)
|
finalDamage *= 1 + 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();
|
}
|
|
/// <summary>
|
/// 处理PVE无尽模式buff增加的伤害
|
/// </summary>
|
/// <param name="finalDamage"></param>
|
protected float ProcessEndlessBuffAttack(float finalDamage)
|
{
|
// 非无尽模式
|
if (!EndlessBuffManager.instanceExists) return 0;
|
|
List<EndlessBuffConfig> 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;
|
}
|
|
/// <summary>
|
/// 处理塔位的属性攻击
|
/// </summary>
|
/// <param name="enemy"></param>
|
/// <param name="attid"></param>
|
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(damager.TowerAttributeId));
|
enemy.SetTargetableMatColor(Color.blue);
|
break;
|
case 3: // 中毒
|
// enemy.poisonAgent(damage, attid);
|
// enemy.SetTargetableMatColor(Color.green);
|
break;
|
case 5: // 破甲
|
enemy.bShieldBreak = true;
|
break;
|
}
|
return;
|
}
|
|
/// <summary>
|
/// Cache the damager component attached to this object
|
/// </summary>
|
protected virtual void Awake()
|
{
|
damager = GetComponent<Damager>();
|
attackRise = 0.0f;
|
}
|
}
|
}
|