using Snxxz.UI;
using TableConfig;
using UnityEngine;
public abstract class HeroAI_Auto : HeroAI_Base
{
private float m_LastUseSkillTime;
private float m_PauseStartTime;
///
/// 定点挂机的坐标
///
protected uint m_LockTargetSID;
protected int m_LockTargetNpcID;
private int m_UserClickSkillID;
private Skill m_DecideSkill = null;
#region 配置相关
private float m_PauseResumeTime;
protected float m_HandupRange;
protected int[] m_HandUpSkill;
#endregion
private bool m_IsDungeon;
private byte m_State;
DungeonModel m_DungeonModel;
DungeonModel dungeonModel
{
get
{
return m_DungeonModel ?? (m_DungeonModel = ModelCenter.Instance.GetModel());
}
}
public bool IsPause()
{
return m_State == 1;
}
public override bool Condition()
{
return false;
}
public sealed override void Enter()
{
m_LastUseSkillTime = 0;
m_PauseStartTime = 0;
m_LockTargetSID = 0;
m_UserClickSkillID = -1;
m_NeedMoveToPos = false;
m_HandUpSkill = null;
m_State = 0;
// 初始化配置
if (m_PauseResumeTime == 0)
{
FuncConfigConfig _func = Config.Instance.Get("HandupResumeTime");
m_PauseResumeTime = float.Parse(_func.Numerical1) * Constants.F_GAMMA;
}
if (xpSkillID == 0)
{
FuncConfigConfig _funcConfig = Config.Instance.Get("XpSkillID");
xpSkillID = ConfigParse.GetDic(_funcConfig.Numerical1)[PlayerDatas.Instance.baseData.Job];//获取各个职业的XP技能
}
GA_Hero _hero = PlayerDatas.Instance.hero;
if (_hero != null)
{
if (!string.IsNullOrEmpty(_hero.JobSetup.DungeonSkillList))
{
var _json = LitJson.JsonMapper.ToObject(_hero.JobSetup.DungeonSkillList);
var _key = PlayerDatas.Instance.baseData.MapID.ToString();
if (((System.Collections.IDictionary)_json).Contains(_key))
{
_json = _json[_key];
m_HandUpSkill = new int[_json.Count];
for (int i = 0; i < _json.Count; ++i)
{
m_HandUpSkill[i] = (int)_json[i];
}
}
}
}
var _mapConfig = Config.Instance.Get(PlayerDatas.Instance.baseData.MapID);
m_IsDungeon = _mapConfig.MapFBType != (int)MapType.OpenCountry;
if (m_IsDungeon)
{
int _dgDataID = dungeonModel.GetDataMapIdByMapId(PlayerDatas.Instance.baseData.MapID);
var dungeonOpen = Config.Instance.Get(_dgDataID);
if (dungeonOpen != null)
{
if (dungeonOpen.DoFight == 1)
{
GA_Hero.forceAutoFight = true;
}
}
}
UserInputHandler.OnCirclePanelTouched += OnActiveInterrupt;
UserInputHandler.OnClickedFloor += OnClickFloor;
GA_Hero.OnLockTargetChanged += OnLockTargetChanged;
HeroBehaviour.OnUserClickSkill += OnUserClickSkill;
OnEnter();
}
public sealed override void Update()
{
if (!DTC0403_tagPlayerLoginLoadOK.finishedLogin)
{
Debug.LogWarning("登陆流程尚未完成");
return;
}
GA_Hero _hero = PlayerDatas.Instance.hero;
if (_hero.IsPolyMorph)
{
return;
}
if (_hero.SelectTarget == _hero)
{
_hero.SelectTarget = null;
}
if (_hero.LockTarget == _hero)
{
_hero.LockTarget = null;
}
if (_hero == null || _hero.ActorInfo.serverDie)
{
return;
}
// 处理仙魔之争
if (PlayerDatas.Instance.baseData.MapID == 31010)
{
if (_hero.heavenBattleModel.IsBattlePrepare)
{
return;
}
}
if (_hero.IsCollect())
{
return;
}
// 当前技能是否已经释放完毕
Skill _skill = _hero.SkillMgr.CurCastSkill;
if (_skill != null)
{
if (!_skill.SkillCompelete)
{
if (_skill.skillInfo.config.CastTime > 0)
{
if (_skill.CSkillPrepareEnd && _hero.SkillMgr.DoingPrepareSkill)
{
_hero.Behaviour.DoAttack(_skill);
_hero.SkillMgr.DoingPrepareSkill = false;
}
}
return;
}
}
// 释放处于释放需要预备的技能状态下
if (_hero.SkillMgr.DoingPrepareSkill)
{
return;
}
_skill = null;
switch (m_State)
{
case 0:// 正常状态
// 挂机状态下等待拾取装备
if (WaitForPickup())
{
return;
}
if (m_IsDungeon)
{
if (dungeonModel.dungeonFightStage == DungeonFightStage.None
|| dungeonModel.dungeonFightStage == DungeonFightStage.Normal
|| PlayerDatas.Instance.baseData.MapID == 31010)
{
// 子类有自己需要在技能释放前处理的逻辑
if (OnUpdate())
{
return;
}
}
}
else
{
// 子类有自己需要在技能释放前处理的逻辑
if (OnUpdate())
{
return;
}
}
break;
case 1:// 暂停状态
if (m_NeedMoveToPos)
{
if (StatusMgr.Instance.CanMove(PlayerDatas.Instance.PlayerId))
{
if (MathUtility.DistanceSqrtXZ(_hero.Pos, m_TargetPos) > 0.25f)
{
_hero.MoveToPosition(m_TargetPos);
return;
}
}
m_NeedMoveToPos = false;
}
if (Time.realtimeSinceStartup - m_PauseStartTime > m_PauseResumeTime)
{
m_State = 0;
}
break;
}
// 是否处于攻击间隔
if (Time.realtimeSinceStartup - m_LastUseSkillTime < (1f / _hero.ActorInfo.atkSpeed))
{
return;
}
if (m_UserClickSkillID == 0)
{
int _index = _hero.nextComAtkIndex;
if (_index == -1)
{
_index = 0;
}
m_UserClickSkillID = _hero.GetCommonSkillID(_index);
}
if (m_State == 0 || m_UserClickSkillID != -1)
{
// 决策此次要使用的技能
_skill = DecideUserSkill(m_HandUpSkill, m_UserClickSkillID);
}
if (_skill == null)
{
return;
}
// 判断周围是否有可攻击目标
GActorFight _atkTarget = null;
// 处理玩家主动切换攻击目标行为
if (m_LockTargetSID != 0)
{
_atkTarget = GAMgr.Instance.GetBySID(m_LockTargetSID) as GActorFight;
if (_atkTarget == null
|| !_atkTarget.CanAtked())
{
m_LockTargetSID = 0;
_atkTarget = null;
}
}
else if (_hero.aiHandler.PriorityNpcID > 0)
{
_atkTarget = DecideAttackTarget(_hero.Pos, m_HandupRange, _hero.aiHandler.PriorityNpcID);
}
else if (m_LockTargetNpcID > 0)
{
_atkTarget = DecideAttackTarget(_hero.Pos, m_HandupRange, m_LockTargetNpcID);
}
else
{
_atkTarget = SelectTarget();
}
bool _forceMove = _skill.skillInfo.soFile != null && _skill.skillInfo.soFile.forceMove;
if ((_atkTarget == null
|| _atkTarget.ActorInfo.serverDie
|| (!_forceMove && !IsSkillNeedMove(_skill.skillInfo.config.Tag, (E_SkillType)_skill.skillInfo.config.SkillType)))
&& m_UserClickSkillID != -1)
{
_hero.Behaviour.DoAttack(_skill);
m_DecideSkill = null;
return;
}
if (_atkTarget == null)
{
_hero.StopRush();
return;
}
_hero.LockTarget = _hero.SelectTarget = _atkTarget;
// 判断技能范围, 不在可释放范围需要移动至目标
float _compareDist = _skill.skillInfo.config.AtkDist * .5f;
float _compareDistSqrt = _compareDist * _compareDist;
// 计算当前和目标的距离
float _currentDistSqrt = MathUtility.DistanceSqrtXZ(_hero.Pos, _atkTarget.Pos);
// 比较距离
if (_currentDistSqrt > _compareDistSqrt)
{
if ((StatusMgr.IsValid()
&& !StatusMgr.Instance.CanMove(_hero.ServerInstID)))
{
return;
}
// 移动至目标
_hero.MoveToTarget(_atkTarget, _compareDist);
// 判断是否需要冲锋
if (_hero.IsNeedRush(_currentDistSqrt))
{
_hero.StartRush();
}
return;
}
// 停止冲锋逻辑
_hero.StopRush();
if (IsSkillNeedMove(_skill.skillInfo.config.Tag, (E_SkillType)_skill.skillInfo.config.SkillType))
{
Vector3 _forward = MathUtility.ForwardXZ(_atkTarget.Pos, _hero.Pos);
_hero.destForward = _hero.Forward = _forward;
}
// 判断是否普通, 调用不同的接口
if (_hero.Behaviour.IsComAtk(_skill.id))
{
_hero.Behaviour.DoCommonAttack();
if (m_DecideSkill != null && m_DecideSkill.id == _skill.id)
{
m_DecideSkill = null;
}
if (_skill.id == m_UserClickSkillID)
{
m_UserClickSkillID = -1;
}
}
else
{
_hero.Behaviour.DoAttack(_skill);
if (m_DecideSkill != null && m_DecideSkill.id == _skill.id)
{
m_DecideSkill = null;
}
if (_skill.id == m_UserClickSkillID)
{
m_UserClickSkillID = -1;
}
}
m_LastUseSkillTime = Time.realtimeSinceStartup;
}
public sealed override void Exit()
{
GA_Hero _hero = PlayerDatas.Instance.hero;
if (_hero != null)
{
_hero.StopRush();
}
UserInputHandler.OnCirclePanelTouched -= OnActiveInterrupt;
UserInputHandler.OnClickedFloor -= OnClickFloor;
HeroBehaviour.OnUserClickSkill -= OnUserClickSkill;
OnExit();
}
public override bool IsOver()
{
GA_Hero _hero = PlayerDatas.Instance.hero;
return _hero == null
|| _hero.ActorInfo.serverDie
|| MapArea.IsInMapArea(_hero.CurMapArea, MapArea.E_Type.Safe)
|| MapArea.IsInMapArea(_hero.CurMapArea, MapArea.E_Type.RebornSafe);
}
protected virtual void OnActiveInterrupt()
{
//if (Time.realtimeSinceStartup - m_PauseStartTime > m_PauseResumeTime)
//{
// // 弹出挂机暂停提示
// SysNotifyMgr.Instance.ShowTip("HookPrompt_Manual");
//}
m_PauseStartTime = Time.realtimeSinceStartup;
m_State = 1;
GA_Hero _hero = PlayerDatas.Instance.hero;
m_NeedMoveToPos = false;
if (_hero != null)
{
_hero.StopRush();
}
Skill _skill = _hero.SkillMgr.CurCastSkill;
if (_skill != null)
{
if (!_skill.SkillCompelete)
{
m_UserClickSkillID = -1;
}
}
}
private Vector3 m_TargetPos;
private bool m_NeedMoveToPos;
protected virtual void OnClickFloor(Vector3 dest)
{
if (!StatusMgr.Instance.CanMove(PlayerDatas.Instance.PlayerId))
{
return;
}
GA_Hero _hero = PlayerDatas.Instance.hero;
m_PauseStartTime = Time.realtimeSinceStartup;
m_State = 1;
m_UserClickSkillID = -1;
if (_hero != null)
{
_hero.StopRush();
}
m_TargetPos = dest;
m_NeedMoveToPos = true;
}
protected virtual void OnUserClickSkill(int skillID)
{
m_UserClickSkillID = skillID;
//if (Time.realtimeSinceStartup - m_PauseStartTime > m_PauseResumeTime)
//{
// // 弹出挂机暂停提示
// SysNotifyMgr.Instance.ShowTip("HookPrompt_Manual");
//}
m_NeedMoveToPos = false;
}
private void OnLockTargetChanged(uint sid)
{
m_LockTargetSID = sid;
}
protected abstract void OnEnter();
protected abstract void OnExit();
protected abstract bool OnUpdate();
protected abstract GActorFight SelectTarget();
}