diff --git a/Legality/Checks.cs b/Legality/Checks.cs index f7c884dd0..1586c0ae6 100644 --- a/Legality/Checks.cs +++ b/Legality/Checks.cs @@ -424,8 +424,8 @@ private LegalityCheck verifyRibbons() private LegalityCheck verifyAbility() { int index = Legal.PersonalAO[pk6.Species].FormeIndex(pk6.Species, pk6.AltForm); - byte[] abilities = Legal.PersonalAO[index].Abilities; - int abilval = Array.IndexOf(abilities, (byte)pk6.Ability); + int[] abilities = Legal.PersonalAO[index].Abilities; + int abilval = Array.IndexOf(abilities, pk6.Ability); if (abilval < 0) return new LegalityCheck(Severity.Invalid, "Ability is not valid for species/form."); diff --git a/Legality/Core.cs b/Legality/Core.cs index 8a9454ab5..05da7a600 100644 --- a/Legality/Core.cs +++ b/Legality/Core.cs @@ -8,8 +8,14 @@ public static partial class Legal // PKHeX master Wonder Card Database internal static WC6[] WC6DB; // PKHeX master personal.dat - internal static readonly PersonalInfo[] PersonalAO = PersonalInfo.getArray(Properties.Resources.personal_ao, PersonalInfo.SizeAO); - internal static readonly PersonalInfo[] PersonalXY = PersonalInfo.getArray(Properties.Resources.personal_xy, PersonalInfo.SizeXY); + internal static readonly PersonalInfo[] PersonalAO = PersonalInfo.getArray(Properties.Resources.personal_ao, GameVersion.ORAS); + internal static readonly PersonalInfo[] PersonalXY = PersonalInfo.getArray(Properties.Resources.personal_xy, GameVersion.XY); + internal static readonly PersonalInfo[] PersonalB2W2 = PersonalInfo.getArray(Properties.Resources.personal_b2w2, GameVersion.B2W2); + internal static readonly PersonalInfo[] PersonalBW = PersonalInfo.getArray(Properties.Resources.personal_bw, GameVersion.BW); + internal static readonly PersonalInfo[] PersonalHGSS = PersonalInfo.getArray(Properties.Resources.personal_hgss, GameVersion.HGSS); + internal static readonly PersonalInfo[] PersonalPt = PersonalInfo.getArray(Properties.Resources.personal_pt, GameVersion.Pt); + internal static readonly PersonalInfo[] PersonalDP = PersonalInfo.getArray(Properties.Resources.personal_dp, GameVersion.DP); + private static readonly EggMoves[] EggMoveXY = EggMoves.getArray(Data.unpackMini(Properties.Resources.eggmove_xy, "xy")); private static readonly Learnset[] LevelUpXY = Learnset.getArray(Data.unpackMini(Properties.Resources.lvlmove_xy, "xy")); private static readonly EggMoves[] EggMoveAO = EggMoves.getArray(Data.unpackMini(Properties.Resources.eggmove_ao, "ao")); @@ -595,16 +601,16 @@ private static IEnumerable getEggMoves(int species, int formnum) } private static IEnumerable getTutorMoves(int species, int formnum, bool ORASTutors) { - PersonalInfo pkAO = PersonalAO[PersonalAO[species].FormeIndex(species, formnum)]; + PersonalInfoORAS pkAO = (PersonalInfoORAS)PersonalAO[PersonalAO[species].FormeIndex(species, formnum)]; // Type Tutor - List moves = TypeTutor.Where((t, i) => pkAO.Tutors[i]).ToList(); + List moves = TypeTutor.Where((t, i) => pkAO.TypeTutors[i]).ToList(); // Varied Tutors if (ORASTutors) for (int i = 0; i < Tutors_AO.Length; i++) for (int b = 0; b < Tutors_AO[i].Length; b++) - if (pkAO.ORASTutors[i][b]) + if (pkAO.SpecialTutors[i][b]) moves.Add(Tutors_AO[i][b]); // Keldeo - Secret Sword diff --git a/Legality/Data.cs b/Legality/Data.cs index 0e0c79f5e..5e76c58a8 100644 --- a/Legality/Data.cs +++ b/Legality/Data.cs @@ -234,127 +234,6 @@ public enum Nature Bashful, Rash, Calm, Gentle, Sassy, Careful, Quirky, } - public class PersonalInfo - { - internal static int SizeAO = 0x50; - internal static int SizeXY = 0x40; - public byte HP, ATK, DEF, SPE, SPA, SPD; - public int BST; - public int EV_HP, EV_ATK, EV_DEF, EV_SPE, EV_SPA, EV_SPD; - public byte[] Types = new byte[2]; - public byte CatchRate, EvoStage; - public ushort[] Items = new ushort[3]; - public byte Gender, HatchCycles, BaseFriendship, EXPGrowth; - public byte[] EggGroups = new byte[2]; - public byte[] Abilities = new byte[3]; - public ushort FormStats, FormeSprite, BaseEXP; - public byte FormeCount, Color; - public float Height, Weight; - public bool[] TMHM; - public bool[] Tutors; - public bool[][] ORASTutors = new bool[4][]; - public byte EscapeRate; - - public PersonalInfo(byte[] data) - { - using (BinaryReader br = new BinaryReader(new MemoryStream(data))) - { - HP = br.ReadByte(); ATK = br.ReadByte(); DEF = br.ReadByte(); - SPE = br.ReadByte(); SPA = br.ReadByte(); SPD = br.ReadByte(); - BST = HP + ATK + DEF + SPE + SPA + SPD; - - Types = new[] { br.ReadByte(), br.ReadByte() }; - CatchRate = br.ReadByte(); - EvoStage = br.ReadByte(); - - ushort EVs = br.ReadUInt16(); - EV_HP = EVs >> 0 & 0x3; - EV_ATK = EVs >> 2 & 0x3; - EV_DEF = EVs >> 4 & 0x3; - EV_SPE = EVs >> 6 & 0x3; - EV_SPA = EVs >> 8 & 0x3; - EV_SPD = EVs >> 10 & 0x3; - - Items = new[] { br.ReadUInt16(), br.ReadUInt16(), br.ReadUInt16() }; - Gender = br.ReadByte(); - HatchCycles = br.ReadByte(); - BaseFriendship = br.ReadByte(); - - EXPGrowth = br.ReadByte(); - EggGroups = new[] { br.ReadByte(), br.ReadByte() }; - Abilities = new[] { br.ReadByte(), br.ReadByte(), br.ReadByte() }; - EscapeRate = br.ReadByte(); - FormStats = br.ReadUInt16(); - - FormeSprite = br.ReadUInt16(); - FormeCount = br.ReadByte(); - Color = br.ReadByte(); - BaseEXP = br.ReadUInt16(); - - Height = br.ReadUInt16(); - Weight = br.ReadUInt16(); - - byte[] TMHMData = br.ReadBytes(0x10); - TMHM = new bool[8 * TMHMData.Length]; - for (int j = 0; j < TMHM.Length; j++) - TMHM[j] = (TMHMData[j / 8] >> (j % 8) & 0x1) == 1; //Bitflags for TMHM - - byte[] TutorData = br.ReadBytes(8); - Tutors = new bool[8 * TutorData.Length]; - for (int j = 0; j < Tutors.Length; j++) - Tutors[j] = (TutorData[j / 8] >> (j % 8) & 0x1) == 1; //Bitflags for Tutors - - if (br.BaseStream.Length - br.BaseStream.Position == 0x10) // ORAS - { - byte[][] ORASTutorData = - { - br.ReadBytes(4), // 15 - br.ReadBytes(4), // 17 - br.ReadBytes(4), // 16 - br.ReadBytes(4), // 15 - }; - for (int i = 0; i < 4; i++) - { - ORASTutors[i] = new bool[8 * ORASTutorData[i].Length]; - for (int b = 0; b < 8 * ORASTutorData[i].Length; b++) - ORASTutors[i][b] = (ORASTutorData[i][b / 8] >> b % 8 & 0x1) == 1; - } - } - } - } - - // Data Manipulation - public int FormeIndex(int species, int forme) - { - return forme == 0 || FormStats == 0 ? species : FormStats + forme - 1; - } - public int RandomGender - { - get - { - switch (Gender) - { - case 255: // Genderless - return 2; - case 254: // Female - return 1; - case 0: // Male - return 0; - default: - return (int)(Util.rnd32() % 2); - } - } - } - public bool HasFormes => FormeCount > 1; - - internal static PersonalInfo[] getArray(byte[] data, int size) - { - PersonalInfo[] d = new PersonalInfo[data.Length / size]; - for (int i = 0; i < d.Length; i++) - d[i] = new PersonalInfo(data.Skip(i * size).Take(size).ToArray()); - return d; - } - } internal static class Data { diff --git a/PKHeX.csproj b/PKHeX.csproj index c3c813445..b93da15f7 100644 --- a/PKHeX.csproj +++ b/PKHeX.csproj @@ -75,6 +75,12 @@ + + + + + + @@ -380,6 +386,11 @@ + + + + + diff --git a/PKM/PKX.cs b/PKM/PKX.cs index 922bdf9e5..8967c5f94 100644 --- a/PKM/PKX.cs +++ b/PKM/PKX.cs @@ -243,7 +243,7 @@ internal static byte[] getRandomEVs() Util.Shuffle(evs); return evs; } - internal static byte getBaseFriendship(int species) + internal static int getBaseFriendship(int species) { return Personal[species].BaseFriendship; } @@ -267,14 +267,14 @@ internal static uint getEXP(int level, int species) if (level > 100) level = 100; return ExpTable[level, Personal[species].EXPGrowth]; } - internal static byte[] getAbilities(int species, int formnum) + internal static int[] getAbilities(int species, int formnum) { return Personal[Personal[species].FormeIndex(species, formnum)].Abilities; } internal static int getAbilityNumber(int species, int ability, int formnum) { - byte[] spec_abilities = getAbilities(species, formnum); - int abilval = Array.IndexOf(spec_abilities, (byte)ability); + int[] spec_abilities = getAbilities(species, formnum); + int abilval = Array.IndexOf(spec_abilities, ability); if (abilval >= 0) return 1 << abilval; return -1; diff --git a/PKX/f1-Main.cs b/PKX/f1-Main.cs index abc515ee1..22252fb1e 100644 --- a/PKX/f1-Main.cs +++ b/PKX/f1-Main.cs @@ -376,8 +376,8 @@ private void clickShowdownImportPK6(object sender, EventArgs e) CB_Form.SelectedIndex = form; // Set Ability - byte[] abilities = PKX.getAbilities(Set.Species, form); - int ability = Array.IndexOf(abilities, (byte)Set.Ability); + int[] abilities = PKX.getAbilities(Set.Species, form); + int ability = Array.IndexOf(abilities, Set.Ability); if (ability < 0) ability = 0; CB_Ability.SelectedIndex = ability; ComboBox[] m = { CB_Move1, CB_Move2, CB_Move3, CB_Move4, }; @@ -1581,15 +1581,9 @@ private void setAbilityList() if (SAV.Generation > 3) // has forms formnum = CB_Form.SelectedIndex; - byte[] abils = SAV.Personal[SAV.Personal[species].FormeIndex(species, formnum)].Abilities; - - List ability_list = new List - { - abilitylist[abils[0]] + " (1)", - abilitylist[abils[1]] + " (2)", - }; - if (SAV.Generation >= 5) // hidden ability - ability_list.Add(abilitylist[abils[2]] + " (H)"); + int[] abils = SAV.Personal[SAV.Personal[species].FormeIndex(species, formnum)].Abilities; + string[] abilIdentifier = {" (1)", " (2)", " (H)"}; + List ability_list = abils.Select((t, i) => abilitylist[t] + abilIdentifier[i]).ToList(); int curAbil = CB_Ability.SelectedIndex; CB_Ability.DataSource = ability_list; diff --git a/PersonalInfo/PersonalInfo.cs b/PersonalInfo/PersonalInfo.cs new file mode 100644 index 000000000..d623102c8 --- /dev/null +++ b/PersonalInfo/PersonalInfo.cs @@ -0,0 +1,151 @@ +using System; + +namespace PKHeX +{ + public abstract class PersonalInfo + { + protected const int SIZE_G4 = 0x2C; + protected const int SIZE_BW = 0x3C; + protected const int SIZE_B2W2 = 0x4C; + protected const int SIZE_XY = 0x40; + protected const int SIZE_AO = 0x50; + + protected byte[] Data; + public abstract int HP { get; set; } + public abstract int ATK { get; set; } + public abstract int DEF { get; set; } + public abstract int SPE { get; set; } + public abstract int SPA { get; set; } + public abstract int SPD { get; set; } + public abstract int EV_HP { get; set; } + public abstract int EV_ATK { get; set; } + public abstract int EV_DEF { get; set; } + public abstract int EV_SPE { get; set; } + public abstract int EV_SPA { get; set; } + public abstract int EV_SPD { get; set; } + + public abstract int[] Types { get; set; } + public abstract int CatchRate { get; set; } + public virtual int EvoStage { get; set; } + public abstract int[] Items { get; set; } + public abstract int Gender { get; set; } + public abstract int HatchCycles { get; set; } + public abstract int BaseFriendship { get; set; } + public abstract int EXPGrowth { get; set; } + public abstract int[] EggGroups { get; set; } + public abstract int [] Abilities { get; set; } + public abstract int EscapeRate { get; set; } + public virtual int FormeCount { get; set; } + protected virtual int FormStatsIndex { get; set; } + public virtual int FormeSprite { get; set; } + public abstract int BaseEXP { get; set; } + public abstract int Color { get; set; } + + public virtual int Height { get; set; } = 0; + public virtual int Weight { get; set; } = 0; + + public bool[] TMHM { get; set; } + public bool[] TypeTutors { get; set; } + public bool[][] SpecialTutors { get; set; } = new bool[0][]; + + protected bool[] getBits(byte[] data) + { + bool[] r = new bool[8 * data.Length]; + for (int i = 0; i < r.Length; i++) + r[i] = (data[i/8] >> (i&7) & 0x1) == 1; + return r; + } + protected byte[] setBits(bool[] bits) + { + byte[] data = new byte[bits.Length/8]; + for (int i = 0; i < bits.Length; i++) + data[i / 8] |= (byte)(bits[i] ? 1 << (i&0x7) : 0); + return data; + } + public virtual byte[] Write() { return Data; } + + // Data Manipulation + public int FormeIndex(int species, int forme) + { + return forme == 0 || FormStatsIndex == 0 ? species : FormStatsIndex + forme - 1; + } + public int RandomGender + { + get + { + switch (Gender) + { + case 255: // Genderless + return 2; + case 254: // Female + return 1; + case 0: // Male + return 0; + default: + return (int)(Util.rnd32() % 2); + } + } + } + public bool HasFormes => FormeCount > 1; + public int BST => HP + ATK + DEF + SPE + SPA + SPD; + + // Array Retrieval + internal static PersonalInfo[] getArray(byte[] data, GameVersion format) + { + int size = 0; + switch (format) + { + case GameVersion.DP: + case GameVersion.Pt: + case GameVersion.HGSS: size = SIZE_G4; break; + case GameVersion.BW: size = SIZE_BW; break; + case GameVersion.B2W2: size = SIZE_B2W2; break; + case GameVersion.XY: size = SIZE_XY; break; + case GameVersion.ORAS: size = SIZE_AO; break; + } + + if (size == 0) + return null; + + byte[][] entries = splitBytes(data, size); + PersonalInfo[] d = new PersonalInfo[data.Length / size]; + + switch (format) + { + case GameVersion.DP: + case GameVersion.Pt: + case GameVersion.HGSS: + for (int i = 0; i < d.Length; i++) + d[i] = new PersonalInfoG4(entries[i]); + break; + case GameVersion.BW: + for (int i = 0; i < d.Length; i++) + d[i] = new PersonalInfoBW(entries[i]); + break; + case GameVersion.B2W2: + for (int i = 0; i < d.Length; i++) + d[i] = new PersonalInfoB2W2(entries[i]); + break; + case GameVersion.XY: + for (int i = 0; i < d.Length; i++) + d[i] = new PersonalInfoXY(entries[i]); + break; + case GameVersion.ORAS: + for (int i = 0; i < d.Length; i++) + d[i] = new PersonalInfoORAS(entries[i]); + break; + } + return d; + } + private static byte[][] splitBytes(byte[] data, int size) + { + byte[][] r = new byte[data.Length/size][]; + for (int i = 0; i < data.Length; i += size) + { + r[i] = new byte[size]; + Array.Copy(data, i, r[i/size], 0, size); + } + return r; + } + } +} diff --git a/PersonalInfo/PersonalInfoB2W2.cs b/PersonalInfo/PersonalInfoB2W2.cs new file mode 100644 index 000000000..a080f2920 --- /dev/null +++ b/PersonalInfo/PersonalInfoB2W2.cs @@ -0,0 +1,36 @@ +using System.Linq; + +namespace PKHeX +{ + public class PersonalInfoB2W2 : PersonalInfoBW + { + public PersonalInfoB2W2(byte[] data) + { + if (data.Length != SIZE_B2W2) + return; + Data = data; + + // Unpack TMHM & Tutors + TMHM = getBits(Data.Skip(0x28).Take(0x10).ToArray()); + TypeTutors = getBits(Data.Skip(0x38).Take(0x4).ToArray()); + SpecialTutors = new[] + { + getBits(Data.Skip(0x3C).Take(0x04).ToArray()), + getBits(Data.Skip(0x40).Take(0x04).ToArray()), + getBits(Data.Skip(0x44).Take(0x04).ToArray()), + getBits(Data.Skip(0x48).Take(0x04).ToArray()), + }; + } + + public override byte[] Write() + { + setBits(TMHM).CopyTo(Data, 0x28); + setBits(TypeTutors).CopyTo(Data, 0x38); + setBits(SpecialTutors[0]).CopyTo(Data, 0x3C); + setBits(SpecialTutors[1]).CopyTo(Data, 0x40); + setBits(SpecialTutors[2]).CopyTo(Data, 0x44); + setBits(SpecialTutors[3]).CopyTo(Data, 0x48); + return Data; + } + } +} diff --git a/PersonalInfo/PersonalInfoBW.cs b/PersonalInfo/PersonalInfoBW.cs new file mode 100644 index 000000000..60cffb035 --- /dev/null +++ b/PersonalInfo/PersonalInfoBW.cs @@ -0,0 +1,95 @@ +using System; +using System.Linq; + +namespace PKHeX +{ + public class PersonalInfoBW : PersonalInfo + { + protected PersonalInfoBW() { } + public PersonalInfoBW(byte[] data) + { + if (data.Length != SIZE_BW) + return; + Data = data; + + TMHM = getBits(Data.Skip(0x28).Take(0x10).ToArray()); + TypeTutors = getBits(Data.Skip(0x38).Take(0x4).ToArray()); + } + public override byte[] Write() + { + setBits(TMHM).CopyTo(Data, 0x28); + setBits(TypeTutors).CopyTo(Data, 0x38); + return Data; + } + + public override int HP { get { return Data[0x00]; } set { Data[0x00] = (byte)value; } } + public override int ATK { get { return Data[0x01]; } set { Data[0x01] = (byte)value; } } + public override int DEF { get { return Data[0x02]; } set { Data[0x02] = (byte)value; } } + public override int SPE { get { return Data[0x03]; } set { Data[0x03] = (byte)value; } } + public override int SPA { get { return Data[0x04]; } set { Data[0x04] = (byte)value; } } + public override int SPD { get { return Data[0x05]; } set { Data[0x05] = (byte)value; } } + public override int[] Types + { + get { return new int[] { Data[0x06], Data[0x07] }; } + set + { + if (value?.Length != 2) return; + Data[0x06] = (byte)value[0]; + Data[0x07] = (byte)value[1]; + } + } + public override int CatchRate { get { return Data[0x08]; } set { Data[0x08] = (byte)value; } } + public override int EvoStage { get { return Data[0x09]; } set { Data[0x09] = (byte)value; } } + private int EVYield { get { return BitConverter.ToUInt16(Data, 0x0A); } set { BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x0A); } } + public override int EV_HP { get { return EVYield >> 0 & 0x3; } set { EVYield = (EVYield & (0x3 << 0)) | (value & 0x3); } } + public override int EV_ATK { get { return EVYield >> 2 & 0x3; } set { EVYield = (EVYield & (0x3 << 2)) | (value & 0x3); } } + public override int EV_DEF { get { return EVYield >> 4 & 0x3; } set { EVYield = (EVYield & (0x3 << 4)) | (value & 0x3); } } + public override int EV_SPE { get { return EVYield >> 6 & 0x3; } set { EVYield = (EVYield & (0x3 << 6)) | (value & 0x3); } } + public override int EV_SPA { get { return EVYield >> 8 & 0x3; } set { EVYield = (EVYield & (0x3 << 8)) | (value & 0x3); } } + public override int EV_SPD { get { return EVYield >> 16 & 0x3; } set { EVYield = (EVYield & (0x3 << 10)) | (value & 0x3); } } + public override int[] Items + { + get { return new int[] { BitConverter.ToInt16(Data, 0xC), BitConverter.ToInt16(Data, 0xE), BitConverter.ToInt16(Data, 0x10) }; } + set + { + if (value?.Length != 3) return; + BitConverter.GetBytes((short)value[0]).CopyTo(Data, 0xC); + BitConverter.GetBytes((short)value[0]).CopyTo(Data, 0xE); + BitConverter.GetBytes((short)value[0]).CopyTo(Data, 0x10); + } + } + public override int Gender { get { return Data[0x12]; } set { Data[0x12] = (byte)value; } } + public override int HatchCycles { get { return Data[0x13]; } set { Data[0x13] = (byte)value; } } + public override int BaseFriendship { get { return Data[0x14]; } set { Data[0x14] = (byte)value; } } + public override int EXPGrowth { get { return Data[0x15]; } set { Data[0x15] = (byte)value; } } + public override int[] EggGroups + { + get { return new int[] { Data[0x16], Data[0x17] }; } + set + { + if (value?.Length != 2) return; + Data[0x16] = (byte)value[0]; + Data[0x17] = (byte)value[1]; + } + } + public override int[] Abilities + { + get { return new int[] { Data[0x18], Data[0x19], Data[0x1A] }; } + set + { + if (value?.Length != 2) return; + Data[0x18] = (byte)value[0]; + Data[0x19] = (byte)value[1]; + Data[0x1A] = (byte)value[2]; + } + } + public override int EscapeRate { get { return Data[0x1B]; } set { Data[0x1B] = (byte)value; } } + protected override int FormStatsIndex { get { return BitConverter.ToUInt16(Data, 0x1C); } set { BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x1C); } } + public override int FormeSprite { get { return BitConverter.ToUInt16(Data, 0x1E); } set { BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x1E); } } + public override int FormeCount { get { return Data[0x20]; } set { Data[0x20] = (byte)value; } } + public override int Color { get { return Data[0x21]; } set { Data[0x21] = (byte)value; } } + public override int BaseEXP { get { return BitConverter.ToUInt16(Data, 0x22); } set { BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x22); } } + public override int Height { get { return BitConverter.ToUInt16(Data, 0x24); } set { BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x24); } } + public override int Weight { get { return BitConverter.ToUInt16(Data, 0x26); } set { BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x26); } } + } +} diff --git a/PersonalInfo/PersonalInfoG4.cs b/PersonalInfo/PersonalInfoG4.cs new file mode 100644 index 000000000..6e7d507b0 --- /dev/null +++ b/PersonalInfo/PersonalInfoG4.cs @@ -0,0 +1,89 @@ +using System; +using System.Linq; + +namespace PKHeX +{ + public class PersonalInfoG4 : PersonalInfo + { + public PersonalInfoG4(byte[] data) + { + if (data.Length != SIZE_G4) + return; + Data = data; + + // Unpack TMHM & Tutors + TMHM = getBits(Data.Skip(0x1C).Take(0x0D).ToArray()); + TypeTutors = new bool[0]; // not stored in personal + } + public override byte[] Write() + { + setBits(TMHM).CopyTo(Data, 0x28); + setBits(TypeTutors).CopyTo(Data, 0x38); + return Data; + } + + public override int HP { get { return Data[0x00]; } set { Data[0x00] = (byte)value; } } + public override int ATK { get { return Data[0x01]; } set { Data[0x01] = (byte)value; } } + public override int DEF { get { return Data[0x02]; } set { Data[0x02] = (byte)value; } } + public override int SPE { get { return Data[0x03]; } set { Data[0x03] = (byte)value; } } + public override int SPA { get { return Data[0x04]; } set { Data[0x04] = (byte)value; } } + public override int SPD { get { return Data[0x05]; } set { Data[0x05] = (byte)value; } } + public override int[] Types + { + get { return new int[] { Data[0x06], Data[0x07] }; } + set + { + if (value?.Length != 2) return; + Data[0x06] = (byte)value[0]; + Data[0x07] = (byte)value[1]; + } + } + public override int CatchRate { get { return Data[0x08]; } set { Data[0x08] = (byte)value; } } + public override int BaseEXP { get { return Data[0x09]; } set { Data[0x09] = (byte)value; } } + private int EVYield { get { return BitConverter.ToUInt16(Data, 0x0A); } set { BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x0A); } } + public override int EV_HP { get { return EVYield >> 0 & 0x3; } set { EVYield = (EVYield & (0x3 << 0)) | (value & 0x3); } } + public override int EV_ATK { get { return EVYield >> 2 & 0x3; } set { EVYield = (EVYield & (0x3 << 2)) | (value & 0x3); } } + public override int EV_DEF { get { return EVYield >> 4 & 0x3; } set { EVYield = (EVYield & (0x3 << 4)) | (value & 0x3); } } + public override int EV_SPE { get { return EVYield >> 6 & 0x3; } set { EVYield = (EVYield & (0x3 << 6)) | (value & 0x3); } } + public override int EV_SPA { get { return EVYield >> 8 & 0x3; } set { EVYield = (EVYield & (0x3 << 8)) | (value & 0x3); } } + public override int EV_SPD { get { return EVYield >> 16 & 0x3; } set { EVYield = (EVYield & (0x3 << 10)) | (value & 0x3); } } + + + public override int[] Items + { + get { return new int[] { BitConverter.ToInt16(Data, 0xC), BitConverter.ToInt16(Data, 0xE) }; } + set + { + if (value?.Length != 2) return; + BitConverter.GetBytes((short)value[0]).CopyTo(Data, 0xC); + BitConverter.GetBytes((short)value[0]).CopyTo(Data, 0xE); + } + } + public override int Gender { get { return Data[0x10]; } set { Data[0x10] = (byte)value; } } + public override int HatchCycles { get { return Data[0x11]; } set { Data[0x11] = (byte)value; } } + public override int BaseFriendship { get { return Data[0x12]; } set { Data[0x12] = (byte)value; } } + public override int EXPGrowth { get { return Data[0x13]; } set { Data[0x13] = (byte)value; } } + public override int[] EggGroups + { + get { return new int[] { Data[0x14], Data[0x15] }; } + set + { + if (value?.Length != 2) return; + Data[0x14] = (byte)value[0]; + Data[0x15] = (byte)value[1]; + } + } + public override int[] Abilities + { + get { return new int[] { Data[0x18], Data[0x19] }; } + set + { + if (value?.Length != 2) return; + Data[0x16] = (byte)value[0]; + Data[0x17] = (byte)value[1]; + } + } + public override int EscapeRate { get { return Data[0x18]; } set { Data[0x18] = (byte)value; } } + public override int Color { get { return Data[0x19]; } set { Data[0x19] = (byte)value; } } + } +} diff --git a/PersonalInfo/PersonalInfoORAS.cs b/PersonalInfo/PersonalInfoORAS.cs new file mode 100644 index 000000000..b71d8b218 --- /dev/null +++ b/PersonalInfo/PersonalInfoORAS.cs @@ -0,0 +1,36 @@ +using System.Linq; + +namespace PKHeX +{ + public class PersonalInfoORAS : PersonalInfoXY + { + public PersonalInfoORAS(byte[] data) + { + if (data.Length != SIZE_AO) + return; + Data = data; + + // Unpack TMHM & Tutors + TMHM = getBits(Data.Skip(0x28).Take(0x10).ToArray()); + TypeTutors = getBits(Data.Skip(0x38).Take(0x4).ToArray()); + // 0x3C-0x40 unknown + SpecialTutors = new[] + { + getBits(Data.Skip(0x40).Take(0x04).ToArray()), + getBits(Data.Skip(0x44).Take(0x04).ToArray()), + getBits(Data.Skip(0x48).Take(0x04).ToArray()), + getBits(Data.Skip(0x4C).Take(0x04).ToArray()), + }; + } + public override byte[] Write() + { + setBits(TMHM).CopyTo(Data, 0x28); + setBits(TypeTutors).CopyTo(Data, 0x38); + setBits(SpecialTutors[0]).CopyTo(Data, 0x40); + setBits(SpecialTutors[1]).CopyTo(Data, 0x44); + setBits(SpecialTutors[2]).CopyTo(Data, 0x48); + setBits(SpecialTutors[3]).CopyTo(Data, 0x4C); + return Data; + } + } +} diff --git a/PersonalInfo/PersonalInfoXY.cs b/PersonalInfo/PersonalInfoXY.cs new file mode 100644 index 000000000..2857fcfe1 --- /dev/null +++ b/PersonalInfo/PersonalInfoXY.cs @@ -0,0 +1,26 @@ +using System; +using System.Linq; + +namespace PKHeX +{ + public class PersonalInfoXY : PersonalInfoBW + { + protected PersonalInfoXY() { } // For ORAS + public PersonalInfoXY(byte[] data) + { + if (data.Length != SIZE_XY) + return; + Data = data; + + TMHM = getBits(Data.Skip(0x28).Take(0x10).ToArray()); + TypeTutors = getBits(Data.Skip(0x38).Take(0x4).ToArray()); + // 0x3C-0x40 unknown + } + public override byte[] Write() + { + setBits(TMHM).CopyTo(Data, 0x28); + setBits(TypeTutors).CopyTo(Data, 0x38); + return Data; + } + } +} diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs index 9e278c637..9056c20f0 100644 --- a/Properties/Resources.Designer.cs +++ b/Properties/Resources.Designer.cs @@ -14635,6 +14635,56 @@ internal class Resources { } } + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] personal_b2w2 { + get { + object obj = ResourceManager.GetObject("personal_b2w2", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] personal_bw { + get { + object obj = ResourceManager.GetObject("personal_bw", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] personal_dp { + get { + object obj = ResourceManager.GetObject("personal_dp", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] personal_hgss { + get { + object obj = ResourceManager.GetObject("personal_hgss", resourceCulture); + return ((byte[])(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Byte[]. + /// + internal static byte[] personal_pt { + get { + object obj = ResourceManager.GetObject("personal_pt", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Looks up a localized resource of type System.Byte[]. /// diff --git a/Properties/Resources.resx b/Properties/Resources.resx index 14e9b3472..531ab0d6a 100644 --- a/Properties/Resources.resx +++ b/Properties/Resources.resx @@ -5869,4 +5869,19 @@ ..\Resources\img\Program\showdown.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\byte\personal_b2w2;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\byte\personal_bw;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\byte\personal_dp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\byte\personal_hgss;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + ..\Resources\byte\personal_pt;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + \ No newline at end of file diff --git a/Resources/byte/personal_b2w2 b/Resources/byte/personal_b2w2 new file mode 100644 index 000000000..dbe6c87e3 Binary files /dev/null and b/Resources/byte/personal_b2w2 differ diff --git a/Resources/byte/personal_bw b/Resources/byte/personal_bw new file mode 100644 index 000000000..78c862814 Binary files /dev/null and b/Resources/byte/personal_bw differ diff --git a/Resources/byte/personal_dp b/Resources/byte/personal_dp new file mode 100644 index 000000000..359024ada Binary files /dev/null and b/Resources/byte/personal_dp differ diff --git a/Resources/byte/personal_hgss b/Resources/byte/personal_hgss new file mode 100644 index 000000000..c69332d50 Binary files /dev/null and b/Resources/byte/personal_hgss differ diff --git a/Resources/byte/personal_pt b/Resources/byte/personal_pt new file mode 100644 index 000000000..47154a84f Binary files /dev/null and b/Resources/byte/personal_pt differ diff --git a/SAV/SAV_SecretBase.cs b/SAV/SAV_SecretBase.cs index f1a0f5ba4..58db065ff 100644 --- a/SAV/SAV_SecretBase.cs +++ b/SAV/SAV_SecretBase.cs @@ -411,7 +411,7 @@ private void setAbilityList() int newabil = Convert.ToInt16(MT_AbilNo.Text) >> 1; int species = Util.getIndex(CB_Species); int formnum = CB_Form.SelectedIndex; - byte[] abils = Legal.PersonalAO[Legal.PersonalAO[species].FormeIndex(species, formnum)].Abilities; + int[] abils = Legal.PersonalAO[Legal.PersonalAO[species].FormeIndex(species, formnum)].Abilities; // Build Ability List List ability_list = new List diff --git a/Saves/SAV4.cs b/Saves/SAV4.cs index 5356c733f..e28c88812 100644 --- a/Saves/SAV4.cs +++ b/Saves/SAV4.cs @@ -26,7 +26,12 @@ public SAV4(byte[] data = null, GameVersion versionOverride = GameVersion.Any) getActiveBlock(); getSAVOffsets(); - Personal = Legal.PersonalAO; // todo + switch (Version) + { + case GameVersion.DP: Personal = Legal.PersonalDP; break; + case GameVersion.Pt: Personal = Legal.PersonalPt; break; + case GameVersion.HGSS: Personal = Legal.PersonalHGSS; break; + } if (!Exportable) resetBoxes(); diff --git a/Saves/SAV5.cs b/Saves/SAV5.cs index 8b17dc7d9..55f5df0f3 100644 --- a/Saves/SAV5.cs +++ b/Saves/SAV5.cs @@ -52,6 +52,8 @@ public SAV5(byte[] data = null, GameVersion versionOverride = GameVersion.Any) LegalTMHMs = Legal.Pouch_TMHM_BW; LegalMedicine = Legal.Pouch_Medicine_BW; LegalBerries = Legal.Pouch_Berries_BW; + + Personal = Legal.PersonalBW; break; case GameVersion.B2W2: // B2W2 BattleBox = 0x20900; @@ -71,10 +73,11 @@ public SAV5(byte[] data = null, GameVersion versionOverride = GameVersion.Any) LegalTMHMs = Legal.Pouch_TMHM_BW; LegalMedicine = Legal.Pouch_Medicine_BW; LegalBerries = Legal.Pouch_Berries_BW; + + Personal = Legal.PersonalB2W2; break; } HeldItems = Legal.HeldItems_BW; - Personal = Legal.PersonalAO; // todo getBlockInfo(); if (!Exportable) diff --git a/Saves/SaveUtil.cs b/Saves/SaveUtil.cs index 4d8019ba6..12d8f07af 100644 --- a/Saves/SaveUtil.cs +++ b/Saves/SaveUtil.cs @@ -18,8 +18,8 @@ public enum GameVersion // Game Groupings (SaveFile type) RS = 100, FRLG = 101, - DP = 103, - HGSS = 104, + DP = 102, + HGSS = 103, BW = 104, B2W2 = 105, XY = 106,