using SceneEditor.Proxy.Plugin; using System.Collections; using System.Collections.Generic; using Thousandto.Cfg.Data; using Thousandto.Code.Global; using Thousandto.Core.Base; using Thousandto.Plugins.Common.UniScene; using UnityEngine; using CoroutinePool = UnityEngine.Gonbest.MagicCube.CoroutinePool; using FLogger = UnityEngine.Gonbest.MagicCube.FLogger; namespace Thousandto.Code.Logic { /// /// 地图传送点信息 /// public class MapPathInfo { #region 结构定义 public class Position { public Position(int mapId, Vector3 pos) { MapId = mapId; Pos = pos; } public int MapId { get; set; } public Vector3 Pos { get; set; } } public class MapObjInfo { public int MapID = 0; public string MapName = ""; public List TeleportInfo = null; public Dictionary NpcInfo = null; public Dictionary> MonsterInfo = null; public Dictionary> CollectInfo = null; public List SpawnInfo = null; } #endregion #region 私有变量及构造 // 地图传送点信息 private Dictionary> _mapTeleporterInfo; // NPC信息 private Dictionary _npcInfo; // 怪物信息 private Dictionary>> _monsterInfo; // 采集信息 private Dictionary>> _collectInfo; //复活点信息 private Dictionary> _spawnInfo; //地图信息 private Dictionary _mapObjInfoTable = null; #endregion #region 公有函数 public bool IsLoadFinish { get { return true; } } public Dictionary MapObjInfoTable { get { return _mapObjInfoTable; } } public MapPathInfo() { _mapTeleporterInfo = new Dictionary>(); _npcInfo = new Dictionary(); _monsterInfo = new Dictionary>>(); _collectInfo = new Dictionary>>(); _spawnInfo = new Dictionary>(); _mapObjInfoTable = new Dictionary(); } // 初始化 public void Initialize() { CoroutinePool.AddTask(LoadCoroutine()); } public void LoadSingleMap(DeclareMapsetting mapCfg) { //已经载入了,直接返回 if (_mapObjInfoTable.ContainsKey(mapCfg.MapId)) return; // 1.加载场景信息 MapInfoBody body = MapInfoDataReader.LoadSceneObjectData(FileUtils.MapInfoDirPath, mapCfg.MapInfo); if (body == null) { FLogger.DebugLogError("[MapPathInfo Initialize] 获取", mapCfg.LevelName, " MapInfoBody失败!", ";;", FileUtils.MapInfoDirPath); return; } MapObjInfo objInfo = new MapObjInfo(); objInfo.MapID = mapCfg.MapId; objInfo.MapName = mapCfg.LevelName; // 2.解析场景传送信息 ReadTriggerData(mapCfg.MapId, body, objInfo); // 3.NPC位置信息 ReadNpcData(mapCfg.MapId, body, objInfo); // 4.怪物位置信息 ReadMonsterData(mapCfg.MapId, 0, body, objInfo); // 5.采集位置信息 ReadCollectData(mapCfg.MapId, 0, body, objInfo); // 6.复活点信息 ReadSpawnData(mapCfg.MapId, body, objInfo); _mapObjInfoTable.Add(mapCfg.MapId, objInfo); } private IEnumerator LoadCoroutine() { //载入飞行传送数据 FlyTeleportDataManager.Load(); yield return null; var iter = DeclareMapsetting.CacheData.GetEnumerator(); while (iter.MoveNext()) { if (string.IsNullOrEmpty(iter.Current.Value.MapInfo)) continue; //先加载普通地图 if (iter.Current.Value.Type != (int)MapTypeDef.Map) continue; if (!_mapObjInfoTable.ContainsKey(iter.Current.Key)) { LoadSingleMap(iter.Current.Value); yield return null; yield return null; yield return null; yield return null; yield return null; } } iter = DeclareMapsetting.CacheData.GetEnumerator(); while (iter.MoveNext()) { if (string.IsNullOrEmpty(iter.Current.Value.MapInfo)) continue; //再加载副本地图 if (iter.Current.Value.Type == (int)MapTypeDef.Map) continue; //已经载入了,直接返回 if (!_mapObjInfoTable.ContainsKey(iter.Current.Key)) { LoadSingleMap(iter.Current.Value); yield return null; yield return null; yield return null; yield return null; yield return null; } } //Debug.Log("MapPathInfo Load Finished!"); } // 获取到目标地图需要穿过的地图列表 public List FindThroughMaps(int from, int to) { const int invalidIdx = -1; // 无效索引 List ret = new List(); // 返回从form到to会经过的地图(包含from,to) List mapList = new List(); // 已经搜索到的地图(用于遍历,探索能到达的地图) Thousandto.Core.Base.HashSet mapSet = new Thousandto.Core.Base.HashSet(); // 已经搜索到的地图(用于判定地图是否已搜索到) List idxList = new List(); // 例: mapList[1],mapList[2]由mapList[0]传送过来,idxList[1],idxList[2]则记为0 if (from == to) { return ret; } // 1.将起始地图放入探索列表 mapList.Add(from); mapSet.Add(from); idxList.Add(invalidIdx); // 2.开始探索 for (int idx = 0; idx < mapList.Count; idx++) { // 2.1 获取地图信息 if (!_mapTeleporterInfo.ContainsKey(mapList[idx])) { FLogger.DebugLogError("[MapPathInfo] FindThroughMaps 获取地图传送点信息失败" , mapList[idx]); break; } var teleportList = _mapTeleporterInfo[mapList[idx]]; // 2.2 探索当前地图能到达的地图 int count; for (count = 0; count < teleportList.Count; count++) { // 2.2.1 将地图加入到探索列表(不能重复加入) int mapID = teleportList[count].MapId; if (mapSet.Contains(mapID)) { continue; } mapList.Add(mapID); mapSet.Add(mapID); idxList.Add(idx); // 2.2.2 找到目标地图,停止探索 if (mapID == to) { break; } } // 2.3 已找到目标地图,获得路径 if (count < teleportList.Count) { for (int mapIdx = mapList.Count - 1; mapIdx != invalidIdx; mapIdx = idxList[mapIdx]) { ret.Add(mapList[mapIdx]); } ret.Reverse(); break; } } return ret; } // 获取到下一地图的传送点 public bool GetTeleport(int from, int to, ref Vector3 outVec) { if (!_mapTeleporterInfo.ContainsKey(from)) { return false; } var teleportList = _mapTeleporterInfo[from]; for (int i = 0; i < teleportList.Count; i++) { var teleport = teleportList[i]; if (teleport.MapId == to) { outVec = teleport.Pos; return true; } } return false; } //是否存在该npcid public bool IsExitNpcPos(int npcId) { if(_npcInfo.ContainsKey(npcId)) { return true; } return false; } // 获取NPC坐标 public Position GetNpcPosition(int npcId) { if (_npcInfo.ContainsKey(npcId)) { return _npcInfo[npcId]; } else { FLogger.DebugLogError(string.Format("NPC{0}没有种在该地图上",npcId)); return null; } } //额外增加npc坐标 public void AddNpcPosition(int npcId, Position pos) { if (!_npcInfo.ContainsKey(npcId)) { _npcInfo[npcId] = pos; } } // 获取怪物坐标(可能存在多个) public List GetMonsterPosition(int monsterId,int campid = 0) { campid = 0; if (_monsterInfo.ContainsKey(monsterId)) { List list; var dic = _monsterInfo[monsterId]; if(campid != 0) { if (dic.TryGetValue(campid, out list)) { return list; } } if (dic.TryGetValue(0, out list)) { return list; } else { FLogger.DebugLogError(string.Format("怪物{0}没有种在该地图上",monsterId)); return null; } } else { FLogger.DebugLogError(string.Format("怪物{0}没有种在该地图上", monsterId)); return null; } } // 获取采集坐标(可能存在多个) public List GetCollectPosition(int collectId, int campid = 0) { campid = 0; if (_collectInfo.ContainsKey(collectId)) { List list; var dic = _collectInfo[collectId]; if (campid != 0) { if (dic.TryGetValue(campid, out list)) { return list; } } if (dic.TryGetValue(0, out list)) { return list; } else { FLogger.DebugLogError(string.Format("采集物{0}没有种在该地图上",collectId)); return null; } } else { FLogger.DebugLogError(string.Format("采集物{0}没有种在该地图上",collectId)); return null; } } // 获取复活点位置,可能有多个 public List GetSpawnPosition(int mapID) { List result = null; _spawnInfo.TryGetValue(mapID, out result); return result; } //获取地图信息 public MapObjInfo GetMapObjInfo(int mapID) { MapObjInfo info = null; _mapObjInfoTable.TryGetValue(mapID, out info); return info; } #endregion #region 私有函数 // 读取地图传送点数据 private void ReadTriggerData(int mapId, MapInfoBody mapInfo, MapObjInfo objInfo) { List list = new List(); for (int i = 0; i < mapInfo.mapTriggers.Count; i++) { TriggerData data = mapInfo.mapTriggers[i]; if (data.m_inArgs == null || data.m_inArgs.Count <= 0) { FLogger.DebugLogError("[MapPathInfo] Initialize 传送点数据异常,mapId:" , mapId); continue; } int targetMapID = 0; if (int.TryParse(data.m_inArgs[0], out targetMapID)) { if (DeclareMapsetting.Get(targetMapID) != null) { list.Add(new Position(targetMapID, data.m_pos)); } } } _mapTeleporterInfo.Add(mapId, list); objInfo.TeleportInfo = list; } // 读取NPC位置信息 private void ReadNpcData(int mapId, MapInfoBody mapInfo, MapObjInfo objInfo) { for (int i = 0; i < mapInfo.mapNpcStubs.Count; i++) { NpcStubData npc = mapInfo.mapNpcStubs[i]; if (_npcInfo.ContainsKey(npc.m_id)) { FLogger.DebugLogError("[MapPathInfo] Initialize NPC 重复:" , npc.m_id , " 1.MapId:" ,mapId , " 2.MapId:" , _npcInfo[npc.m_id].MapId); FLogger.DebugAssert(false, "Initialize NPC 重复"); continue; } _npcInfo.Add(npc.m_id, new Position(mapId, npc.m_pos)); } objInfo.NpcInfo = new Dictionary(); for (int i = 0; i < mapInfo.mapNpcStubs.Count; i++) { NpcStubData npc = mapInfo.mapNpcStubs[i]; if (objInfo.NpcInfo.ContainsKey(npc.m_id)) { FLogger.DebugLogError("[MapPathInfo] Initialize NPC 重复:" , npc.m_id , " 1.MapId:" ,mapId , " 2.MapId:" , _npcInfo[npc.m_id].MapId); FLogger.DebugAssert(false, "Initialize NPC 重复"); continue; } objInfo.NpcInfo.Add(npc.m_id, new Position(mapId, npc.m_pos)); } ReadStatueNpcData(mapId, mapInfo, objInfo); } //读取雕像的npc信息 private void ReadStatueNpcData(int mapId,MapInfoBody mapInfo, MapObjInfo objInfo) { var iter = DeclareStatueModel.CacheData.GetEnumerator(); try { while(iter.MoveNext()) { DeclareStatueModel cfg = iter.Current.Value; int npcid = cfg.Npcid; int MapId = cfg.Mapid; if (MapId == mapId) { Vector3 Pos = new Vector3(cfg.X, 0.0f, cfg.Y); Position pos = new Position(MapId, Pos); if (_npcInfo.ContainsKey(npcid)) { continue; } _npcInfo.Add(npcid, new Position(MapId, Pos)); objInfo.NpcInfo.Add(npcid, new Position(MapId, Pos)); } } } finally { iter.Dispose(); } } // 读取怪物位置信息 private void ReadMonsterData(int mapId, int campID, MapInfoBody mapInfo, MapObjInfo objInfo) { for (int i = 0; i < mapInfo.mapMonsterStubs.Count; i++) { Dictionary> table; MonsterStubData monster = mapInfo.mapMonsterStubs[i]; if (!_monsterInfo.TryGetValue(monster.m_id, out table)) { table = new Dictionary>(); } List list = null; if (!table.TryGetValue(campID, out list)) { list = new List(); } list.Add(new Position(mapId, monster.m_pos)); table[campID] = list; _monsterInfo[monster.m_id] = table; } objInfo.MonsterInfo = new Dictionary>(); for (int i = 0; i < mapInfo.mapMonsterStubs.Count; i++) { List list; MonsterStubData monster = mapInfo.mapMonsterStubs[i]; if (objInfo.MonsterInfo.ContainsKey(monster.m_id)) { list = objInfo.MonsterInfo[monster.m_id]; } else { list = new List(); objInfo.MonsterInfo.Add(monster.m_id, list); } list.Add(new Position(mapId, monster.m_pos)); } } // 读取采集位置信息 private void ReadCollectData(int mapId, int campID, MapInfoBody mapInfo, MapObjInfo objInfo) { for (int i = 0; i < mapInfo.mapCollections.Count; i++) { Dictionary> table; CollectionData collect = mapInfo.mapCollections[i]; if (!_collectInfo.TryGetValue(collect.m_id, out table)) { table = new Dictionary>(); } List list = null; if (!table.TryGetValue(campID, out list)) { list = new List(); } list.Add(new Position(mapId, collect.m_pos)); table[campID] = list; _collectInfo[collect.m_id] = table; } objInfo.CollectInfo = new Dictionary>(); for (int i = 0; i < mapInfo.mapCollections.Count; i++) { List list; CollectionData collect = mapInfo.mapCollections[i]; if (objInfo.CollectInfo.ContainsKey(collect.m_id)) { list = objInfo.CollectInfo[collect.m_id]; } else { list = new List(); objInfo.CollectInfo.Add(collect.m_id, list); } list.Add(new Position(mapId, collect.m_pos)); } } //读取复活点信息 private void ReadSpawnData(int mapId, MapInfoBody mapInfo, MapObjInfo objInfo) { List list = new List(); for (int i = 0; i < mapInfo.mapSpawnPoints.Count; i++) { list.Add(new Vector2(mapInfo.mapSpawnPoints[i].m_pos.x, mapInfo.mapSpawnPoints[i].m_pos.z)); } _spawnInfo.Add(mapId, list); objInfo.SpawnInfo = list; } #endregion } }