Add wc3->pk3 conversion

fixes 10ANIV pikachu having Thunderbolt twice
un-duplicates CHANNEL event data
adds seed->PIDIV generator template for M1/2/4, CXD, Channel, and BACD

improve pkm converter to update nickname of hatched eggs. isn't perfect
(farfetch'd) but works better than before
This commit is contained in:
Kurt 2017-07-15 18:36:55 -07:00
parent 569873701b
commit 2a2f5669e4
10 changed files with 316 additions and 31 deletions

View File

@ -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,
};
}
/// <summary>
/// Generates an IV for each RNG call using the top 5 bits of frame seeds.
/// </summary>
/// <param name="method">RNG advancement method</param>
/// <param name="seed">RNG seed</param>
/// <returns>Array of 6 IVs</returns>
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)
{

View File

@ -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;
}
}
}
}

View File

@ -30,5 +30,31 @@ public uint Reverse(uint seed, int frames)
seed = Prev(seed);
return seed;
}
/// <summary>
/// Generates an IV for each RNG call using the top 5 bits of frame seeds.
/// </summary>
/// <param name="seed">RNG seed</param>
/// <returns>Array of 6 IVs</returns>
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;
}
}
}

View File

@ -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

View File

@ -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 { } }

View File

@ -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; }

View File

@ -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)
{

View File

@ -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";

View File

@ -90,7 +90,7 @@ public SAV_MysteryGiftDB(PKMEditor tabs, SAVEditor sav)
RawDB.AddRange(Legal.MGDB_G6);
RawDB.AddRange(Legal.MGDB_G7);
RawDB = new List<MysteryGift>(RawDB.Where(mg => !mg.IsItem && mg.IsPokémon && mg.Species > 0).Distinct().OrderBy(mg => mg.Species));
RawDB = new List<MysteryGift>(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)

View File

@ -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]