Map.cs 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /**
  2. * 魔力宝贝图档解析脚本 - CGTool
  3. *
  4. * @Author HonorLee (dev@honorlee.me)
  5. * @Version 1.0 (2023-04-15)
  6. * @License GPL-3.0
  7. *
  8. * Map.cs 服务端地图解析类
  9. */
  10. using System;
  11. using System.Collections.Generic;
  12. using System.IO;
  13. namespace CGTool
  14. {
  15. //地图文件信息
  16. public class MapFileInfo
  17. {
  18. public uint Serial;
  19. public string Name;
  20. public string FileName;
  21. }
  22. //地图块数据
  23. public class MapBlockData
  24. {
  25. public GraphicInfoData GraphicInfo;
  26. // public uint GraphicIndex;
  27. public uint MapSerial;
  28. }
  29. //地图信息
  30. public class MapInfo
  31. {
  32. //地图编号
  33. public uint Serial;
  34. //地图宽度
  35. public uint Width;
  36. //地图高度
  37. public uint Height;
  38. // 地图名称
  39. public string Name;
  40. //未知数据
  41. public byte[] Unknow;
  42. //地面数据
  43. public List<MapBlockData> GroundDatas = new List<MapBlockData>();
  44. //地表数据
  45. public List<MapBlockData> ObjectDatas = new List<MapBlockData>();
  46. public bool[] BlockedIndexs;
  47. public bool[,] MapPoints;
  48. }
  49. public class Map
  50. {
  51. //缓存数据
  52. private static Dictionary<uint, MapInfo> _cache = new Dictionary<uint, MapInfo>();
  53. private static Dictionary<uint, MapFileInfo> _mapIndexFiles = new Dictionary<uint, MapFileInfo>();
  54. //初始化地图文件列表
  55. public static void Init()
  56. {
  57. DirectoryInfo mapDirectory = new DirectoryInfo(CGTool.MapFolder);
  58. FileInfo[] mapFiles = mapDirectory.GetFiles();
  59. foreach (var fileInfo in mapFiles)
  60. {
  61. string filename = fileInfo.Name;
  62. if(filename.Equals(".DS_Store")) continue;
  63. MapFileInfo _file = new MapFileInfo();
  64. string[] indexName = filename.Split(("_").ToCharArray());
  65. _file.Serial = uint.Parse(indexName[0]);
  66. _file.Name = indexName[1];
  67. _file.FileName = filename;
  68. _mapIndexFiles.Add(_file.Serial, _file);
  69. }
  70. }
  71. //获取全部地图列表
  72. public static List<MapFileInfo> GetMapList()
  73. {
  74. List<MapFileInfo> _list = new List<MapFileInfo>();
  75. foreach (var mapIndexFile in _mapIndexFiles)
  76. {
  77. _list.Add(mapIndexFile.Value);
  78. }
  79. return _list;
  80. }
  81. //获取地图数据
  82. public static MapInfo GetMap(uint serial)
  83. {
  84. //返回缓存数据
  85. if (_cache.ContainsKey(serial)) return _cache[serial];
  86. //加载数据
  87. MapInfo mapInfo = _loadMap(serial);
  88. return mapInfo;
  89. }
  90. //加载地图数据
  91. private static MapInfo _loadMap(uint serial)
  92. {
  93. // CGTool.Logger.Write("开始加载时间:" + DateTime.Now);
  94. if (!_mapIndexFiles.ContainsKey(serial)) return null;
  95. // print("找到地图文件: " + mapFileInfo.Name);
  96. FileStream mapFileStream = new FileStream(CGTool.MapFolder + "/" + _mapIndexFiles[serial].FileName, FileMode.Open);
  97. BinaryReader mapFileReader = new BinaryReader(mapFileStream);
  98. MapInfo mapInfo = new MapInfo();
  99. mapInfo.Serial = serial;
  100. //地图文件头
  101. byte[] mapHeader = mapFileReader.ReadBytes( 8);
  102. //地图名称
  103. byte[] mapNameBytes = mapFileReader.ReadBytes(32);
  104. mapInfo.Name = System.Text.Encoding.GetEncoding("GBK").GetString(mapNameBytes).Split('|')[0];
  105. //读取地图宽度
  106. byte[] bytes = mapFileReader.ReadBytes(2);
  107. Array.Reverse(bytes);
  108. mapInfo.Width = (uint)BitConverter.ToUInt16(bytes,0);
  109. //读取地图高度
  110. bytes = mapFileReader.ReadBytes(2);
  111. Array.Reverse(bytes);
  112. mapInfo.Height = (uint)BitConverter.ToUInt16(bytes,0);
  113. byte[] mapBytes = mapFileReader.ReadBytes((int) (mapInfo.Width * mapInfo.Height * 2));
  114. byte[] mapCoverBytes = mapFileReader.ReadBytes((int) (mapInfo.Width * mapInfo.Height * 2));
  115. mapFileReader.Dispose();
  116. mapFileReader.Close();
  117. mapFileStream.Close();
  118. // print(JsonUtility.ToJson(mapInfo));
  119. BinaryReader mapReader = new BinaryReader(new MemoryStream(mapBytes));
  120. BinaryReader mapCoverReader = new BinaryReader(new MemoryStream(mapCoverBytes));
  121. // BinaryReader mapInfoReader = new BinaryReader(new MemoryStream(mapInfoBytes));
  122. List<MapBlockData> tempGroundTiles = new List<MapBlockData>();
  123. List<MapBlockData> tempObjectTiles = new List<MapBlockData>();
  124. // CGTool.Logger.Write("开始解析时间:" + DateTime.Now);
  125. uint len = mapInfo.Width * mapInfo.Height;
  126. for (uint i = 0; i < len; i++)
  127. {
  128. //地面数据
  129. MapBlockData mapTile = null;
  130. bytes = mapReader.ReadBytes(2);
  131. Array.Reverse(bytes);
  132. uint mapGraphicSerial = BitConverter.ToUInt16(bytes,0);
  133. int Version = 0;
  134. if (mapGraphicSerial > 20000)
  135. {
  136. mapGraphicSerial += 200000;
  137. Version = 1;
  138. }
  139. GraphicInfoData graphicInfoData = GraphicInfo.GetGraphicInfoDataByMapSerial(Version, mapGraphicSerial);
  140. if (graphicInfoData != null)
  141. {
  142. mapTile = new MapBlockData();
  143. mapTile.GraphicInfo = graphicInfoData;
  144. mapTile.MapSerial = mapGraphicSerial;
  145. }
  146. tempGroundTiles.Add(mapTile);
  147. MapBlockData mapCoverTile = null;
  148. bytes = mapCoverReader.ReadBytes(2);
  149. Array.Reverse(bytes);
  150. uint mapCoverGraphicSerial = BitConverter.ToUInt16(bytes,0);
  151. Version = 0;
  152. if (mapCoverGraphicSerial > 30000 || mapCoverGraphicSerial==25290)
  153. {
  154. mapCoverGraphicSerial += 200000;
  155. Version = 1;
  156. }
  157. graphicInfoData = GraphicInfo.GetGraphicInfoDataByMapSerial(Version, mapCoverGraphicSerial);
  158. if (graphicInfoData != null)
  159. {
  160. mapCoverTile = new MapBlockData();
  161. mapCoverTile.GraphicInfo = graphicInfoData;
  162. mapCoverTile.MapSerial = mapCoverGraphicSerial;
  163. }
  164. tempObjectTiles.Add(mapCoverTile);
  165. }
  166. List<MapBlockData> GroundTiles = new List<MapBlockData>();
  167. List<MapBlockData> ObjectTiles = new List<MapBlockData>();
  168. bool[] blockedIndexs = new bool[mapInfo.Width * mapInfo.Height];
  169. // CGTool.Logger.Write("开始排序时间:" + DateTime.Now);
  170. for (int y = 0; y < mapInfo.Height; y++)
  171. {
  172. for (int x = 0; x < mapInfo.Width; x++)
  173. {
  174. // int index = i * (int) mapInfo.Width + ((int) mapInfo.Width - j - 1);
  175. int _tmpindex = x + (int)((mapInfo.Height - y - 1) * mapInfo.Width);
  176. int index = x + y * (int)mapInfo.Width;
  177. MapBlockData mapTile = tempGroundTiles[_tmpindex];
  178. MapBlockData ObjectTile = tempObjectTiles[_tmpindex];
  179. GroundTiles.Add(mapTile);
  180. ObjectTiles.Add(ObjectTile);
  181. if (mapTile==null || mapTile.GraphicInfo.Blocked) blockedIndexs[index] = true;
  182. if (ObjectTile!=null && ObjectTile.GraphicInfo.Blocked)
  183. {
  184. blockedIndexs[index] = true;
  185. if (ObjectTile.GraphicInfo.East > 0 || ObjectTile.GraphicInfo.South > 0)
  186. {
  187. for (int i = x; i < (x + ObjectTile.GraphicInfo.East); i++)
  188. {
  189. for (int j = y; j < (y+ ObjectTile.GraphicInfo.South); j++)
  190. {
  191. if(i>=mapInfo.Width || j>=mapInfo.Height) continue;
  192. int _index = (int) (j * mapInfo.Width + i);
  193. blockedIndexs[_index] = true;
  194. }
  195. }
  196. }
  197. }
  198. }
  199. }
  200. bool[,] points = new bool[mapInfo.Width, mapInfo.Height];
  201. for (int y = 0; y < mapInfo.Height; y++)
  202. {
  203. for (int x = 0; x < mapInfo.Width; x++)
  204. {
  205. int index = x + y * (int)mapInfo.Width;
  206. points[x, y] = !blockedIndexs[index];
  207. }
  208. }
  209. mapInfo.GroundDatas = GroundTiles;
  210. mapInfo.ObjectDatas = ObjectTiles;
  211. mapInfo.BlockedIndexs = blockedIndexs;
  212. mapInfo.MapPoints = points;
  213. _cache[serial] = mapInfo;
  214. // CGTool.Logger.Write("地图解析完成时间:" + DateTime.Now);
  215. return mapInfo;
  216. }
  217. }
  218. }