using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace OpenVIII { namespace Kernel { /// /// Junctionable GFs Data /// /// public class JunctionableGFsData { #region Fields public const int Count = 16; public const int ID = 2; #endregion Fields #region Constructors private JunctionableGFsData(BinaryReader br, int i) { Name = Memory.Strings.Read(Strings.FileID.Kernel, ID, i * 2); Description = Memory.Strings.Read(Strings.FileID.Kernel, ID, i * 2 + 1); br.BaseStream.Seek(4, SeekOrigin.Current); MagicID = (MagicID)br.ReadUInt16(); //0x0004 2 bytes[[Magic ID AttackType = (AttackType)br.ReadByte(); //0x0006 1 byte Attack type GFPower = br.ReadByte(); //0x0007 1 byte GF power(used in damage formula) Unknown0 = br.ReadBytes(2); //0x0008 2 bytes Unknown AttackFlags = (AttackFlags)(br.ReadByte()); //0x000A 1 byte Attack Flags Unknown1 = br.ReadBytes(2); //0x000B 2 bytes Unknown Element = (Element)br.ReadByte(); //0x000D 1 byte[[Element Statuses0 = (PersistentStatuses)br.ReadUInt16(); //0x000E 2 bytes[[Statuses 0 Statuses1 = (BattleOnlyStatuses)br.ReadUInt32(); //0x0010 4 bytes[[Statuses 1 HPMod = br.ReadByte(); //0x0014 1 byte GF HP Modifier(used in GF HP formula) Unknown21 = br.ReadBytes(3); //0x0015 3 bytes Unknown ExpPerLevel = (ushort)((br.ReadByte()) * 10); //0x0018 Unknown22 = br.ReadBytes(2); //0x0019 2 bytes Unknown StatusAttack = br.ReadByte(); //0x001B 1 byte Status attack enabler Ability = new OrderedDictionary(21); for (i = 0; i < 21; i++) { var val = (Unlocker)br.ReadByte(); br.BaseStream.Seek(1, SeekOrigin.Current); var key = (Abilities)br.ReadUInt16(); Ability.Add(key, val); } //doomtrain shows this is a decimal number. i got formula from code. GFCompatibility = Enumerable.Range(0, 16) .ToDictionary(x => (GFs)x, x => (100 - Convert.ToDecimal(br.ReadByte())) / 5); Unknown3 = br.ReadBytes(2); //0x0080 2 bytes Unknown PowerMod = br.ReadByte(); //0x0082 1 byte Power Mod(used in damage formula) LevelMod = br.ReadByte(); //0x0083 1 byte Level Mod(used in damage formula) } #endregion Constructors #region Properties public OrderedDictionary Ability { get; } ///0x000A 1 byte Attack Flags public AttackFlags AttackFlags { get; } ///0x0006 1 byte Attack type public AttackType AttackType { get; } ///0x0002 2 bytes Offset to GF attack description public FF8String Description { get; } ///0x000D 1 byte[[Element public Element Element { get; } ///0x18 1 byte *10; public ushort ExpPerLevel { get; } /// /// 0x0070 1 byte Quezacotl compatibility /// 0x0071 1 byte Shiva compatibility /// 0x0072 1 byte Ifrit compatibility /// 0x0073 1 byte Siren compatibility /// 0x0074 1 byte Brothers compatibility /// 0x0075 1 byte Diablos compatibility /// 0x0076 1 byte Carbuncle compatibility /// 0x0077 1 byte Leviathan compatibility /// 0x0078 1 byte Pandemona compatibility /// 0x0079 1 byte Cerberus compatibility /// 0x007A 1 byte Alexander compatibility /// 0x007B 1 byte Doomtrain compatibility /// 0x007C 1 byte Bahamut compatibility /// 0x007D 1 byte Cactuar compatibility /// 0x007E 1 byte Tonberry compatibility /// 0x007F 1 byte Eden compatibility /// public IReadOnlyDictionary GFCompatibility { get; } ///0x0007 1 byte GF power(used in damage formula) public byte GFPower { get; } ///0x0014 1 byte GF HP Modifier(used in GF HP formula) public byte HPMod { get; } ///0x0083 1 byte Level Mod(used in damage formula) public byte LevelMod { get; } ///0x0004 2 bytes[[Magic ID public MagicID MagicID { get; } ///0x0000 2 bytes Offset to GF attack name public FF8String Name { get; } ///0x0082 1 byte Power Mod(used in damage formula) public byte PowerMod { get; } ///0x001B 1 byte Status attack enabler public byte StatusAttack { get; } ///0x000E 2 bytes[[Statuses 0 public PersistentStatuses Statuses0 { get; } ///0x0010 4 bytes[[Statuses 1 public BattleOnlyStatuses Statuses1 { get; } ///0x0008 2 bytes Unknown public byte[] Unknown0 { get; } ///0x000B 2 bytes Unknown public byte[] Unknown1 { get; } ///0x0015 3 bytes Unknown public byte[] Unknown21 { get; } ///0x0019 2 bytes Unknown public byte[] Unknown22 { get; } ///0x0080 2 bytes Unknown public byte[] Unknown3 { get; } #endregion Properties #region Methods public static JunctionableGFsData CreateInstance(BinaryReader br, int i) => new JunctionableGFsData(br, i); public static IReadOnlyDictionary Read(BinaryReader br) => Enumerable.Range(0, Count).ToDictionary(x => (GFs)x, x => CreateInstance(br, x)); public override string ToString() => Name; #endregion Methods } } }