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; } }