using H2Engine; using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public class ClientSceneManager : Singleton { private H2Engine.MapData m_MapData; private List m_TransferGroupList = new List(); private Dictionary m_EventHandlerDict = new Dictionary(); private List m_ReadyRemoveEventHandlerList = new List(); private Dictionary m_TriggerIDToMissionIDDict = new Dictionary(); private Dictionary m_TriggerHandlerDict = new Dictionary(); private List m_ReadyRemoveTriggerList = new List(); private Dictionary> m_EventActorDict = new Dictionary>(); public bool IsClientFightMode { get; private set; } public event Action ClientSceneChangeEvent; public void ExitTransStatus() { foreach (var _t in m_TransferGroupList) { _t.StartMoveTo(); } } private IEnumerator DelayUnTrigger(int id) { while (m_MapData == null) { yield return null; } float _escapeTime = 0; while (m_TriggerHandlerDict.Count == 0) { _escapeTime += Time.deltaTime; if (_escapeTime > 1f) { yield break; } yield return null; } Debug.LogFormat("= 结束触发: {0} =", id); foreach (var _trigger in m_MapData.triggers) { if (_trigger.id != id) { continue; } if (_trigger.evevntIDs == null || _trigger.evevntIDs.Length == 0) { continue; } Debug.LogFormat("= 触发器有: {0} 个事件 =", _trigger.evevntIDs.Length); foreach (var _eventID in _trigger.evevntIDs) { if (!m_EventActorDict.ContainsKey(_eventID)) { continue; } if (m_EventActorDict[_eventID] == null || m_EventActorDict[_eventID].Count == 0) { continue; } Debug.LogFormat("= 残留有: {0} 个NPC =", m_EventActorDict[_eventID].Count); foreach (var _npc in m_EventActorDict[_eventID]) { _npc.KillerServerInstID = PlayerDatas.Instance.PlayerId; _npc.ActorInfo.serverDie = true; GAMgr.Instance.ServerDie(_npc.ServerInstID); GAMgr.Instance.Release(_npc); } m_EventHandlerDict.Remove(_eventID); } break; } } public void NpcBorn(int eventID, GActor npc) { if (!m_EventActorDict.ContainsKey(eventID)) { m_EventActorDict.Add(eventID, new List()); } if (!m_EventActorDict[eventID].Contains(npc)) { m_EventActorDict[eventID].Add(npc); Debug.LogFormat("= 为事件: {0} 增加Npc: {1}", eventID, npc.ServerInstID); } } public Vector3 lastDeadPos { get; set; } private bool HasStartCheck = false; public void NpcDead(int eventID, GActor npc, int npcID) { if (eventID < 0 || npc == null) { return; } var _eventHandler = GetEventHandler(eventID) as EventRefreshNPCHandler; if (_eventHandler != null) { _eventHandler.NpcDead(npcID); } if (m_EventActorDict.ContainsKey(eventID)) { if (m_EventActorDict[eventID].Contains(npc)) { m_EventActorDict[eventID].Remove(npc); } } lastDeadPos = npc.Pos; } public bool isWaitPickup = false; private IEnumerator DoWaitJiaPickup() { isWaitPickup = true; yield return WaitingForSecondConst.WaitMS500; while (ClientDropItemUtility.Instance.HasDropItem()) { yield return null; } isWaitPickup = false; CA225_tagCMClientTaskCount _a225 = new CA225_tagCMClientTaskCount { CountID = 10001 }; GameNetSystem.Instance.SendInfo(_a225); } public void Handle_0820(H0820_tagMissionDict package) { if (package.DictKey.Equals("gonpc")) { MapTransferUtility.Instance.MoveToNPC((int)package.DictValue); } m_ReadyRemoveTriggerList.Clear(); foreach (var _triggerID in m_TriggerIDToMissionIDDict.Keys) { if (m_TriggerIDToMissionIDDict[_triggerID] == package.MissionID) { if (package.DictKey.Equals("state")) { if (package.DictValue > 2) { m_ReadyRemoveTriggerList.Add(_triggerID); SnxxzGame.Instance.StartCoroutine(DelayUnTrigger(_triggerID)); } } } } foreach (var _id in m_ReadyRemoveTriggerList) { m_TriggerIDToMissionIDDict.Remove(_id); } if (package.DictKey.Equals("riggerID")) { int _triggerID = (int)package.DictValue; if (_triggerID == 0) { Debug.LogFormat("退出当前触发事件, 已触发数量: {0}", m_TriggerIDToMissionIDDict.Count); foreach (var _removeTriggerID in m_TriggerIDToMissionIDDict.Keys) { SnxxzGame.Instance.StartCoroutine(DelayUnTrigger(_removeTriggerID)); } SnxxzGame.Instance.StartCoroutine(DoWaitJiaPickup()); } else { m_TriggerIDToMissionIDDict[_triggerID] = package.MissionID; SnxxzGame.Instance.StartCoroutine(DelayTrigger(package.MissionID, _triggerID)); } } else if (package.DictKey.Equals("xinshou")) { if (package.DictValue == 0) { Debug.LogFormat("= 退出了前端模式 ="); IsClientFightMode = false; } else { Debug.LogFormat("= 进入了前端模式 ="); IsClientFightMode = true; JiaPlayerManager.UnInit(); } ClientSceneChangeEvent?.Invoke(); } } private bool m_Inited = false; public void Init() { if (m_Inited) { return; } m_Inited = true; int _mapID = PlayerDatas.Instance.baseData.MapID; m_MapData = MapData.LoadFormFile(_mapID); if (m_MapData == null) { return; } foreach (var _trasfer in m_MapData.transfers) { m_TransferGroupList.Add(new TransferGroup(_trasfer)); } TriggerHandler.OnEnter += OnTriggerEnter; TriggerHandler.OnExit += OnTriggerExit; } public void UnInit() { foreach (var _t in m_TransferGroupList) { _t.UnInit(); } m_TransferGroupList.Clear(); ReConnectClear(); m_MapData = null; TriggerHandler.OnEnter -= OnTriggerEnter; TriggerHandler.OnExit -= OnTriggerExit; m_Inited = false; IsClientFightMode = false; m_EventActorDict.Clear(); m_EventHandlerDict.Clear(); } public void ReConnectClear() { foreach (var _triggerID in m_TriggerIDToMissionIDDict.Keys) { DelayUnTrigger(_triggerID); } m_TriggerIDToMissionIDDict.Clear(); m_TriggerHandlerDict.Clear(); } public void Update() { foreach (var _trasfer in m_TransferGroupList) { _trasfer.Update(); } foreach (var _triggerHandler in m_TriggerHandlerDict.Values) { _triggerHandler.Update(); } m_ReadyRemoveEventHandlerList.Clear(); foreach (var _eventHandler in m_EventHandlerDict.Values) { _eventHandler.Update(); if (_eventHandler.IsCompelete()) { m_ReadyRemoveEventHandlerList.Add(_eventHandler); } } foreach (var _eventHandler in m_ReadyRemoveEventHandlerList) { _eventHandler.UnInit(); m_EventHandlerDict.Remove(_eventHandler.GetEventID()); } } public IEventHandler GetEventHandler(int id) { if (m_EventHandlerDict.ContainsKey(id)) { return m_EventHandlerDict[id]; } return null; } private List m_ChkedList = new List(); private List m_ChkedList1 = new List(); private int count = 0; // 是否已经找到了一个可以移动到目标的点 // 因为可能存在多个, 这里加一个标识,可以在此路不通的时候另寻他路 private bool hasFindWalkable = false; private Vector3 m_DestPos; private List m_CloseList = new List(); private List m_OpenList = new List(); private List m_WalkableList = new List(); public bool AAA(Vector3 start, Vector3 end, out Vector3 next) { //Debug.LogFormat("起点: {0}, 终点: {1}", start, end); if (PathFinder.WalkAble(start, end)) { next = end; //Debug.LogFormat("得到结果: {0}", next); return true; } next = Vector3.zero; m_CloseList.Clear(); m_OpenList.Clear(); m_WalkableList.Clear(); // 1. 寻找以当前可寻路的节点为首节点, 加入关闭列表和开启列表 Vector3 _nextPos; Vector3 _walkablePos; Vector3 _input = end; int _count = 0; // 5. 遍历所有剩下的节点, 排除开启列表和关闭列表, 排除不可行走至的节点 while (true) { if (_count > 30) { return false; } var _nextTransfer = GetWalkableTransferUnIncludeOpenedAndClosed(_input, out _walkablePos, out _nextPos); if (_nextTransfer != null) { // 6. 如果没有到达终点,但是找得到合适的节点,继续第二步 if (!m_WalkableList.Contains(_walkablePos)) { m_WalkableList.Add(_walkablePos); } if (!m_OpenList.Contains(_nextTransfer) && !m_CloseList.Contains(_nextTransfer)) { m_OpenList.Add(_nextTransfer); //Debug.LogFormat("添加进打开列表:{0} ------- walkable: {1}, next: {2}", _nextTransfer.GetHashCode(), _walkablePos, _nextPos); } // Debug.LogFormat("找到了下一个传送点, 当前可行走点为: {0}, 将会跳跃至: {1}", _walkablePos, _nextPos); // 如果这次的寻找到达了终点,则返回第一个可行走的节点 if (PathFinder.WalkAble(_nextPos, start)) { //Debug.LogFormat("此次寻找已经找到了可以到达终点的点, 返回可行走到的点: {0}", _nextPos); next = _nextPos; //Debug.LogFormat("得到结果: {0}", next); return true; } else { _input = _nextPos; //Debug.LogFormat("此次寻找没有找到终点, 以下一个点为起点: {0}", _nextPos); } } else { // 如果起点 if (_input == start) { return false; } // 以这个节点为起始节点, 看下是否有另外的节点. // 前提是有可回退的节点 if (m_OpenList.Count > 0) { var _tmp = m_OpenList[m_OpenList.Count - 1]; m_OpenList.Remove(_tmp); if (!m_CloseList.Contains(_tmp)) { m_CloseList.Add(_tmp); //Debug.LogFormat("添加进关闭列表: {0}", _tmp.GetHashCode()); } _input = m_WalkableList[m_WalkableList.Count - 1]; //Debug.LogFormat("此次寻找并没有找到任何可用的传送点, 开始回退到上一个节点开始寻找, 传入坐标为: {0}", _input); m_WalkableList.RemoveAt(m_WalkableList.Count - 1); } else { // 没有可回退的节点, 则重新从传入的起点寻找. // 可能一开始就会有另一条路 // 先清空所有的可行走 //Debug.LogFormat("此次寻找没有到任何节点,也没有上一个节点可以回退, 从起点开始重新寻找"); m_WalkableList.Clear(); _input = start; } } _count++; } } private MapTrasfer GetWalkableTransferUnIncludeOpenedAndClosed(Vector3 input, out Vector3 walkable, out Vector3 next) { GA_Hero _hero = PlayerDatas.Instance.hero; walkable = Vector3.zero; next = Vector3.zero; if (m_MapData == null || _hero == null) { return null; } foreach (var _transfer in m_MapData.transfers) { if (m_CloseList.Contains(_transfer) || m_OpenList.Contains(_transfer)) { continue; } for (int i = 0; i < _transfer.transferPoints.Length; ++i) { var _point = _transfer.transferPoints[i]; if (PathFinder.WalkAble(input, _point.position)) { if (i == 0) { walkable = _point.position; next = _transfer.transferPoints[_transfer.transferPoints.Length - 1].position; } else { walkable = _point.position; next = _transfer.transferPoints[0].position; } return _transfer; } } } return null; } public Vector3 GetNext1(Vector3 start, Vector3 dest) { if (m_MapData == null) { return Vector3.zero; } count = 0; m_ChkedList1.Clear(); if (PathFinder.WalkAble(start, dest)) { float _dis = PathFinder.CalculateDistance(start, dest); //Debug.Log("得出的距离平方为: " + _dis); int _chkIndex = -1; float _compareDis = float.MaxValue; float _chkDis1; float _chkDis2; float _totalDis = 0; foreach (var _t in m_MapData.transfers) { if (_t.transferPoints.Length >= 2) { if (!PathFinder.WalkAble(_t.transferPoints[0].position, dest) && !PathFinder.WalkAble(_t.transferPoints[_t.transferPoints.Length - 1].position, dest)) { continue; } _chkDis1 = Vector3.Distance(_t.transferPoints[0].position, dest); _chkDis2 = Vector3.Distance(_t.transferPoints[_t.transferPoints.Length - 1].position, dest); if (_chkDis1 > _compareDis && _chkDis2 > _compareDis) { continue; } if (_chkDis1 < _chkDis2) { _compareDis = _chkDis1; _chkIndex = 0; } else { _compareDis = _chkDis2; _chkIndex = _t.transferPoints.Length - 1; } m_ChkedList1.Add(_t); } } // Debug.LogFormat("离终点最近的点为飞跃组: {0} 的第 {1} 个点", _chkTransID, _chkIndex); if (m_ChkedList1.Count == 0) { return Vector3.zero; } var _t1 = m_ChkedList1[m_ChkedList1.Count - 1]; for (int i = 0; i < _t1.transferPoints.Length - 1; ++i) { var _p1 = _t1.transferPoints[i].position; _p1.y = 0; var _p2 = _t1.transferPoints[i + 1].position; _p2.y = 0; _totalDis += Vector3.Distance(_p1, _p2); // Debug.LogFormat(" ### 2个点的距离: {0}, {1}", Vector3.Distance(_p1, _p2), _totalDis); } var _p = _t1.transferPoints[_chkIndex].position; _p.y = 0; _totalDis += Vector3.Distance(_p, dest); //Debug.LogFormat(" ### 终点和跳跃点的距离: {0}, {1}", Vector3.Distance(_p, dest), _totalDis); var _nextIdx = _chkIndex == 0 ? _t1.transferPoints.Length - 1 : 0; _p = _t1.transferPoints[_nextIdx].position; var _startDis = PathFinder.CalculateDistance(start, _p); _totalDis += _startDis; //Debug.LogFormat(" ### 起点和跳跃点的距离: {0}, {1}", _startDis, _totalDis); if (_totalDis < _dis) { return _p; } var _next = GetNext11(start, _p, ref _totalDis, _dis); if (_totalDis < _dis) { return _next; } else { return Vector3.zero; } } else { return GetNext(start, dest); } } private Vector3 GetNext11(Vector3 start, Vector3 dest, ref float dis, float totalDis) { float _chkDis1; float _chkDis2; float _compareDis = float.MaxValue; int _chkTransID = -1; int _chkIndex = -1; foreach (var _t in m_MapData.transfers) { if (m_ChkedList1.Contains(_t)) { continue; } if (_t.transferPoints.Length >= 2) { if (!PathFinder.WalkAble(_t.transferPoints[0].position, dest) && !PathFinder.WalkAble(_t.transferPoints[_t.transferPoints.Length - 1].position, dest)) { continue; } _chkDis1 = Vector3.Distance(_t.transferPoints[0].position, dest); _chkDis2 = Vector3.Distance(_t.transferPoints[_t.transferPoints.Length - 1].position, dest); if (_chkDis1 > _compareDis && _chkDis2 > _compareDis) { continue; } if (_chkDis1 < _chkDis2) { _compareDis = _chkDis1; _chkIndex = 0; } else { _compareDis = _chkDis2; _chkIndex = _t.transferPoints.Length - 1; } m_ChkedList1.Add(_t); _chkTransID = _t.id; } } if (m_ChkedList1.Count == 0) { return Vector3.zero; } var _t1 = m_ChkedList1[m_ChkedList1.Count - 1]; if (_chkTransID != -1) { for (int i = 0; i < _t1.transferPoints.Length - 1; ++i) { var _p1 = _t1.transferPoints[i].position; _p1.y = 0; var _p2 = _t1.transferPoints[i + 1].position; _p2.y = 0; dis += Vector3.Distance(_p1, _p2); // Debug.LogFormat(" ### 2个点的距离: {0}", Vector3.Distance(_p1, _p2)); } var _p = _t1.transferPoints[_chkIndex].position; _p.y = 0; dis += Vector3.Distance(_p, dest); _p = _t1.transferPoints[_chkIndex].position; _p.y = 0; //Debug.LogFormat(" ### 终点和跳跃点的距离: {0}", Vector3.Distance(_p, dest)); int _nextIdx = _chkIndex == 0 ? _t1.transferPoints.Length - 1 : 0; return GetNext11(start, _t1.transferPoints[_nextIdx].position, ref dis, totalDis); } else { int _nextIdx = _chkIndex == 0 ? _t1.transferPoints.Length - 1 : 0; return _t1.transferPoints[_nextIdx].position; } } private Vector3 GetNext(Vector3 start, Vector3 next) { count += 1; if (count > 20 || next == Vector3.zero || m_MapData == null) { return Vector3.zero; } Vector3 _targetPos = Vector3.zero; // 遍历寻找到可移动至目标点的跳跃点 foreach (var _t in m_MapData.transfers) { if (m_ChkedList.Contains(_t)) { continue; } for (int i = 0; i < _t.transferPoints.Length; ++i) { var _tp = _t.transferPoints[i]; if (PathFinder.WalkAble(next, _tp.position)) { if (i == 0) { _targetPos = _t.transferPoints[_t.transferPoints.Length - 1].position; } else { _targetPos = _t.transferPoints[0].position; } m_ChkedList.Add(_t); break; } } if (_targetPos != Vector3.zero) { hasFindWalkable = true; break; } } if (PathFinder.WalkAble(start, _targetPos)) { return _targetPos; } else { if (hasFindWalkable) { hasFindWalkable = false; _targetPos = GetNext(start, m_DestPos); } else { _targetPos = GetNext(start, _targetPos); } } //Debug.Log("_targetPos: " + _targetPos); return _targetPos; } public Vector3 GetCloseTransPoint(Vector3 pos) { Vector3 _targetPos = Vector3.zero; foreach (var _t in m_MapData.transfers) { for (int i = 0; i < _t.transferPoints.Length; ++i) { if (PathFinder.WalkAble(pos, _t.transferPoints[i].position)) { if (i == 0) { _targetPos = _t.transferPoints[_t.transferPoints.Length - 1].position; } else { _targetPos = _t.transferPoints[0].position; } break; } } if (_targetPos != Vector3.zero) { break; } } if (_targetPos == Vector3.zero) { Debug.LogWarningFormat("寻找最近的寻路飞跃点, 没有找到任何结果..."); } return _targetPos; } public void TriggerTest(int triggerID) { SnxxzGame.Instance.StartCoroutine(DelayTrigger(99999999, triggerID)); } private IEnumerator DelayTrigger(uint missionID, int triggerID) { // ID为0, 约定为清空触发 if (triggerID == 0) { yield return SnxxzGame.Instance.StartCoroutine(DelayUnTrigger(triggerID)); yield break; } while (StageLoad.Instance.isLoadingScene) { yield return null; } Debug.LogFormat("= 任务: {0} 触发: {1} =", missionID, triggerID); if (m_MapData == null) { Init(); } if (m_MapData == null || m_MapData.triggers == null || m_MapData.triggers.Length == 0) { yield break; } foreach (var _trigger in m_MapData.triggers) { if (_trigger.id != triggerID) { continue; } if (_trigger.evevntIDs == null || _trigger.evevntIDs.Length == 0) { continue; } var _triggerHandler = new TriggerHandler(_trigger); m_TriggerHandlerDict[_trigger.id] = _triggerHandler; foreach (var _eventID in _trigger.evevntIDs) { if (!m_MapData.eventDict.ContainsKey(_eventID)) { continue; } var _event = m_MapData.eventDict[_eventID]; if (_event.type == Evt.E_EventType.Enemy) { var _refreshEvent = new EventRefreshNPCHandler(); _refreshEvent.Init(_event as Evt_RefreshMonster); if (!m_EventHandlerDict.ContainsKey(_refreshEvent.GetEventID())) { m_EventHandlerDict.Add(_refreshEvent.GetEventID(), _refreshEvent); } HasStartCheck = false; } } break; } } private void OnTriggerEnter(int id) { //Debug.Log("进入了触发器范围: " + id); } private void OnTriggerExit(int id) { if (m_TriggerHandlerDict.ContainsKey(id)) { //Debug.Log("退出了触发器范围: " + id); CA225_tagCMClientTaskCount _a225 = new CA225_tagCMClientTaskCount { CountID = 10000 }; GameNetSystem.Instance.SendInfo(_a225); } } public void ExitClientFightMode() { CA225_tagCMClientTaskCount _a225 = new CA225_tagCMClientTaskCount { CountID = 10000 }; GameNetSystem.Instance.SendInfo(_a225); } }