diff --git a/PKHeX.Core/Legality/Checks.cs b/PKHeX.Core/Legality/Checks.cs index b46a3f609..013715e8d 100644 --- a/PKHeX.Core/Legality/Checks.cs +++ b/PKHeX.Core/Legality/Checks.cs @@ -1158,7 +1158,7 @@ private void verifyLevel() } else if (lvl < pkm.Met_Level) AddLine(Severity.Invalid, V85, CheckIdentifier.Level); - else if ((pkm.WasEgg || EncounterMatch == null) && !Legal.getEvolutionValid(pkm) && pkm.Species != 350) + else if (!verifyEvolution()) // flag if invalid evo AddLine(Severity.Invalid, V86, CheckIdentifier.Level); else if (lvl > pkm.Met_Level && lvl > 1 && lvl != 100 && pkm.EXP == PKX.getEXP(pkm.Stat_Level, pkm.Species)) AddLine(Severity.Fishy, V87, CheckIdentifier.Level); @@ -2595,6 +2595,20 @@ private void verifyMisc() } } } + private bool verifyEvolution() + { + if ((pkm.WasEgg || EncounterMatch == null) && !Legal.getEvolutionValid(pkm) && pkm.Species != 350) + return false; + + var match = EncounterMatch as IEncounterable; + if (match == null) + return true; + + var evos = Legal.getValidPreEvolutions(pkm); + var matchEvo = evos.FirstOrDefault(z => z.Species == match.Species); + bool IsValid = matchEvo == null || matchEvo.Level < match.LevelMin; + return IsValid; + } private void verifyVersionEvolution() { if (pkm.Format < 7) diff --git a/PKHeX.Core/Legality/Core.cs b/PKHeX.Core/Legality/Core.cs index a6cec8a96..0b73810e9 100644 --- a/PKHeX.Core/Legality/Core.cs +++ b/PKHeX.Core/Legality/Core.cs @@ -270,6 +270,34 @@ private static EncounterArea[] addExtraTableSlots(params EncounterArea[][] table : new EncounterArea {Location = t.First().Location, Slots = t.SelectMany(s => s.Slots).ToArray()}) .ToArray(); } + private static void MarkEncountersStaticMagnetPull(ref EncounterArea[] Areas, PersonalTable t) + { + const int steel = 8; + const int electric = 12; + foreach (EncounterArea Area in Areas) + { + var s = new List(); // Static + var m = new List(); // Magnet Pull + foreach (EncounterSlot Slot in Area.Slots) + { + var types = t[Slot.Species].Types; + if (types[0] == steel || types[1] == steel) + m.Add(Slot); + if (types[0] == electric || types[1] == electric) + s.Add(Slot); + } + foreach (var slot in s) + { + slot.Static = true; + slot.StaticCount = s.Count; + } + foreach (var slot in m) + { + slot.MagnetPull = true; + slot.MagnetPullCount = s.Count; + } + } + } private static void MarkEncountersGeneration(ref EncounterStatic[] Encounters, int Generation) { foreach (EncounterStatic Encounter in Encounters) @@ -764,6 +792,12 @@ private static EncounterArea[] getTables2(GameVersion Version) MarkG3SlotsSafariZones(ref FR_Slots, 136); MarkG3SlotsSafariZones(ref LG_Slots, 136); + MarkEncountersStaticMagnetPull(ref R_Slots, PersonalTable.SM); + MarkEncountersStaticMagnetPull(ref S_Slots, PersonalTable.SM); + MarkEncountersStaticMagnetPull(ref E_Slots, PersonalTable.SM); + MarkEncountersStaticMagnetPull(ref FR_Slots, PersonalTable.SM); + MarkEncountersStaticMagnetPull(ref LG_Slots, PersonalTable.SM); + SlotsR = addExtraTableSlots(R_Slots, SlotsRSEAlt); SlotsS = addExtraTableSlots(S_Slots, SlotsRSEAlt); SlotsE = addExtraTableSlots(E_Slots, SlotsRSEAlt); @@ -796,6 +830,13 @@ private static EncounterArea[] getTables2(GameVersion Version) var Pt_Slots = getEncounterTables(GameVersion.Pt); var HG_Slots = getEncounterTables(GameVersion.HG); var SS_Slots = getEncounterTables(GameVersion.SS); + + MarkEncountersStaticMagnetPull(ref D_Slots, PersonalTable.SM); + MarkEncountersStaticMagnetPull(ref P_Slots, PersonalTable.SM); + MarkEncountersStaticMagnetPull(ref Pt_Slots, PersonalTable.SM); + MarkEncountersStaticMagnetPull(ref HG_Slots, PersonalTable.SM); + MarkEncountersStaticMagnetPull(ref SS_Slots, PersonalTable.SM); + var DP_Trophy = EncounterArea.getTrophyArea(TrophyDP, new[] {16, 18}); var Pt_Trophy = EncounterArea.getTrophyArea(TrophyPt, new[] {22, 22}); var HG_Headbutt_Slots = EncounterArea.getArray4HGSS_Headbutt(Data.unpackMini(Util.getBinaryResource("encunters_hb_hg.pkl"), "hg")); @@ -3322,7 +3363,7 @@ internal static IEnumerable getValidPreEvolutions(PKM pkm, int maxspec return new List { new DexLevel { Species = 292, Level = lvl, MinLevel = 20 }, - new DexLevel { Species = 290, Level = lvl-1, MinLevel = 1 } + new DexLevel { Species = 290, Level = lvl - 1, MinLevel = 1 } }; if (maxspeciesorigin == -1 && pkm.InhabitedGeneration(2) && pkm.GenNumber == 1) maxspeciesorigin = MaxSpeciesID_2; @@ -3330,7 +3371,7 @@ internal static IEnumerable getValidPreEvolutions(PKM pkm, int maxspec var et = maxspeciesorigin == MaxSpeciesID_2 ? getEvolutionTable(2) : getEvolutionTable(pkm); return et.getValidPreEvolutions(pkm, lvl: lvl, maxSpeciesOrigin: maxspeciesorigin, skipChecks: skipChecks); } - private static IEnumerable getStatic(PKM pkm, IEnumerable table, int maxspeciesorigin =-1, int lvl = -1) + private static IEnumerable getStatic(PKM pkm, IEnumerable table, int maxspeciesorigin = -1, int lvl = -1) { IEnumerable dl = getValidPreEvolutions(pkm, maxspeciesorigin: maxspeciesorigin, lvl: lvl); return table.Where(e => dl.Any(d => d.Species == e.Species)); diff --git a/PKHeX.Core/Legality/Structures/EncounterSlot.cs b/PKHeX.Core/Legality/Structures/EncounterSlot.cs index 036d30ca9..f1ee5fd6c 100644 --- a/PKHeX.Core/Legality/Structures/EncounterSlot.cs +++ b/PKHeX.Core/Legality/Structures/EncounterSlot.cs @@ -18,6 +18,11 @@ public class EncounterSlot : IEncounterable, IGeneration public bool EggEncounter => false; public int Generation { get; set; } = -1; + public bool Static; + public bool MagnetPull; + public int StaticCount; + public int MagnetPullCount; + public virtual EncounterSlot Clone() { return new EncounterSlot diff --git a/PKHeX.Core/Legality/Structures/EvolutionTree.cs b/PKHeX.Core/Legality/Structures/EvolutionTree.cs index 45b30ecf9..310d51636 100644 --- a/PKHeX.Core/Legality/Structures/EvolutionTree.cs +++ b/PKHeX.Core/Legality/Structures/EvolutionTree.cs @@ -161,7 +161,7 @@ private int getIndex(EvolutionMethod evo) return Personal.getFormeIndex(evolvesToSpecies, evolvesToForm); } - public IEnumerable getValidPreEvolutions(PKM pkm, int lvl, int maxSpeciesOrigin =-1 ,bool skipChecks = false) + public IEnumerable getValidPreEvolutions(PKM pkm, int lvl, int maxSpeciesOrigin = -1, bool skipChecks = false) { int index = getIndex(pkm); if (maxSpeciesOrigin <= 0) @@ -610,7 +610,7 @@ public void Insert(EvolutionStage evo) public IEnumerable getExplicitLineage(PKM pkm, int lvl, bool skipChecks, int maxSpeciesTree, int maxSpeciesOrigin) { List dl = new List { new DexLevel { Species = pkm.Species, Level = lvl, Form = pkm.AltForm } }; - for (int i = Chain.Count-1; i >= 0; i--) // reverse evolution! + for (int i = Chain.Count - 1; i >= 0; i--) // reverse evolution! { bool oneValid = false; foreach (var evo in Chain[i].StageEntryMethods) @@ -626,10 +626,9 @@ public IEnumerable getExplicitLineage(PKM pkm, int lvl, bool skipCheck if (evo.Species > maxSpeciesTree) species = pkm.Species - Chain.Count + i; - dl.Add(evo.GetDexLevel(species, lvl)); - if (evo.RequiresLevelUp) lvl--; + dl.Add(evo.GetDexLevel(species, lvl)); break; } if (!oneValid) diff --git a/PKHeX.Core/Legality/Tables2.cs b/PKHeX.Core/Legality/Tables2.cs index 3cd3b9f99..28de487eb 100644 --- a/PKHeX.Core/Legality/Tables2.cs +++ b/PKHeX.Core/Legality/Tables2.cs @@ -16,7 +16,7 @@ public static partial class Legal 1, 2, 4, 5, 157, 159, 160, 161, 164, 165, 166 }; internal static readonly ushort[] Pouch_Key_GS = { - 7, 54, 55, 58, 59, 61, 66, 67, 68 , 69, 71, 127, 128, 130, 133, 134, 175, 178 + 7, 54, 55, 58, 59, 61, 66, 67, 68, 69, 71, 127, 128, 130, 133, 134, 175, 178 }; internal static readonly ushort[] Pouch_Key_C = Pouch_Key_GS.Concat(new ushort[]{70, 115, 116, 129}).ToArray(); internal static readonly ushort[] Pouch_TMHM_GSC = { diff --git a/PKHeX.Core/Legality/Tables4.cs b/PKHeX.Core/Legality/Tables4.cs index a5f9e4763..64c9902fe 100644 --- a/PKHeX.Core/Legality/Tables4.cs +++ b/PKHeX.Core/Legality/Tables4.cs @@ -1333,7 +1333,7 @@ public static partial class Legal }; internal static readonly int[] ValidMet_Pt = ValidMet_DP.Concat(new[] { - 63, 79 , 85, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, + 63, 79, 85, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, }).ToArray(); internal static readonly int[] ValidMet_HGSS = {