diff --git a/pkNX.Structures/Encounter/EncounterTrade7b.cs b/pkNX.Structures/Encounter/EncounterTrade7b.cs index 49a994f1..a2347c5c 100644 --- a/pkNX.Structures/Encounter/EncounterTrade7b.cs +++ b/pkNX.Structures/Encounter/EncounterTrade7b.cs @@ -7,9 +7,8 @@ public class EncounterTrade7b : EncounterTrade public const int SIZE = 0x58; public EncounterTrade7b(byte[] data) => Data = data ?? new byte[SIZE]; - public ulong Hash1 => BitConverter.ToUInt64(Data, 0x00); - public ulong Hash2 => BitConverter.ToUInt64(Data, 0x30); - public ulong Hash3 => BitConverter.ToUInt64(Data, 0x50); + // game loops over all trades to find which one is being offered + public ulong HashTradeID => BitConverter.ToUInt64(Data, 0x00); public override int Species { @@ -20,18 +19,13 @@ public override int Species public override int Form { get => Data[0x0A]; set => Data[0x0A] = (byte)value; } public override int Level { get => Data[0x0C]; set => Data[0x0C] = (byte)value; } // minimum level? - public override Shiny Shiny // 0 = 0x3..., 1 = 0x2, 2 = 0x1 - { - get => (Shiny)(Data[0x0D] & 3); - set => Data[0x0D] = (byte)((Data[0x0D] & ~3) | ((byte)value & 3)); - } - - public override FixedGender Gender // 0 = Random, 1 = Male, 2 = Female, 3 = Panic - { - get => (FixedGender)(Data[0x0D] & 3); - set => Data[0x0D] = (byte)((Data[0x0D] & ~3) | ((byte)value & 3)); - } + public override Shiny Shiny { get => Shiny.Random; set { } } // Ignored + // Value randomness + /* val:8 + * unused:7 + * randAny:1 (signed bit) + */ private int GetIV(int index) { var val = BitConverter.ToUInt16(Data, 0xE + (2 * index)); @@ -52,13 +46,82 @@ private void SetIV(int index, int value) public override int IV_SPD { get => GetIV(4); set => SetIV(4, value); } public override int IV_SPE { get => GetIV(5); set => SetIV(5, value); } - // AV randomness - public int AV_HP { get => Data[0x1A]; set => Data[0x1A] = (byte)value; } - public int AV_ATK { get => Data[0x1C]; set => Data[0x1C] = (byte)value; } - public int AV_DEF { get => Data[0x1E]; set => Data[0x1E] = (byte)value; } - public int AV_SPA { get => Data[0x20]; set => Data[0x20] = (byte)value; } - public int AV_SPD { get => Data[0x22]; set => Data[0x22] = (byte)value; } - public int AV_SPE { get => Data[0x24]; set => Data[0x24] = (byte)value; } + // Value randomness + /* val:8 + * unused:6 + * randUpToVal:1 + * randAny:1 + */ + private int AVP_HP { get => BitConverter.ToInt16(Data, 0x1A); set => BitConverter.GetBytes((short)value).CopyTo(Data, 0x1A); } + private int AVP_ATK { get => BitConverter.ToInt16(Data, 0x1C); set => BitConverter.GetBytes((short)value).CopyTo(Data, 0x1C); } + private int AVP_DEF { get => BitConverter.ToInt16(Data, 0x1E); set => BitConverter.GetBytes((short)value).CopyTo(Data, 0x1E); } + private int AVP_SPA { get => BitConverter.ToInt16(Data, 0x20); set => BitConverter.GetBytes((short)value).CopyTo(Data, 0x20); } + private int AVP_SPD { get => BitConverter.ToInt16(Data, 0x22); set => BitConverter.GetBytes((short)value).CopyTo(Data, 0x22); } + private int AVP_SPE { get => BitConverter.ToInt16(Data, 0x24); set => BitConverter.GetBytes((short)value).CopyTo(Data, 0x24); } + + public int AV_HP { get => AVP_HP & 0xFF; set => AVP_HP = (AVP_HP & 0xFF00) | (byte)value; } + public int AV_ATK { get => AVP_ATK & 0xFF; set => AVP_ATK = (AVP_ATK & 0xFF00) | (byte)value; } + public int AV_DEF { get => AVP_DEF & 0xFF; set => AVP_DEF = (AVP_DEF & 0xFF00) | (byte)value; } + public int AV_SPA { get => AVP_SPA & 0xFF; set => AVP_SPA = (AVP_SPA & 0xFF00) | (byte)value; } + public int AV_SPD { get => AVP_SPD & 0xFF; set => AVP_SPD = (AVP_SPD & 0xFF00) | (byte)value; } + public int AV_SPE { get => AVP_SPE & 0xFF; set => AVP_SPE = (AVP_SPE & 0xFF00) | (byte)value; } + + public bool AV_HPRand { get => AVP_HP == -32768; set => AVP_HP = value ? 0x8000 : AVP_HP & 0x7FFF; } + public bool AV_ATKRand { get => AVP_ATK == -32768; set => AVP_ATK = value ? 0x8000 : AVP_ATK & 0x7FFF; } + public bool AV_DEFRand { get => AVP_DEF == -32768; set => AVP_DEF = value ? 0x8000 : AVP_DEF & 0x7FFF; } + public bool AV_SPARand { get => AVP_SPA == -32768; set => AVP_SPA = value ? 0x8000 : AVP_SPA & 0x7FFF; } + public bool AV_SPDRand { get => AVP_SPD == -32768; set => AVP_SPD = value ? 0x8000 : AVP_SPD & 0x7FFF; } + public bool AV_SPERand { get => AVP_SPE == -32768; set => AVP_SPE = value ? 0x8000 : AVP_SPE & 0x7FFF; } + + public bool AV_HPRandUpTo { get => (AVP_HP & 0x4000) != 0; set => AVP_HP = value ? 0x4000 | (AVP_HP & 0xFF) : AVP_HP & 0xBFFF; } + public bool AV_ATKRandUpTo { get => (AVP_ATK & 0x4000) != 0; set => AVP_ATK = value ? 0x4000 | (AVP_ATK & 0xFF) : AVP_ATK & 0xBFFF; } + public bool AV_DEFRandUpTo { get => (AVP_DEF & 0x4000) != 0; set => AVP_DEF = value ? 0x4000 | (AVP_DEF & 0xFF) : AVP_DEF & 0xBFFF; } + public bool AV_SPARandUpTo { get => (AVP_SPA & 0x4000) != 0; set => AVP_SPA = value ? 0x4000 | (AVP_SPA & 0xFF) : AVP_SPA & 0xBFFF; } + public bool AV_SPDRandUpTo { get => (AVP_SPD & 0x4000) != 0; set => AVP_SPD = value ? 0x4000 | (AVP_SPD & 0xFF) : AVP_SPD & 0xBFFF; } + public bool AV_SPERandUpTo { get => (AVP_SPE & 0x4000) != 0; set => AVP_SPE = value ? 0x4000 | (AVP_SPE & 0xFF) : AVP_SPE & 0xBFFF; } + + public override FixedGender Gender + { + get + { + var val = BitConverter.ToInt16(Data, 0x26); + if (val < 0) + return FixedGender.Random; + return (FixedGender)(val + 1); + } + set + { + if (value == FixedGender.Random) + value = unchecked((FixedGender) 0x8000); + else + value--; + BitConverter.GetBytes((short) value).CopyTo(Data, 0x26); + } + } + + public override Nature Nature + { + get + { + var val = BitConverter.ToInt16(Data, 0x28); + if (val < 0) + return Nature.Random; + return (Nature) val; + } + set + { + if (value == Nature.Random) + value = unchecked((Nature)0x8000); + BitConverter.GetBytes((short) value).CopyTo(Data, 0x28); + } + } + + public int OT_Gender { get => BitConverter.ToInt16(Data, 0x2A); set => BitConverter.GetBytes((short)value).CopyTo(Data, 0x2A); } + public uint TrainerID { get => BitConverter.ToUInt32(Data, 0x2C); set => BitConverter.GetBytes(value).CopyTo(Data, 0x2C); } + + public ulong HashTradeStringOTName => BitConverter.ToUInt64(Data, 0x30); + + // 0x38-0x40 are languageIDs to figure out which language to use (do indexOf current save language -> language message file) public int RequiredSpecies { @@ -72,12 +135,22 @@ public int RequiredForm set => BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x44); } - // what are these? + // what are these? not referenced public sbyte UV_HP { get => (sbyte)Data[0x46]; set => Data[0x46] = (byte)value; } public sbyte UV_ATK { get => (sbyte)Data[0x47]; set => Data[0x47] = (byte)value; } public sbyte UV_DEF { get => (sbyte)Data[0x48]; set => Data[0x48] = (byte)value; } public sbyte UV_SPA { get => (sbyte)Data[0x49]; set => Data[0x49] = (byte)value; } public sbyte UV_SPD { get => (sbyte)Data[0x4A]; set => Data[0x4A] = (byte)value; } public sbyte UV_SPE { get => (sbyte)Data[0x4B]; set => Data[0x4B] = (byte)value; } + + public ulong HashTradeStringNickname => BitConverter.ToUInt64(Data, 0x50); + + public int Ball => 4; + } + + public enum OptionalTradeValue : short + { + Random = unchecked((short)0x8000), + RandRange = 0x4000, } }