using ActionGameFramework.Health;
using Core.Utilities;
using System;
using TowerDefense.Agents;
using TowerDefense.UI.HUD;
using UnityEngine;
namespace TowerDefense.Towers.Projectiles
{
///
/// Implementation of hitscan projectile
/// The principle behind this weapon is that it instantly attacks enemies
///
[RequireComponent(typeof(Damager))]
public class HitscanAttack : MonoBehaviour
{
///
/// The amount of time to delay
///
public float delay;
///
/// 攻击敌人后,重设敌人到开始位置的概率,默认为零,不需要重设。
///
public float resetStartPosRate = 0;
///
/// 链式攻击的概率,目前只有一个链式攻击的模式,暂时不需要处理细节,先测试起来
///
public float chainAttackRate = 0;
///
/// 当前攻击塔位对应的属性ID
///
public int attributeId = 0;
///
/// The delay timer
///
protected Timer m_Timer;
///
/// The enemy this projectile will attack
///
protected Targetable m_Enemy;
///
/// The Damager attached to the object
///
protected Damager m_Damager;
///
/// The towers projectile position
///
protected Vector3 m_Origin;
///
/// Configuration for pausing the timer delay timer
/// without setting Time.timeScale to 0
///
protected bool m_PauseTimer;
protected int mLiveID = 0;
///
/// 随机数数据
///
protected System.Random mRand;
///
/// 攻击增加.
///
public float attackRise { get; set; }
///
/// The delay configuration for the attacking
///
///
/// The point the attack will be fired from
///
///
/// The enemy to attack
///
public void AttackEnemy(Vector3 origin, Targetable enemy, float delayTime = 0)
{
m_Enemy = enemy;
m_Origin = origin;
// 更快的击中目标:
if (delayTime > 0)
m_Timer.SetTime(delayTime / 4.0f);
m_Timer.Reset();
m_PauseTimer = false;
mLiveID = enemy.liveID;
}
///
/// 处理塔位的属性攻击
///
///
///
protected void ProcessTowerAttributeAttack(Targetable enemy, float damage, int attid)
{
int id = (int)Math.Floor(attid / 10000.0f);
switch (id)
{
case 2: // 减速.
(enemy as Agent).addSpeedSlowRate(0.15f);
break;
case 3: // 中毒
(enemy as Agent).poisonAgent(damage, attid);
break;
}
return;
}
///
/// The actual attack of the hitscan attack.
/// Early returns from the method if the there is no enemy to attack.
///
protected void DealDamage()
{
Poolable.TryPool(gameObject);
if (m_Enemy == null)
{
return;
}
// 攻击目标已经经历过了Pool了,不能再攻击了。
if (mLiveID != m_Enemy.liveID) return;
float finalDamage = m_Damager.finalDamage;
bool crit = m_Damager.isCrit;
if (crit)
{
finalDamage += finalDamage;
}
// 处理光塔对应的攻击增加:
if (attackRise > 0)
finalDamage += (finalDamage * attackRise);
// 提前处理非当前Enemy的爆炸攻击:
if (chainAttackRate > 0)
AgentInsManager.instance.StartExplodeAttack(m_Enemy as Agent, finalDamage);
int tid = m_Enemy.liveID;
Vector3 backPos = m_Enemy.position;
m_Enemy.TakeDamage(finalDamage, m_Enemy.position, m_Damager.alignmentProvider, attributeId);
// 处理塔位的技能攻击:
ProcessTowerAttributeAttack(m_Enemy, finalDamage, attributeId);
if (!m_Enemy.opponentAgent)
GameUI.instance.generateBloodText(backPos, finalDamage, crit);
// 播放受击动画:
if ((!m_Enemy.isDead) && (m_Enemy.liveID == tid))
(m_Enemy as Agent).PlayOnHit();
m_PauseTimer = true;
}
///
/// Cache the damager component attached to this object
///
protected virtual void Awake()
{
m_Damager = GetComponent();
float fdelay = delay - 0.05f;
if (fdelay < 0) fdelay = 0.0f;
m_Timer = new Timer(fdelay, DealDamage);
if ((resetStartPosRate > 0) || (chainAttackRate > 0))
mRand = new System.Random();
attackRise = 0.0f;
}
///
/// Update the m_Timer if it is available
///
protected virtual void Update()
{
if (!m_PauseTimer)
{
m_Timer.Tick(Time.deltaTime);
}
}
}
}