using UnityEngine; using System.Collections; using System.Collections.Generic; using vnxbqy.UI; public class MapTransferUtility : SingletonMonobehaviour { public static UnityEngine.Events.UnityAction s_OnHeroLeaveFuncNpc; public static UnityEngine.Events.UnityAction s_OnHeroStartMoveToNPC; public static int tagetNPCforRush = 0; //用于冲锋 public enum E_MapTransferDoType { None, DaZuo, Npc, Fight, } private E_MapTransferDoType m_MapTransferType; public E_MapTransferDoType MapTransferDoType { get { return m_MapTransferType; } set { m_MapTransferType = value; #if UNITY_EDITOR // Debug.LogFormat("设置方式: {0}", m_MapTransferType); #endif } } private float m_ClosedFuncNpcDistSqrt; public float conversationDistSqrt; private List m_MapTransportCfgs; private List m_TransMapLine = new List(); public void Initialize() { FuncConfigConfig _funcModel = FuncConfigConfig.Get("ConversationDistanc"); if (_funcModel != null) { conversationDistSqrt = float.Parse(_funcModel.Numerical1); conversationDistSqrt *= conversationDistSqrt; m_ClosedFuncNpcDistSqrt = float.Parse(_funcModel.Numerical2); m_ClosedFuncNpcDistSqrt *= m_ClosedFuncNpcDistSqrt; } m_MapTransportCfgs = maptransportConfig.GetValues(); m_TransMapLine.Clear(); var _id = 122549; var _configs = maptransportConfig.Get(_id); m_TransMapLine.Add(_configs.OriginalMapID); while (true) { if (!m_TransMapLine.Contains(_configs.TargetMapID)) { m_TransMapLine.Add(_configs.TargetMapID); } else { break; } var _nextID = GetMapID(_configs.TargetMapID, _configs.OriginalMapID); if (_nextID == -1) { break; } _configs = maptransportConfig.Get(_nextID); } conversationDistSqrt = conversationDistSqrt == 0 ? 6 : conversationDistSqrt; m_ClosedFuncNpcDistSqrt = m_ClosedFuncNpcDistSqrt == 0 ? 1 : m_ClosedFuncNpcDistSqrt; } private int GetMapID(int start, int target) { var _configs = maptransportConfig.GetValues(); foreach (var _cfg in _configs) { if (_cfg.OriginalMapID == start && _cfg.TargetMapID != target) { return _cfg.TransportID; } } return -1; } private int GetNextTransportID(int start, int end) { foreach (var _cfg in m_MapTransportCfgs) { if (_cfg.OriginalMapID == start && _cfg.TargetMapID == end) { return _cfg.TransportID; } } return -1; } #region 打坐 public void MoveToDazuo(int mapID) { GA_Hero _hero = PlayerDatas.Instance.hero; _hero.Behaviour.StopHandupAI(); _hero.Behaviour.StopKillUntilDieAI(); if (_hero.SkillMgr.CurCastSkill != null) { if (_hero.SkillMgr.CurCastSkill.SkillCompelete == false) { return; } } if (_hero.IsRushing) { return; } MapTransferDoType = E_MapTransferDoType.DaZuo; MapModel _model = ModelCenter.Instance.GetModel(); if (mapID != PlayerDatas.Instance.baseData.MapID) { if (_model.IsMapUnlocked(mapID) == false) { SysNotifyMgr.Instance.ShowTip("Map_Delivery"); return; } _model.RequestMapTransport(mapID); } else { if (MapArea.IsInMapArea(_hero.CurMapArea, MapArea.E_Type.Dazuo)) { Debug.Log("当前已经在打坐区域内了"); return; } List _list; if (DungeonStage.s_MapAreaDict.TryGetValue(MapArea.E_Type.Dazuo, out _list) == false) { Debug.LogWarningFormat("地图没有打坐区域, 是否配置出错?"); return; } if (_list == null || _list.Count == 0) { Debug.LogWarningFormat("地图没有打坐区域, 是否配置出错?"); return; } float _x = Random.Range(_list[0].startPosition.x, _list[0].endPosition.x); float _z = Random.Range(_list[0].startPosition.z, _list[0].endPosition.z); Vector3 _destPos = new Vector3(_x, _hero.Pos.y, _z); _hero.Behaviour.StopHandupAI(); _hero.Behaviour.StopKillUntilDieAI(); _hero.MoveToPosition(_destPos); } } #endregion #region npc public int NpcID { get; set; } #endregion bool m_DelayMoveToNPC = false; int m_TempNpcID; bool m_DelayMoveToPos = false; Vector3 m_TempPos = Vector3.zero; private void Update() { if (m_DelayMoveToNPC) { GA_Hero _hero = PlayerDatas.Instance.hero; if (_hero.IsIdle() && !StageLoad.Instance.isLoadingScene) { _hero.Behaviour.StopHandupAI(); _hero.Behaviour.StopKillUntilDieAI(); _hero.StopRush(); _hero.LockTarget = null; MoveToNPC(m_TempNpcID); m_DelayMoveToNPC = false; } } if (m_DelayMoveToPos) { GA_Hero _hero = PlayerDatas.Instance.hero; if (_hero.IsIdle()) { _hero.Behaviour.StopHandupAI(); _hero.Behaviour.StopKillUntilDieAI(); _hero.StopRush(); _hero.LockTarget = null; _hero.MoveToPosition(new Vector3(m_TempPos.x * 0.5f, 0f, m_TempPos.y * 0.5f)); m_DelayMoveToPos = false; } } } public int lastMoveToWorldBossNpcID; public float lastMoveToWorldBossTime; private bool m_SwitchMapFinished = true; private int m_MapID; public void CheckMap(int mapID, bool force = false) { if (m_MapID == mapID || force) { m_SwitchMapFinished = true; } } public bool forceMove = false; private struct MoveToData { public int npcID; public int sid; public bool directTransfer; } public void MoveToNPC(int _npcID, int _sid = 0, bool direct = false) { #if UNITY_EDITOR Debug.LogFormat("想要切换至目标npc: {0}", _npcID); #endif StopCoroutine("CoMoveToNPC"); var _data = new MoveToData { npcID = _npcID, sid = _sid, directTransfer = direct }; StartCoroutine("CoMoveToNPC", _data); } private IEnumerator CoMoveToNPC(MoveToData data) { var _hero = PlayerDatas.Instance.hero; if (_hero == null) { yield break; } var sid = data.sid; NpcID = data.npcID; MapTransferDoType = E_MapTransferDoType.Npc; tagetNPCforRush = NpcID; Vector3 _destPostion = Vector3.zero; var _curStage = StageLoad.Instance.currentStage as DungeonStage; if (AdventureStage.Instance.IsInAdventureStage) { GActor _actor = GAMgr.Instance.GetCloserNPC(_hero.Pos, NpcID); if (_actor != null) { MoveToExistNpc(NpcID, _actor); yield break; } } // 判断是否能够得到到达指定点 // 获取NPC位置数据 GAStaticDefine.NPCLocation _npcLocation; var _findLocation = GAStaticDefine.TryGetMapNPCLocation(NpcID, out _npcLocation); if (!_findLocation) { #if UNITY_EDITOR Debug.LogWarningFormat("需要传送至的npcid有错,无法在mapnpc表中查询到, id: {0}", NpcID); #endif // 如果找不到配置, 可能为客户端战斗配置的刷怪逻辑 // 由于可能有回包慢问题, 这里等待 yield return WaitingForSecondConst.WaitMS200; GActor _npc = GAMgr.Instance.GetCloserNPC(_hero.Pos, NpcID); if (_npc != null) { _destPostion = _npc.Pos; NpcID = NpcID; MapTransferDoType = E_MapTransferDoType.Npc; while (true) { if (PathFinder.WalkAble(_hero.Pos, _destPostion)) { break; } Vector3 _nextPos; if (!ClientSceneManager.Instance.AAA(_hero.Pos, _destPostion, out _nextPos)) { Debug.LogErrorFormat("移动至NPC: {0} 时找不到任何跳跃点, NextPos: {1}", NpcID, _nextPos); break; } tagetNPCforRush = 0; float _dis = MathUtility.DistanceSqrtXZ(_hero.Pos, _nextPos); while (_dis > 0.01f) { _dis = MathUtility.DistanceSqrtXZ(_hero.Pos, _nextPos); _hero.MoveToPosition(_nextPos); yield return null; } while (!GA_Hero.s_Flying) { yield return null; } while (GA_Hero.s_Flying) { yield return null; } } _hero.MoveToPosition(_destPostion, 1); yield break; } } else { // 判断是否在同一张地图中 if (_npcLocation.mapId != PlayerDatas.Instance.baseData.MapID) { if (data.directTransfer) { _MoveToNPC(NpcID, sid); } else { int _idx1 = m_TransMapLine.IndexOf(PlayerDatas.Instance.baseData.MapID); int _idx2 = m_TransMapLine.IndexOf(_npcLocation.mapId); bool _valid = true; if (_idx1 == -1) { _valid = false; Debug.LogFormat("没有传送点: {0}", PlayerDatas.Instance.baseData.MapID); } if (_idx2 == -1) { _valid = false; Debug.LogFormat("没有传送点: {0}", _npcLocation.mapId); } if (_valid) { int _nextMapID = -1; // 顺序 if (_idx2 > _idx1) { _nextMapID = m_TransMapLine[_idx1 + 1]; } // 逆序 else { _nextMapID = m_TransMapLine[_idx1 - 1]; } // 先寻找传送点 int _transportID = GetNextTransportID(PlayerDatas.Instance.baseData.MapID, _nextMapID); if (_transportID != -1) { if (_curStage) { Vector3 _moveToPos; if (_curStage.TryGetTransportPosition(_transportID, out _moveToPos)) { while (true) { if (PathFinder.WalkAble(_hero.Pos, _moveToPos)) { break; } Vector3 _nextPos; if (!ClientSceneManager.Instance.AAA(_hero.Pos, _moveToPos, out _nextPos)) { Debug.LogErrorFormat("移动至NPC: {0} 时找不到任何跳跃点", NpcID); break; } tagetNPCforRush = 0; float _dis = MathUtility.DistanceSqrtXZ(_hero.Pos, _nextPos); while (_dis > 0.01f) { _dis = MathUtility.DistanceSqrtXZ(_hero.Pos, _nextPos); _hero.MoveToPosition(_nextPos); yield return null; } while (!GA_Hero.s_Flying) { yield return null; } while (GA_Hero.s_Flying) { yield return null; } } _hero.MoveToPosition(_moveToPos); yield break; } } } } _MoveToNPC(NpcID, sid); } yield break; } _destPostion = new Vector3(_npcLocation.position.x, 0, _npcLocation.position.y); } if (_destPostion == Vector3.zero) { Debug.LogErrorFormat("移动至NPC: {0} 时找不到一个可以到达的点.", NpcID); yield break; } float _dist = 0.01f; var _config = NPCConfig.Get(NpcID); if (_config != null) { _dist = Mathf.Max(GeneralDefine.CloseNpcDist + _config.ModelRadius - 0.3f, 0); } if (PathFinder.WalkAble(_hero.Pos, _destPostion, _dist) || NpcID == 32504001) { while (true) { Vector3 _nextPos = ClientSceneManager.Instance.GetNext1(_hero.Pos, _destPostion); if (_nextPos == Vector3.zero) { break; } ClientSceneManager.Instance.ExitTransStatus(); float _dis = MathUtility.DistanceSqrtXZ(_hero.Pos, _nextPos); while (_dis > 0.01f) { _dis = MathUtility.DistanceSqrtXZ(_hero.Pos, _nextPos); _hero.MoveToPosition(_nextPos); yield return null; } while (!GA_Hero.s_Flying) { yield return null; } while (GA_Hero.s_Flying) { yield return null; } } _MoveToNPC(NpcID, sid); } else { while (true) { if (PathFinder.WalkAble(_hero.Pos, _destPostion, _dist)) { break; } Vector3 _nextPos; if (!ClientSceneManager.Instance.AAA(_hero.Pos, _destPostion, out _nextPos)) { Debug.LogErrorFormat("移动至NPC: {0} 时找不到任何跳跃点, NextPos: {1}", NpcID, _nextPos); break; } tagetNPCforRush = 0; float _dis = MathUtility.DistanceSqrtXZ(_hero.Pos, _nextPos); if (_dis <= 0.01f) { ClientSceneManager.Instance.ExitTransStatus(); } while (_dis > 0.01f) { _dis = MathUtility.DistanceSqrtXZ(_hero.Pos, _nextPos); _hero.MoveToPosition(_nextPos); yield return null; } while (!GA_Hero.s_Flying) { yield return null; } while (GA_Hero.s_Flying) { yield return null; } } _MoveToNPC(NpcID, sid); } } private void _MoveToNPC(int npcID, int sid = 0) { if (npcID != NpcID) { forceMove = false; } if (sid != 0) { GActor _actor = GAMgr.Instance.GetBySID((uint)sid); if (_actor != null) { NpcID = npcID; MapTransferDoType = E_MapTransferDoType.Npc; MoveToExistNpc(npcID, _actor); return; } } NPCConfig _config = NPCConfig.Get(npcID); if (_config == null) { return; } m_DelayMoveToNPC = false; m_TempNpcID = 0; GA_Hero _hero = PlayerDatas.Instance.hero; if (_hero == null) { return; } NpcID = npcID; MapTransferDoType = E_MapTransferDoType.Npc; // 获取NPC位置数据 GAStaticDefine.NPCLocation _npcLocation; var _findLocation = GAStaticDefine.TryGetMapNPCLocation(npcID, out _npcLocation); if (!_findLocation) { #if UNITY_EDITOR Debug.LogWarningFormat("需要传送至的npcid有错,无法在mapnpc表中查询到, id: {0}", npcID); #endif } if (_npcLocation.mapId != PlayerDatas.Instance.baseData.MapID) { if (PlayerDatas.Instance.extersion.pkState == 1) { SysNotifyMgr.Instance.ShowTip("PK_Leave"); return; } } _hero.Behaviour.StopHandupAI(true); _hero.Behaviour.StopKillUntilDieAI(); _hero.LockTarget = null;// 强制清空当前锁定目标 if ((_hero.SkillMgr.CurCastSkill != null && !_hero.SkillMgr.CurCastSkill.SkillCompelete) || _hero.IsRushing || StageLoad.Instance.isLoadingScene) { m_DelayMoveToNPC = true; m_TempNpcID = npcID; return; } MapModel _model = ModelCenter.Instance.GetModel(); GActor _npc = null; // 加入判断是否世界BOSS判断 var isWorldBoss = WorldBossConfig.Has(npcID); var isCrossServerBoss = CrossServerBossConfig.Has(npcID); var isBossHome = BossHomeConfig.Has(npcID); //if (_findLocation) //{ // var _mapConfig = MapConfig.Get(_npcLocation.mapId); // // 中立地图 // if (_mapConfig.Camp == 5 && (isWorldBoss || isCrossServerBoss)) // { // if (_npcLocation.mapId == PlayerDatas.Instance.baseData.MapID) // { // Send_WorldTransfer(_npcLocation.mapId, // new Vector3(_hero.Pos.x * 2, 0, _hero.Pos.z * 2), // MapTransferType.WorldTransport, 0, npcID); // } // else // { // Send_WorldTransfer(_npcLocation.mapId, // new Vector3(_mapConfig.BornPoints[0].x, 0, _mapConfig.BornPoints[0].y), // MapTransferType.WorldTransport, 0, npcID); // } // return; // } //} // 增加一项针对BOSS的逻辑判断 if (_config.NPCType == (int)E_NpcType.Fight) { var _boss = GAMgr.Instance.GetCloserNPC(_hero.Pos, npcID) as GA_NpcFightBoss; if (_boss != null) { _hero.MoveToPosition(_boss.Pos, _npcLocation.scope); _hero.SelectTarget = _hero.LockTarget = _boss; return; } } bool _isBoss = isWorldBoss || isCrossServerBoss || isBossHome; if (_isBoss && _findLocation) { // Debug.LogFormat("目标是boss"); _npc = GAMgr.Instance.GetCloserNPC(_hero.Pos, npcID); if (_npc != null) { //Debug.LogFormat(" |-- 在视野内"); _hero.MoveToPosition(_npc.Pos, _npcLocation.scope); } else { //Debug.LogFormat(" |-- 不在视野内"); var _mapConfig = MapConfig.Get(_npcLocation.mapId); var _lineID = 255; if (isBossHome) { _lineID = BossInfoConfig.Get(npcID).RefreshLine - 1; } var _forceTransfer = false; // 如果不是处于相同地图, 则切图 if (_npcLocation.mapId != PlayerDatas.Instance.baseData.MapID || _forceTransfer) { if (PlayerDatas.Instance.extersion.pkState == 1) { SysNotifyMgr.Instance.ShowTip("PK_Leave"); return; } //Debug.LogFormat(" |-- 不在本地图"); var mapId = _npcLocation.mapId; var position = new Vector3(_mapConfig.BornPoints[0].x, 0, _mapConfig.BornPoints[0].y); Send_WorldTransfer(mapId, position, MapTransferType.WorldTransport, (byte)_lineID, npcID); forceMove = true; if (BossJiaLineUtility.Instance.IsShuntBoss(npcID)) { BossJiaLineUtility.Instance.makeJiaLineTimes = 1; } m_SwitchMapFinished = false; m_MapID = _npcLocation.mapId; } else { //boss之家存在层数,但不存在分流 if (PlayerDatas.Instance.baseData.MapID != BossHomeModel.BOSSHOME_MAPID) { if (((lastMoveToWorldBossNpcID == npcID && Time.realtimeSinceStartup - lastMoveToWorldBossTime < 60) && PlayerDatas.Instance.baseData.FBID == 0) || (BossJiaLineUtility.Instance.showJiaLine && ModelCenter.Instance.GetModel().IsBossAlive(npcID)) || forceMove) { //PlayerDatas.Instance.baseData.FBID); Vector3 _destPos = new Vector3(_npcLocation.position.x, _hero.Pos.y, _npcLocation.position.y); _hero.MoveToPosition(_destPos, _npcLocation.scope); forceMove = false; } else { // 处于相同地图 if (!BossJiaLineUtility.Instance.HasSawBossRecently(npcID)) { if (BossJiaLineUtility.Instance.IsShuntBoss(npcID)) { BossJiaLineUtility.Instance.makeJiaLineTimes = 1; } //Debug.LogFormat(" |-- 非想去的boss记录,或则见到boss时差超过60秒"); Send_WorldTransfer(_npcLocation.mapId, new Vector3(_hero.Pos.x * 2, 0, _hero.Pos.z * 2), MapTransferType.WorldTransport, (byte)_lineID, npcID); forceMove = true; } else { Vector3 _destPos = new Vector3(_npcLocation.position.x, _hero.Pos.y, _npcLocation.position.y); _hero.MoveToPosition(_destPos, _npcLocation.scope); } } } else { //BOSS之家 if (_lineID != PlayerDatas.Instance.baseData.FBID) { var mapId = _npcLocation.mapId; var position = new Vector3(_mapConfig.BornPoints[0].x, 0, _mapConfig.BornPoints[0].y); Send_WorldTransfer(mapId, position, MapTransferType.WorldTransport, (byte)_lineID, npcID); } else { Vector3 _destPos = new Vector3(_npcLocation.position.x, _hero.Pos.y, _npcLocation.position.y); _hero.MoveToPosition(_destPos, _npcLocation.scope); } } } lastMoveToWorldBossTime = Time.realtimeSinceStartup; lastMoveToWorldBossNpcID = npcID; } return; } // 判断是否是在别的地图 if (_findLocation && _npcLocation.mapId != PlayerDatas.Instance.baseData.MapID) { if (_config != null) { if (_config.NPCType == (int)E_NpcType.OpenWorldMap) { if (!WindowCenter.Instance.IsOpen()) { WindowCenter.Instance.Open(); if (_hero.State == E_ActorState.AutoRun) { _hero.StopPathFind(); } _hero.IdleImmediate(); } return; } } if (PlayerDatas.Instance.extersion.pkState == 1) { SysNotifyMgr.Instance.ShowTip("PK_Leave"); return; } // 判断地图是否解锁 if (_model.IsMapUnlocked(_npcLocation.mapId) == false) { SysNotifyMgr.Instance.ShowTip("Map_Delivery"); return; } var _curMapConfig = MapConfig.Get(PlayerDatas.Instance.baseData.MapID); // 副本中不可以传送 if (_curMapConfig.MapFBType != 0 && PlayerDatas.Instance.baseData.MapID != 31020) { SysNotifyMgr.Instance.ShowTip("InDungeon_CantGo"); return; } _model.RequestMapTransport(_npcLocation.mapId); m_SwitchMapFinished = false; m_MapID = _npcLocation.mapId; } // 找不到或者是本地图 // 找不到可能是客户端对象,也可能是配置不存在 else { _npc = GAMgr.Instance.GetCloserNPC(_hero.Pos, npcID); MoveToExistNpc(npcID, _npc); } } private void MoveToExistNpc(int npcID, GActor npc) { GA_Hero _hero = PlayerDatas.Instance.hero; NPCConfig _config = NPCConfig.Get(npcID); // 目标点, 默认为主角坐标, 找不到任务终点的时候不移动 Vector3 _destPos = _hero.Pos; // 获取NPC位置数据 GAStaticDefine.NPCLocation _npcLocation; var _findLocation = GAStaticDefine.TryGetMapNPCLocation(npcID, out _npcLocation); Vector2 _calculPos = _destPos; if (_findLocation) { _calculPos = _npcLocation.position; } _destPos = new Vector3(_calculPos.x, _hero.Pos.y, _calculPos.y); //} if (npc != null) { if (_config.NPCType != (int)E_NpcType.Fight) { _destPos = npc.Pos; } } else { if (GeneralDefine.NpcPosOffset.ContainsKey(_config.NPCID)) { _destPos = GeneralDefine.NpcPosOffset[_config.NPCID]; } } // 判断距离 float _distSqrt = MathUtility.DistanceSqrtXZ(_hero.Pos, _destPos); // 判断是否需要骑马移动 if (_distSqrt > Mathf.Pow(10, 2)) { DTC0428_tagPlayerRideHorse.Send_tagPlayerRideHorse(true); } float _chkDist = Mathf.Max(GeneralDefine.CloseNpcDist + _config.ModelRadius, 0); if (_config.NPCType == (int)E_NpcType.OpenWorldMap) { _chkDist = 1; } // 针对挖洞对象保持距离为0 if (_config.Dig == 1) { if (npc == null) { _chkDist = 1.5f; } else { _chkDist = 0; } } // 大于配置的距离, 移动至 if (_distSqrt > Mathf.Pow(_chkDist + 0.1f, 2)) { _hero.MoveToPosition(_destPos, _chkDist, true); if (s_OnHeroStartMoveToNPC != null) { s_OnHeroStartMoveToNPC(); } } // 小于距离则判断目标的类型,执行相应的逻辑 else { if (_config != null) { if (_config.NPCType == (int)E_NpcType.Fight) { _hero.Behaviour.StartHandupAI(); } else if (_config.NPCType == (int)E_NpcType.Collect) { GA_NpcCollect _collect = npc as GA_NpcCollect; if (_collect != null) { PrepareHandler.Instance.Arrive(_collect); if (_distSqrt < Mathf.Pow(_collect.NpcConfig.ModelRadius + 0.4f + GeneralDefine.CloseNpcDist, 2)) { NPCInteractProcessor.InvokeEvent(E_NpcType.Collect, _collect.NpcConfig.NPCID, _collect.ServerInstID); var _dir = MathUtility.ForwardXZ(_collect.Pos, _hero.Pos); _hero.Forward = _dir; } } } else { // 如果目标已经在之前搜索中确定了 // 没确定其实在这里应该是异常情况 if (npc != null) { _hero.LockTarget = npc; _hero.SelectTarget = npc; Clear(); HeroAIRecorder.ClearRecord(); NPCInteractProcessor.InvokeEvent((E_NpcType)_config.NPCType, npcID, npc.ServerInstID); Vector3 _npc2heroDir = MathUtility.ForwardXZ(npc.Pos, _hero.Pos); if (_config.AutomaticFace == 1) { npc.Forward = -_npc2heroDir; } _hero.Forward = _npc2heroDir; } // 会有为空的时候, 例如是小飞鞋飞的情况, 这里直接判断与配置的坐标的距离 else { } } } } } public void MoveToLocalMapPosition(Vector2 pos) { StopCoroutine("_MoveToLocalPos"); StartCoroutine("_MoveToLocalPos", pos); } private IEnumerator _MoveToLocalPos(Vector2 pos) { var _hero = PlayerDatas.Instance.hero; if (_hero == null || GA_Hero.s_MapSwitching) { yield break; } var _dest = new Vector3(pos.x, 0, pos.y); if (PathFinder.WalkAble(_hero.Pos, _dest)) { while (true) { Vector3 _nextPos = ClientSceneManager.Instance.GetNext1(_hero.Pos, _dest); if (_nextPos == Vector3.zero) { break; } float _dis = MathUtility.DistanceSqrtXZ(_hero.Pos, _nextPos); while (_dis > 0.01f) { _dis = MathUtility.DistanceSqrtXZ(_hero.Pos, _nextPos); _hero.MoveToPosition(_nextPos); yield return null; } while (!GA_Hero.s_Flying) { yield return null; } while (GA_Hero.s_Flying) { yield return null; } } _hero.MoveToPosition(_dest); DTC0428_tagPlayerRideHorse.Send_tagPlayerRideHorse(true); } else { while (true) { if (PathFinder.WalkAble(_hero.Pos, _dest)) { break; } Vector3 _nextPos; if (!ClientSceneManager.Instance.AAA(_hero.Pos, _dest, out _nextPos)) { Debug.LogErrorFormat("移动至NPC: {0} 时找不到任何跳跃点", NpcID); break; } float _dis = MathUtility.DistanceSqrtXZ(_hero.Pos, _nextPos); while (_dis > 0.01f) { _dis = MathUtility.DistanceSqrtXZ(_hero.Pos, _nextPos); _hero.MoveToPosition(_nextPos); yield return null; } while (!GA_Hero.s_Flying) { yield return null; } while (GA_Hero.s_Flying) { yield return null; } } _hero.MoveToPosition(_dest); DTC0428_tagPlayerRideHorse.Send_tagPlayerRideHorse(true); } } // public void MoveToLocalMapPosition(Vector2 _position) // { // var hero = PlayerDatas.Instance.hero; // if (GA_Hero.s_MapSwitching || hero == null) // { // return; // } // MapTransferDoType = E_MapTransferDoType.None; // m_DelayMoveToPos = false; // m_TempPos = hero.Pos; // hero.Behaviour.StopHandupAI(true); // hero.Behaviour.StopKillUntilDieAI(); // if ((hero.SkillMgr.CurCastSkill != null && !hero.SkillMgr.CurCastSkill.SkillCompelete) // || hero.IsRushing) // { // m_TempPos = _position; // m_DelayMoveToPos = true; // return; // } // hero.MoveToPosition(new Vector3(_position.x * 0.5f, 0f, _position.y * 0.5f)); // DTC0428_tagPlayerRideHorse.Send_tagPlayerRideHorse(true); // } public void MissionFlyTo(int mapId, int npcId, MapTransferType mapTransferType = MapTransferType.MissionTransport) { if (PlayerDatas.Instance.extersion.pkState == 1) { SysNotifyMgr.Instance.ShowTip("PK_Leave"); return; } GA_Hero _hero = PlayerDatas.Instance.hero; Vector3 _position = _hero.Pos; Vector3 _result = new Vector2(_position.x, _position.z); Quaternion _rot = Quaternion.identity; GAStaticDefine.NPCLocation npcLocation; var findLocation = GAStaticDefine.TryGetMapNPCLocation(npcId, out npcLocation); if (_hero.State == E_ActorState.AutoRun) { _hero.StopPathFind(); } if (findLocation) { mapId = npcLocation.mapId; _result = npcLocation.position; _rot = MathUtility.GetClientRotationFromAngle(npcLocation.face); } else { GActor _npc = GAMgr.Instance.GetCloserNPC(_hero.Pos, npcId); if (_npc != null) { _result.x = _npc.Pos.x; _result.y = _npc.Pos.z; } } _position.x = _result.x; _position.y = _hero.Pos.y; _position.z = _result.y; MapTransferDoType = E_MapTransferDoType.Npc; NpcID = npcId; // 如果处于相同地图且距离小于一定的值, 则不传送 if (mapId == PlayerDatas.Instance.baseData.MapID) { FuncConfigConfig _func = FuncConfigConfig.Get("flyMinDistance"); if (_func != null) { float _distance = float.Parse(_func.Numerical1); if (Vector3.SqrMagnitude(_hero.Pos - _position) < _distance * _distance) { MoveToNPC(npcId); SysNotifyMgr.Instance.ShowTip("NearbyHint"); return; } } } else { var _curMapConfig = MapConfig.Get(PlayerDatas.Instance.baseData.MapID); // 副本中不可以传送(某些特定地图可以进行传送Zxw) var mainModel = ModelCenter.Instance.GetModel(); int MapId = PlayerDatas.Instance.baseData.MapID; if (_curMapConfig.MapFBType != 0 && !mainModel.OneKeyList.Contains(MapId)) { SysNotifyMgr.Instance.ShowTip("Map_Delivery"); return; } MapModel _model = ModelCenter.Instance.GetModel(); if (_model.IsMapUnlocked(npcLocation.mapId) == false) { SysNotifyMgr.Instance.ShowTip("Map_Delivery"); return; } if (PlayerDatas.Instance.extersion.pkState == 1) { SysNotifyMgr.Instance.ShowTip("PK_Leave"); return; } if (PlayerDatas.Instance.extersion.bossState == 1) { ConfirmCancel.ShowPopConfirm(Language.Get("Mail101"), Language.Get("ZLMapQuit"), (bool isOk) => { //不传送 if (!isOk) { return; } else { _hero.Behaviour.StopHandupAI(true); _hero.Behaviour.StopKillUntilDieAI(); _position += _rot * Vector3.forward * 1; Send_WorldTransfer(mapId, _position * 2, mapTransferType); } }); return; } } _hero.Behaviour.StopHandupAI(true); _hero.Behaviour.StopKillUntilDieAI(); _position += _rot * Vector3.forward * 1; Send_WorldTransfer(mapId, _position * 2, mapTransferType); } //拷贝RichMoveEvent逻辑,按坐标移动 public void MoveToMapPos(int _mapId, float x, float y, byte line = 255) { PlayerDatas.Instance.hero.StopAll(); MapModel _model = ModelCenter.Instance.GetModel(); if (PlayerDatas.Instance.baseData.MapID != _mapId) { if (_mapId == CrossServerBossModel.DATA_MAPID) { if (!FuncOpen.Instance.IsFuncOpen((int)FuncOpenEnum.CrossServerBoss)) { FuncOpen.Instance.ProcessorFuncErrorTip((int)FuncOpenEnum.CrossServerBoss); return; } var model = ModelCenter.Instance.GetModel(); model.selectedBoss = model.GetRecommendNpc(); var error = 0; if (!model.CanEnter(out error)) { model.ProcessEnterError(error); return; } model.RequestEnter(); } else if (_mapId == 32080) { CrossServerMHBossModel.Instance.GotoKillBoss(); } else { var currentMapConfig = MapConfig.Get(PlayerDatas.Instance.baseData.MapID); if (currentMapConfig.MapFBType != 0) { SysNotifyMgr.Instance.ShowTip("Map_Delivery"); return; } if (_model.IsMapUnlocked(_mapId) == false) { SysNotifyMgr.Instance.ShowTip("Map_Delivery"); return; } _model.RequestMapTransport(_mapId, line); } WorldMapSkip.Instance.PushCMD(() => { SnxxzGame.Instance.StartCoroutine(WaitForSkillFinished1(new Vector3(x / 2, 0, y / 2))); }); } else { if (PlayerDatas.Instance.baseData.FBID != line) { DTC0401_tagPlayerMapInit.OnMapInitEvent -= OnMapInitEvent; DTC0401_tagPlayerMapInit.OnMapInitEvent += OnMapInitEvent; _model.RequestSelectedLine(line); m_Posx = x; m_Posy = y; return; } PlayerDatas.Instance.hero.Behaviour.StopHandupAI(); SnxxzGame.Instance.StartCoroutine(WaitForSkillFinished1(new Vector3(x / 2, 0, y / 2))); } } float m_Posx; float m_Posy; void OnMapInitEvent() { DTC0401_tagPlayerMapInit.OnMapInitEvent -= OnMapInitEvent; SnxxzGame.Instance.StartCoroutine(Co_DelayMoveTo1()); } private IEnumerator Co_DelayMoveTo1() { yield return WaitingForSecondConst.WaitMS1000; SnxxzGame.Instance.StartCoroutine(WaitForSkillFinished1(new Vector3(m_Posx / 2, 0, m_Posy / 2))); } private IEnumerator WaitForSkillFinished1(Vector3 pos) { GA_Hero _hero = PlayerDatas.Instance.hero; if (_hero == null) { yield break; } while (_hero != null && _hero.SkillMgr.CurCastSkill != null && _hero.SkillMgr.CurCastSkill.SkillCompelete == false) { yield return null; } if (_hero == null) { yield break; } pos.y = _hero.Pos.y; _hero.MoveToPosition(pos); } public void FlyTo(int mapID, Vector3 pos, byte lineID = 255) { if (PlayerDatas.Instance.extersion.pkState == 1) { SysNotifyMgr.Instance.ShowTip("PK_Leave"); return; } if (PlayerDatas.Instance.extersion.bossState == 1) { ConfirmCancel.ShowPopConfirm(Language.Get("Mail101"), Language.Get("ZLMapQuit"), (bool isOk) => { //不传送 if (!isOk) { return; } else { _FlyTo(mapID, pos, lineID); } }); return; } _FlyTo(mapID, pos, lineID); } private void _FlyTo(int mapID, Vector3 pos, byte lineID = 255) { GA_Hero _hero = PlayerDatas.Instance.hero; // 如果处于相同地图且距离小于一定的值, 则不传送 if (mapID == PlayerDatas.Instance.baseData.MapID && lineID == PlayerDatas.Instance.baseData.FBID) { FuncConfigConfig _func = FuncConfigConfig.Get("flyMinDistance"); if (_func != null) { float _distance = float.Parse(_func.Numerical1); if (Vector3.SqrMagnitude(_hero.Pos - pos) < _distance * _distance) { _hero.MoveToPosition(pos); SysNotifyMgr.Instance.ShowTip("NearbyHint"); return; } } } else { var _curMapConfig = MapConfig.Get(PlayerDatas.Instance.baseData.MapID); // 副本中不可以传送 if (_curMapConfig.MapFBType != 0) { SysNotifyMgr.Instance.ShowTip("Map_Delivery"); return; } MapModel _model = ModelCenter.Instance.GetModel(); if (_model.IsMapUnlocked(mapID) == false) { SysNotifyMgr.Instance.ShowTip("Map_Delivery"); return; } } _hero.Behaviour.StopHandupAI(true); _hero.Behaviour.StopKillUntilDieAI(); Send_WorldTransfer(mapID, pos * 2, MapTransferType.MissionTransport, lineID); } public static bool Send_WorldTransfer(int mapId, Vector3 position, MapTransferType type, byte lineID = 255, int _npcId = 0) { if (CrossServerLogin.Instance.IsEnterCrossServerPreparing()) { return false; } if (!AssetSource.sceneFromEditor) { var assetValid = AssetVersionUtility.IsSceneAssetValid(mapId, 0); if (!assetValid) { InGameDownLoad.Instance.TryDownLoad(InGameDownLoad.Dominant.Whole); return false; } } var _transfer = new CB005_tagCMWorldTransfer { MapID = (uint)mapId, PosX = (ushort)(position.x), PosY = (ushort)(position.z), Type = (byte)type,// 1 世界传送; 2 大地图传送; 3 任务传送 LineID = lineID, ExData1 = (uint)_npcId }; if (CrossServerUtility.IsCrossServer()) { GameNetSystem.Instance.SendToCrossServer(_transfer); } else { GameNetSystem.Instance.SendInfo(_transfer); } return true; } public void OnHeroPathFinding() { //if (MapTransferDoType != E_MapTransferDoType.Npc) //{ // return; //} //GA_Hero _hero = PlayerDatas.Instance.hero; //if (_hero == null) //{ // return; //} //NPCConfig _npcConfig = NPCConfig.Get(NpcID); //if (_npcConfig == null) //{ // return; //} //float _checkDistSqrt; //// 这里对战斗类型的NPC特殊处理, 如果在地图中已经出现了, 就找那个最近的那个 //if (_npcConfig.NPCType == (int)E_NpcType.Fight) //{ // // 是否要移动至的目标已经出现在地图中 // GActor _closerNpc = GAMgr.Instance.GetCloserNPC(_hero.Pos, NpcID); // if (_closerNpc != null) // { // _checkDistSqrt = MathUtility.DistanceSqrtXZ(_hero.Pos, _closerNpc.Pos); // if (_checkDistSqrt < Mathf.Pow(4, 2))// 这里的2M是暂定值 // { // _hero.StopPathFind(); // _hero.Behaviour.StartHandupAI(); // Clear(); // } // } //} } public void OnHeroStopPathFind() { // 非寻路至NPC逻辑停下, 不做后续操作 if (MapTransferDoType != E_MapTransferDoType.Npc) { return; } GA_Hero _hero = PlayerDatas.Instance.hero; if (_hero == null) { Clear(); return; } // 找不到配置, 不做后续操作 NPCConfig _npcConfig = NPCConfig.Get(NpcID); if (_npcConfig == null) { Clear(); return; } GAStaticDefine.NPCLocation _npcLocation; var _findLocation = GAStaticDefine.TryGetMapNPCLocation(NpcID, out _npcLocation); float _chkDistSqrt = 0; if (_findLocation) { _chkDistSqrt = MathUtility.DistanceSqrtXZ(_hero.Pos, new Vector3(_npcLocation.position.x, 0, _npcLocation.position.y)); } // 如果停止下来的时候并没有找到目标NPC, 则不做后续操作 GActor _npc = GAMgr.Instance.GetCloserNPC(_hero.Pos, NpcID); if (_npc != null) { _chkDistSqrt = MathUtility.DistanceSqrtXZ(_hero.Pos, _npc.Pos); } if (_npcConfig.NPCType == (int)E_NpcType.Fight) { float _fightConfigDist = _findLocation ? _npcLocation.scope : 4; if (_chkDistSqrt < Mathf.Pow(_fightConfigDist, 2) || (_npc != null && PathFinder.WalkAble(_hero.Pos, _npc.Pos)))// 这里的2M是暂定值 { _hero.Behaviour.StartHandupAI(); Clear(); } else { Debug.LogFormat("_npc == null : {0}, _chkDistSqrt < Mathf.Pow(_fightConfigDist, 2): {1}", _npc == null, _chkDistSqrt < Mathf.Pow(_fightConfigDist, 2)); } } else if (_npcConfig.NPCType == (int)E_NpcType.Collect || _npcConfig.NPCType == (int)E_NpcType.Flag) { float _chkDist = GeneralDefine.CloseNpcDist + _npcConfig.ModelRadius + 0.3f; if (_chkDistSqrt <= Mathf.Pow(_chkDist, 2)) { if (!UserInputHandler.isTouched && (_hero.SkillMgr.CurCastSkill == null || _hero.SkillMgr.CurCastSkill.SkillCompelete)) { if (NpcID != GeneralDefine.GatherSoulDZ) { if (_npc != null) { if (_npc is GA_NpcCollect) { NPCInteractProcessor.InvokeEvent(E_NpcType.Func, NpcID, _npc.ServerInstID); } else if (_npc is GA_NpcClientCollect) { if (_npcConfig.NPCID == 10104200) { ClientCollectUtility.HandleCallback(E_NpcType.Collect, _npcConfig.NPCID, _npc.ServerInstID); } else if (_npcConfig.NPCID == 40208007) { if (ModelCenter.Instance.GetModel().auto) { ClientCollectUtility.HandleCallback(E_NpcType.Collect, _npcConfig.NPCID, _npc.ServerInstID); } } } } } Clear(); } } } else { float _chkDist = GeneralDefine.CloseNpcDist + _npcConfig.ModelRadius + 0.6f; // 因为守护副本美术有挖洞, 洞太大了. 这里无法按照配置走,特殊处理 if (_npcConfig.NPCID == 32504001) { _chkDist = 2; } if (_findLocation) { Vector3 _configPos = new Vector3(_npcLocation.position.x, 0, _npcLocation.position.y); _chkDistSqrt = MathUtility.DistanceSqrtXZ(_hero.Pos, _configPos); //Debug.Log("1.....当前距离: " + Mathf.Sqrt(_chkDistSqrt) // + ".....应该保持的距离: " + _chkDist // + ".....目标在: " + _configPos); } //else //{ // Debug.Log("2.....当前距离: " + Vector3.Distance(_npc.Pos, _hero.Pos) // + ".....应该保持的距离: " + _chkDist); //} if (_npc != null) { _chkDistSqrt = MathUtility.DistanceSqrtXZ(_npc.Pos, _hero.Pos); if (_chkDistSqrt <= Mathf.Pow(_chkDist, 2)) { Clear(); HeroAIRecorder.ClearRecord(); NPCInteractProcessor.InvokeEvent((E_NpcType)_npcConfig.NPCType, _npcConfig.NPCID, _npc.ServerInstID); _hero.LockTarget = _npc; _hero.SelectTarget = _npc; Vector3 _npc2heroDir = MathUtility.ForwardXZ(_npc.Pos, _hero.Pos); if (_npcConfig.AutomaticFace == 1) { _npc.Forward = -_npc2heroDir; } _hero.Forward = _npc2heroDir; } } } } public void Clear() { if (m_SwitchMapFinished) { StopCoroutine("CoMoveToNPC"); StopCoroutine("_MoveToLocalPos"); NpcID = 0; MapTransferDoType = E_MapTransferDoType.None; m_DelayMoveToNPC = false; } } public void StopMovetoNpc() { StopCoroutine("CoMoveToNPC"); } }