Refactoring

Extract mystery gift matching criteria into separate method
This commit is contained in:
Kurt 2017-08-24 10:09:34 -07:00
parent c2124a4bbd
commit 4f7c19d0cd
2 changed files with 250 additions and 204 deletions

View file

@ -950,46 +950,12 @@ namespace PKHeX.Core
var validWC3 = new List<MysteryGift>();
var vs = GetValidPreEvolutions(pkm, MaxSpeciesID_3).ToArray();
foreach (WC3 wc in DB.OfType<WC3>().Where(wc => vs.Any(dl => dl.Species == wc.Species)))
var enumerable = DB.OfType<WC3>().Where(wc => vs.Any(dl => dl.Species == wc.Species));
foreach (WC3 wc in enumerable)
{
// Gen3 Version MUST match.
if (wc.Version != 0 && !((GameVersion)wc.Version).Contains((GameVersion)pkm.Version))
if (!GetIsMatchWC3(pkm, wc))
continue;
bool hatchedEgg = wc.IsEgg && !pkm.IsEgg;
if (!hatchedEgg)
{
if (wc.SID != -1 && wc.SID != pkm.SID) continue;
if (wc.TID != -1 && wc.TID != pkm.TID) continue;
if (wc.OT_Name != null && wc.OT_Name != pkm.OT_Name) continue;
if (wc.OT_Gender < 3 && wc.OT_Gender != pkm.OT_Gender) continue;
}
if (wc.Language != -1 && wc.Language != pkm.Language) continue;
if (wc.Ball != pkm.Ball) continue;
if (wc.Fateful != pkm.FatefulEncounter)
{
// XD Gifts only at level 20 get flagged after transfer
bool valid = wc.Level == 20 && pkm is XK3;
if (!valid)
continue;
}
if (pkm.IsNative)
{
if (wc.Met_Level != pkm.Met_Level)
continue;
if (wc.Met_Location != pkm.Met_Location && (!wc.IsEgg || pkm.IsEgg))
continue;
}
else
{
if (pkm.IsEgg)
break;
if (wc.Level > pkm.Met_Level)
continue;
}
if (wc.Species == pkm.Species) // best match
yield return wc;
else
@ -1011,51 +977,12 @@ namespace PKHeX.Core
var validPCD = new List<MysteryGift>();
var vs = GetValidPreEvolutions(pkm).ToArray();
foreach (PCD mg in DB.OfType<PCD>().Where(wc => vs.Any(dl => dl.Species == wc.Species)))
var enumerable = DB.OfType<PCD>().Where(wc => vs.Any(dl => dl.Species == wc.Species));
foreach (PCD mg in enumerable)
{
var wc = mg.Gift.PK;
if (!wc.IsEgg)
{
if (wc.TID != pkm.TID) continue;
if (wc.SID != pkm.SID) continue;
if (wc.OT_Name != pkm.OT_Name) continue;
if (wc.OT_Gender != pkm.OT_Gender) continue;
if (wc.Language != 0 && wc.Language != pkm.Language) continue;
if (pkm.Format != 4) // transferred
{
// met location: deferred to general transfer check
if (wc.CurrentLevel > pkm.Met_Level) continue;
}
else
{
if (wc.Egg_Location + 3000 != pkm.Met_Location) continue;
if (wc.CurrentLevel != pkm.Met_Level) continue;
}
}
else // Egg
{
if (wc.Egg_Location + 3000 != pkm.Egg_Location && pkm.Egg_Location != 2002) // traded
continue;
if (wc.CurrentLevel != pkm.Met_Level)
continue;
if (pkm.IsEgg && !pkm.IsNative)
continue;
}
if (wc.AltForm != pkm.AltForm && vs.All(dl => !IsFormChangeable(pkm, dl.Species))) continue;
if (wc.Ball != pkm.Ball) continue;
if (wc.OT_Gender < 3 && wc.OT_Gender != pkm.OT_Gender) continue;
if (wc.PID == 1 && pkm.IsShiny) continue;
if (wc.Gender != 3 && wc.Gender != pkm.Gender) continue;
if (wc.CNT_Cool > pkm.CNT_Cool) continue;
if (wc.CNT_Beauty > pkm.CNT_Beauty) continue;
if (wc.CNT_Cute > pkm.CNT_Cute) continue;
if (wc.CNT_Smart > pkm.CNT_Smart) continue;
if (wc.CNT_Tough > pkm.CNT_Tough) continue;
if (wc.CNT_Sheen > pkm.CNT_Sheen) continue;
if (!GetIsMatchPCD(pkm, wc, vs))
continue;
bool receivable = mg.CanBeReceivedBy(pkm.Version);
if (wc.Species == pkm.Species && receivable) // best match
@ -1073,44 +1000,11 @@ namespace PKHeX.Core
var validPGF = new List<MysteryGift>();
var vs = GetValidPreEvolutions(pkm).ToArray();
foreach (PGF wc in DB.OfType<PGF>().Where(wc => vs.Any(dl => dl.Species == wc.Species)))
var enumerable = DB.OfType<PGF>().Where(wc => vs.Any(dl => dl.Species == wc.Species));
foreach (PGF wc in enumerable)
{
if (!wc.IsEgg)
{
if (wc.SID != pkm.SID) continue;
if (wc.TID != pkm.TID) continue;
if (wc.OT != pkm.OT_Name) continue;
if (wc.OTGender < 3 && wc.OTGender != pkm.OT_Gender) continue;
if (wc.PID != 0 && pkm.PID != wc.PID) continue;
if (wc.PIDType == 0 && pkm.IsShiny) continue;
if (wc.PIDType == 2 && !pkm.IsShiny) continue;
if (wc.OriginGame != 0 && wc.OriginGame != pkm.Version) continue;
if (wc.Language != 0 && wc.Language != pkm.Language) continue;
if (wc.EggLocation != pkm.Egg_Location) continue;
if (wc.MetLocation != pkm.Met_Location) continue;
}
else
{
if (wc.EggLocation != pkm.Egg_Location && pkm.Egg_Location != 30003) // traded
continue;
if (pkm.IsEgg && !pkm.IsNative)
continue;
}
if (wc.Form != pkm.AltForm && vs.All(dl => !IsFormChangeable(pkm, dl.Species))) continue;
if (wc.Level != pkm.Met_Level) continue;
if (wc.Ball != pkm.Ball) continue;
if (wc.Nature != 0xFF && wc.Nature != pkm.Nature) continue;
if (wc.Gender != 2 && wc.Gender != pkm.Gender) continue;
if (wc.CNT_Cool > pkm.CNT_Cool) continue;
if (wc.CNT_Beauty > pkm.CNT_Beauty) continue;
if (wc.CNT_Cute > pkm.CNT_Cute) continue;
if (wc.CNT_Smart > pkm.CNT_Smart) continue;
if (wc.CNT_Tough > pkm.CNT_Tough) continue;
if (wc.CNT_Sheen > pkm.CNT_Sheen) continue;
if (!GetIsMatchPGF(pkm, wc, vs))
continue;
if (wc.Species == pkm.Species) // best match
yield return wc;
@ -1126,48 +1020,11 @@ namespace PKHeX.Core
yield break;
List<MysteryGift> validWC6 = new List<MysteryGift>();
var vs = GetValidPreEvolutions(pkm).ToArray();
foreach (WC6 wc in DB.OfType<WC6>().Where(wc => vs.Any(dl => dl.Species == wc.Species)))
var enumerable = DB.OfType<WC6>().Where(wc => vs.Any(dl => dl.Species == wc.Species));
foreach (WC6 wc in enumerable)
{
if (pkm.Egg_Location == 0) // Not Egg
{
if (wc.CardID != pkm.SID) continue;
if (wc.TID != pkm.TID) continue;
if (wc.OT != pkm.OT_Name) continue;
if (wc.OTGender != pkm.OT_Gender) continue;
if (wc.PIDType == 0 && pkm.PID != wc.PID) continue;
if (wc.PIDType == 2 && !pkm.IsShiny) continue;
if (wc.PIDType == 3 && pkm.IsShiny) continue;
if (wc.OriginGame != 0 && wc.OriginGame != pkm.Version) continue;
if (wc.EncryptionConstant != 0 && wc.EncryptionConstant != pkm.EncryptionConstant) continue;
if (wc.Language != 0 && wc.Language != pkm.Language) continue;
}
if (wc.Form != pkm.AltForm && vs.All(dl => !IsFormChangeable(pkm, dl.Species))) continue;
if (wc.IsEgg)
{
if (wc.EggLocation != pkm.Egg_Location && pkm.Egg_Location != 30002) // traded
continue;
if (pkm.IsEgg && !pkm.IsNative)
continue;
}
else
{
if (wc.EggLocation != pkm.Egg_Location) continue;
if (wc.MetLocation != pkm.Met_Location) continue;
}
if (wc.Level != pkm.Met_Level) continue;
if (wc.Ball != pkm.Ball) continue;
if (wc.OTGender < 3 && wc.OTGender != pkm.OT_Gender) continue;
if (wc.Nature != 0xFF && wc.Nature != pkm.Nature) continue;
if (wc.Gender != 3 && wc.Gender != pkm.Gender) continue;
if (wc.CNT_Cool > pkm.CNT_Cool) continue;
if (wc.CNT_Beauty > pkm.CNT_Beauty) continue;
if (wc.CNT_Cute > pkm.CNT_Cute) continue;
if (wc.CNT_Smart > pkm.CNT_Smart) continue;
if (wc.CNT_Tough > pkm.CNT_Tough) continue;
if (wc.CNT_Sheen > pkm.CNT_Sheen) continue;
if (!GetIsMatchWC6(pkm, wc, vs))
continue;
if (wc.Species == pkm.Species) // best match
yield return wc;
@ -1183,51 +1040,11 @@ namespace PKHeX.Core
yield break;
List<MysteryGift> validWC7 = new List<MysteryGift>();
var vs = GetValidPreEvolutions(pkm).ToArray();
foreach (WC7 wc in DB.OfType<WC7>().Where(wc => vs.Any(dl => dl.Species == wc.Species)))
var enumerable = DB.OfType<WC7>().Where(wc => vs.Any(dl => dl.Species == wc.Species));
foreach (WC7 wc in enumerable)
{
if (pkm.Egg_Location == 0) // Not Egg
{
if (wc.OTGender != 3)
{
if (wc.SID != pkm.SID) continue;
if (wc.TID != pkm.TID) continue;
if (wc.OTGender != pkm.OT_Gender) continue;
}
if (!string.IsNullOrEmpty(wc.OT) && wc.OT != pkm.OT_Name) continue;
if (wc.OriginGame != 0 && wc.OriginGame != pkm.Version) continue;
if (wc.EncryptionConstant != 0 && wc.EncryptionConstant != pkm.EncryptionConstant) continue;
if (wc.Language != 0 && wc.Language != pkm.Language) continue;
}
if (wc.Form != pkm.AltForm && vs.All(dl => !IsFormChangeable(pkm, dl.Species))) continue;
if (wc.IsEgg)
{
if (wc.EggLocation != pkm.Egg_Location && pkm.Egg_Location != 30002) // traded
continue;
if (pkm.IsEgg && !pkm.IsNative)
continue;
}
else
{
if (wc.EggLocation != pkm.Egg_Location) continue;
if (wc.MetLocation != pkm.Met_Location) continue;
}
if (wc.MetLevel != pkm.Met_Level) continue;
if (wc.Ball != pkm.Ball) continue;
if (wc.OTGender < 3 && wc.OTGender != pkm.OT_Gender) continue;
if (wc.Nature != 0xFF && wc.Nature != pkm.Nature) continue;
if (wc.Gender != 3 && wc.Gender != pkm.Gender) continue;
if (wc.CNT_Cool > pkm.CNT_Cool) continue;
if (wc.CNT_Beauty > pkm.CNT_Beauty) continue;
if (wc.CNT_Cute > pkm.CNT_Cute) continue;
if (wc.CNT_Smart > pkm.CNT_Smart) continue;
if (wc.CNT_Tough > pkm.CNT_Tough) continue;
if (wc.CNT_Sheen > pkm.CNT_Sheen) continue;
if (wc.PIDType == 2 && !pkm.IsShiny) continue;
if (wc.PIDType == 3 && pkm.IsShiny) continue;
if (!GetIsMatchWC7(pkm, wc, vs))
continue;
if ((pkm.SID << 16 | pkm.TID) == 0x79F57B49) // Greninja WC has variant PID and can arrive @ 36 or 37
{
@ -1245,6 +1062,229 @@ namespace PKHeX.Core
foreach (var z in validWC7)
yield return z;
}
private static bool GetIsMatchWC3(PKM pkm, WC3 wc)
{
// Gen3 Version MUST match.
if (wc.Version != 0 && !((GameVersion)wc.Version).Contains((GameVersion)pkm.Version))
return false;
bool hatchedEgg = wc.IsEgg && !pkm.IsEgg;
if (!hatchedEgg)
{
if (wc.SID != -1 && wc.SID != pkm.SID) return false;
if (wc.TID != -1 && wc.TID != pkm.TID) return false;
if (wc.OT_Name != null && wc.OT_Name != pkm.OT_Name) return false;
if (wc.OT_Gender < 3 && wc.OT_Gender != pkm.OT_Gender) return false;
}
if (wc.Language != -1 && wc.Language != pkm.Language) return false;
if (wc.Ball != pkm.Ball) return false;
if (wc.Fateful != pkm.FatefulEncounter)
{
// XD Gifts only at level 20 get flagged after transfer
bool valid = wc.Level == 20 && pkm is XK3;
if (!valid)
return false;
}
if (pkm.IsNative)
{
if (wc.Met_Level != pkm.Met_Level)
return false;
if (wc.Met_Location != pkm.Met_Location && (!wc.IsEgg || pkm.IsEgg))
return false;
}
else
{
if (pkm.IsEgg)
return false;
if (wc.Level > pkm.Met_Level)
return false;
}
return true;
}
private static bool GetIsMatchPCD(PKM pkm, PKM wc, IEnumerable<DexLevel> vs)
{
if (!wc.IsEgg)
{
if (wc.TID != pkm.TID) return false;
if (wc.SID != pkm.SID) return false;
if (wc.OT_Name != pkm.OT_Name) return false;
if (wc.OT_Gender != pkm.OT_Gender) return false;
if (wc.Language != 0 && wc.Language != pkm.Language) return false;
if (pkm.Format != 4) // transferred
{
// met location: deferred to general transfer check
if (wc.CurrentLevel > pkm.Met_Level) return false;
}
else
{
if (wc.Egg_Location + 3000 != pkm.Met_Location) return false;
if (wc.CurrentLevel != pkm.Met_Level) return false;
}
}
else // Egg
{
if (wc.Egg_Location + 3000 != pkm.Egg_Location && pkm.Egg_Location != 2002) // traded
return false;
if (wc.CurrentLevel != pkm.Met_Level)
return false;
if (pkm.IsEgg && !pkm.IsNative)
return false;
}
if (wc.AltForm != pkm.AltForm && vs.All(dl => !IsFormChangeable(pkm, dl.Species)))
return false;
if (wc.Ball != pkm.Ball) return false;
if (wc.OT_Gender < 3 && wc.OT_Gender != pkm.OT_Gender) return false;
if (wc.PID == 1 && pkm.IsShiny) return false;
if (wc.Gender != 3 && wc.Gender != pkm.Gender) return false;
if (wc.CNT_Cool > pkm.CNT_Cool) return false;
if (wc.CNT_Beauty > pkm.CNT_Beauty) return false;
if (wc.CNT_Cute > pkm.CNT_Cute) return false;
if (wc.CNT_Smart > pkm.CNT_Smart) return false;
if (wc.CNT_Tough > pkm.CNT_Tough) return false;
if (wc.CNT_Sheen > pkm.CNT_Sheen) return false;
return false;
}
private static bool GetIsMatchPGF(PKM pkm, PGF wc, IEnumerable<DexLevel> vs)
{
if (!wc.IsEgg)
{
if (wc.SID != pkm.SID) return false;
if (wc.TID != pkm.TID) return false;
if (wc.OT != pkm.OT_Name) return false;
if (wc.OTGender < 3 && wc.OTGender != pkm.OT_Gender) return false;
if (wc.PID != 0 && pkm.PID != wc.PID) return false;
if (wc.PIDType == 0 && pkm.IsShiny) return false;
if (wc.PIDType == 2 && !pkm.IsShiny) return false;
if (wc.OriginGame != 0 && wc.OriginGame != pkm.Version) return false;
if (wc.Language != 0 && wc.Language != pkm.Language) return false;
if (wc.EggLocation != pkm.Egg_Location) return false;
if (wc.MetLocation != pkm.Met_Location) return false;
}
else
{
if (wc.EggLocation != pkm.Egg_Location && pkm.Egg_Location != 30003) // traded
return false;
if (pkm.IsEgg && !pkm.IsNative)
return false;
}
if (wc.Form != pkm.AltForm && vs.All(dl => !IsFormChangeable(pkm, dl.Species))) return false;
if (wc.Level != pkm.Met_Level) return false;
if (wc.Ball != pkm.Ball) return false;
if (wc.Nature != 0xFF && wc.Nature != pkm.Nature) return false;
if (wc.Gender != 2 && wc.Gender != pkm.Gender) return false;
if (wc.CNT_Cool > pkm.CNT_Cool) return false;
if (wc.CNT_Beauty > pkm.CNT_Beauty) return false;
if (wc.CNT_Cute > pkm.CNT_Cute) return false;
if (wc.CNT_Smart > pkm.CNT_Smart) return false;
if (wc.CNT_Tough > pkm.CNT_Tough) return false;
if (wc.CNT_Sheen > pkm.CNT_Sheen) return false;
return true;
}
private static bool GetIsMatchWC6(PKM pkm, WC6 wc, IEnumerable<DexLevel> vs)
{
if (pkm.Egg_Location == 0) // Not Egg
{
if (wc.CardID != pkm.SID) return false;
if (wc.TID != pkm.TID) return false;
if (wc.OT != pkm.OT_Name) return false;
if (wc.OTGender != pkm.OT_Gender) return false;
if (wc.PIDType == 0 && pkm.PID != wc.PID) return false;
if (wc.PIDType == 2 && !pkm.IsShiny) return false;
if (wc.PIDType == 3 && pkm.IsShiny) return false;
if (wc.OriginGame != 0 && wc.OriginGame != pkm.Version) return false;
if (wc.EncryptionConstant != 0 && wc.EncryptionConstant != pkm.EncryptionConstant) return false;
if (wc.Language != 0 && wc.Language != pkm.Language) return false;
}
if (wc.Form != pkm.AltForm && vs.All(dl => !IsFormChangeable(pkm, dl.Species))) return false;
if (wc.IsEgg)
{
if (wc.EggLocation != pkm.Egg_Location && pkm.Egg_Location != 30002) // traded
return false;
if (pkm.IsEgg && !pkm.IsNative)
return false;
}
else
{
if (wc.EggLocation != pkm.Egg_Location) return false;
if (wc.MetLocation != pkm.Met_Location) return false;
}
if (wc.Level != pkm.Met_Level) return false;
if (wc.Ball != pkm.Ball) return false;
if (wc.OTGender < 3 && wc.OTGender != pkm.OT_Gender) return false;
if (wc.Nature != 0xFF && wc.Nature != pkm.Nature) return false;
if (wc.Gender != 3 && wc.Gender != pkm.Gender) return false;
if (wc.CNT_Cool > pkm.CNT_Cool) return false;
if (wc.CNT_Beauty > pkm.CNT_Beauty) return false;
if (wc.CNT_Cute > pkm.CNT_Cute) return false;
if (wc.CNT_Smart > pkm.CNT_Smart) return false;
if (wc.CNT_Tough > pkm.CNT_Tough) return false;
if (wc.CNT_Sheen > pkm.CNT_Sheen) return false;
return true;
}
private static bool GetIsMatchWC7(PKM pkm, WC7 wc, IEnumerable<DexLevel> vs)
{
if (pkm.Egg_Location == 0) // Not Egg
{
if (wc.OTGender != 3)
{
if (wc.SID != pkm.SID) return false;
if (wc.TID != pkm.TID) return false;
if (wc.OTGender != pkm.OT_Gender) return false;
}
if (!string.IsNullOrEmpty(wc.OT) && wc.OT != pkm.OT_Name) return false;
if (wc.OriginGame != 0 && wc.OriginGame != pkm.Version) return false;
if (wc.EncryptionConstant != 0 && wc.EncryptionConstant != pkm.EncryptionConstant) return false;
if (wc.Language != 0 && wc.Language != pkm.Language) return false;
}
if (wc.Form != pkm.AltForm && vs.All(dl => !IsFormChangeable(pkm, dl.Species))) return false;
if (wc.IsEgg)
{
if (wc.EggLocation != pkm.Egg_Location && pkm.Egg_Location != 30002) // traded
return false;
if (pkm.IsEgg && !pkm.IsNative)
return false;
}
else
{
if (wc.EggLocation != pkm.Egg_Location) return false;
if (wc.MetLocation != pkm.Met_Location) return false;
}
if (wc.MetLevel != pkm.Met_Level) return false;
if (wc.Ball != pkm.Ball) return false;
if (wc.OTGender < 3 && wc.OTGender != pkm.OT_Gender) return false;
if (wc.Nature != 0xFF && wc.Nature != pkm.Nature) return false;
if (wc.Gender != 3 && wc.Gender != pkm.Gender) return false;
if (wc.CNT_Cool > pkm.CNT_Cool) return false;
if (wc.CNT_Beauty > pkm.CNT_Beauty) return false;
if (wc.CNT_Cute > pkm.CNT_Cute) return false;
if (wc.CNT_Smart > pkm.CNT_Smart) return false;
if (wc.CNT_Tough > pkm.CNT_Tough) return false;
if (wc.CNT_Sheen > pkm.CNT_Sheen) return false;
if (wc.PIDType == 2 && !pkm.IsShiny) return false;
if (wc.PIDType == 3 && pkm.IsShiny) return false;
return true;
}
// EncounterEgg
private static IEnumerable<EncounterEgg> GenerateEggs(PKM pkm)
@ -1260,7 +1300,11 @@ namespace PKHeX.Core
if (baseSpecies <= max)
yield return new EncounterEgg { Game = ver, Level = lvl, Species = baseSpecies };
if (GetSplitBreedGeneration(pkm).Contains(pkm.Species) && (baseSpecies = GetBaseSpecies(pkm, 1)) <= max)
if (!GetSplitBreedGeneration(pkm).Contains(pkm.Species))
yield break;
baseSpecies = GetBaseSpecies(pkm, 1);
if (baseSpecies <= max)
yield return new EncounterEgg { Game = ver, Level = lvl, Species = baseSpecies, SplitBreed = true };
}
@ -1293,7 +1337,8 @@ namespace PKHeX.Core
return false;
IEnumerable<EncounterArea> locs = GetDexNavAreas(pkm);
return locs.Select(loc => GetValidEncounterSlots(pkm, loc, DexNav: true)).Any(slots => slots.Any(slot => slot.Permissions.AllowDexNav && slot.Permissions.DexNav));
var d_areas = locs.Select(loc => GetValidEncounterSlots(pkm, loc, DexNav: true));
return d_areas.Any(slots => slots.Any(slot => slot.Permissions.AllowDexNav && slot.Permissions.DexNav));
}
internal static EncounterArea GetCaptureLocation(PKM pkm)
{

View file

@ -12,6 +12,7 @@
public bool WhiteFlute { get; set; }
public bool BlackFlute { get; set; }
public bool IsNormalLead => !(WhiteFlute || BlackFlute || DexNav);
public bool IsDexNav => AllowDexNav && DexNav;
}
public class EncounterSlot : IEncounterable, IGeneration
{