private static int[] GetNeededMoves(PKM pk, IEnumerable <int> moves, IReadOnlyList <EvoCriteria> chain) { if (pk.Species == (int)Species.Smeargle) { return(moves.Where(z => !Legal.IsValidSketch(z, pk.Format)).ToArray()); // Can learn anything } // Roughly determine the generation the PKM is originating from var ver = pk.Version; int origin = pk.Generation; if (origin < 0) { origin = ((GameVersion)ver).GetGeneration(); } // Temporarily replace the Version for VC1 transfers, so that they can have VC2 moves if needed. bool vcBump = origin == 1 && pk.Format >= 7; if (vcBump) { pk.Version = (int)GameVersion.C; } var gens = GenerationTraversal.GetVisitedGenerationOrder(pk, origin); var canlearn = gens.SelectMany(z => GetMovesForGeneration(pk, chain, z)); var result = moves.Except(canlearn).Where(z => z != 0).ToArray(); if (vcBump) { pk.Version = ver; } return(result); }
private static CheckMoveResult[] ParseMoves(PKM pkm, MoveParseSource source, LegalInfo info) { var res = new CheckMoveResult[4]; bool AllParsed() => res.All(z => z != null); // Special considerations! const int NoMinGeneration = 0; int minGeneration = NoMinGeneration; if (pkm is IBattleVersion { BattleVersion : not 0 } v) { minGeneration = ((GameVersion)v.BattleVersion).GetGeneration(); source.ResetSources(); } // Check empty moves and relearn moves before generation specific moves for (int m = 0; m < 4; m++) { var move = source.CurrentMoves[m]; if (move == 0) { res[m] = new CheckMoveResult(None, pkm.Format, Valid, LMoveSourceEmpty, CurrentMove); } else if (minGeneration == NoMinGeneration && info.EncounterMoves.Relearn.Contains(move)) { res[m] = new CheckMoveResult(Relearn, info.Generation, Valid, LMoveSourceRelearn, CurrentMove); } } if (AllParsed()) { return(res); } // Encapsulate arguments to simplify method calls var moveInfo = new LearnInfo(pkm, source); // Check moves going backwards, marking the move valid in the most current generation when it can be learned int[] generations = GenerationTraversal.GetVisitedGenerationOrder(pkm, info.EncounterOriginal.Generation); if (pkm.Format <= 2) { generations = Array.FindAll(generations, z => z < info.EncounterMoves.LevelUpMoves.Length); } if (minGeneration != NoMinGeneration) { generations = Array.FindAll(generations, z => z >= minGeneration); } if (generations.Length != 0) { int lastgen = generations[^ 1];
private static CheckMoveResult[] ParseMoves(PKM pkm, MoveParseSource source, LegalInfo info) { var res = new CheckMoveResult[4]; bool AllParsed() => res.All(z => z != null); var required = pkm is not PK1 pk1 ? 1 : GBRestrictions.GetRequiredMoveCount(pk1, source.CurrentMoves, info, source.Base); // Special considerations! int reset = 0; if (pkm is IBattleVersion { BattleVersion : not 0 } v) { reset = ((GameVersion)v.BattleVersion).GetGeneration(); source.ResetSources(); } // Check empty moves and relearn moves before generation specific moves for (int m = 0; m < 4; m++) { if (source.CurrentMoves[m] == 0) { res[m] = new CheckMoveResult(None, pkm.Format, m < required ? Fishy : Valid, LMoveSourceEmpty, CurrentMove); } else if (reset == 0 && info.EncounterMoves.Relearn.Contains(source.CurrentMoves[m])) { res[m] = new CheckMoveResult(Relearn, info.Generation, Valid, LMoveSourceRelearn, CurrentMove); } } if (AllParsed()) { return(res); } // Encapsulate arguments to simplify method calls var moveInfo = new LearnInfo(pkm, source); // Check moves going backwards, marking the move valid in the most current generation when it can be learned int[] generations = GenerationTraversal.GetVisitedGenerationOrder(pkm, info.EncounterOriginal.Generation); if (pkm.Format <= 2) { generations = generations.Where(z => z < info.EncounterMoves.LevelUpMoves.Length).ToArray(); } if (reset != 0) { generations = generations.Where(z => z >= reset).ToArray(); } int lastgen = generations.Length == 0 ? 0 : generations[^ 1];
private static int[] GetNeededMoves(PKM pk, IEnumerable <int> moves, IReadOnlyList <EvoCriteria> chain) { if (pk.Species == (int)Species.Smeargle) { return(moves.Where(z => !Legal.IsValidSketch(z, pk.Format)).ToArray()); // Can learn anything } // Roughly determine the generation the PKM is originating from var ver = pk.Version; int origin = pk.Generation; if (origin < 0) { origin = ((GameVersion)ver).GetGeneration(); } // Temporarily replace the Version for VC1 transfers, so that they can have VC2 moves if needed. bool vcBump = origin == 1 && pk.Format >= 7; if (vcBump) { pk.Version = (int)GameVersion.C; } var gens = GenerationTraversal.GetVisitedGenerationOrder(pk, origin); var canlearn = gens.SelectMany(z => GetMovesForGeneration(pk, chain, z)); if (origin is (1 or 2)) // gb initial moves { var max = origin == 1 ? Legal.MaxSpeciesID_1 : Legal.MaxSpeciesID_2; foreach (var evo in chain) { var species = evo.Species; if (species > max) { continue; } var enc = MoveLevelUp.GetEncounterMoves(species, 0, 1, (GameVersion)ver); canlearn = canlearn.Concat(enc); } } var result = moves.Where(z => z != 0).Except(canlearn).ToArray(); if (vcBump) { pk.Version = ver; } return(result); }