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]