Kernel_bin.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. namespace OpenVIII.Kernel
  5. {
  6. public class KernelBin
  7. {
  8. #region Fields
  9. public const ushort MaxHPValue = 9999;
  10. public const byte MaxStatValue = 255;
  11. #endregion Fields
  12. #region Constructors
  13. /// <summary>
  14. /// Read binary data from into structures and arrays
  15. /// </summary>
  16. /// <see cref="http://forums.qhimm.com/index.php?topic=16923.msg240609#msg240609"/>
  17. /// <seealso cref="https://github.com/alexfilth/doomtrain"/>
  18. /// <seealso cref="https://github.com/alexfilth/doomtrain/wiki/Kernel.bin"/>
  19. public KernelBin()
  20. {
  21. Memory.Log.WriteLine($"{nameof(KernelBin)} :: new ");
  22. ArchiveBase aw = ArchiveWorker.Load(ArchiveString);
  23. byte[] buffer = aw.GetBinaryFile(Memory.Strings[Strings.FileID.KERNEL].GetFilenames()[0]);
  24. List<Loc> subPositions = Memory.Strings[Strings.FileID.KERNEL].GetFiles().subPositions;
  25. MemoryStream ms;
  26. if (buffer == null) return;
  27. using (BinaryReader br = new BinaryReader(ms = new MemoryStream(buffer)))
  28. {
  29. ms.Seek(subPositions[BattleCommand.ID], SeekOrigin.Begin);
  30. BattleCommands = BattleCommand.Read(br);
  31. ms.Seek(subPositions[Magic_Data.id], SeekOrigin.Begin);
  32. MagicData = Magic_Data.Read(br);
  33. ms.Seek(subPositions[Junctionable_GFs_Data.id], SeekOrigin.Begin);
  34. JunctionableGFsData = Junctionable_GFs_Data.Read(br);
  35. ms.Seek(subPositions[Enemy_Attacks_Data.id], SeekOrigin.Begin);
  36. EnemyAttacksData = Enemy_Attacks_Data.Read(br);
  37. ms.Seek(subPositions[Weapons_Data.id], SeekOrigin.Begin);
  38. WeaponsData = Weapons_Data.Read(br);
  39. ms.Seek(subPositions[Renzokuken_Finishers_Data.id], SeekOrigin.Begin);
  40. RenzokukenFinishersData = Renzokuken_Finishers_Data.Read(br);
  41. ms.Seek(subPositions[Character_Stats.id], SeekOrigin.Begin);
  42. CharacterStats = Character_Stats.Read(br);
  43. ms.Seek(subPositions[BattleItemData.ID], SeekOrigin.Begin);
  44. BattleItemsData = BattleItemData.Read(br);
  45. NonBattleItemsData = Non_battle_Items_Data.Read();
  46. ms.Seek(subPositions[Non_Junctionable_GFs_Attacks_Data.id], SeekOrigin.Begin);
  47. NonJunctionableGFsAttacksData = Non_Junctionable_GFs_Attacks_Data.Read(br);
  48. ms.Seek(subPositions[Command_ability_data.id], SeekOrigin.Begin);
  49. CommandAbilityData = Command_ability_data.Read(br);
  50. ms.Seek(subPositions[Kernel.JunctionAbilities.ID], SeekOrigin.Begin);
  51. JunctionAbilities = Kernel.JunctionAbilities.Read(br);
  52. ms.Seek(subPositions[Kernel.CommandAbilities.ID], SeekOrigin.Begin);
  53. CommandAbilities = Kernel.CommandAbilities.Read(br);
  54. ms.Seek(subPositions[StatPercentageAbilities.ID], SeekOrigin.Begin);
  55. StatPercentAbilities = StatPercentageAbilities.Read(br);
  56. ms.Seek(subPositions[Kernel.CharacterAbilities.ID], SeekOrigin.Begin);
  57. CharacterAbilities = Kernel.CharacterAbilities.Read(br);
  58. ms.Seek(subPositions[Kernel.PartyAbilities.ID], SeekOrigin.Begin);
  59. PartyAbilities = Kernel.PartyAbilities.Read(br);
  60. ms.Seek(subPositions[Kernel.GFAbilities.ID], SeekOrigin.Begin);
  61. GFAbilities = Kernel.GFAbilities.Read(br);
  62. ms.Seek(subPositions[Kernel.MenuAbilities.ID], SeekOrigin.Begin);
  63. MenuAbilities = Kernel.MenuAbilities.Read(br);
  64. ms.Seek(subPositions[Temporary_character_limit_breaks.id], SeekOrigin.Begin);
  65. TemporaryCharacterLimitBreaks = Temporary_character_limit_breaks.Read(br);
  66. ms.Seek(subPositions[Blue_Magic_Quistis_limit_break.id], SeekOrigin.Begin);
  67. BlueMagicQuistisLimitBreak = Blue_Magic_Quistis_limit_break.Read(br);
  68. //ms.Seek(subPositions[Quistis_limit_break_parameters.BattleID], SeekOrigin.Begin);
  69. //QuistisLimitBreakParameters = Quistis_limit_break_parameters.Read(br);
  70. ms.Seek(subPositions[Shot_Irvine_limit_break.id], SeekOrigin.Begin);
  71. ShotIrvineLimitBreak = Shot_Irvine_limit_break.Read(br);
  72. ms.Seek(subPositions[Duel_Zell_limit_break.id], SeekOrigin.Begin);
  73. DuelZellLimitBreak = Duel_Zell_limit_break.Read(br);
  74. ms.Seek(subPositions[Zell_limit_break_parameters.id], SeekOrigin.Begin);
  75. ZellLimitBreakParameters = Zell_limit_break_parameters.Read(br);
  76. ms.Seek(subPositions[Rinoa_limit_breaks_part_1.id], SeekOrigin.Begin);
  77. RinoaLimitBreaksPart1 = Rinoa_limit_breaks_part_1.Read(br);
  78. ms.Seek(subPositions[Rinoa_limit_breaks_part_2.id], SeekOrigin.Begin);
  79. RinoaLimitBreaksPart2 = Rinoa_limit_breaks_part_2.Read(br);
  80. ms.Seek(subPositions[Slot_array.id], SeekOrigin.Begin);
  81. SlotArray = Slot_array.Read(br);
  82. ms.Seek(subPositions[Selphie_limit_break_sets.id], SeekOrigin.Begin);
  83. SelphieLimitBreakSets = Selphie_limit_break_sets.Read(br);
  84. ms.Seek(subPositions[Kernel.Devour.id], SeekOrigin.Begin);
  85. List<Devour> tmp = Kernel.Devour.Read(br);
  86. tmp.Add(new Devour { Description = Memory.Strings.Read(Strings.FileID.KERNEL, 30, 112) });
  87. Devour = tmp;
  88. ms.Seek(subPositions[Misc_section.id], SeekOrigin.Begin);
  89. MiscSection = Misc_section.Read(br);
  90. MiscTextPointers = Misc_text_pointers.Read();
  91. Dictionary<Abilities, Ability> allAbilities = new Dictionary<Abilities, Ability>(Kernel.MenuAbilities.Count + Kernel.JunctionAbilities.Count + Kernel.CommandAbilities.Count + StatPercentageAbilities.Count + Kernel.CharacterAbilities.Count + Kernel.PartyAbilities.Count + Kernel.GFAbilities.Count);
  92. foreach (Abilities ability in (Abilities[])(Enum.GetValues(typeof(Abilities))))
  93. {
  94. combine(MenuAbilities);
  95. combine(StatPercentAbilities);
  96. combine(JunctionAbilities);
  97. combine(CommandAbilities);
  98. combine(CharacterAbilities);
  99. combine(PartyAbilities);
  100. combine(GFAbilities);
  101. void combine<T>(IReadOnlyDictionary<Abilities, T> dict)
  102. where T : Ability
  103. {
  104. if (!dict.TryGetValue(ability, out T a)) return;
  105. allAbilities.Add(ability, a);
  106. }
  107. }
  108. AllAbilities = allAbilities;
  109. Dictionary<Abilities, EquippableAbility> equippableAbilities = new Dictionary<Abilities, EquippableAbility>(
  110. StatPercentageAbilities.Count +
  111. Kernel.CharacterAbilities.Count +
  112. Kernel.PartyAbilities.Count +
  113. Kernel.GFAbilities.Count);
  114. foreach (Abilities ability in (Abilities[])(Enum.GetValues(typeof(Abilities))))
  115. {
  116. if (StatPercentAbilities.ContainsKey(ability))
  117. equippableAbilities[ability] = StatPercentAbilities[ability];
  118. else if (CharacterAbilities.ContainsKey(ability))
  119. equippableAbilities[ability] = CharacterAbilities[ability];
  120. else if (PartyAbilities.ContainsKey(ability))
  121. equippableAbilities[ability] = PartyAbilities[ability];
  122. else if (CharacterAbilities.ContainsKey(ability))
  123. equippableAbilities[ability] = CharacterAbilities[ability];
  124. }
  125. EquippableAbilities = equippableAbilities;
  126. }
  127. }
  128. #endregion Constructors
  129. #region Properties
  130. public static IReadOnlyList<Stat> AutoAtk { get; } = new List<Stat>
  131. {
  132. Stat.STR,
  133. Stat.HIT,
  134. Stat.EL_Atk,
  135. Stat.ST_Atk,
  136. Stat.MAG,
  137. Stat.SPD,
  138. Stat.LUCK,
  139. Stat.HP,
  140. Stat.VIT,
  141. Stat.SPR,
  142. Stat.EVA,
  143. Stat.EL_Def_1,
  144. Stat.ST_Def_1,
  145. Stat.EL_Def_2,
  146. Stat.ST_Def_2,
  147. Stat.EL_Def_3,
  148. Stat.ST_Def_3,
  149. Stat.EL_Def_4,
  150. Stat.ST_Def_4
  151. };
  152. public static IReadOnlyList<Stat> AutoDef { get; } = new List<Stat>
  153. {
  154. Stat.HP,
  155. Stat.VIT,
  156. Stat.SPR,
  157. Stat.EVA,
  158. Stat.EL_Def_1,
  159. Stat.ST_Def_1,
  160. Stat.EL_Def_2,
  161. Stat.ST_Def_2,
  162. Stat.EL_Def_3,
  163. Stat.ST_Def_3,
  164. Stat.EL_Def_4,
  165. Stat.ST_Def_4,
  166. Stat.SPD,
  167. Stat.LUCK,
  168. Stat.MAG,
  169. Stat.STR,
  170. Stat.HIT,
  171. Stat.EL_Atk,
  172. Stat.ST_Atk
  173. };
  174. public static IReadOnlyList<Stat> AutoMAG { get; } = new List<Stat>
  175. {
  176. Stat.MAG,
  177. Stat.SPR,
  178. Stat.SPD,
  179. Stat.LUCK,
  180. Stat.HP,
  181. Stat.VIT,
  182. Stat.EVA,
  183. Stat.EL_Def_1,
  184. Stat.ST_Def_1,
  185. Stat.EL_Def_2,
  186. Stat.ST_Def_2,
  187. Stat.EL_Def_3,
  188. Stat.ST_Def_3,
  189. Stat.EL_Def_4,
  190. Stat.ST_Def_4,
  191. Stat.STR,
  192. Stat.HIT,
  193. Stat.EL_Atk,
  194. Stat.ST_Atk
  195. };
  196. /// <summary>
  197. /// Convert stat to stat junction
  198. /// </summary>
  199. public static IReadOnlyDictionary<Stat, Abilities> Stat2Ability { get; } = new Dictionary<Stat, Abilities>
  200. {
  201. { Stat.HP, Abilities.HPJ },
  202. { Stat.STR, Abilities.StrJ },
  203. { Stat.VIT, Abilities.VitJ},
  204. { Stat.MAG, Abilities.MagJ},
  205. { Stat.SPR, Abilities.SprJ },
  206. { Stat.SPD, Abilities.SpdJ },
  207. { Stat.EVA, Abilities.EvaJ },
  208. { Stat.LUCK, Abilities.LuckJ },
  209. { Stat.HIT, Abilities.HitJ },
  210. { Stat.EL_Atk, Abilities.ElAtkJ },
  211. { Stat.ST_Atk, Abilities.StAtkJ },
  212. { Stat.EL_Def_1, Abilities.ElDefJ },//or Elem_Def_Jx2 or Elem_Def_Jx4
  213. { Stat.EL_Def_2, Abilities.ElDefJ2 },//or Elem_Def_Jx4
  214. { Stat.EL_Def_3, Abilities.ElDefJ4 },
  215. { Stat.EL_Def_4, Abilities.ElDefJ4 },
  216. { Stat.ST_Def_1, Abilities.StDefJ },//or ST_Def_Jx2 or ST_Def_Jx4
  217. { Stat.ST_Def_2, Abilities.StDefJ2 },//or ST_Def_Jx4
  218. { Stat.ST_Def_3, Abilities.StDefJ4 },
  219. { Stat.ST_Def_4, Abilities.StDefJ4 }
  220. };
  221. public IReadOnlyDictionary<Abilities, Ability> AllAbilities { get; }
  222. public IReadOnlyList<BattleCommand> BattleCommands { get; }
  223. public IReadOnlyList<BattleItemData> BattleItemsData { get; }
  224. public IReadOnlyDictionary<Blue_Magic, Blue_Magic_Quistis_limit_break> BlueMagicQuistisLimitBreak { get; }
  225. public IReadOnlyDictionary<Abilities, CharacterAbilities> CharacterAbilities { get; }
  226. public IReadOnlyDictionary<Characters, Character_Stats> CharacterStats { get; }
  227. public IReadOnlyDictionary<Abilities, CommandAbilities> CommandAbilities { get; }
  228. public IReadOnlyDictionary<Abilities, Command_ability_data> CommandAbilityData { get; }
  229. public IReadOnlyList<Devour> Devour { get; }
  230. public IReadOnlyList<Duel_Zell_limit_break> DuelZellLimitBreak { get; }
  231. public IReadOnlyList<Enemy_Attacks_Data> EnemyAttacksData { get; }
  232. // should contain all abilities
  233. public IReadOnlyDictionary<Abilities, EquippableAbility> EquippableAbilities { get; }
  234. public IReadOnlyDictionary<Abilities, GFAbilities> GFAbilities { get; }
  235. //10
  236. public IReadOnlyDictionary<Abilities, JunctionAbilities> JunctionAbilities { get; }
  237. public IReadOnlyDictionary<GFs, Junctionable_GFs_Data> JunctionableGFsData { get; }
  238. public IReadOnlyList<Magic_Data> MagicData { get; }
  239. //16
  240. public IReadOnlyDictionary<Abilities, MenuAbilities> MenuAbilities { get; }
  241. //28
  242. public IReadOnlyList<Misc_section> MiscSection { get; }
  243. //29 //only_strings
  244. public IReadOnlyList<Misc_text_pointers> MiscTextPointers { get; }
  245. //6
  246. //7
  247. public IReadOnlyList<Non_battle_Items_Data> NonBattleItemsData { get; }
  248. //8 //only strings
  249. public IReadOnlyList<Non_Junctionable_GFs_Attacks_Data> NonJunctionableGFsAttacksData { get; }
  250. //14
  251. public IReadOnlyDictionary<Abilities, PartyAbilities> PartyAbilities { get; }
  252. public IReadOnlyDictionary<Renzokeken_Finisher, Renzokuken_Finishers_Data> RenzokukenFinishersData { get; }
  253. public IReadOnlyList<Rinoa_limit_breaks_part_1> RinoaLimitBreaksPart1 { get; }
  254. //24
  255. public IReadOnlyList<Rinoa_limit_breaks_part_2> RinoaLimitBreaksPart2 { get; }
  256. public IReadOnlyList<Selphie_limit_break_sets> SelphieLimitBreakSets { get; }
  257. //public static List<Quistis_limit_break_parameters> QuistisLimitBreakParameters { get; private set; }//20
  258. public IReadOnlyList<Shot_Irvine_limit_break> ShotIrvineLimitBreak { get; }
  259. //25
  260. public IReadOnlyList<Slot_array> SlotArray { get; }
  261. //5
  262. //9
  263. //11
  264. //12
  265. public IReadOnlyDictionary<Abilities, StatPercentageAbilities> StatPercentAbilities { get; }
  266. //13
  267. //15
  268. //17
  269. public IReadOnlyList<Temporary_character_limit_breaks> TemporaryCharacterLimitBreaks { get; }
  270. //0
  271. //1
  272. //2
  273. //3
  274. public IReadOnlyList<Weapons_Data> WeaponsData { get; }
  275. //22
  276. public IReadOnlyList<Zell_limit_break_parameters> ZellLimitBreakParameters { get; }
  277. private Memory.Archive ArchiveString { get; } = Memory.Archives.A_MAIN;
  278. #endregion Properties
  279. //4
  280. //18
  281. //19
  282. //21
  283. //23
  284. //26
  285. //27
  286. //30
  287. // contains 4 types;
  288. }
  289. }