using UnityEngine; using System.Collections.Generic; using Snxxz.UI; using UnityEngine.Events; public class HeroBehaviour { TreasureSkillModel treasureSkillModel = null; TreasureSkillModel tsModel { get { return treasureSkillModel ?? (treasureSkillModel = ModelCenter.Instance.GetModel()); } } /// /// 挂机开始 /// 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 = FuncConfigConfig.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]; if(ArenaManager.isArenaPK) { for(int j = 0; j < m_Hero.JobSetup.ComAtkIdList.Length;j++) { _index = Mathf.Clamp(m_Hero.nextComAtkIndex, 0, m_Hero.JobSetup.ComAtkIdList.Length - 1); skillID = m_Hero.JobSetup.ComAtkIdList[_index]; bool bWork = true; for (int i = 0; i < GeneralDefine.WorkNotSkills.Length; i++) { skillID = m_Hero.JobSetup.ComAtkIdList[_index]; if (skillID != GeneralDefine.WorkNotSkills[i]) bWork = false; } if (bWork) break; } } } Skill _skill = m_Hero.SkillMgr.Get(skillID); bool _forceCast = false; SkillHelper.EffectValue _effectValue; if (SkillHelper.Instance.TryGetExpertSkillEvByMainSkillID(_skill.id, 4093, out _effectValue)) { _forceCast = true; } if ((!StatusMgr.Instance.CanAttack(m_Hero.ServerInstID, _skill.skillInfo.config) || m_Hero.IsStun()) && !_forceCast) { 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()) { float _range = m_Hero.JobSetup.SearchEnemyDist * Constants.F_DELTA; 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 || m_Hero.aiHandler.currentType == E_HeroAIType.KillUntilDie) { 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; if (OnUserClickSkill != null) { OnUserClickSkill(m_WillUsedSkillID); } } 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 = DungeonConfig.Get(_configID); if (_dgConfig != null && _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(bool force = false) { if (!force) { if (StageLoad.Instance.stageType == Stage.E_StageType.Dungeon) { if (DungeonStage.CurrentMapType != MapType.OpenCountry) { return; } } } if (!PreFightMission.Instance.IsFinished()) { return; } if (m_Hero.aiHandler.IsAuto()) { m_Hero.aiHandler.Stop(); } 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 > GeneralDefine.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)) { 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 && PlayerDatas.Instance.crossServerTick == 0) { return; } if (skill == null || GA_Hero.s_MapSwitching) { return; } if (m_Hero.ActorInfo.serverDie) { return; } // 可能有残留之前的伤害列表, 只在进入前端伤害的时候进行清除 if (ClientSceneManager.Instance.IsClientFightMode) { skill.ClearServerHurtList(); } skill.mainTarget = null; skill.targetPosition = Vector3.zero; skill.hitTargetList.Clear(); skill.hitClientBattleTargetList.Clear(); SoSkill _soSkill = ScriptableObjectLoader.LoadSoSkill(skill.skillInfo.config.SkillTypeID); 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 (PlayerDatas.Instance.baseData.AttackMode == (byte)E_AttackMode.Contest) { _hitTestLimit = 1; } 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()) { GActorFight _fight = m_Hero.LockTarget as GActorFight; if (_fight != null && _fight.CanAtked()) { _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); } } } if (_realDir == Vector3.zero) { _realDir = m_Hero.Root.forward; } 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, LayerUtility.WalkbleMask)) { _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) { GActorFight _fight = m_Hero.LockTarget as GActorFight; if (_fight != null && _fight.CanAtked()) { 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; GActorFight _fight = m_Hero.LockTarget as GActorFight; if (_fight != null && _fight.CanAtked()) { 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 && _npcFight.CanAtked()) { _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); if (_dir == Vector3.zero) { _dir = m_Hero.Root.forward; } 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.SelectTarget is GA_NpcClientFightNorm) { if (CheckCanAttackTarget(m_Hero.SelectTarget as GActorFight, skill, _soSkill, skill.targetPosition)) { if (PersonalEnemy.m_CBinSdDict.ContainsKey(m_Hero.SelectTarget.ServerInstID)) { //绑定木桩的算服务端 AddToHitTargetList(skill, m_Hero.SelectTarget); } else { AddToHitClientBattleTargetList(skill, m_Hero.SelectTarget); } } } else { if (CheckCanAttackTarget(m_Hero.SelectTarget as GActorFight, skill, _soSkill, skill.targetPosition)) { AddToHitTargetList(skill, m_Hero.SelectTarget); } } // 判断范围内的目标是否可以接入可攻击列表中 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)) { var _sid = _actorList[i].ServerInstID; if (PersonalEnemy.GetPersionEnemySID(_sid) != 0) { AddToHitTargetList(skill, _actorList[i]); } else { AddToHitClientBattleTargetList(skill, _actorList[i]); } } } else if (_actorList[i] is GA_NpcFightSgzcZZ) { 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; } } } ulong _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 = null; if (!AdventureStage.Instance.IsInAdventureStage #if UNITY_EDITOR && !RuntimeLogUtility.TEST_CLIENT_PVP #endif ) { // 创建发包协议 _b405 = new CB405_tagCMSuperAtk(); _b405.SkillID = (ushort)SkillHelper.Instance.GetSkillID(skill.skillInfo.config.SkillTypeID); _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(); if (ClientDungeonStageUtility.isClientDungeon) { _b405.PosX = (ushort)(GA_Hero.recordServerPos.x + GA_Hero.MapOffset.x); _b405.PosY = (ushort)(GA_Hero.recordServerPos.z + GA_Hero.MapOffset.z); _b405.TagPosX = (ushort)(GA_Hero.recordServerPos.x + GA_Hero.MapOffset.x); _b405.TagPosY = (ushort)(GA_Hero.recordServerPos.z + GA_Hero.MapOffset.z); } // Debug.LogFormat("释放了技能: {0},当前位置: {1} 目标位置: {2}", _b405.SkillID, new Vector2(_b405.PosX, _b405.PosY), new Vector2(_b405.TagPosX, _b405.TagPosY)); uint _bindID = 0; // 创建出攻击客户端攻击对象和服务端攻击对象 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; } _bindID = 0; ClientSceneManager.Instance.lastDeadPos = _target.Pos; if (_target is GA_NpcClientFightNorm || _target is GA_PVPClientPlayer) { _bindID = PersonalEnemy.GetPersionEnemySID(_target.ServerInstID); } // 选中对象都要生成服务端对象 CB405_tagCMSuperAtk.tagSkillPosHurtObj _hurtObj = new CB405_tagCMSuperAtk.tagSkillPosHurtObj(); _hurtObj.ObjID = _bindID == 0 ? _target.ServerInstID : _bindID; if (_target is GA_PlayerXMZZ || _target is GA_PVPClientPlayer || _target is GA_ILClientPlayer) { _hurtObj.ObjType = (byte)GameObjType.gotNPC; } else { _hurtObj.ObjType = (byte)_target.ActorType; } _serverHurtList.Add(_hurtObj); if (m_ClientFightEnable == false) { continue; } // 人物, 非小怪不计算伤害,不生成客户端数据 if (_target.ActorType == GameObjType.gotPlayer && !(_target is GA_PVPClientPlayer || _target is GA_ILClientPlayer)) { 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 && !(_target is GA_NpcFightSgzcZZ)) { GActorNpcFight _npc = _target as GActorNpcFight; if (_npc.NpcConfig.IsBoss != (int)E_MonsterType.Normal) { continue; } } if (_bindID != 0) { continue; } // 计算此次伤害 AttackHandler.CalculateDamage(m_Hero, _target, skill, i, ref _hurtValue, ref _attackType); // 服务端伤害赋值 _hurtObj.HurtHP = (uint)(_hurtValue % Constants.ExpPointValue); _hurtObj.HurtHPEx = (uint)(_hurtValue / Constants.ExpPointValue); _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.RealHurtHP = _hurtValue; _hurtObject.AttackType = _attackType; skill.hurtClientList.Add(_hurtObject); } if (_b405 != null) { _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, HurtHPEx = _serverHurtList[i].HurtHPEx }; } if (!ArenaManager.isArenaPK) { if (!CrossServerUtility.IsCrossServer()) { GameNetSystem.Instance.SendInfo(_b405); } else { GameNetSystem.Instance.SendToCrossServer(_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) { GActorFight _target = null; for (int i = 0; i < skill.hitClientBattleTargetList.Count; ++i) { _target = GAMgr.Instance.GetByCID(skill.hitClientBattleTargetList[i]) as GActorFight; if (PersonalEnemy.m_CBinSdDict.ContainsKey(_target.ServerInstID)) { continue; } 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); _hurtObject.HurtHP = _hurtValue; if (_target.ActorInfo.RealHp < _hurtValue) { _hurtObject.CurHP = 0; } else { _hurtObject.CurHP = _target.ActorInfo.RealHp - _hurtValue; } _hurtObject.RealHurtHP = _hurtValue; _hurtObject.AttackType = _attackType; _target.ActorInfo.SyncServerHp = _hurtObject.CurHP; var _clientNpc = _target as GA_NpcClientFightNorm; if (_clientNpc != null) { _clientNpc.BeAttacked(); } HandleExpertSkill(skill.id, m_Hero.ServerInstID, _target.ServerInstID); skill.hurtClntFightNpcList.Add(_hurtObject); if (_target.ActorInfo.RealHp <= _hurtValue && (_clientNpc == null || _clientNpc.lockHp <= 0)) { if (_clientNpc != null && _clientNpc.NpcConfig.AIType != 198) { _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 (_clientNpc != null && _clientNpc.belongEventID != -1) { ClientSceneManager.Instance.NpcDead(_clientNpc.belongEventID, _clientNpc, _clientNpc.NpcConfig.NPCID); } ClientSceneManager.Instance.lastDeadPos = _clientNpc.Pos; } // 前期战斗只发送石头人的 //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) { if (ArenaManager.isArenaPK) { soSkill.chkDistance = ArenaManager.ArenaCheckDistance; soSkill.chkRange = ArenaManager.ArenaCheckAngle; } // 取得可攻击的目标类型 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; GA_NpcFightSgzcZZ _sgzcRobot = actor as GA_NpcFightSgzcZZ; if (_fightNpc != null) { if (_fightNpc.NpcConfig.NPCType != (int)E_NpcType.PersonalEnemy) { 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,不能对其造成伤害"); Debug.LogFormat("|-- 对象类型不对"); return false; } } // 可攻击怪物 else if (_targetType == E_SkillCastTarget.CanAttackedMonster) { if (_fightNpc == null) { Debug.LogFormat("|-- 对象类型不对"); Debug.LogFormat(" |-- 目标: {0} 不是战斗npc,不能对其造成伤害"); return false; } if (_fightNpc.ActorType != GameObjType.gotNPC) { Debug.LogFormat("|-- 对象类型不对"); Debug.LogFormat(" |-- 目标: {0} 不是战斗npc,不能对其造成伤害"); 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 && _sgzcRobot == null) { Debug.LogFormat("|-- 对象类型不对"); Debug.LogFormat(" |-- 目标: {0} 不是战斗npc,不能对其造成伤害"); 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 = GeneralDefine.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}, range: {2}, distance: {3}", // soSkill.hitTestType, // m_Hero.Pos, // soSkill.chkRange, // soSkill.chkDistance); 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; } private void HandleExpertSkill(int skillID, uint aSid, uint tSid) { // if (!ClientSceneManager.Instance.IsClientFightMode) // { // return; // } // 增加一些buff效果 int _expertSkillId = 0; if (tsModel.TryGetExpertSkill(skillID, out _expertSkillId)) { var _skillInfo = SkillHelper.Instance.Get(_expertSkillId); SkillHelper.EffectValue _effectValue; // 不满足概率 if (_skillInfo.effectValue.TryGetValue(4004, out _effectValue)) { if (UnityEngine.Random.Range(0, 10000) > _effectValue.value1) { return; } } if (_skillInfo.config.SkillType == (int)E_SkillType.PassiveSustainedReduction) { StatusMgr.Instance.AddClientBuff(tSid, _expertSkillId, aSid, 0, _skillInfo.config.LastTime6); } } } }