diff --git a/PKHeX.Core/Legality/RNG/MethodFinder.cs b/PKHeX.Core/Legality/RNG/MethodFinder.cs index e56a8ad44..a8edce6c5 100644 --- a/PKHeX.Core/Legality/RNG/MethodFinder.cs +++ b/PKHeX.Core/Legality/RNG/MethodFinder.cs @@ -223,7 +223,7 @@ private static bool GetChannelMatch(uint top, uint bot, uint[] IVs, out PIDIV pi if (E >> 31 != pk.OT_Gender) continue; - if (!GetIVs(RNG.XDRNG, E).SequenceEqual(IVs)) + if (!RNG.XDRNG.GetSequentialIVsUInt32(E).SequenceEqual(IVs)) continue; if (seed >> 16 != pk.SID) @@ -494,21 +494,17 @@ private static uint[] GetIVs(uint r1, uint r2) r2 >> 10 & 31, }; } - /// - /// Generates an IV for each RNG call using the top 5 bits of frame seeds. - /// - /// RNG advancement method - /// RNG seed - /// Array of 6 IVs - private static uint[] GetIVs(RNG method, uint seed) + internal static int[] GetIVsInt32(uint r1, uint r2) { - uint[] ivs = new uint[6]; - for (int i = 0; i < 6; i++) + return new[] { - seed = method.Next(seed); - ivs[i] = seed >> 27; - } - return ivs; + (int)r1 & 31, + (int)r1 >> 5 & 31, + (int)r1 >> 10 & 31, + (int)r2 & 31, + (int)r2 >> 5 & 31, + (int)r2 >> 10 & 31, + }; } private static uint GetIVChunk(uint[] IVs, int start) { diff --git a/PKHeX.Core/Legality/RNG/PIDGenerator.cs b/PKHeX.Core/Legality/RNG/PIDGenerator.cs new file mode 100644 index 000000000..c5afe0a72 --- /dev/null +++ b/PKHeX.Core/Legality/RNG/PIDGenerator.cs @@ -0,0 +1,133 @@ +namespace PKHeX.Core +{ + public static class PIDGenerator + { + private static void SetValuesFromSeedLCRNG(PKM pk, PIDType type, uint seed) + { + var rng = RNG.LCRNG; + var A = rng.Next(seed); + var B = rng.Next(A); + pk.PID = B & 0xFFFF0000 | A >> 16; + + var skipIV1Frame = type == PIDType.Method_2 || type == PIDType.Method_2_Unown; + if (skipIV1Frame) + B = rng.Next(B); + var C = rng.Next(B); + var D = rng.Next(C); + + var skipIV2Frame = type == PIDType.Method_4 || type == PIDType.Method_4_Unown; + if (skipIV2Frame) + D = rng.Next(D); + + pk.IVs = MethodFinder.GetIVsInt32(C >> 16, D >> 16); + } + private static void SetValuesFromSeedBACD(PKM pk, PIDType type, uint seed) + { + var rng = RNG.LCRNG; + bool shiny = type == PIDType.BACD_R_S || type == PIDType.BACD_U_S; + uint X = shiny ? rng.Next(seed) : seed; + var A = rng.Next(X); + var B = rng.Next(A); + var C = rng.Next(B); + var D = rng.Next(C); + + if (shiny) + { + uint PID; + PID = X & 0xFFFF0000 | (uint)pk.SID ^ (uint)pk.TID ^ X >> 16; + PID &= 0xFFFFFFF8; + PID |= B >> 16 & 0x7; // lowest 3 bits + + pk.PID = PID; + } + else + pk.PID = A & 0xFFFF0000 | B >> 16; + + pk.IVs = MethodFinder.GetIVsInt32(C >> 16, D >> 16); + + bool antishiny = type == PIDType.BACD_R_A || type == PIDType.BACD_U_A; + while (antishiny && pk.IsShiny) + pk.PID = unchecked(pk.PID + 1); + } + private static void SetValuesFromSeedXDRNG(PKM pk, uint seed) + { + var rng = RNG.XDRNG; + var A = rng.Next(seed); // IV1 + var B = rng.Next(A); // IV2 + var C = rng.Next(B); // Ability? + var D = rng.Next(C); // PID + var E = rng.Next(D); // PID + + pk.PID = D & 0xFFFF0000 | E >> 16; + pk.IVs = MethodFinder.GetIVsInt32(A >> 16, B >> 16); + } + private static void SetValuesFromSeedChannel(PKM pk, uint seed) + { + var rng = RNG.XDRNG; + var O = rng.Next(seed); // SID + var A = rng.Next(O); // PID + var B = rng.Next(A); // PID + var C = rng.Next(B); // Held Item + var D = rng.Next(C); // Version + var E = rng.Next(D); // OT Gender + + pk.SID = (int)(O >> 16); + pk.PID = (A & 0xFFFF0000 | B >> 16) ^ 0x80000000; + pk.HeldItem = (int)(C >> 31) + 169; // 0-Ganlon, 1-Salac + pk.Version = (int)(D >> 31) + 1; // 0-Sapphire, 1-Ruby + pk.OT_Gender = (int)(E >> 31); + pk.IVs = rng.GetSequentialIVsInt32(E); + } + + public static void SetValuesFromSeed(PKM pk, PIDType type, uint seed) + { + switch (type) + { + case PIDType.Channel: + SetValuesFromSeedChannel(pk, seed); + break; + case PIDType.CXD: + SetValuesFromSeedXDRNG(pk, seed); + break; + + case PIDType.Method_1: + case PIDType.Method_2: + case PIDType.Method_4: + SetValuesFromSeedLCRNG(pk, type, seed); + break; + + case PIDType.BACD_R: + case PIDType.BACD_R_A: + case PIDType.BACD_R_S: + SetValuesFromSeedBACD(pk, type, seed); + break; + case PIDType.BACD_U: + case PIDType.BACD_U_A: + case PIDType.BACD_U_S: + SetValuesFromSeedBACD(pk, type, seed); + break; + + // others: unimplemented + case PIDType.ChainShiny: + break; + case PIDType.Method_1_Unown: + case PIDType.Method_2_Unown: + case PIDType.Method_4_Unown: + break; + case PIDType.Method_1_Roamer: + break; + + case PIDType.CuteCharm: + break; + case PIDType.PokeSpot: + break; + case PIDType.G4MGAntiShiny: + break; + case PIDType.G5MGShiny: + break; + case PIDType.Pokewalker: + break; + } + } + } +} diff --git a/PKHeX.Core/Legality/RNG/RNG.cs b/PKHeX.Core/Legality/RNG/RNG.cs index f504dbc93..29cac98ca 100644 --- a/PKHeX.Core/Legality/RNG/RNG.cs +++ b/PKHeX.Core/Legality/RNG/RNG.cs @@ -30,5 +30,31 @@ public uint Reverse(uint seed, int frames) seed = Prev(seed); return seed; } + + /// + /// Generates an IV for each RNG call using the top 5 bits of frame seeds. + /// + /// RNG seed + /// Array of 6 IVs + internal uint[] GetSequentialIVsUInt32(uint seed) + { + uint[] ivs = new uint[6]; + for (int i = 0; i < 6; i++) + { + seed = Next(seed); + ivs[i] = seed >> 27; + } + return ivs; + } + internal int[] GetSequentialIVsInt32(uint seed) + { + int[] ivs = new int[6]; + for (int i = 0; i < 6; i++) + { + seed = Next(seed); + ivs[i] = (int)(seed >> 27); + } + return ivs; + } } } diff --git a/PKHeX.Core/Legality/Tables3.cs b/PKHeX.Core/Legality/Tables3.cs index 57cf662c8..a2336100f 100644 --- a/PKHeX.Core/Legality/Tables3.cs +++ b/PKHeX.Core/Legality/Tables3.cs @@ -240,7 +240,6 @@ public static partial class Legal internal static readonly MysteryGift[] Encounter_Event3 = { - new WC3 { Species = 385, Level = 05, TID = 40122, OT_Gender = 3, OT_Name = "CHANNEL", CardTitle = "Channel Jirachi", Method = PIDType.Channel, Version = (int)GameVersion.RS }, new WC3 { Species = 251, Level = 10, TID = 31121, OT_Gender = 1, OT_Name = "アゲト", CardTitle = "Agate Celebi", Method = PIDType.CXD, Shiny = false, Language = 1 }, new WC3 { Species = 025, Level = 10, TID = 31121, OT_Gender = 0, OT_Name = "コロシアム", CardTitle = "Colosseum Pikachu", Method = PIDType.CXD, Shiny = false, Language = 1 }, @@ -328,7 +327,7 @@ public static partial class Legal new WC3 { Species = 263, Level = 5, Version = (int)GameVersion.S, Language = 2, Method = PIDType.BACD_R_S, TID = 30317, OT_Name = "SAPHIRE", OT_Gender = 0 }, // Channel Jirachi - new WC3 { Species = 385, Level = 5, Version = (int)GameVersion.RS, Method = PIDType.Channel, TID = 40122, SID = -1, OT_Name = "CHANNEL", Met_Level = 0 }, + new WC3 { Species = 385, Level = 5, Version = (int)GameVersion.RS, Method = PIDType.Channel, TID = 40122, OT_Gender = 3,SID = -1, OT_Name = "CHANNEL", CardTitle = "Channel Jirachi", Met_Level = 0 }, // Aura Mew new WC3 { Species = 151, Level = 10, Version = (int)GameVersion.R, Language = 2, Method = PIDType.BACD_R, TID = 20078, OT_Name = "Aura", Fateful = true }, // Mew @@ -339,7 +338,7 @@ public static partial class Legal // English Events new WC3 { Species = 006, Level = 70, Version = (int)GameVersion.R, Moves = new[] {017,163,082,083}, Language = 2, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANNIV" }, // Charizard - new WC3 { Species = 025, Level = 70, Version = (int)GameVersion.R, Moves = new[] {085,097,085,113}, Language = 2, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANNIV" }, // Pikachu + new WC3 { Species = 025, Level = 70, Version = (int)GameVersion.R, Moves = new[] {085,097,087,113}, Language = 2, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANNIV" }, // Pikachu new WC3 { Species = 144, Level = 70, Version = (int)GameVersion.R, Moves = new[] {097,170,058,115}, Language = 2, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANNIV" }, // Articuno new WC3 { Species = 243, Level = 70, Version = (int)GameVersion.R, Moves = new[] {098,209,115,242}, Language = 2, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANNIV" }, // Raikou new WC3 { Species = 244, Level = 70, Version = (int)GameVersion.R, Moves = new[] {083,023,053,207}, Language = 2, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANNIV" }, // Entei @@ -351,7 +350,7 @@ public static partial class Legal // French new WC3 { Species = 006, Level = 70, Version = (int)GameVersion.R, Moves = new[] {017,163,082,083}, Language = 3, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANNIV" }, // Charizard - new WC3 { Species = 025, Level = 70, Version = (int)GameVersion.R, Moves = new[] {085,097,085,113}, Language = 3, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANNIV" }, // Pikachu + new WC3 { Species = 025, Level = 70, Version = (int)GameVersion.R, Moves = new[] {085,097,087,113}, Language = 3, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANNIV" }, // Pikachu new WC3 { Species = 144, Level = 70, Version = (int)GameVersion.R, Moves = new[] {097,170,058,115}, Language = 3, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANNIV" }, // Articuno new WC3 { Species = 243, Level = 70, Version = (int)GameVersion.R, Moves = new[] {098,209,115,242}, Language = 3, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANNIV" }, // Raikou new WC3 { Species = 244, Level = 70, Version = (int)GameVersion.R, Moves = new[] {083,023,053,207}, Language = 3, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANNIV" }, // Entei @@ -363,7 +362,7 @@ public static partial class Legal // Italian new WC3 { Species = 006, Level = 70, Version = (int)GameVersion.R, Moves = new[] {017,163,082,083}, Language = 4, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANNI" }, // Charizard - new WC3 { Species = 025, Level = 70, Version = (int)GameVersion.R, Moves = new[] {085,097,085,113}, Language = 4, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANNI" }, // Pikachu + new WC3 { Species = 025, Level = 70, Version = (int)GameVersion.R, Moves = new[] {085,097,087,113}, Language = 4, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANNI" }, // Pikachu new WC3 { Species = 144, Level = 70, Version = (int)GameVersion.R, Moves = new[] {097,170,058,115}, Language = 4, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANNI" }, // Articuno new WC3 { Species = 243, Level = 70, Version = (int)GameVersion.R, Moves = new[] {098,209,115,242}, Language = 4, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANNI" }, // Raikou new WC3 { Species = 244, Level = 70, Version = (int)GameVersion.R, Moves = new[] {083,023,053,207}, Language = 4, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANNI" }, // Entei @@ -375,7 +374,7 @@ public static partial class Legal // German new WC3 { Species = 006, Level = 70, Version = (int)GameVersion.R, Moves = new[] {017,163,082,083}, Language = 5, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10JAHRE" }, // Charizard - new WC3 { Species = 025, Level = 70, Version = (int)GameVersion.R, Moves = new[] {085,097,085,113}, Language = 5, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10JAHRE" }, // Pikachu + new WC3 { Species = 025, Level = 70, Version = (int)GameVersion.R, Moves = new[] {085,097,087,113}, Language = 5, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10JAHRE" }, // Pikachu new WC3 { Species = 144, Level = 70, Version = (int)GameVersion.R, Moves = new[] {097,170,058,115}, Language = 5, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10JAHRE" }, // Articuno new WC3 { Species = 243, Level = 70, Version = (int)GameVersion.R, Moves = new[] {098,209,115,242}, Language = 5, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10JAHRE" }, // Raikou new WC3 { Species = 244, Level = 70, Version = (int)GameVersion.R, Moves = new[] {083,023,053,207}, Language = 5, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10JAHRE" }, // Entei @@ -387,7 +386,7 @@ public static partial class Legal // Spanish new WC3 { Species = 006, Level = 70, Version = (int)GameVersion.R, Moves = new[] {017,163,082,083}, Language = 7, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANIV" }, // Charizard - new WC3 { Species = 025, Level = 70, Version = (int)GameVersion.R, Moves = new[] {085,097,085,113}, Language = 7, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANIV" }, // Pikachu + new WC3 { Species = 025, Level = 70, Version = (int)GameVersion.R, Moves = new[] {085,097,087,113}, Language = 7, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANIV" }, // Pikachu new WC3 { Species = 144, Level = 70, Version = (int)GameVersion.R, Moves = new[] {097,170,058,115}, Language = 7, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANIV" }, // Articuno new WC3 { Species = 243, Level = 70, Version = (int)GameVersion.R, Moves = new[] {098,209,115,242}, Language = 7, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANIV" }, // Raikou new WC3 { Species = 244, Level = 70, Version = (int)GameVersion.R, Moves = new[] {083,023,053,207}, Language = 7, Method = PIDType.BACD_R, TID = 06227, OT_Name = "10ANIV" }, // Entei diff --git a/PKHeX.Core/MysteryGifts/MysteryGift.cs b/PKHeX.Core/MysteryGifts/MysteryGift.cs index b70b0f3a7..9c3e20519 100644 --- a/PKHeX.Core/MysteryGifts/MysteryGift.cs +++ b/PKHeX.Core/MysteryGifts/MysteryGift.cs @@ -105,7 +105,7 @@ public MysteryGift Clone() public abstract bool IsPokémon { get; set; } public virtual int Quantity { get => 1; set { } } - public bool Empty => Data.SequenceEqual(new byte[Data.Length]); + public virtual bool Empty => Data.All(z => z == 0); public virtual bool IsBP { get => false; set { } } public virtual int BP { get => 0; set { } } diff --git a/PKHeX.Core/MysteryGifts/WC3.cs b/PKHeX.Core/MysteryGifts/WC3.cs index 91859f532..b1999b695 100644 --- a/PKHeX.Core/MysteryGifts/WC3.cs +++ b/PKHeX.Core/MysteryGifts/WC3.cs @@ -39,7 +39,8 @@ public class WC3 : MysteryGift, IRibbonSetEvent3 public override int CardID { get; set; } public override bool IsItem { get; set; } public override int ItemID { get; set; } - public override bool IsPokémon { get; set; } + public override bool IsPokémon { get; set; } = true; + public override bool Empty => false; // Synthetic private int? _metLevel; @@ -51,7 +52,103 @@ public int Met_Level public override PKM ConvertToPKM(SaveFile SAV) { - throw new NotImplementedException(); + var pi = SAV.Personal.GetFormeEntry(Species, 0); + PK3 pk = new PK3 + { + Species = Species, + Met_Level = Met_Level, + Met_Location = Met_Location, + Ball = 4, + + EXP = PKX.GetEXP(Level, Species), + + // Ribbons + RibbonCountry = RibbonCountry, + RibbonNational = RibbonNational, + RibbonEarth = RibbonEarth, + RibbonChampionBattle = RibbonChampionBattle, + RibbonChampionRegional = RibbonChampionRegional, + RibbonChampionNational = RibbonChampionNational, + + Language = Language < 0 ? SAV.Language : Language, + FatefulEncounter = Fateful, + }; + if (IsEgg) + { + pk.IsEgg = true; + pk.IsNicknamed = true; + } + + bool hatchedEgg = IsEgg && SAV.Generation != 3; + if (hatchedEgg) // ugly workaround for character table interactions + { + pk.IsEgg = false; + pk.Language = SAV.Language; + pk.OT_Name = "PKHeX"; + pk.OT_Gender = SAV.Gender; + pk.TID = SAV.TID; + pk.SID = SAV.SID; + pk.OT_Friendship = pi.BaseFriendship; + pk.IsEgg = true; + } + else + { + pk.OT_Name = OT_Name ?? SAV.OT; + pk.OT_Gender = OT_Gender != 3 ? OT_Gender & 1 : SAV.Gender; + pk.TID = TID; + pk.SID = SID; + pk.OT_Friendship = IsEgg ? pi.HatchCycles : pi.BaseFriendship; + } + pk.Nickname = PKX.GetSpeciesNameGeneration(Species, pk.Language, 3); // will be set to Egg nickname if appropriate by PK3 setter + + if (Version == 0) + { + if (SAV.Game > 15) // above CXD + pk.Version = (int) GameVersion.R; + else + pk.Version = SAV.Game; + } + else + { + if (Version < 100) // single game + pk.Version = Version; + else + { + int rand = Util.Rand.Next(1); + switch (Version) + { + case (int) GameVersion.FRLG: + pk.Version = (int)GameVersion.FR + rand; // or LG + break; + case (int)GameVersion.RS: + pk.Version = (int)GameVersion.R + rand; // or S + break; + default: + throw new Exception($"Unknown GameVersion: {Version}"); + } + } + } + + // Generate PIDIV + var seed = Util.Rand32(); + switch (Method) + { + case PIDType.BACD_R: + seed &= 0xFFFF; + break; + case PIDType.BACD_R_S: + seed &= 0xFF; + break; + } + PIDGenerator.SetValuesFromSeed(pk, Method, seed); + + var moves = Moves ?? Legal.GetBaseEggMoves(pk, Species, (GameVersion)pk.Version, Level); + if (moves.Length != 4) + Array.Resize(ref moves, 4); + pk.Moves = moves; + pk.HeldItem = 0; // clear, only random for Jirachis(?), no loss + pk.RefreshChecksum(); + return pk; } public bool RibbonEarth { get; set; } diff --git a/PKHeX.Core/PKM/PKMConverter.cs b/PKHeX.Core/PKM/PKMConverter.cs index 4d0c79318..a4cf2b300 100644 --- a/PKHeX.Core/PKM/PKMConverter.cs +++ b/PKHeX.Core/PKM/PKMConverter.cs @@ -221,6 +221,8 @@ public static PKM ConvertToType(PKM pk, Type PKMType, out string comment) pkm.Met_Location = 16; // Route 16 else pkm.Met_Location = 30001; // Pokétransfer + pkm.IsNicknamed = false; + pkm.Nickname = PKX.GetSpeciesNameGeneration(pkm.Species, pkm.Language, fromFormat); } switch (fromType.Name) { diff --git a/PKHeX.WinForms/Subforms/SAV_MysteryGiftDB.Designer.cs b/PKHeX.WinForms/Subforms/SAV_MysteryGiftDB.Designer.cs index 7066fb497..d12c0546c 100644 --- a/PKHeX.WinForms/Subforms/SAV_MysteryGiftDB.Designer.cs +++ b/PKHeX.WinForms/Subforms/SAV_MysteryGiftDB.Designer.cs @@ -1418,7 +1418,8 @@ private void InitializeComponent() ".wc7", ".wc6", ".pgf", - ".pcd/pgt"}); + ".pcd/pgt", + ".wc3"}); this.CB_Format.Location = new System.Drawing.Point(54, 0); this.CB_Format.Margin = new System.Windows.Forms.Padding(0); this.CB_Format.Name = "CB_Format"; diff --git a/PKHeX.WinForms/Subforms/SAV_MysteryGiftDB.cs b/PKHeX.WinForms/Subforms/SAV_MysteryGiftDB.cs index 97486b9da..e616f2070 100644 --- a/PKHeX.WinForms/Subforms/SAV_MysteryGiftDB.cs +++ b/PKHeX.WinForms/Subforms/SAV_MysteryGiftDB.cs @@ -90,7 +90,7 @@ public SAV_MysteryGiftDB(PKMEditor tabs, SAVEditor sav) RawDB.AddRange(Legal.MGDB_G6); RawDB.AddRange(Legal.MGDB_G7); - RawDB = new List(RawDB.Where(mg => !mg.IsItem && mg.IsPokémon && mg.Species > 0).Distinct().OrderBy(mg => mg.Species)); + RawDB = new List(RawDB.Where(mg => !mg.IsItem && mg.IsPokémon && mg.Species > 0).Distinct().Concat(Legal.MGDB_G3).OrderBy(mg => mg.Species)); foreach (var mg in RawDB) mg.GiftUsed = false; SetResults(RawDB); @@ -125,7 +125,7 @@ private void ClickView(object sender, EventArgs e) PKME_Tabs.PopulateFields(Results[index].ConvertToPKM(SAV), false); slotSelected = index; slotColor = Properties.Resources.slotView; - FillPKXBoxes(SCR_Box.Value); + UpdateSlotColor(SCR_Box.Value); L_Viewed.Text = string.Format(Viewed, Results[index].FileName); } private void ClickSavePK(object sender, EventArgs e) @@ -143,6 +143,11 @@ private void ClickSaveMG(object sender, EventArgs e) if (index < 0) return; var gift = Results[index]; + if (gift.Data == null) // WC3 + { + WinFormsUtil.Alert("Unable to save WC3 data. No data to save!"); + return; + } WinFormsUtil.SaveMGDialog(gift); } @@ -234,7 +239,7 @@ private void Menu_Export_Click(object sender, EventArgs e) if (!Directory.Exists(path)) // just in case... Directory.CreateDirectory(path); - foreach (var gift in Results) + foreach (var gift in Results.Where(g => g.Data != null)) // WC3 have no data File.WriteAllBytes(Path.Combine(path, Util.CleanFileName(gift.FileName)), gift.Data); } @@ -345,7 +350,10 @@ private void FillPKXBoxes(int start) PKXBOXES[i].Image = Results[i + begin].Sprite(SAV); for (int i = end; i < RES_MAX; i++) PKXBOXES[i].Image = null; - + UpdateSlotColor(start); + } + private void UpdateSlotColor(int start) + { for (int i = 0; i < RES_MAX; i++) PKXBOXES[i].BackgroundImage = Properties.Resources.slotTrans; if (slotSelected != -1 && slotSelected >= RES_MIN * start && slotSelected < RES_MIN * start + RES_MAX) diff --git a/Tests/PKHeX.Tests/PKM/PIDIVTests.cs b/Tests/PKHeX.Tests/PKM/PIDIVTests.cs index 18e591052..60914cb30 100644 --- a/Tests/PKHeX.Tests/PKM/PIDIVTests.cs +++ b/Tests/PKHeX.Tests/PKM/PIDIVTests.cs @@ -16,11 +16,17 @@ public void PIDIVMatchingTest3() { // Method 1/2/4 var pk1 = new PK3 {PID = 0xE97E0000, IVs = new[] {17, 19, 20, 16, 13, 12}}; - Assert.AreEqual(PIDType.Method_1, MethodFinder.Analyze(pk1)?.Type, "Unable to match PID to Method 1 spread"); + var ga1 = MethodFinder.Analyze(pk1); + Assert.AreEqual(PIDType.Method_1, ga1.Type, "Unable to match PID to Method 1 spread"); var pk2 = new PK3 {PID = 0x5271E97E, IVs = new[] {02, 18, 03, 12, 22, 24}}; Assert.AreEqual(PIDType.Method_2, MethodFinder.Analyze(pk2)?.Type, "Unable to match PID to Method 2 spread"); var pk4 = new PK3 {PID = 0x31B05271, IVs = new[] {02, 18, 03, 05, 30, 11}}; Assert.AreEqual(PIDType.Method_4, MethodFinder.Analyze(pk4)?.Type, "Unable to match PID to Method 4 spread"); + + var gk1 = new PK3(); + PIDGenerator.SetValuesFromSeed(gk1, ga1.Type, ga1.OriginSeed); + Assert.AreEqual(pk1.PID, gk1.PID, "Unable to match generated PID to Method 1 PID"); + Assert.IsTrue(gk1.IVs.SequenceEqual(pk1.IVs), "Unable to match generated PID to Method 1 IVs"); } [TestMethod] @@ -42,11 +48,23 @@ public void PIDIVMatchingTest3Misc() { // Colosseum / XD var pk3 = new PK3 {PID = 0x0985A297, IVs = new[] {06, 01, 00, 07, 17, 07}}; + var ak3 = MethodFinder.Analyze(pk3); Assert.AreEqual(PIDType.CXD, MethodFinder.Analyze(pk3)?.Type, "Unable to match PID to CXD spread"); + var gk3 = new PK3(); + PIDGenerator.SetValuesFromSeed(gk3, PIDType.CXD, ak3.OriginSeed); + Assert.AreEqual(pk3.PID, gk3.PID, "Unable to match generated PID to Channel spread"); + Assert.IsTrue(pk3.IVs.SequenceEqual(gk3.IVs), "Unable to match generated IVs to Channel spread"); + // Channel Jirachi var pkC = new PK3 {PID = 0x264750D9, IVs = new[] {06, 31, 14, 27, 05, 27}, SID = 45819, OT_Gender = 1, Version = (int)GameVersion.R}; - Assert.AreEqual(PIDType.Channel, MethodFinder.Analyze(pkC)?.Type, "Unable to match PID to Channel spread"); + var akC = MethodFinder.Analyze(pkC); + Assert.AreEqual(PIDType.Channel,akC.Type, "Unable to match PID to Channel spread"); + + var gkC = new PK3(); + PIDGenerator.SetValuesFromSeed(gkC, PIDType.Channel, akC.OriginSeed); + Assert.AreEqual(pkC.PID, gkC.PID, "Unable to match generated PID to Channel spread"); + Assert.IsTrue(pkC.IVs.SequenceEqual(gkC.IVs), "Unable to match generated IVs to Channel spread"); } [TestMethod] @@ -74,6 +92,11 @@ public void PIDIVMatchingTest3Event() var a_pkRS = MethodFinder.Analyze(pkRS); Assert.AreEqual(PIDType.BACD_R_S, a_pkRS?.Type, "Unable to match PID to BACD-R shiny spread"); Assert.IsTrue(0x0020 == a_pkRS?.OriginSeed, "Unable to match PID to BACD-R shiny spread origin seed"); + + var gkRS = new PK3 { TID = 30317, SID = 00000 }; + PIDGenerator.SetValuesFromSeed(gkRS, PIDType.BACD_R_S, a_pkRS.OriginSeed); + Assert.AreEqual(pkRS.PID, gkRS.PID, "Unable to match generated PID to BACD-R shiny spread"); + Assert.IsTrue(pkRS.IVs.SequenceEqual(gkRS.IVs), "Unable to match generated IVs to BACD-R shiny spread"); } [TestMethod]