Anime.cs 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /**
  2. * 魔力宝贝图档解析脚本 - CGTool
  3. *
  4. * @Author HonorLee (dev@honorlee.me)
  5. * @Version 1.0 (2023-04-15)
  6. * @License GPL-3.0
  7. *
  8. * Anime.cs 动画基础类
  9. */
  10. using System;
  11. using System.Collections.Generic;
  12. using System.IO;
  13. using UnityEngine;
  14. namespace CGTool
  15. {
  16. //动画信息
  17. public class AnimeInfo
  18. {
  19. public int Version;
  20. //4 bytes 动画索引
  21. public uint Index;
  22. //4 bytes 动画文件地址
  23. public uint Addr;
  24. //2 bytes 动作数量
  25. public int ActionCount;
  26. //2 bytes 未知字节
  27. public byte[] Unknow;
  28. //动画数据 Direction -> ActionType -> AnimeData
  29. public Dictionary<int, Dictionary<int, AnimeDetail>> AnimeDatas = new Dictionary<int, Dictionary<int, AnimeDetail>>();
  30. }
  31. //动画帧数据
  32. public class AnimeFrameInfo
  33. {
  34. //图档编号
  35. public uint GraphicIndex;
  36. //偏移X
  37. public int OffsetX;
  38. //偏移Y
  39. public int OffsetY;
  40. //音效编号
  41. public int AudioIndex;
  42. //动效编号
  43. public Anime.EffectType Effect;
  44. }
  45. //动画数据
  46. public class AnimeDetail
  47. {
  48. public uint Index;
  49. public int Version;
  50. public int Direction;
  51. public int ActionType;
  52. public uint CycleTime;
  53. public uint FrameCount;
  54. public AnimeFrameInfo[] AnimeFrameInfos;
  55. // public byte[] unknown;
  56. }
  57. //动画相关Enum类型
  58. public class Anime : MonoBehaviour
  59. {
  60. //方向
  61. public enum DirectionType
  62. {
  63. NULL=-1,
  64. North=0,
  65. NorthEast=1,
  66. East=2,
  67. SouthEast=3,
  68. South=4,
  69. SouthWest=5,
  70. West=6,
  71. NorthWest=7
  72. }
  73. //动作(未补全)
  74. public enum ActionType
  75. {
  76. Stand=0,
  77. Walk=1,
  78. BeforeRun=2,
  79. Run=3,
  80. AfterRun=4,
  81. Attack=5,
  82. }
  83. //动效
  84. public enum EffectType
  85. {
  86. Hit=1,
  87. HitOver=2
  88. }
  89. //动画列表缓存 Index -> AnimeInfo
  90. private static Dictionary<uint, AnimeInfo> _animeInfoCache = new Dictionary<uint, AnimeInfo>();
  91. //动画序列缓存 Direction -> Action -> AnimeData
  92. // private static Dictionary<uint, Dictionary<int, AnimeData>> _animeCache =
  93. // new Dictionary<uint, Dictionary<int, AnimeData>>();
  94. private static List<string> _animeInfoFiles = new List<string>()
  95. {
  96. //龙之沙漏 之前版本前Info数据
  97. "AnimeInfo_4.bin",
  98. //龙之沙漏 版本Info数据
  99. "AnimeInfoEx_1.Bin"
  100. };
  101. private static List<string> _animeDataFiles = new List<string>()
  102. {
  103. "Anime_4.bin", "AnimeEx_1.Bin"
  104. };
  105. //获取动画数据信息
  106. public static AnimeInfo GetAnimeInfo(uint Index)
  107. {
  108. //返回缓存
  109. if (_animeInfoCache.ContainsKey(Index)) return _animeInfoCache[Index];
  110. //动画编号大于105000的属于 龙之沙漏 版本
  111. int Version = 0;
  112. if (Index >= 105000) Version = 1;
  113. Dictionary<uint, AnimeInfo> animeInfos = _loadAnimeInfo(Version);
  114. if (animeInfos.ContainsKey(Index)) return animeInfos[Index];
  115. return null;
  116. }
  117. //获取动画数据
  118. public static AnimeDetail GetAnimeDetail(uint serial,DirectionType Direction,ActionType Action)
  119. {
  120. AnimeInfo animeInfo = GetAnimeInfo(serial);
  121. if (animeInfo == null) return null;
  122. if (animeInfo.AnimeDatas.ContainsKey((int)Direction))
  123. {
  124. if (animeInfo.AnimeDatas[(int)Direction].ContainsKey((int) Action))
  125. return animeInfo.AnimeDatas[(int)Direction][(int) Action];
  126. }
  127. return null;
  128. }
  129. //加载动画数据
  130. private static Dictionary<uint, AnimeInfo> _loadAnimeInfo(int Version)
  131. {
  132. //查找Info文件
  133. string infoFileName = _animeInfoFiles[Version];
  134. string dataFileName = _animeDataFiles[Version];
  135. FileInfo infoFile = new FileInfo(CGTool.BaseFolder + "/" + infoFileName);
  136. FileInfo dataFile = new FileInfo(CGTool.BaseFolder + "/" + dataFileName);
  137. if (!infoFile.Exists || !dataFile.Exists) return null;
  138. //创建流读取器
  139. FileStream infoFileStream = infoFile.OpenRead();
  140. FileStream dataFileStream = dataFile.OpenRead();
  141. BinaryReader infoFileReader = new BinaryReader(infoFileStream);
  142. BinaryReader dataFileReader = new BinaryReader(dataFileStream);
  143. // Dictionary<uint, AnimeInfo> animeInfos = new Dictionary<uint, AnimeInfo>();
  144. long DataLength = infoFileStream.Length / 12;
  145. for (int i = 0; i < DataLength; i++)
  146. {
  147. //初始化对象
  148. AnimeInfo animeInfo = new AnimeInfo();
  149. animeInfo.Version = Version;
  150. animeInfo.Index = BitConverter.ToUInt32(infoFileReader.ReadBytes(4),0);
  151. animeInfo.Addr = BitConverter.ToUInt32(infoFileReader.ReadBytes(4),0);
  152. animeInfo.ActionCount = infoFileReader.ReadUInt16();
  153. animeInfo.Unknow = infoFileReader.ReadBytes(2);
  154. // print(JsonUtility.ToJson(animeInfo));
  155. dataFileStream.Position = animeInfo.Addr;
  156. for (int j = 0; j < animeInfo.ActionCount; j++)
  157. {
  158. AnimeDetail animeData = new AnimeDetail();
  159. animeData.Index = animeInfo.Index;
  160. animeData.Version = Version;
  161. animeData.Direction = dataFileReader.ReadUInt16();
  162. animeData.ActionType = dataFileReader.ReadUInt16();
  163. animeData.CycleTime = BitConverter.ToUInt32(dataFileReader.ReadBytes(4),0);
  164. animeData.FrameCount = BitConverter.ToUInt32(dataFileReader.ReadBytes(4),0);
  165. animeData.AnimeFrameInfos = new AnimeFrameInfo[animeData.FrameCount];
  166. // if (animeInfo.Index == 101201) Debug.Log("----------------------------------");
  167. for (int k = 0; k < animeData.FrameCount; k++)
  168. {
  169. animeData.AnimeFrameInfos[k] = new AnimeFrameInfo();
  170. //GraphicIndex序号
  171. animeData.AnimeFrameInfos[k].GraphicIndex = BitConverter.ToUInt32(dataFileReader.ReadBytes(4),0);
  172. //未知字节
  173. // animeData.unknown = dataFileReader.ReadBytes(6);
  174. // if (animeInfo.Index == 101201)
  175. // {
  176. // byte[] tt = dataFileReader.ReadBytes(6);
  177. //
  178. // Debug.Log(tt[0]+" "+tt[1]+" "+tt[2]+" "+tt[3]+" "+tt[4]+" "+tt[5]);
  179. // }
  180. // else
  181. // {
  182. // dataFileReader.ReadBytes(6);
  183. // }
  184. animeData.AnimeFrameInfos[k].OffsetX = BitConverter.ToInt16(dataFileReader.ReadBytes(2),0);
  185. animeData.AnimeFrameInfos[k].OffsetY = BitConverter.ToInt16(dataFileReader.ReadBytes(2),0);
  186. animeData.AnimeFrameInfos[k].AudioIndex = dataFileReader.ReadByte();
  187. int effect = dataFileReader.ReadByte();
  188. if (effect == 0x27 || effect == 0x28)
  189. {
  190. animeData.AnimeFrameInfos[k].Effect = EffectType.Hit;
  191. }
  192. else if(effect == 0x4E || effect == 0x4F)
  193. {
  194. animeData.AnimeFrameInfos[k].Effect = EffectType.HitOver;
  195. }
  196. // animeData.AnimeFrameInfos[k].Effect = dataFileReader.ReadByte();
  197. }
  198. if (!animeInfo.AnimeDatas.ContainsKey(animeData.Direction))
  199. animeInfo.AnimeDatas.Add(animeData.Direction, new Dictionary<int, AnimeDetail>());
  200. if (animeInfo.AnimeDatas[animeData.Direction].ContainsKey(animeData.ActionType))
  201. {
  202. animeInfo.AnimeDatas[animeData.Direction][animeData.ActionType] = animeData;
  203. }
  204. else
  205. {
  206. animeInfo.AnimeDatas[animeData.Direction].Add(animeData.ActionType, animeData);
  207. }
  208. if (_animeInfoCache.ContainsKey(animeInfo.Index))
  209. {
  210. _animeInfoCache[animeInfo.Index] = animeInfo;
  211. }
  212. else
  213. {
  214. _animeInfoCache.Add(animeInfo.Index, animeInfo);
  215. }
  216. }
  217. }
  218. infoFileReader.Dispose();
  219. infoFileReader.Close();
  220. dataFileReader.Dispose();
  221. dataFileReader.Close();
  222. infoFileStream.Close();
  223. dataFileStream.Close();
  224. return _animeInfoCache;
  225. }
  226. }
  227. }