diff --git a/Misc/PK6.cs b/Misc/PK6.cs index 790f02575..c2665ece1 100644 --- a/Misc/PK6.cs +++ b/Misc/PK6.cs @@ -407,7 +407,12 @@ namespace PKHeX get { return CurrentHandler == 1 ? OT_Friendship : HT_Friendship; } set { if (CurrentHandler == 1) OT_Friendship = value; else HT_Friendship = value; } } - public int[] IVs { get { return new[] { IV_HP, IV_ATK, IV_DEF, IV_SPE, IV_SPA, IV_SPD }; } } + + public int[] IVs { + get { return new[] {IV_HP, IV_ATK, IV_DEF, IV_SPE, IV_SPA, IV_SPD}; } + set { if (value == null || value.Length != 6) return; + IV_HP = value[0]; IV_ATK = value[1]; IV_DEF = value[2]; + IV_SPE = value[3]; IV_SPA = value[4]; IV_SPD = value[5]; } } public int[] EVs { get { return new[] { EV_HP, EV_ATK, EV_DEF, EV_SPE, EV_SPA, EV_SPD }; } } public int[] Moves { get { return new[] { Move1, Move2, Move3, Move4 }; } } public int PSV { get { return (int)(((PID >> 16) ^ (PID & 0xFFFF)) >> 4); } } @@ -667,7 +672,7 @@ namespace PKHeX Geo1_Country = Country; Geo1_Region = Region; } - private void TradeMemory(bool Bank) + public void TradeMemory(bool Bank) { HT_Memory = 4; // Link trade to [VAR: General Location] HT_TextVar = Bank ? 0 : 9; // Somewhere (Bank) : Pokécenter (Trade) diff --git a/Misc/PKX.cs b/Misc/PKX.cs index e4c4e00d5..4d36a5f6f 100644 --- a/Misc/PKX.cs +++ b/Misc/PKX.cs @@ -1,6 +1,7 @@ using System; using System.Drawing; using System.Drawing.Text; +using System.IO; using System.Linq; namespace PKHeX @@ -136,6 +137,40 @@ namespace PKHeX }; #endregion + internal static string[][] SpeciesLang = + { + Util.getStringList("Species", "ja"), // none + Util.getStringList("Species", "ja"), // 1 + Util.getStringList("Species", "en"), // 2 + Util.getStringList("Species", "fr"), // 3 + Util.getStringList("Species", "it"), // 4 + Util.getStringList("Species", "de"), // 5 + Util.getStringList("Species", "es"), // none + Util.getStringList("Species", "es"), // 7 + Util.getStringList("Species", "ko"), // 8 + }; + + internal static string getSpeciesName(int species, int lang) + { + try { return SpeciesLang[lang][species]; } + catch { return ""; } + } + internal static PersonalInfo[] Personal = getPersonalArray(Properties.Resources.personal); + internal static PersonalInfo[] getPersonalArray(byte[] data) + { + PersonalInfo[] d = new PersonalInfo[data.Length / PersonalInfo.Size]; + int formeIndex = 723; + for (int i = 0; i < d.Length; i++) + { + d[i] = new PersonalInfo(data.Skip(i*PersonalInfo.Size).Take(PersonalInfo.Size).ToArray()); + if (d[i].FormeCount <= 1) continue; + + d[i].FormeOffset = formeIndex; + formeIndex += d[i].FormeCount; + } + return d; + } + // Stat Fetching internal static int getMovePP(int move, int ppup) { @@ -200,14 +235,13 @@ namespace PKHeX } internal static byte getBaseFriendship(int species) { - return PersonalGetter.GetPersonal(species).BaseFriendship; + return Personal[species].BaseFriendship; } internal static int getLevel(int species, uint exp) { if (exp == 0) { return 1; } - PersonalParser.Personal MonData = PersonalGetter.GetPersonal(species); - int growth = MonData.EXPGrowth; + int growth = Personal[species].EXPGrowth; // Iterate upwards to find the level above our current level int tl = 0; // Initial Level, immediately incremented before loop. @@ -231,15 +265,11 @@ namespace PKHeX if ((level == 0) || (level == 1)) return 0; if (level > 100) level = 100; - - PersonalParser.Personal MonData = PersonalGetter.GetPersonal(species); - int growth = MonData.EXPGrowth; - - return ExpTable[level, growth]; + return ExpTable[level, Personal[species].EXPGrowth]; } internal static byte[] getAbilities(int species, int formnum) { - return PersonalGetter.GetPersonal(species, formnum).Abilities; + return Personal[Personal[species].FormeIndex(species, formnum)].Abilities; } internal static int getGender(string s) { @@ -382,13 +412,13 @@ namespace PKHeX int HP_EV, int ATK_EV, int DEF_EV, int SPA_EV, int SPD_EV, int SPE_EV, int HP_IV, int ATK_IV, int DEF_IV, int SPA_IV, int SPD_IV, int SPE_IV) { - PersonalParser.Personal MonData = PersonalGetter.GetPersonal(species, form); - int HP_B = MonData.BaseStats[0]; - int ATK_B = MonData.BaseStats[1]; - int DEF_B = MonData.BaseStats[2]; - int SPE_B = MonData.BaseStats[3]; - int SPA_B = MonData.BaseStats[4]; - int SPD_B = MonData.BaseStats[5]; + PersonalInfo p = Personal[Personal[species].FormeIndex(species, form)]; + int HP_B = p.HP; + int ATK_B = p.ATK; + int DEF_B = p.DEF; + int SPE_B = p.SPE; + int SPA_B = p.SPA; + int SPD_B = p.SPD; // Calculate Stats ushort[] stats = new ushort[6]; // Stats are stored as ushorts in the PKX structure. We'll cap them as such. @@ -529,8 +559,7 @@ namespace PKHeX } internal static uint getRandomPID(int species, int cg) { - PersonalParser.Personal MonData = PersonalGetter.GetPersonal(species); - int gt = MonData.GenderRatio; + int gt = Personal[species].Gender; uint pid = Util.rnd32(); if (gt == 255) //Genderless return pid; @@ -800,48 +829,6 @@ namespace PKHeX } // Personal.dat - internal static PersonalParser PersonalGetter = new PersonalParser(); - internal class PersonalParser - { - internal byte[] file = Properties.Resources.personal; - internal const int EntryLength = 0xE; - internal struct Personal - { - public byte[] BaseStats; - public byte[] Abilities; - public byte BaseFriendship; - public byte GenderRatio; - public byte EXPGrowth; - public byte AltFormCount; - public byte FormPointer; // 721 + FormPointer + (FormID - 1) = SpeciesIndex - } - - internal Personal GetPersonal(int species) - { - Personal data = new Personal(); - byte[] MonData = new byte[EntryLength]; - data.BaseStats = new byte[6]; - data.Abilities = new byte[3]; - Array.Copy(file, species * EntryLength, MonData, 0, EntryLength); - Array.Copy(MonData, data.BaseStats, 6); - Array.Copy(MonData, 6, data.Abilities, 0, 3); - data.BaseFriendship = MonData[0x9]; - data.GenderRatio = MonData[0xA]; - data.EXPGrowth = MonData[0xB]; - data.AltFormCount = MonData[0xC]; - data.FormPointer = MonData[0xD]; - return data; - } - internal Personal GetPersonal(int species, int formID) - { - Personal data = GetPersonal(species); - if (formID <= 0 || formID > data.AltFormCount || data.AltFormCount <= 0 || data.FormPointer <= 0) - return data; - - // Working with an Alt Forme with a base stat change - return GetPersonal(721 + --formID + data.FormPointer); - } - } internal static string[] getFormList(int species, string[] t, string[] f, string[] g) { @@ -1373,5 +1360,118 @@ namespace PKHeX } } } + + public class PersonalInfo + { + internal static int Size = 0x50; + 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(2), // 15 + br.ReadBytes(3), // 17 + br.ReadBytes(2), // 16 + br.ReadBytes(2), // 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 FormeOffset; + public int FormeIndex(int species, int forme) + { + return forme == 0 ? species : FormeOffset; + } + 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; + } + } + } + } } } \ No newline at end of file diff --git a/Misc/pk2pk.cs b/Misc/pk2pk.cs index 226f6fd00..6b25fa081 100644 --- a/Misc/pk2pk.cs +++ b/Misc/pk2pk.cs @@ -52,9 +52,7 @@ namespace PKHeX public int g6trgend; private int getAbilityNumber(int species, int ability, int formnum) { - PKX.PersonalParser.Personal MonData = PKX.PersonalGetter.GetPersonal(species, formnum); - int[] spec_abilities = new int[3]; - Array.Copy(MonData.Abilities, spec_abilities, 3); + byte[] spec_abilities = PKX.Personal[PKX.Personal[species].FormeIndex(species, formnum)].Abilities; int abilval = Array.IndexOf(spec_abilities, ability); if (abilval >= 0) return 1 << abilval; @@ -126,8 +124,7 @@ namespace PKHeX } // Gender Form Fateful - PKX.PersonalParser.Personal MonData = PKX.PersonalGetter.GetPersonal(species); - int genderratio = MonData.GenderRatio; + int genderratio = PKX.Personal[species].Gender; uint PID = BitConverter.ToUInt32(pk4, 0); int gv = (int)(PID & 0xFF); int gender; diff --git a/PKX/f1-Main.cs b/PKX/f1-Main.cs index b59642fb8..8d6770e37 100644 --- a/PKX/f1-Main.cs +++ b/PKX/f1-Main.cs @@ -594,7 +594,7 @@ namespace PKHeX } #endregion #region Wondercard - else if (input.Length == 0x108 && ext == ".wc6") + else if (input.Length == 0x108 && ext == ".wc6") new SAV_Wondercard(input).Show(); #endregion else @@ -877,7 +877,7 @@ namespace PKHeX int[] ball_nums = { 7, 576, 13, 492, 497, 14, 495, 493, 496, 494, 11, 498, 8, 6, 12, 15, 9, 5, 499, 10, 1, 16 }; int[] ball_vals = { 7, 25, 13, 17, 22, 14, 20, 18, 21, 19, 11, 23, 8, 6, 12, 15, 9, 5, 24, 10, 1, 16 }; BallDataSource = Util.getVariedCBList(Util.getCBList(itemlist, new[] { 4 }, new[] { 3 }, new[] { 2 }, new[] { 1 }), itemlist, ball_nums, ball_vals); - ItemDataSource = Util.getCBList(itemlist, (DEV_Ability.Enabled) ? null : Legal.Items_Held); + ItemDataSource = Util.getCBList(itemlist, DEV_Ability.Enabled ? null : Legal.Items_Held); SpeciesDataSource = Util.getCBList(specieslist, null); NatureDataSource = Util.getCBList(natures, null); AbilityDataSource = Util.getCBList(abilitylist, null); @@ -1094,8 +1094,7 @@ namespace PKHeX // Form Tables cb.DisplayMember = "Text"; cb.ValueMember = "Value"; - PKX.PersonalParser.Personal MonData = PKX.PersonalGetter.GetPersonal(species); - bool hasForms = !(MonData.AltFormCount == 0 && species != 664 && species != 665); // If no forms & not Scatterbug / Spewpa... + bool hasForms = !(PKX.Personal[species].FormeCount == 1 && species != 664 && species != 665); // If no forms & not Scatterbug / Spewpa... cb.Enabled = cb.Visible = hasForms; if (l != null) l.Visible = hasForms; @@ -1191,8 +1190,7 @@ namespace PKHeX private void clickGender(object sender, EventArgs e) { // Get Gender Threshold - PKX.PersonalParser.Personal MonData = PKX.PersonalGetter.GetPersonal(Util.getIndex(CB_Species)); - int gt = MonData.GenderRatio; + int gt = PKX.Personal[Util.getIndex(CB_Species)].Gender; if (gt == 255 || gt == 0 || gt == 254) // Single gender/genderless return; @@ -1638,8 +1636,7 @@ namespace PKHeX // Check for Gender Changes // Get Gender Threshold - PKX.PersonalParser.Personal MonData = PKX.PersonalGetter.GetPersonal(Species); - int gt = MonData.GenderRatio; + int gt = PKX.Personal[Species].Gender; int genderflag; if (gt == 255) // Genderless diff --git a/Resources/byte/personal b/Resources/byte/personal index 62d10267b..c5a8b6c0c 100644 Binary files a/Resources/byte/personal and b/Resources/byte/personal differ diff --git a/SAV/SAV_HallOfFame.cs b/SAV/SAV_HallOfFame.cs index fd0451317..4617feac8 100644 --- a/SAV/SAV_HallOfFame.cs +++ b/SAV/SAV_HallOfFame.cs @@ -377,8 +377,7 @@ namespace PKHeX { // Get Gender Threshold int species = Util.getIndex(CB_Species); - PKX.PersonalParser.Personal MonData = PKX.PersonalGetter.GetPersonal(species); - int gt = MonData.GenderRatio; + int gt = PKX.Personal[species].Gender; if (gt == 255) Label_Gender.Text = gendersymbols[2]; diff --git a/SAV/SAV_PokedexORAS.cs b/SAV/SAV_PokedexORAS.cs index 7895bab89..3ad6fccd9 100644 --- a/SAV/SAV_PokedexORAS.cs +++ b/SAV/SAV_PokedexORAS.cs @@ -86,8 +86,7 @@ namespace PKHeX CHK_P1.Enabled = true; int index = LB_Species.SelectedIndex + 1; - PKX.PersonalParser.Personal MonData = PKX.PersonalGetter.GetPersonal(index); - int gt = MonData.GenderRatio; + int gt = PKX.Personal[index].Gender; CHK_P2.Enabled = CHK_P4.Enabled = CHK_P6.Enabled = CHK_P8.Enabled = (gt != 254); // Not Female-Only CHK_P3.Enabled = CHK_P5.Enabled = CHK_P7.Enabled = CHK_P9.Enabled = (gt != 0) && (gt != 255); // Not Male-Only and Not Genderless @@ -253,9 +252,7 @@ namespace PKHeX CHK_P1.Checked = ModifierKeys != Keys.Control; } int index = LB_Species.SelectedIndex+1; - - PKX.PersonalParser.Personal MonData = PKX.PersonalGetter.GetPersonal(index); - int gt = MonData.GenderRatio; + int gt = PKX.Personal[index].Gender; CHK_P2.Checked = CHK_P4.Checked = (gt != 254) && ModifierKeys != Keys.Control; CHK_P3.Checked = CHK_P5.Checked = (gt != 0) && (gt != 255) && ModifierKeys != Keys.Control; diff --git a/SAV/SAV_PokedexXY.cs b/SAV/SAV_PokedexXY.cs index 70162554d..27f8296db 100644 --- a/SAV/SAV_PokedexXY.cs +++ b/SAV/SAV_PokedexXY.cs @@ -100,8 +100,7 @@ namespace PKHeX CHK_P1.Enabled = true; int index = LB_Species.SelectedIndex + 1; - PKX.PersonalParser.Personal MonData = PKX.PersonalGetter.GetPersonal(index); - int gt = MonData.GenderRatio; + int gt = PKX.Personal[index].Gender; CHK_P2.Enabled = CHK_P4.Enabled = CHK_P6.Enabled = CHK_P8.Enabled = (gt != 254); // Not Female-Only CHK_P3.Enabled = CHK_P5.Enabled = CHK_P7.Enabled = CHK_P9.Enabled = (gt != 0) && (gt != 255); // Not Male-Only and Not Genderless @@ -284,8 +283,7 @@ namespace PKHeX CHK_F1.Checked = ModifierKeys != Keys.Control; } int index = LB_Species.SelectedIndex+1; - PKX.PersonalParser.Personal MonData = PKX.PersonalGetter.GetPersonal(index); - int gt = MonData.GenderRatio; + int gt = PKX.Personal[index].Gender; CHK_P2.Checked = CHK_P4.Checked = (gt != 254) && ModifierKeys != Keys.Control; CHK_P3.Checked = CHK_P5.Checked = (gt != 0) && (gt != 255) && ModifierKeys != Keys.Control; diff --git a/SAV/SAV_SecretBase.cs b/SAV/SAV_SecretBase.cs index d1a287422..e3b6d8482 100644 --- a/SAV/SAV_SecretBase.cs +++ b/SAV/SAV_SecretBase.cs @@ -426,8 +426,7 @@ namespace PKHeX // Check for Gender Changes // Get Gender Threshold - PKX.PersonalParser.Personal MonData = PKX.PersonalGetter.GetPersonal(Util.getIndex(CB_Species)); - int gt = MonData.GenderRatio; + int gt = PKX.Personal[Util.getIndex(CB_Species)].Gender; if (gt == 255) // Genderless genderflag = 2; @@ -452,8 +451,7 @@ namespace PKHeX private void Label_Gender_Click(object sender, EventArgs e) { // Get Gender Threshold - PKX.PersonalParser.Personal MonData = PKX.PersonalGetter.GetPersonal(Util.getIndex(CB_Species)); - int gt = MonData.GenderRatio; + int gt = PKX.Personal[Util.getIndex(CB_Species)].Gender; if (gt == 255 || gt == 0 || gt == 254) // Single gender/genderless return;