Kernel_bin.Magic_Data.cs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. using System.Collections.Generic;
  2. using System.IO;
  3. namespace OpenVIII
  4. {
  5. namespace Kernel
  6. {
  7. /// <summary>
  8. /// Magic Data
  9. /// </summary>
  10. /// <see cref="https://github.com/alexfilth/doomtrain/wiki/Magic-data"/>
  11. public class Magic_Data
  12. {
  13. public const int id = 1;
  14. public const int count = 57;
  15. public FF8String Name { get; private set; }
  16. public FF8String Description { get; private set; }
  17. public byte ID { get; private set; }
  18. public bool PositiveMagic
  19. {
  20. get
  21. {
  22. switch (Attack_type)
  23. {
  24. case AttackType.CurativeItem:
  25. case AttackType.CurativeMagic:
  26. case AttackType.GivePercentageHP:
  27. case AttackType.Revive:
  28. case AttackType.ReviveAtFullHP:
  29. case AttackType.WhiteWindQuistis:
  30. case AttackType.Scan: //scan is kinda both.
  31. return true;
  32. }
  33. return false;
  34. }
  35. }
  36. public override string ToString() => Name;
  37. //0x0000 2 bytes Offset to spell name
  38. //0x0002 2 bytes Offset to spell description
  39. public Magic_ID MagicID { get; private set; } //0x0004 2 bytes Magic ID
  40. public byte Unknown { get; private set; } //0x0006 1 byte Unknown
  41. public AttackType Attack_type { get; private set; } //0x0007 1 byte Attack type
  42. public byte Spellpower { get; private set; } //0x0008 1 byte Spell power(used in damage formula)
  43. public byte Unknown2 { get; private set; } //0x0009 1 byte Unknown
  44. public Target Target { get; private set; }//0x000A 1 byte Default_target
  45. public AttackFlags Attack_flags { get; private set; } //0x000B 1 byte Attack Flags
  46. public byte Draw_resist { get; private set; } //0x000C 1 byte Draw resist(how hard is the magic to draw)
  47. public byte Hit_count { get; private set; } //0x000D 1 byte Hit Count(works with meteor animation, not sure about others)
  48. public Element Element { get; private set; } //0x000E 1 byte Element
  49. public byte Unknown3 { get; private set; } //0x000F 1 byte Unknown
  50. public Persistent_Statuses Statuses0 { get; private set; } //0x0014 2 bytes Statuses 0
  51. public Battle_Only_Statuses Statuses1 { get; private set; } //0x0010 4 bytes Statuses 1
  52. public byte Status_attack { get; private set; } //0x0016 1 byte Status attack enabler\
  53. public IReadOnlyDictionary<Stat, byte> J_Val { get => _j_Val; }
  54. //public byte HP_J; //0x0017 1 byte Characters HP junction value
  55. //public byte STR_J; //0x0018 1 byte Characters STR junction value
  56. //public byte VIT_J; //0x0019 1 byte Characters VIT junction value
  57. //public byte MAG_J; //0x001A 1 byte Characters MAG junction value
  58. //public byte SPR_J; //0x001B 1 byte Characters SPR junction value
  59. //public byte SPD_J; //0x001C 1 byte Characters SPD junction value
  60. //public byte EVA_J; //0x001D 1 byte Characters EVA junction value
  61. //public byte HIT_J; //0x001E 1 byte Characters HIT junction value
  62. //public byte LUCK_J; //0x001F 1 byte Characters LUCK junction value
  63. public Element EL_Atk { get; private set; } //0x0020 1 byte Characters J - Elem attack
  64. //public byte J_Val[Kernel_bin.Stat.EL_Atk];//0x0021 1 byte Characters J - Elem attack value
  65. public Element EL_Def { get; private set; } //0x0022 1 byte Characters J - Elem defense
  66. //public byte J_Val[Kernel_bin.Stat.EL_Def_1];//0x0023 1 byte Characters J - Elem defense value
  67. //public byte J_Val[Kernel_bin.Stat.ST_Atk];//0x0024 1 byte Characters J - Status attack value
  68. //public byte J_Val[Kernel_bin.Stat.ST_Def_1];//0x0025 1 byte Characters J - Status defense value
  69. public J_Statuses ST_Atk { get; private set; } //0x0026 2 bytes Characters J - Statuses Attack
  70. public J_Statuses ST_Def { get; private set; } //0x0028 2 bytes Characters J - Statuses Defend
  71. public byte[] GF_Compatibility { get; private set; }
  72. //0x002A 1 byte Quezacolt compatibility
  73. //0x002B 1 byte Shiva compatibility
  74. //0x002C 1 byte Ifrit compatibility
  75. //0x002D 1 byte Siren compatibility
  76. //0x002E 1 byte Brothers compatibility
  77. //0x002F 1 byte Diablos compatibility
  78. //0x0030 1 byte Carbuncle compatibility
  79. //0x0031 1 byte Leviathan compatibility
  80. //0x0032 1 byte Pandemona compatibility
  81. //0x0033 1 byte Cerberus compatibility
  82. //0x0034 1 byte Alexander compatibility
  83. //0x0035 1 byte Doomtrain compatibility
  84. //0x0036 1 byte Bahamut compatibility
  85. //0x0037 1 byte Cactuar compatibility
  86. //0x0038 1 byte Tonberry compatibility
  87. //0x0039 1 byte Eden compatibility
  88. public byte[] Unknown4 { get; private set; } //0x003A 2 bytes Unknown
  89. private Dictionary<Stat, byte> _j_Val;
  90. public void Read(BinaryReader br, int i)
  91. {
  92. Name = Memory.Strings.Read(Strings.FileID.KERNEL, id, i * 2);
  93. Description = Memory.Strings.Read(Strings.FileID.KERNEL, id, i * 2 + 1);
  94. ID = (byte)i;
  95. br.BaseStream.Seek(4, SeekOrigin.Current);
  96. MagicID = (Magic_ID)br.ReadUInt16();
  97. Unknown = br.ReadByte();
  98. Attack_type = (AttackType)br.ReadByte();
  99. Spellpower = br.ReadByte();
  100. Unknown2 = br.ReadByte();
  101. Target = (Target)br.ReadByte();
  102. Attack_flags = (AttackFlags)br.ReadByte();
  103. Draw_resist = br.ReadByte();
  104. Hit_count = br.ReadByte();
  105. Element = (Element)br.ReadByte();
  106. Unknown3 = br.ReadByte();
  107. Statuses1 = (Battle_Only_Statuses)br.ReadUInt32();
  108. Statuses0 = (Persistent_Statuses)br.ReadUInt16();
  109. Status_attack = br.ReadByte();
  110. _j_Val = new Dictionary<Stat, byte>(6)
  111. {
  112. { Stat.HP, br.ReadByte() },
  113. { Stat.STR, br.ReadByte() },
  114. { Stat.VIT, br.ReadByte() },
  115. { Stat.MAG, br.ReadByte() },
  116. { Stat.SPR, br.ReadByte() },
  117. { Stat.SPD, br.ReadByte() },
  118. { Stat.EVA, br.ReadByte() },
  119. { Stat.HIT, br.ReadByte() },
  120. { Stat.LUCK, br.ReadByte() }
  121. };
  122. EL_Atk = (Element)br.ReadByte();
  123. _j_Val.Add(Stat.EL_Atk, br.ReadByte());
  124. EL_Def = (Element)br.ReadByte();
  125. _j_Val.Add(Stat.EL_Def_1, br.ReadByte());
  126. _j_Val.Add(Stat.EL_Def_2, _j_Val[Stat.EL_Def_1]);
  127. _j_Val.Add(Stat.EL_Def_3, _j_Val[Stat.EL_Def_1]);
  128. _j_Val.Add(Stat.EL_Def_4, _j_Val[Stat.EL_Def_1]);
  129. _j_Val.Add(Stat.ST_Atk, br.ReadByte());
  130. _j_Val.Add(Stat.ST_Def_1, br.ReadByte());
  131. _j_Val.Add(Stat.ST_Def_2, _j_Val[Stat.ST_Def_1]);
  132. _j_Val.Add(Stat.ST_Def_3, _j_Val[Stat.ST_Def_1]);
  133. _j_Val.Add(Stat.ST_Def_4, _j_Val[Stat.ST_Def_1]);
  134. ST_Atk = (J_Statuses)br.ReadUInt16();
  135. ST_Def = (J_Statuses)br.ReadUInt16();
  136. GF_Compatibility = br.ReadBytes(16);
  137. Unknown4 = br.ReadBytes(2);
  138. }
  139. public uint totalStatVal(Stat stat)
  140. {
  141. if (stat < Stat.EL_Atk)
  142. return J_Val[stat];
  143. else if (stat == Stat.EL_Atk)
  144. return J_Val[stat] * EL_Atk.Count();
  145. else if (stat == Stat.ST_Atk)
  146. return J_Val[stat] * ST_Atk.Count();
  147. else if (stat >= Stat.EL_Def_1 && stat <= Stat.EL_Def_4)
  148. return J_Val[stat] * EL_Def.Count();
  149. else if (stat >= Stat.ST_Def_1 && stat <= Stat.ST_Def_4)
  150. return J_Val[stat] * ST_Def.Count();
  151. return 0;
  152. }
  153. public static List<Magic_Data> Read(BinaryReader br)
  154. {
  155. var ret = new List<Magic_Data>(count);
  156. for (int i = 0; i < count; i++)
  157. {
  158. var tmp = new Magic_Data();
  159. tmp.Read(br, i);
  160. ret.Add(tmp);
  161. }
  162. return ret;
  163. }
  164. }
  165. }
  166. }