using UnityEngine;
using System.Collections.Generic;
using TableConfig;
using Snxxz.UI;
using UnityEngine.Events;
public class HeroBehaviour
{
///
/// 挂机开始
///
public static event System.Action OnStopHandupAI;
///
/// 挂机结束
///
public static event System.Action OnStartHandupAI;
public static event UnityAction onCastSkill;
///
/// 当用户点击了技能按钮, 并切技能可以释放的时候调用
///
public static event UnityAction OnUserClickSkill;
public enum E_BehaviourState
{
None,
KillUntilDie,
Auto,
FixedPosition,
}
private int curComAtkIndex;
private float m_LastCommonAtkTime;
private bool m_ClientFightEnable = false;
private GA_Hero m_Hero;
private int m_WillUsedSkillID;
public HeroBehaviour(GA_Hero hero)
{
m_Hero = hero;
FuncConfigConfig _func = Config.Instance.Get("ClientFightEnable");
int _enable = int.Parse(_func.Numerical1);
m_ClientFightEnable = (_enable == 1);
}
private List _serverHurtList = new List();
public void DoPrepareCast(int skillID)
{
Skill _skill = m_Hero.SkillMgr.Get(skillID);
if (_skill.SkillPreparing == false)
{
return;
}
if (_skill.skillInfo.config.CastTime == 0)
{
return;
}
_skill.CSkillPrepareEnd = true;
}
public void StartKillUntilDieAI(int skillID = -1)
{
if (!DTC0403_tagPlayerLoginLoadOK.finishedLogin)
{
Debug.LogWarning("登陆流程尚未完成");
return;
}
MapTransferUtility.Instance.Clear();
// 安全区直接退出
if (MapArea.IsInMapArea(m_Hero.CurMapArea, MapArea.E_Type.Safe)
|| MapArea.IsInMapArea(m_Hero.CurMapArea, MapArea.E_Type.RebornSafe))
{
SysNotifyMgr.Instance.ShowTip("NoFighting");
return;
}
if (m_Hero.IsPolyMorph)
{
return;
}
if (m_Hero.aiHandler.currentType == E_HeroAIType.KillUntilDie)
{
if (IsComAtk(skillID))
{
return;
}
}
if (skillID < 0)
{
int _index = Mathf.Clamp(m_Hero.nextComAtkIndex, 0, m_Hero.JobSetup.ComAtkIdList.Length - 1);
skillID = m_Hero.JobSetup.ComAtkIdList[_index];
}
Skill _skill = m_Hero.SkillMgr.Get(skillID);
if (!StatusMgr.Instance.CanAttack(m_Hero.ServerInstID, _skill.skillInfo.config.SkillOfSeries))
{
return;
}
if (_skill.IsValid() == false)
{
return;
}
m_WillUsedSkillID = skillID;
if (_skill.skillInfo.config.CastTime > 0)
{
_skill.CSkillPrepareEnd = false;
}
GActorFight _fightTarget = m_Hero.LockTarget as GActorFight;
if (_fightTarget != null && _fightTarget.CanAtked())
{
m_Hero.SelectTarget = _fightTarget;
}
else
{
_fightTarget = m_Hero.SelectTarget as GActorFight;
if (_fightTarget != null && _fightTarget.CanAtked())
{
m_Hero.LockTarget = m_Hero.SelectTarget;
}
else
{
float _range = m_Hero.JobSetup.SearchEnemyDist * Constants.F_DELTA;
m_Hero.LockTarget = m_Hero.SelectTarget = GAMgr.Instance.FindAtkTarget(m_Hero.Pos, _range, 360);
_fightTarget = m_Hero.SelectTarget as GActorFight;
}
}
if (m_Hero.aiHandler.currentType == E_HeroAIType.None)
{
byte _type = (byte)E_HeroAIType.KillUntilDie;
KillUntilDieData _data = m_Hero.aiHandler.aiData[_type] as KillUntilDieData;
if (_fightTarget != null)
{
_data.targetServerInstID = _fightTarget.ServerInstID;
}
_data.defaultSkillID = m_WillUsedSkillID;
m_Hero.aiHandler.currentType = E_HeroAIType.KillUntilDie;
}
else
{
if (OnUserClickSkill != null)
{
OnUserClickSkill(m_WillUsedSkillID);
}
}
}
public void StopKillUntilDieAI()
{
if (m_Hero.aiHandler.currentType == E_HeroAIType.KillUntilDie)
{
m_Hero.aiHandler.currentType = E_HeroAIType.None;
}
}
public void StartHandupAI()
{
if (!DTC0403_tagPlayerLoginLoadOK.finishedLogin)
{
Debug.LogWarning("登陆流程尚未完成");
return;
}
MapTransferUtility.Instance.Clear();
// 安全区直接退出
if (MapArea.IsInMapArea(m_Hero.CurMapArea, MapArea.E_Type.Safe)
|| MapArea.IsInMapArea(m_Hero.CurMapArea, MapArea.E_Type.RebornSafe))
{
SysNotifyMgr.Instance.ShowTip("NoFighting");
//
return;
}
if (PreFightMission.Instance.IsFinished() == false)
{
return;
}
m_Hero.aiHandler.currentType = E_HeroAIType.NormalAuto;
// 判断是什么副本类型
DungeonModel _dgModel = ModelCenter.Instance.GetModel();
int _dataMapID = _dgModel.GetDataMapIdByMapId(PlayerDatas.Instance.baseData.MapID);
if (_dataMapID != 0)
{
int _configID = _dataMapID * 10 + _dgModel.mission.lineID;
DungeonConfig _dgConfig = Config.Instance.Get(_configID);
if (_dgConfig.AutomaticATK > 1)
{
m_Hero.aiHandler.currentType = (E_HeroAIType)_dgConfig.AutomaticATK;
}
}
//#if UNITY_EDITOR
// Debug.LogFormat("AI类型: {0}", m_Hero.aiHandler.currentType.ToString());
//#endif
if (OnStartHandupAI != null)
{
OnStartHandupAI();
}
}
public void StopHandupAI()
{
if (PreFightMission.Instance.IsFinished() == false)
{
return;
}
if (m_Hero.aiHandler.IsAuto())
{
m_Hero.aiHandler.currentType = E_HeroAIType.None;
}
if (OnStopHandupAI != null)
{
OnStopHandupAI();
}
m_Hero.forceAutoFightTime = Time.realtimeSinceStartup;
}
public bool IsComAtk(int skillID)
{
for (int i = 0; i < m_Hero.JobSetup.ComAtkIdList.Length; ++i)
{
if (skillID == m_Hero.JobSetup.ComAtkIdList[i])
{
return true;
}
}
return false;
}
public void ResetComAtkConnectTime()
{
m_LastCommonAtkTime = Time.realtimeSinceStartup;
}
public int DoCommonAttack()
{
if (Time.realtimeSinceStartup - m_LastCommonAtkTime > GeneralConfig.Instance.ResetComAtkTime)
{
m_Hero.nextComAtkIndex = 0;
}
if (m_Hero.State == E_ActorState.DaZuo
|| GA_Hero.s_MapSwitching
|| MapArea.IsInMapArea(m_Hero.CurMapArea, MapArea.E_Type.Safe)
|| MapArea.IsInMapArea(m_Hero.CurMapArea, MapArea.E_Type.RebornSafe))
{
return -1;
}
int skillId = 0;
Skill _skill = null;
if (m_Hero.nextComAtkIndex >= 0 && m_Hero.nextComAtkIndex < m_Hero.JobSetup.ComAtkIdList.Length)
{
curComAtkIndex = m_Hero.nextComAtkIndex;
}
else
{
curComAtkIndex = 0;
}
skillId = m_Hero.GetCommonSkillID(curComAtkIndex);
_skill = m_Hero.SkillMgr.Get(skillId);
if (!StatusMgr.Instance.CanAttack(m_Hero.ServerInstID, _skill.skillInfo.config.SkillOfSeries))
{
return -1;
}
if (_skill.IsValid() == false)
{
return -1;
}
int _chkIndex = curComAtkIndex == 0 ? m_Hero.JobSetup.ComAtkIdList.Length - 1 : curComAtkIndex - 1;
skillId = m_Hero.GetCommonSkillID(_chkIndex);
_skill = m_Hero.SkillMgr.Get(skillId);
if (_skill != null)
{
//Debug.LogFormat("取得技能: {0} 是否完成: {1}", skillId, _skill.SkillCompelete);
if (_skill.SkillCompelete)
{
skillId = m_Hero.GetCommonSkillID(curComAtkIndex);
_skill = m_Hero.SkillMgr.Get(skillId);
if (_skill != null)
{
DoAttack(_skill);
m_Hero.nextComAtkIndex = curComAtkIndex + 1;
}
}
}
return skillId;
}
public void DoAttack(Skill skill)
{
if (PlayerDatas.Instance.extersion.Tick == 0)
{
return;
}
if (!PreFightMission.Instance.IsFinished() && skill.id == 190)
{
}
else
{
if (skill == null || GA_Hero.s_MapSwitching)
{
return;
}
}
if (m_Hero.ActorInfo.serverDie)
{
return;
}
skill.mainTarget = null;
skill.targetPosition = Vector3.zero;
skill.hitTargetList.Clear();
skill.hitClientBattleTargetList.Clear();
SoSkill _soSkill = ScriptableObjectLoader.LoadSoSkill(skill.id);
if (_soSkill == null)
{
DebugEx.LogWarningFormat("技能: {0} 没有配置SoSkill文件, 将没有范围检测能力.", skill.id);
return;
}
// 确定此次可检测的目标数量
int _hitTestLimit = 1;
SkillHelper.EffectValue _effectValue;
if (skill.skillInfo.effectValue.TryGetValue(1200, out _effectValue))
{
_hitTestLimit = _effectValue.value1;
}
var _spSkillInfo = SkillHelper.Instance.GetSpSkill(skill.id);
if (_spSkillInfo != null)
{
for (int i = 0; i < _spSkillInfo.Count; ++i)
{
if (_spSkillInfo[i].effectValue.TryGetValue(4036, out _effectValue))
{
_hitTestLimit += _effectValue.value1;
#if UNITY_EDITOR
if (RuntimeLogUtility.s_SkillEffectLog)
{
Debug.LogFormat("技能 {0} 触发了效果 {1} , _hitTestLimit 增加了 {2}", _spSkillInfo[i].config.SkillID, 4036, _effectValue.value1);
}
#endif
}
}
}
if (PreFightMission.Instance.IsFinished() == false)
{
_hitTestLimit = 10;
}
E_SkillCastType _castType = (E_SkillCastType)(skill.skillInfo.config.Tag % 10);
E_SkillCastTarget _targetType = (E_SkillCastTarget)(skill.skillInfo.config.Tag / 10);
if (UserInputHandler.isTouched)
{
m_Hero.Forward = m_Hero.destForward;
}
Vector3 _sourcePosition = m_Hero.Pos;
_sourcePosition.y = 0;
Vector3 _realDir = m_Hero.Forward;
if (skill.id == 190)
{
_realDir = m_Hero.destForward;
}
if (!UserInputHandler.isTouched)
{
if (m_Hero.aiHandler.IsAuto())
{
if (m_Hero.LockTarget != null)
{
_realDir = m_Hero.Forward = MathUtility.ForwardXZ(m_Hero.LockTarget.Pos, m_Hero.Pos);
}
else if (m_Hero.SelectTarget != null)
{
_realDir = m_Hero.Forward = MathUtility.ForwardXZ(m_Hero.SelectTarget.Pos, m_Hero.Pos);
}
}
}
Vector3 _targetPosition = m_Hero.Pos + _realDir * (skill.skillInfo.config.AtkDist * .5f);
_targetPosition.y = 0;
UnityEngine.AI.NavMeshHit _navMeshHit;
if (UnityEngine.AI.NavMesh.Raycast(_sourcePosition, _targetPosition, out _navMeshHit, -1))
{
_targetPosition = _navMeshHit.position;
}
_targetPosition.y = m_Hero.Pos.y;
skill.targetPosition = _targetPosition;
// 如果技能是对地的技能, 则基准点应该为目标
// 没有目标则基准点为技能的施法距离
if (_castType == E_SkillCastType.Ground)
{
if (skill.skillInfo.config.Skillactmark != GAStaticDefine.Act_Roll
&& skill.skillInfo.config.AtkType != (int)E_AtkType.FlashMove)
{
if (m_Hero.LockTarget != null)
{
skill.targetPosition = m_Hero.LockTarget.Pos;
}
else if (m_Hero.SelectTarget != null)
{
skill.targetPosition = m_Hero.SelectTarget.Pos;
}
}
}
else if (_castType == E_SkillCastType.NeedTarget)
{
Vector3 _dir;
float _radius = 0.5f;
if (m_Hero.LockTarget != null)
{
GActorNpcFight _npcFight = m_Hero.LockTarget as GActorNpcFight;
if (_npcFight != null)
{
_radius = _npcFight.NpcConfig.ModelRadius;
}
_dir = MathUtility.ForwardXZ(m_Hero.Pos, m_Hero.LockTarget.Pos);
skill.targetPosition = m_Hero.LockTarget.Pos + _dir * _radius;
skill.mainTarget = m_Hero.LockTarget as GActorFight;
}
else if (m_Hero.SelectTarget != null)
{
GActorNpcFight _npcFight = m_Hero.SelectTarget as GActorNpcFight;
if (_npcFight != null)
{
_radius = _npcFight.NpcConfig.ModelRadius;
}
_dir = MathUtility.ForwardXZ(m_Hero.Pos, m_Hero.SelectTarget.Pos);
skill.targetPosition = m_Hero.SelectTarget.Pos + _dir * _radius;
skill.mainTarget = m_Hero.SelectTarget as GActorFight;
}
}
else
{
if (skill.id != 190)
{
GActorNpcFight _npcFight = m_Hero.SelectTarget as GActorNpcFight;
if (m_Hero.SelectTarget != null
&& (m_Hero.SelectTarget.ActorType != GameObjType.gotNPC
|| (_npcFight != null && _npcFight.NpcConfig.IsBoss > 1)))
{
float _distSqrt2 = MathUtility.DistanceSqrtXZ(m_Hero.SelectTarget.Pos, skill.targetPosition);
float _chkDist = m_Hero.JobSetup.MoveLimitDist * Constants.F_DELTA;
float _chkDistSqrt = Mathf.Pow(_chkDist, 2);
if (_distSqrt2 > _chkDistSqrt)
{
Vector3 _dir = MathUtility.ForwardXZ(m_Hero.SelectTarget.Pos, m_Hero.Pos);
skill.targetPosition = m_Hero.SelectTarget.Pos + _dir * _chkDist;
}
}
}
}
if (m_Hero.SelectTarget != null)
{
// 检测复活buff是否存在
if (StatusMgr.Instance.IsInvincible(m_Hero.SelectTarget.ServerInstID))
{
SysNotifyMgr.Instance.ShowTip("PKFuHuo");
}
}
if (skill.targetPosition != Vector3.zero)
{
Vector3 _adjustPos = PathFinder.AdjustPosition(skill.targetPosition);
skill.targetPosition = new Vector3(_adjustPos.x, skill.targetPosition.y, _adjustPos.z);
}
if (!StatusMgr.Instance.CanMove(m_Hero.ServerInstID))
{
skill.targetPosition = m_Hero.Pos;
}
if (_targetType == E_SkillCastTarget.CanAttacked)
{
if (m_Hero.SelectTarget != null)
{
if (StatusMgr.Instance.IsInvincible(m_Hero.SelectTarget.ServerInstID))
{
GAStaticDefine.PopHp(m_Hero, m_Hero.SelectTarget, (int)HurtAttackType.Immune, 0);
}
}
}
// 判断当前目标是否可以加入可攻击列表中
if (m_Hero.LockTarget is GA_NpcClientFightNorm)
{
if (CheckCanAttackTarget(m_Hero.LockTarget as GActorFight, skill, _soSkill, skill.targetPosition))
{
AddToHitClientBattleTargetList(skill, m_Hero.LockTarget);
}
}
else
{
if (CheckCanAttackTarget(m_Hero.LockTarget as GActorFight, skill, _soSkill, skill.targetPosition))
{
AddToHitTargetList(skill, m_Hero.LockTarget);
}
}
// 判断范围内的目标是否可以接入可攻击列表中
List _actorList = GAMgr.Instance.GetAll();
_actorList.Sort((GActor a1, GActor a2) =>
{
float _distA1 = MathUtility.DistanceSqrtXZ(a1.Pos, skill.targetPosition);
float _distA2 = MathUtility.DistanceSqrtXZ(a2.Pos, skill.targetPosition);
if (_distA1 < _distA2)
{
return -1;
}
else if (_distA1 > _distA2)
{
return 1;
}
return 0;
});
for (int i = 0; i < _actorList.Count && skill.hitTargetList.Count + skill.hitClientBattleTargetList.Count < _hitTestLimit; ++i)
{
#if UNITY_EDITOR
if (RuntimeLogUtility.s_ForceOneEnemy && i > 0)
{
continue;
}
#endif
if (_actorList[i] is GA_NpcClientFightNorm)
{
if (CheckCanAttackTarget(_actorList[i] as GActorFight, skill, _soSkill, skill.targetPosition))
{
AddToHitClientBattleTargetList(skill, _actorList[i]);
}
}
else
{
if (CheckCanAttackTarget(_actorList[i] as GActorFight, skill, _soSkill, skill.targetPosition))
{
AddToHitTargetList(skill, _actorList[i]);
}
}
}
if (skill.hitTargetList.Count == 0 && skill.hitClientBattleTargetList.Count == 0)
{
if (_castType == E_SkillCastType.NeedTarget)
{
SysNotifyMgr.Instance.ShowTip("SkillSelectedTarget");
return;
}
}
m_Hero.OnHorse(0);
DTC0428_tagPlayerRideHorse.Send_tagPlayerRideHorse(false);
// 处理吟唱和蓄力类技能
if (skill.skillInfo.config.CastTime > 0)
{
if (m_Hero.SkillMgr.CurCastSkill != skill || m_Hero.SkillMgr.CurCastSkill.SkillCompelete)
{
// 带进度条技能只设置当前技能, 并不将其释放
m_Hero.SkillMgr.CastSkill(m_Hero.ServerInstID, skill.id);
skill.SkillPreparing = true;
m_Hero.NextAction = 200;
m_Hero.SkillMgr.DoingPrepareSkill = true;
}
}
else
{
if (skill.id == 190)
{
m_Hero.StopPathFind();
m_Hero.State = E_ActorState.Roll;
}
// 开始执行表现层技能逻辑
m_Hero.SkillMgr.CastSkill(m_Hero.ServerInstID, skill.id);
if (skill.skillInfo.config.Skillactmark > 0
&& skill.skillInfo.config.Skillactmark < 20)
{
switch (skill.skillInfo.config.Skillactmark)
{
case 10:
m_Hero.Play(GAStaticDefine.State_Attack1Hash, 0);
break;
case 11:
m_Hero.Play(GAStaticDefine.State_Attack2Hash, 0);
break;
case 12:
m_Hero.Play(GAStaticDefine.State_Attack3Hash, 0);
break;
case 13:
m_Hero.Play(GAStaticDefine.State_Attack4Hash, 0);
break;
}
m_LastCommonAtkTime = Time.realtimeSinceStartup;
}
else
{
m_Hero.NextAction = skill.skillInfo.config.Skillactmark;
switch (skill.skillInfo.config.Skillactmark)
{
case 21:
m_Hero.Play(GAStaticDefine.State_Skill21, 0);
break;
case 22:
m_Hero.Play(GAStaticDefine.State_Skill22, 0);
break;
case 23:
m_Hero.Play(GAStaticDefine.State_Skill23, 0);
break;
case 24:
m_Hero.Play(GAStaticDefine.State_Skill24, 0);
break;
case 25:
m_Hero.Play(GAStaticDefine.State_Skill25, 0);
break;
case 26:
m_Hero.Play(GAStaticDefine.State_Skill26, 0);
break;
case 27:
m_Hero.Play(GAStaticDefine.State_Skill27, 0);
break;
case 28:
m_Hero.Play(GAStaticDefine.State_Skill28, 0);
break;
case 29:
m_Hero.Play(GAStaticDefine.State_Skill29, 0);
break;
case 99:
m_Hero.Play(GAStaticDefine.State_RollHash, 0);
break;
}
}
}
uint _hurtValue = 0;
byte _attackType = 0;
if (PreFightMission.Instance.IsFinished())
{
if (_castType != E_SkillCastType.NeedTarget || skill.hitTargetList.Count > 0
|| skill.skillInfo.config.Skillactmark == GAStaticDefine.Act_Roll)
{
GActorFight _target = null;
// 创建发包协议
CB405_tagCMSuperAtk _b405 = new CB405_tagCMSuperAtk();
_b405.SkillID = (ushort)skill.id;
_b405.PosX = (ushort)(m_Hero.Pos.x * 2 + GA_Hero.MapOffset.x);
_b405.PosY = (ushort)(m_Hero.Pos.z * 2 + GA_Hero.MapOffset.z);
_b405.TagPosX = (ushort)(skill.targetPosition.x * 2 + GA_Hero.MapOffset.x);
_b405.TagPosY = (ushort)(skill.targetPosition.z * 2 + GA_Hero.MapOffset.z);
_b405.WorldTick = PlayerDatas.Instance.GetWorldTick();
_serverHurtList.Clear();
// Debug.LogFormat("释放了技能: {0},当前位置: {1} 目标位置: {2}", _b405.SkillID, new Vector2(_b405.PosX, _b405.PosY), new Vector2(_b405.TagPosX, _b405.TagPosY));
// 创建出攻击客户端攻击对象和服务端攻击对象
for (int i = 0; i < skill.hitTargetList.Count; ++i)
{
_target = GAMgr.Instance.GetByCID(skill.hitTargetList[i]) as GActorFight;
if (_target == null)
{
Debug.LogFormat("找到的目标对象: C:{0} 为空....", skill.hitTargetList[i]);
continue;
}
// 选中对象都要生成服务端对象
CB405_tagCMSuperAtk.tagSkillPosHurtObj _hurtObj = new CB405_tagCMSuperAtk.tagSkillPosHurtObj();
_hurtObj.ObjID = (uint)_target.ServerInstID;
if (_target is GA_PlayerXMZZ)
{
_hurtObj.ObjType = (byte)GameObjType.gotNPC;
}
else
{
_hurtObj.ObjType = (byte)_target.ActorType;
}
_serverHurtList.Add(_hurtObj);
if (m_ClientFightEnable == false)
{
continue;
}
// 人物, 非小怪不计算伤害,不生成客户端数据
if (_target.ActorType == GameObjType.gotPlayer)
{
GA_Player _player = _target as GA_Player;
if (_player != null)
{
if (_player.MovingState == E_MovingState.Ride)
{
_player.SwitchHorse(0);
}
}
continue;
}
if (_target.ActorType == GameObjType.gotNPC)
{
GActorNpcFight _npc = _target as GActorNpcFight;
if (_npc.NpcConfig.IsBoss != (int)E_MonsterType.Normal)
{
continue;
}
}
// 计算此次伤害
AttackHandler.CalculateDamage(m_Hero, _target, skill, i, ref _hurtValue, ref _attackType);
// 服务端伤害赋值
_hurtObj.HurtHP = _hurtValue;
_hurtObj.AttackType = _attackType;
if (_target.ActorInfo.Hp < _hurtValue)
{
_target.ActorInfo.SyncServerHp = 0;
}
else
{
_target.ActorInfo.SyncServerHp = _target.ActorInfo.Hp - _hurtValue;
}
_serverHurtList[_serverHurtList.Count - 1] = _hurtObj;
AttackHandler.HurtObjs _hurtObject = new AttackHandler.HurtObjs
{
ObjID = _target.ServerInstID,
ObjType = (byte)_target.ActorType,
clientInstID = _target.ClientInstID
};
// 客户端表现用伤害赋值
_hurtObject.HurtHP = _hurtValue;
_hurtObject.AttackType = _attackType;
skill.hurtClientList.Add(_hurtObject);
}
_b405.HurtCount = (ushort)_serverHurtList.Count;
_b405.HurtList = new CB405_tagCMSuperAtk.tagSkillPosHurtObj[_b405.HurtCount];
for (int i = 0; i < _b405.HurtCount; ++i)
{
_b405.HurtList[i] = new CB405_tagCMSuperAtk.tagSkillPosHurtObj()
{
ObjType = _serverHurtList[i].ObjType,
ObjID = _serverHurtList[i].ObjID,
AttackType = _serverHurtList[i].AttackType,
HurtHP = _serverHurtList[i].HurtHP
};
}
GameNetSystem.Instance.SendInfo(_b405);
#if UNITY_EDITOR
string _content = string.Format("# CB405_tagCMSuperAtk => {0} 使用技能 {1}",
m_Hero.ServerInstID,
skill.id);
RuntimeLogUtility.AddLog_Blue(_content);
#endif
}
}
if (skill.hitClientBattleTargetList.Count > 0)
{
GA_NpcClientFightNorm _target = null;
for (int i = 0; i < skill.hitClientBattleTargetList.Count; ++i)
{
_target = GAMgr.Instance.GetByCID(skill.hitClientBattleTargetList[i]) as GA_NpcClientFightNorm;
AttackHandler.HurtObjs _hurtObject = new AttackHandler.HurtObjs
{
ObjID = (uint)_target.ServerInstID,
ObjType = (byte)_target.ActorType,
clientInstID = _target.ClientInstID
};
AttackHandler.CalculateDamage(m_Hero, _target, skill, i, ref _hurtValue, ref _attackType);
if (_target.NpcConfig.NPCID == 1007)
{
if (_target.ActorInfo.RealHp < _hurtValue)
{
_hurtValue = (uint)(_target.ActorInfo.RealHp - 10);
}
}
_hurtObject.HurtHP = _hurtValue;
_hurtObject.AttackType = _attackType;
skill.hurtClntFightNpcList.Add(_hurtObject);
if (_target.ActorInfo.RealHp <= _hurtValue)
{
_target.KillerServerInstID = m_Hero.ServerInstID;
_target.ActorInfo.serverDie = true;
GAMgr.Instance.ServerDie(_target.ServerInstID);
GAMgr.Instance.DoDelayDie(_target);
if (m_Hero.LockTarget == _target)
{
m_Hero.LockTarget = null;
}
if (m_Hero.SelectTarget == _target)
{
m_Hero.SelectTarget = null;
}
// 前期战斗只发送石头人的
if (1000 == _target.NpcConfig.NPCID)
{
CA225_tagCMClientTaskCount _a225 = new CA225_tagCMClientTaskCount
{
CountID = (uint)_target.NpcConfig.NPCID
};
GameNetSystem.Instance.SendInfo(_a225);
}
}
}
}
if (onCastSkill != null)
{
onCastSkill(skill.id);
}
}
private void AddToHitTargetList(Skill skill, GActor target)
{
if (skill.hitTargetList.Contains(target.ClientInstID))
{
return;
}
skill.hitTargetList.Add(target.ClientInstID);
}
private void AddToHitClientBattleTargetList(Skill skill, GActor target)
{
if (skill.hitClientBattleTargetList.Contains(target.ClientInstID))
{
return;
}
skill.hitClientBattleTargetList.Add(target.ClientInstID);
}
private bool CheckCanAttackTarget(GActorFight actor, Skill skill, SoSkill soSkill, Vector3 basePosition)
{
// 取得可攻击的目标类型
E_SkillCastTarget _targetType = (E_SkillCastTarget)(skill.skillInfo.config.Tag / 10);
E_SkillCastType _castType = (E_SkillCastType)(skill.skillInfo.config.Tag % 10);
if (actor == null
|| actor.ActorInfo.serverDie)
{
return false;
}
if (actor.ServerInstID == m_Hero.ServerInstID)
{
return false;
}
GActorNpcFight _fightNpc = actor as GActorNpcFight;
if (_fightNpc != null)
{
if (_fightNpc.Group != E_ActorGroup.Enemy
|| _fightNpc.NpcConfig.Country == 1)
{
return false;
}
}
//Debug.LogFormat(" |-- 只对: {0} 伤害的技能", _targetType);
// 只对小怪进行伤害的类型
if (_targetType == E_SkillCastTarget.Monster)
{
// 不是怪物类型无法伤害
if (_fightNpc == null)
{
//Debug.LogFormat(" |-- 目标: {0} 不是战斗npc,不能对其造成伤害", _monster.ServerObjID);
//Debug.LogFormat("|-- 对象类型不对: {0}", actor.ServerObjID);
return false;
}
}
// 可攻击怪物
else if (_targetType == E_SkillCastTarget.CanAttackedMonster)
{
if (_fightNpc == null)
{
//Debug.LogFormat("|-- 对象类型不对: {0}", actor.ServerObjID);
//Debug.LogFormat(" |-- 目标: {0} 不是战斗npc,不能对其造成伤害", _monster.ServerObjID);
return false;
}
if (_fightNpc.ActorType != GameObjType.gotNPC)
{
//Debug.LogFormat("|-- 对象类型不对: {0}", actor.ServerObjID);
//Debug.LogFormat(" |-- 目标: {0} 不是战斗npc,不能对其造成伤害", _monster.ServerObjID);
return false;
}
}
// 可攻击对象类型
else if (_targetType == E_SkillCastTarget.CanAttacked)
{
if (actor.ActorType == GameObjType.gotPlayer)
{
GA_Player _player = actor as GA_Player;
if (_player != null)
{
if (!_player.CanAtked())
{
return false;
}
}
}
else
{
if (_fightNpc == null)
{
//Debug.LogFormat("|-- 对象类型不对: {0}", actor.ServerObjID);
//Debug.LogFormat(" |-- 目标: {0} 不是战斗npc,不能对其造成伤害", _monster.ServerObjID);
return false;
}
}
}
// -----------------------
// 这里检测是否在技能释放范围内
if (soSkill != null)
{
if (soSkill.chkDistance == 0)
{
//Debug.LogFormat("|-- 配置的检测范围为空: {0}", skill.id);
return false;
}
float _chkDistance = soSkill.chkDistance;
if (!PreFightMission.Instance.IsFinished())
{
_chkDistance = GeneralConfig.Instance.PrefightAtkRange;
}
SkillHelper.EffectValue _effectValue;
List _spSkillInfo = SkillHelper.Instance.GetSpSkill(skill.id);
if (_spSkillInfo != null)
{
for (int i = 0; i < _spSkillInfo.Count; ++i)
{
if (_spSkillInfo[i].effectValue.TryGetValue(4045, out _effectValue))
{
_chkDistance += (_effectValue.value1 * .5f);
#if UNITY_EDITOR
if (RuntimeLogUtility.s_SkillEffectLog)
{
Debug.LogFormat("技能 {0} 触发了效果 {1} , 搜怪范围 增加了 {2}", _spSkillInfo[i].config.SkillID, 4045, (_effectValue.value1 * .5f));
}
#endif
}
}
}
Vector3 _centerPos = m_Hero.Pos;
if (soSkill.hitTestType == E_HitTestType.Sector
&& soSkill.chkRange == 0)
{
// 非自身的时候,执行目标点索引
if (_castType != E_SkillCastType.None)
{
_centerPos = skill.targetPosition;
}
}
// 默认取1的范围内的怪, 没有的情况再判断范围
float _defaultCircleDisSqrt = MathUtility.DistanceSqrtXZ(_centerPos, actor.Pos);
if (_defaultCircleDisSqrt > 1)
{
//Debug.LogFormat(" |-- 检测方式为: {0}, center: {1}, forward: {2}, range: {3}, distance: {4}, target: {5}",
// soSkill.hitTestType,
// m_Hero.Pos,
// m_Hero.forwardDestination,
// soSkill.chkRange,
// soSkill.chkDistance,
// actor.Position);
if (soSkill.hitTestType == E_HitTestType.Rect)
{
if (!CollisionUtility.IsPointInRectangle(_centerPos, m_Hero.destForward,
soSkill.chkRange, soSkill.chkDistance,
actor.Pos))
{
//Debug.LogFormat("|-- 对象不再范围内: {0}", actor.ServerObjID);
//Debug.LogFormat(" |-- 目标: {0} 不在检测范围内", actor.ServerObjID);
return false;
}
}
else if (soSkill.hitTestType == E_HitTestType.Sector)
{
int _chkAngle = soSkill.chkRange == 0 ? 360 : soSkill.chkRange;
if (!CollisionUtility.IsPointInSector2(_centerPos, m_Hero.destForward,
soSkill.chkDistance, _chkAngle,
actor.Pos))
{
//Debug.LogFormat("|-- 对象不再范围内: {0}", actor.ServerObjID);
//Debug.LogFormat(" |-- 目标: {0} 不在检测范围内", actor.ServerObjID);
return false;
}
}
}
}
return true;
}
}