diff --git a/PKHeX/Legality/Analysis.cs b/PKHeX/Legality/Analysis.cs index ffe270071..6e3168e7e 100644 --- a/PKHeX/Legality/Analysis.cs +++ b/PKHeX/Legality/Analysis.cs @@ -259,7 +259,7 @@ public int[] getSuggestedMoves(bool tm, bool tutor, bool reminder) return null; if (!Parsed) return new int[4]; - return Legal.getValidMoves(pkm, EvoChain, Tutor: tutor, Machine: tm, MoveReminder: reminder).Skip(1).ToArray(); // skip move 0 + return Legal.getValidMoves(pkm, EvoChainsAllGens, Tutor: tutor, Machine: tm, MoveReminder: reminder).Skip(1).ToArray(); // skip move 0 } public EncounterStatic getSuggestedMetInfo() diff --git a/PKHeX/Legality/Checks.cs b/PKHeX/Legality/Checks.cs index d51396610..a96fe8d82 100644 --- a/PKHeX/Legality/Checks.cs +++ b/PKHeX/Legality/Checks.cs @@ -1433,8 +1433,11 @@ private CheckResult verifyCommonMemory(int handler) resultPrefix = "HT "; break; } + int[] generations = new int[1] { pkm.Format }; + if (pkm.GenNumber == 6 && pkm.Format == 7) + generations = new int[2] { 6, 7 }; int matchingMoveMemory = Array.IndexOf(Legal.MoveSpecificMemories[0], m); - if (matchingMoveMemory != -1 && pkm.Species != 235 && !Legal.getCanLearnMachineMove(pkm, Legal.MoveSpecificMemories[1][matchingMoveMemory])) + if (matchingMoveMemory != -1 && pkm.Species != 235 && !Legal.getCanLearnMachineMove(pkm, Legal.MoveSpecificMemories[1][matchingMoveMemory], generations)) { return new CheckResult(Severity.Invalid, resultPrefix + "Memory: Species cannot learn this move.", CheckIdentifier.Memory); } @@ -1444,14 +1447,14 @@ private CheckResult verifyCommonMemory(int handler) } if (m == 21) // {0} saw {2} carrying {1} on its back. {4} that {3}. { - if (!Legal.getCanLearnMachineMove(new PK6 {Species = t, EXP = PKX.getEXP(100, t)}, 19)) + if (!Legal.getCanLearnMachineMove(new PK6 {Species = t, EXP = PKX.getEXP(100, t)}, 19, generations)) return new CheckResult(Severity.Invalid, resultPrefix + "Memory: Argument Species cannot learn Fly.", CheckIdentifier.Memory); } - if ((m == 16 || m == 48) && (t == 0 || !Legal.getCanKnowMove(pkm, t, GameVersion.Any))) + if ((m == 16 || m == 48) && (t == 0 || !Legal.getCanKnowMove(pkm, t, generations, GameVersion.Any))) { return new CheckResult(Severity.Invalid, resultPrefix + "Memory: Species cannot know this move.", CheckIdentifier.Memory); } - if (m == 49 && (t == 0 || !Legal.getCanRelearnMove(pkm, t, GameVersion.Any))) // {0} was able to remember {2} at {1}'s instruction. {4} that {3}. + if (m == 49 && (t == 0 || !Legal.getCanRelearnMove(pkm, t, generations, GameVersion.Any))) // {0} was able to remember {2} at {1}'s instruction. {4} that {3}. { return new CheckResult(Severity.Invalid, resultPrefix + "Memory: Species cannot relearn this move.", CheckIdentifier.Memory); } @@ -1897,9 +1900,9 @@ private CheckResult[] verifyMoves() for (int i = 0; i < 4; i++) res[i] = new CheckResult(CheckIdentifier.Move); - var validMoves = Legal.getValidMoves(pkm, EvoChain, Tutor: false, Machine: false).ToArray(); - var validTMHM = Legal.getValidMoves(pkm, EvoChain, Tutor: false, MoveReminder: false).ToArray(); - var validTutor = Legal.getValidMoves(pkm, EvoChain, Machine: false, MoveReminder: false).ToArray(); + var validMoves = Legal.getValidMoves(pkm, EvoChainsAllGens, Tutor: false, Machine: false).ToArray(); + var validTMHM = Legal.getValidMoves(pkm, EvoChainsAllGens, Tutor: false, MoveReminder: false).ToArray(); + var validTutor = Legal.getValidMoves(pkm, EvoChainsAllGens, Machine: false, MoveReminder: false).ToArray(); if (pkm.Species == 235) // Smeargle { for (int i = 0; i < 4; i++) diff --git a/PKHeX/Legality/Core.cs b/PKHeX/Legality/Core.cs index de3582856..27d5ca64a 100644 --- a/PKHeX/Legality/Core.cs +++ b/PKHeX/Legality/Core.cs @@ -192,12 +192,19 @@ private static void MarkG7SMSlots(ref EncounterArea[] Areas) } // Moves - internal static IEnumerable getValidMoves(PKM pkm, IEnumerable evoChain, bool Tutor = true, bool Machine = true, bool MoveReminder = true) + internal static IEnumerable getValidMoves(PKM pkm, DexLevel[][] evoChains, bool Tutor = true, bool Machine = true, bool MoveReminder = true) { GameVersion version = (GameVersion)pkm.Version; if (!pkm.IsUntraded) version = GameVersion.Any; - return getValidMoves(pkm, version, evoChain, LVL: true, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder); + return getValidMoves(pkm, version, evoChains, LVL: true, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder); + } + internal static IEnumerable getValidMoves(PKM pkm, IEnumerable evoChain,int generation, bool Tutor = true, bool Machine = true, bool MoveReminder = true) + { + GameVersion version = (GameVersion)pkm.Version; + if (!pkm.IsUntraded) + version = GameVersion.Any; + return getValidMoves(pkm, version, evoChain, generation,LVL: true, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder); } internal static IEnumerable getValidRelearn(PKM pkm, int skipOption) { @@ -414,7 +421,7 @@ internal static int getMaxSpeciesOrigin(int generation) default: return -1; } } - + internal static int getMaxSpeciesOrigin(PKM pkm) { if (pkm.Format == 1 || pkm.VC1) // Gen1 VC could not trade with gen 2 yet @@ -705,25 +712,52 @@ private static bool getCanBeCaptured(int species, IEnumerable are return false; } - internal static bool getCanLearnMachineMove(PKM pkm, int move, GameVersion version = GameVersion.Any) + internal static bool getCanLearnMachineMove(PKM pkm, int move, int[] generations, GameVersion version = GameVersion.Any) { - return getValidMoves(pkm, version, getValidPreEvolutions(pkm), Machine: true).Contains(move); + foreach (int generation in generations) + if (getCanLearnMachineMove(pkm, generation, move, version)) + return true; + return false; } - internal static bool getCanRelearnMove(PKM pkm, int move, GameVersion version = GameVersion.Any) + internal static bool getCanRelearnMove(PKM pkm,int move, int[] generations, GameVersion version = GameVersion.Any) { - return getValidMoves(pkm, version, getValidPreEvolutions(pkm), LVL: true, Relearn: true).Contains(move); + foreach (int generation in generations) + if (getCanRelearnMove(pkm, move, generation, version)) + return true; + return false; } - internal static bool getCanLearnMove(PKM pkm, int move, GameVersion version = GameVersion.Any) + internal static bool getCanLearnMove(PKM pkm, int move, int[] generations, GameVersion version = GameVersion.Any) { - return getValidMoves(pkm, version, getValidPreEvolutions(pkm), Tutor: true, Machine: true).Contains(move); + foreach (int generation in generations) + if (getCanLearnMove(pkm, move, generation, version)) + return true; + return false; } - internal static bool getCanKnowMove(PKM pkm, int move, GameVersion version = GameVersion.Any) + internal static bool getCanKnowMove(PKM pkm, int move, int[] generations, GameVersion version = GameVersion.Any) + { + foreach (int generation in generations) + if (getCanKnowMove(pkm, move, generation, version)) + return true; + return false; + } + internal static bool getCanLearnMachineMove(PKM pkm,int move, int generation, GameVersion version = GameVersion.Any) + { + return getValidMoves(pkm, version, getValidPreEvolutions(pkm), generation, Machine: true).Contains(move); + } + internal static bool getCanRelearnMove(PKM pkm, int move, int generation, GameVersion version = GameVersion.Any) + { + return getValidMoves(pkm, version, getValidPreEvolutions(pkm), generation, LVL: true, Relearn: true).Contains(move); + } + internal static bool getCanLearnMove(PKM pkm,int move, int generation, GameVersion version = GameVersion.Any) + { + return getValidMoves(pkm, version, getValidPreEvolutions(pkm), generation, Tutor: true, Machine: true).Contains(move); + } + internal static bool getCanKnowMove(PKM pkm,int move, int generation, GameVersion version = GameVersion.Any) { if (pkm.Species == 235 && !InvalidSketch.Contains(move)) return true; - return getValidMoves(pkm, Version: version, vs: getValidPreEvolutions(pkm), LVL: true, Relearn: true, Tutor: true, Machine: true).Contains(move); + return getValidMoves(pkm, version,getValidPreEvolutions(pkm), generation, LVL: true, Relearn: true, Tutor: true, Machine: true).Contains(move); } - internal static int getBaseSpecies(PKM pkm, int skipOption = 0) { if (pkm.Species == 292) @@ -838,7 +872,7 @@ internal static DexLevel[] getEvolutionChain(PKM pkm, object Encounter,int maxsp //Maxlevel is also used for previous generations, it removes evolutions imposible before the transfer level //For example a fire red charizard whose current level in XY is 50 but met level is 20, it couldnt be a Charizard in gen 3 and 4 games vs = vs.Skip(skip).Where(e=>e.MinLevel <= maxlevel).ToArray(); - //Reduce the evolution chain levels to max level, because met level is the las one when the pokemon could be and learn moves in that generation + //Reduce the evolution chain levels to max level, because met level is the last one when the pokemon could be and learn moves in that generation foreach (DexLevel d in vs) d.Level = Math.Min(d.Level, maxlevel); return vs; @@ -1039,13 +1073,13 @@ private static IEnumerable getValidPreEvolutions(PKM pkm, int lvl = -1 if (lvl == 1 && pkm.IsEgg) return new List { - new DexLevel { Species = pkm.Species, Level = 1 }, + new DexLevel { Species = pkm.Species, Level = 1, MinLevel = 1 }, }; - if (pkm.Species == 292 && pkm.Met_Level + 1 <= lvl && lvl >= 20) + if (pkm.Species == 292 && lvl >= 20 && (!pkm.HasOriginalMetLocation || pkm.Met_Level + 1 <= lvl)) return new List { - new DexLevel { Species = 292, Level = lvl }, - new DexLevel { Species = 290, Level = lvl-1 } + new DexLevel { Species = 292, Level = lvl, MinLevel =20 }, + new DexLevel { Species = 290, Level = lvl - 1, MinLevel = 1 } }; var et = getEvolutionTable(pkm); @@ -1056,11 +1090,22 @@ private static IEnumerable getStatic(PKM pkm, IEnumerable dl = getValidPreEvolutions(pkm, lvl); return table.Where(e => dl.Any(d => d.Species == e.Species)); } - private static IEnumerable getValidMoves(PKM pkm, GameVersion Version, IEnumerable vs, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false, bool MoveReminder = true) + private static IEnumerable getValidMoves(PKM pkm, GameVersion Version, DexLevel[][] vs, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false, bool MoveReminder = true) { List r = new List { 0 }; + for(int gen =1;gen<=7;gen++) + { + if (vs[gen].Any()) + r.AddRange(getValidMoves(pkm, Version, vs[gen], gen, LVL, Tutor, Machine, MoveReminder)); + } + return r.Distinct().ToArray(); + } + private static IEnumerable getValidMoves(PKM pkm, GameVersion Version, IEnumerable vs, int Generation, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false, bool MoveReminder = true) + { + List r = new List { 0 }; + if (!vs.Any()) + return r; int species = pkm.Species; - int lvl = pkm.CurrentLevel; // Special Type Tutors Availability bool moveTutor = Tutor || MoveReminder; // Usually true, except when called for move suggestions (no tutored moves) @@ -1069,15 +1114,13 @@ private static IEnumerable getValidMoves(PKM pkm, GameVersion Version, IEnu { int formcount = pkm.PersonalInfo.FormeCount; for (int i = 0; i < formcount; i++) - r.AddRange(getMoves(pkm, species, lvl, i, moveTutor, Version, LVL, Tutor, Machine, MoveReminder)); + r.AddRange(getMoves(pkm, species, vs.First().Level, i, moveTutor, Version, LVL, Tutor, Machine, Generation, MoveReminder)); if (Relearn) r.AddRange(pkm.RelearnMoves); return r.Distinct().ToArray(); } - r.AddRange(getMoves(pkm, species, lvl, pkm.AltForm, moveTutor, Version, LVL, Tutor, Machine, MoveReminder)); - foreach (DexLevel evo in vs) - r.AddRange(getMoves(pkm, evo.Species, evo.Level, pkm.AltForm, moveTutor, Version, LVL, Tutor, Machine, MoveReminder)); + r.AddRange(getMoves(pkm, evo.Species, evo.Level, evo.Form, moveTutor, Version, LVL, Tutor, Machine, Generation, MoveReminder)); if (pkm.Format <= 3) return r.Distinct().ToArray();