using System.Collections.Generic;
using UnityEngine;
///
/// 每隔一段时间检测周围目标脚本
///
public class Bhv_FindEnemy : MonoBehaviour
{
[Tooltip("清空锁定目标的距离")]
public float reSetLockTargetDist;
[Tooltip("重新确定当前对象的距离")]
public float reFindSelectTargetDist;
[Tooltip("每次重新检测的间隔事件")]
public float reDoInterval = 0.3f;
private float m_LastChkTime;
private void Start()
{
FuncConfigConfig _funcConfig = FuncConfigConfig.Get("MaxTargetRange");
reSetLockTargetDist = float.Parse(_funcConfig.Numerical1);
JobSetupConfig _jobConfig = JobSetupConfig.Get(PlayerDatas.Instance.baseData.Job);
reFindSelectTargetDist = _jobConfig.MaxSwitchTargetDist * Constants.F_DELTA;
}
private void Update()
{
if (Time.time - m_LastChkTime < reDoInterval)
{
return;
}
m_LastChkTime = Time.time;
GA_Hero _hero = PlayerDatas.Instance.hero;
if (_hero == null)
{
return;
}
if (_hero.LockTarget != null
&& !(_hero.LockTarget is GA_NpcCollect)
&& !(_hero.LockTarget.ActorInfo.faction == 1))
{
// 判断是否要清空锁定目标
DoIfClearLockTarget();
return;
}
if (!_hero.aiHandler.IsAuto()
|| _hero.aiHandler.IsPause())
{
// 只有当前主角没有锁定目标的时候才进行搜怪
DoReFindSelectTarget();
}
}
private void DoIfClearLockTarget()
{
GA_Hero _hero = PlayerDatas.Instance.hero;
if (_hero.LockTarget is GA_NpcFightBoss
|| _hero.LockTarget is GA_NpcClientFightBoss
|| _hero.LockTarget is GActorNpcNoFight)
{
return;
}
Vector3 _targetPos = _hero.LockTarget.Pos;
Vector3 _heroPos = _hero.Pos;
float _distSqrt = MathUtility.DistanceSqrtXZ(_targetPos, _heroPos);
if (_distSqrt > Mathf.Pow(reSetLockTargetDist, 2)
|| StatusMgr.Instance.IsInvisible(_hero.LockTarget.ServerInstID))
{
_hero.LockTarget = null;
}
}
private void DoReFindSelectTarget()
{
GA_Hero _hero = PlayerDatas.Instance.hero;
if (_hero.SelectTarget == null)
{
var _actor = GAMgr.Instance.FindAtkTarget(_hero.Pos, reSetLockTargetDist);
if (!(_actor is GActorFight))
{
_hero.SelectTarget = _actor;
}
else
{
if (_actor.CanAtked())
{
_hero.SelectTarget = _actor;
}
}
}
else
{
Vector3 _targetPos = _hero.SelectTarget.Pos;
Vector3 _heroPos = _hero.Pos;
float _distSqrt = MathUtility.DistanceSqrtXZ(_targetPos, _heroPos);
var _chkDis = reFindSelectTargetDist;
if (PlayerDatas.Instance.baseData.MapID == 31340 && _hero.SelectTarget is GA_NpcCollect)
{
_chkDis += 1;
}
if (_distSqrt > Mathf.Pow(_chkDis, 2))
{
var _actor = GAMgr.Instance.FindAtkTarget(_hero.Pos, reSetLockTargetDist);
if (!(_actor is GActorFight))
{
_hero.SelectTarget = _actor;
}
else
{
if (_actor.CanAtked())
{
_hero.SelectTarget = _actor;
if (_actor is GA_NpcFightBoss && _hero.LockTarget == null)
{
_hero.LockTarget = _actor;
}
}
}
}
}
}
#region 界面切换目标
private List m_SelectedTarget = new List();
public void SwitchTarget()
{
GA_Hero _hero = PlayerDatas.Instance.hero;
if (_hero == null)
{
return;
}
if (_hero.IsRushing)
{
return;
}
if (_hero.SelectTarget != null)
{
if (!m_SelectedTarget.Contains(_hero.SelectTarget.ServerInstID))
{
m_SelectedTarget.Add(_hero.SelectTarget.ServerInstID);
}
}
GActorFight _fight = null;
uint _curResultID = 0;
uint _bestPlayerID = 0;
uint _bestNpcID = 0;
uint _bestTargetID = 0;// 有可能找不到的最优解, 此时用上面变量来决定最优解
if (PlayerDatas.Instance.baseData.AttackMode == (int)E_AttackMode.All
|| PlayerDatas.Instance.baseData.AttackMode == (int)E_AttackMode.Family
|| PlayerDatas.Instance.maliciousAtkPlayer.Count > 0)
{
//Debug.LogFormat("当前模式: {0}, 开始搜索Player对象...", (E_AttackMode)PlayerDatas.Instance.baseData.AttackMode);
List _actorList = GAMgr.Instance.GetGroupList(E_ActorGroup.Player);
if (_actorList != null)
{
_actorList.Sort(CompareDistance);
for (int i = 0; i < _actorList.Count; ++i)
{
_fight = _actorList[i] as GActorFight;
if (_fight == null || !_fight.CanAtked())
{
continue;
}
if (MathUtility.DistanceSqrtXZ(_hero.Pos, _fight.Pos)
> Mathf.Pow(reSetLockTargetDist, 2))
{
continue;
}
if (_bestPlayerID == 0)
{
_bestPlayerID = _fight.ServerInstID;
}
// 排除之前选择过的
if (m_SelectedTarget.Contains(_fight.ServerInstID))
{
continue;
}
// 确定此次解
_curResultID = _fight.ServerInstID;
break;
}
if (_curResultID != 0)
{
//Debug.LogFormat(" |-- 此次有最优解: {0}", _curResultID);
_bestTargetID = _curResultID;
}
//else if (_bestPlayerID != 0)
//{
// //Debug.LogFormat(" |-- 此次没有最优解, 使用所有Player里面的最优解: {0}", _bestPlayerID);
// _bestTargetID = _bestPlayerID;
// // 清空过滤列表
// m_SelectedTarget.Clear();
//}
}
}
// 在上面的角色选择中选不到目标, 即场上可见范围内是没有任何玩家的
// 开始判断NPC
if (_bestTargetID == 0)
{
//Debug.Log("没有找到任何Player对象, 开始搜索NPC对象");
List _actorList = GAMgr.Instance.GetGroupList(E_ActorGroup.Enemy);
if (_actorList != null)
{
_actorList.Sort(CompareDistance);
for (int i = 0; i < _actorList.Count; ++i)
{
_fight = _actorList[i] as GActorFight;
if (_fight == null || !_fight.CanAtked())
{
continue;
}
if (MathUtility.DistanceSqrtXZ(_hero.Pos, _fight.Pos)
> Mathf.Pow(reSetLockTargetDist, 2))
{
continue;
}
if (_bestNpcID == 0)
{
_bestNpcID = _fight.ServerInstID;
}
// 排除之前选择过的
if (m_SelectedTarget.Contains(_fight.ServerInstID))
{
continue;
}
// 确定此次解
_curResultID = _fight.ServerInstID;
break;
}
if (_curResultID != 0)
{
//Debug.LogFormat(" |-- 此次有最优解: {0}", _curResultID);
_bestTargetID = _curResultID;
}
}
}
// 最后进行判断取哪个值
// 如果出现都选不中的情况, 有可能是所有的怪都被遍历了一遍了
if (_bestTargetID == 0)
{
// 这里判断是不是还有最优选中对象
if (_bestPlayerID != 0)
{
_bestTargetID = _bestPlayerID;
//Debug.LogFormat(" |-- 此次没有最优解, 使用所有Player里面的最优解: {0}", _bestPlayerID);
}
else if (_bestNpcID != 0)
{
_bestTargetID = _bestNpcID;
//Debug.LogFormat(" |-- 此次没有最优解, 使用所有NPC里面的最优解: {0}", _bestNpcID);
}
// 清空过滤列表
m_SelectedTarget.Clear();
}
if (_bestTargetID != 0)
{
_hero.LockTarget = GAMgr.Instance.GetBySID(_bestTargetID);
_hero.SelectTarget = _hero.LockTarget;
m_SelectedTarget.Add(_bestTargetID);
if (_hero.LockTarget != null)
{
GA_Hero.CallLockTargetChanged(_hero.LockTarget.ServerInstID);
}
}
}
public int CompareDistance(GActor a1, GActor a2)
{
GA_Hero _hero = PlayerDatas.Instance.hero;
if (_hero == null)
{
return 0;
}
float _chk1 = MathUtility.DistanceSqrtXZ(a1.Pos, _hero.Pos);
float _chk2 = MathUtility.DistanceSqrtXZ(a2.Pos, _hero.Pos);
if (_chk1 < _chk2)
{
return -1;
}
else if (_chk1 > _chk2)
{
return 1;
}
return 0;
}
#endregion
}