Files
Main/Assets/Code/Logic/_Required/PathFinder/MapPathInfo.cs
2025-01-25 04:38:09 +08:00

569 lines
19 KiB
C#

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
{
/// <summary>
/// 地图传送点信息
/// </summary>
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<Position> TeleportInfo = null;
public Dictionary<int, Position> NpcInfo = null;
public Dictionary<int, List<Position>> MonsterInfo = null;
public Dictionary<int, List<Position>> CollectInfo = null;
public List<Vector2> SpawnInfo = null;
}
#endregion
#region
// 地图传送点信息
private Dictionary<int, List<Position>> _mapTeleporterInfo;
// NPC信息
private Dictionary<int, Position> _npcInfo;
// 怪物信息
private Dictionary<int, Dictionary<int,List<Position>>> _monsterInfo;
// 采集信息
private Dictionary<int, Dictionary<int, List<Position>>> _collectInfo;
//复活点信息
private Dictionary<int, List<Vector2>> _spawnInfo;
//地图信息
private Dictionary<int, MapObjInfo> _mapObjInfoTable = null;
#endregion
#region
public bool IsLoadFinish
{
get
{
return true;
}
}
public Dictionary<int, MapObjInfo> MapObjInfoTable
{
get
{
return _mapObjInfoTable;
}
}
public MapPathInfo()
{
_mapTeleporterInfo = new Dictionary<int, List<Position>>();
_npcInfo = new Dictionary<int, Position>();
_monsterInfo = new Dictionary<int, Dictionary<int, List<Position>>>();
_collectInfo = new Dictionary<int, Dictionary<int, List<Position>>>();
_spawnInfo = new Dictionary<int, List<Vector2>>();
_mapObjInfoTable = new Dictionary<int, MapObjInfo>();
}
// 初始化
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<int> FindThroughMaps(int from, int to)
{
const int invalidIdx = -1; // 无效索引
List<int> ret = new List<int>(); // 返回从form到to会经过的地图(包含from,to)
List<int> mapList = new List<int>(); // 已经搜索到的地图(用于遍历,探索能到达的地图)
Thousandto.Core.Base.HashSet<int> mapSet = new Thousandto.Core.Base.HashSet<int>(); // 已经搜索到的地图(用于判定地图是否已搜索到)
List<int> idxList = new List<int>(); // 例: 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<Position> GetMonsterPosition(int monsterId,int campid = 0)
{
campid = 0;
if (_monsterInfo.ContainsKey(monsterId))
{
List<Position> 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<Position> GetCollectPosition(int collectId, int campid = 0)
{
campid = 0;
if (_collectInfo.ContainsKey(collectId))
{
List<Position> 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<Vector2> GetSpawnPosition(int mapID)
{
List<Vector2> 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<Position> list = new List<Position>();
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<int, Position>();
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<int, List<Position>> table;
MonsterStubData monster = mapInfo.mapMonsterStubs[i];
if (!_monsterInfo.TryGetValue(monster.m_id, out table))
{
table = new Dictionary<int, List<Position>>();
}
List<Position> list = null;
if (!table.TryGetValue(campID, out list))
{
list = new List<Position>();
}
list.Add(new Position(mapId, monster.m_pos));
table[campID] = list;
_monsterInfo[monster.m_id] = table;
}
objInfo.MonsterInfo = new Dictionary<int, List<Position>>();
for (int i = 0; i < mapInfo.mapMonsterStubs.Count; i++)
{
List<Position> list;
MonsterStubData monster = mapInfo.mapMonsterStubs[i];
if (objInfo.MonsterInfo.ContainsKey(monster.m_id))
{
list = objInfo.MonsterInfo[monster.m_id];
}
else
{
list = new List<Position>();
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<int, List<Position>> table;
CollectionData collect = mapInfo.mapCollections[i];
if (!_collectInfo.TryGetValue(collect.m_id, out table))
{
table = new Dictionary<int, List<Position>>();
}
List<Position> list = null;
if (!table.TryGetValue(campID, out list))
{
list = new List<Position>();
}
list.Add(new Position(mapId, collect.m_pos));
table[campID] = list;
_collectInfo[collect.m_id] = table;
}
objInfo.CollectInfo = new Dictionary<int, List<Position>>();
for (int i = 0; i < mapInfo.mapCollections.Count; i++)
{
List<Position> list;
CollectionData collect = mapInfo.mapCollections[i];
if (objInfo.CollectInfo.ContainsKey(collect.m_id))
{
list = objInfo.CollectInfo[collect.m_id];
}
else
{
list = new List<Position>();
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<Vector2> list = new List<Vector2>();
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
}
}