diff --git a/PKHeX.Core/Legality/Encounters/EncounterGenerator.cs b/PKHeX.Core/Legality/Encounters/EncounterGenerator.cs index 4691a7985..a90de7445 100644 --- a/PKHeX.Core/Legality/Encounters/EncounterGenerator.cs +++ b/PKHeX.Core/Legality/Encounters/EncounterGenerator.cs @@ -950,46 +950,12 @@ private static IEnumerable GetMatchingWC3(PKM pkm, IEnumerable(); var vs = GetValidPreEvolutions(pkm, MaxSpeciesID_3).ToArray(); - foreach (WC3 wc in DB.OfType().Where(wc => vs.Any(dl => dl.Species == wc.Species))) + var enumerable = DB.OfType().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 @@ private static IEnumerable GetMatchingPCD(PKM pkm, IEnumerable(); var vs = GetValidPreEvolutions(pkm).ToArray(); - foreach (PCD mg in DB.OfType().Where(wc => vs.Any(dl => dl.Species == wc.Species))) + var enumerable = DB.OfType().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 @@ private static IEnumerable GetMatchingPGF(PKM pkm, IEnumerable(); var vs = GetValidPreEvolutions(pkm).ToArray(); - foreach (PGF wc in DB.OfType().Where(wc => vs.Any(dl => dl.Species == wc.Species))) + var enumerable = DB.OfType().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 @@ private static IEnumerable GetMatchingWC6(PKM pkm, IEnumerable validWC6 = new List(); var vs = GetValidPreEvolutions(pkm).ToArray(); - foreach (WC6 wc in DB.OfType().Where(wc => vs.Any(dl => dl.Species == wc.Species))) + var enumerable = DB.OfType().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 @@ private static IEnumerable GetMatchingWC7(PKM pkm, IEnumerable validWC7 = new List(); var vs = GetValidPreEvolutions(pkm).ToArray(); - foreach (WC7 wc in DB.OfType().Where(wc => vs.Any(dl => dl.Species == wc.Species))) + var enumerable = DB.OfType().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 @@ private static IEnumerable GetMatchingWC7(PKM pkm, IEnumerable pkm.Met_Level) + return false; + } + return true; + } + private static bool GetIsMatchPCD(PKM pkm, PKM wc, IEnumerable 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 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 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 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 GenerateEggs(PKM pkm) @@ -1260,7 +1300,11 @@ private static IEnumerable GenerateEggs(PKM pkm) 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 @@ internal static bool IsDexNavValid(PKM pkm) return false; IEnumerable 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) { diff --git a/PKHeX.Core/Legality/Structures/EncounterSlot.cs b/PKHeX.Core/Legality/Structures/EncounterSlot.cs index 6c93c7bc1..bc5fece73 100644 --- a/PKHeX.Core/Legality/Structures/EncounterSlot.cs +++ b/PKHeX.Core/Legality/Structures/EncounterSlot.cs @@ -12,6 +12,7 @@ public class EncounterSlotPermissions 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 {