Extract EvoBase and MoveList from Core

These are really old bloated parts of the original legality checking logic; separating for now to rewrite.
This commit is contained in:
Kurt 2020-06-20 19:44:05 -05:00
parent 4f7845547e
commit 645db23706
16 changed files with 444 additions and 444 deletions

View file

@ -79,7 +79,7 @@ namespace PKHeX.Core
{
if (!Parsed)
return new int[4];
return _allSuggestedRelearnMoves ??= Legal.GetValidRelearn(pkm, Info.EncounterMatch.Species, Info.EncounterMatch.Form, (GameVersion)pkm.Version).ToArray();
return _allSuggestedRelearnMoves ??= MoveList.GetValidRelearn(pkm, Info.EncounterMatch.Species, Info.EncounterMatch.Form, (GameVersion)pkm.Version).ToArray();
}
}
@ -470,7 +470,7 @@ namespace PKHeX.Core
if (!Parsed)
return new int[4];
if (pkm.IsEgg && pkm.Format <= 5) // pre relearn
return Legal.GetBaseEggMoves(pkm, pkm.Species, 0, (GameVersion)pkm.Version, pkm.CurrentLevel);
return MoveList.GetBaseEggMoves(pkm, pkm.Species, 0, (GameVersion)pkm.Version, pkm.CurrentLevel);
if (!tm && !tutor && !reminder)
{
@ -487,7 +487,7 @@ namespace PKHeX.Core
}
}
var evos = Info.EvoChainsAllGens;
return Legal.GetValidMoves(pkm, evos, Tutor: tutor, Machine: tm, MoveReminder: reminder).Skip(1).ToArray(); // skip move 0
return MoveList.GetValidMoves(pkm, evos, Tutor: tutor, Machine: tm, MoveReminder: reminder).Skip(1).ToArray(); // skip move 0
}
}
}

View file

@ -61,240 +61,6 @@ namespace PKHeX.Core
internal static readonly EggMoves7[] EggMovesSWSH = EggMoves7.GetArray(BinLinker.Unpack(Util.GetBinaryResource("eggmove_swsh.pkl"), "ss"));
internal static readonly Learnset[] LevelUpSWSH = LearnsetReader.GetArray(BinLinker.Unpack(Util.GetBinaryResource("lvlmove_swsh.pkl"), "ss"));
internal static IReadOnlyList<int>[] GetValidMovesAllGens(PKM pkm, IReadOnlyList<EvoCriteria>[] evoChains, int minLvLG1 = 1, int minLvLG2 = 1, bool LVL = true, bool Tutor = true, bool Machine = true, bool MoveReminder = true, bool RemoveTransferHM = true)
{
var Moves = new IReadOnlyList<int>[evoChains.Length];
for (int i = 1; i < evoChains.Length; i++)
{
if (evoChains[i].Count != 0)
Moves[i] = GetValidMoves(pkm, evoChains[i], i, minLvLG1, minLvLG2, LVL, Tutor, Machine, MoveReminder, RemoveTransferHM).ToList();
else
Moves[i] = Array.Empty<int>();
}
return Moves;
}
internal static IEnumerable<int> GetValidMoves(PKM pkm, IReadOnlyList<EvoCriteria>[] evoChains, bool LVL = true, bool Tutor = true, bool Machine = true, bool MoveReminder = true, bool RemoveTransferHM = true)
{
GameVersion version = (GameVersion)pkm.Version;
if (!pkm.IsUntraded)
version = GameVersion.Any;
return GetValidMoves(pkm, version, evoChains, minLvLG1: 1, minLvLG2: 1, LVL: LVL, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder, RemoveTransferHM: RemoveTransferHM);
}
internal static IEnumerable<int> GetValidMoves(PKM pkm, IReadOnlyList<EvoCriteria> evoChain, int generation, int minLvLG1 = 1, int minLvLG2 = 1, bool LVL = true, bool Tutor = true, bool Machine = true, bool MoveReminder = true, bool RemoveTransferHM = true)
{
GameVersion version = (GameVersion)pkm.Version;
if (!pkm.IsUntraded)
version = GameVersion.Any;
return GetValidMoves(pkm, version, evoChain, generation, minLvLG1: minLvLG1, minLvLG2: minLvLG2, LVL: LVL, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder, RemoveTransferHM: RemoveTransferHM);
}
internal static IEnumerable<int> GetValidRelearn(PKM pkm, int species, int form, GameVersion version = GameVersion.Any)
{
return GetValidRelearn(pkm, species, form, GetCanInheritMoves(species), version);
}
internal static IEnumerable<int> GetValidRelearn(PKM pkm, int species, int form, bool inheritlvlmoves, GameVersion version = GameVersion.Any)
{
if (pkm.GenNumber < 6)
return Array.Empty<int>();
var r = new List<int>();
r.AddRange(MoveEgg.GetRelearnLVLMoves(pkm, species, 1, form, version));
if (pkm.Format == 6 && pkm.Species != 678)
form = 0;
r.AddRange(MoveEgg.GetEggMoves(pkm, species, form, version));
if (inheritlvlmoves)
r.AddRange(MoveEgg.GetRelearnLVLMoves(pkm, species, 100, form, version));
return r.Distinct();
}
internal static int[] GetShedinjaEvolveMoves(PKM pkm, int generation, int lvl)
{
if (pkm.Species != (int)Species.Shedinja || lvl < 20)
return Array.Empty<int>();
// If Nincada evolves into Ninjask and learns a move after evolution from Ninjask's LevelUp data, Shedinja would appear with that move.
// Only one move above level 20 is allowed; check the count of Ninjask moves elsewhere.
return generation switch
{
3 when pkm.InhabitedGeneration(3) => LevelUpE[(int)Species.Ninjask].GetMoves(lvl, 20), // Same LevelUp data in all Gen3 games
4 when pkm.InhabitedGeneration(4) => LevelUpPt[(int)Species.Ninjask].GetMoves(lvl, 20), // Same LevelUp data in all Gen4 games
_ => Array.Empty<int>(),
};
}
internal static int GetShedinjaMoveLevel(int species, int move, int generation)
{
var src = generation == 4 ? LevelUpPt : LevelUpE;
var moves = src[species];
return moves.GetLevelLearnMove(move);
}
internal static int[] GetBaseEggMoves(PKM pkm, int species, int form, GameVersion gameSource, int lvl)
{
if (gameSource == GameVersion.Any)
gameSource = (GameVersion)pkm.Version;
switch (gameSource)
{
case GameVersion.GSC:
case GameVersion.GS:
// If checking back-transfer specimen (GSC->RBY), remove moves that must be deleted prior to transfer
int[] getRBYCompatibleMoves(int[] moves) => pkm.Format == 1 ? moves.Where(m => m <= MaxMoveID_1).ToArray() : moves;
if (pkm.InhabitedGeneration(2))
return getRBYCompatibleMoves(LevelUpGS[species].GetMoves(lvl));
break;
case GameVersion.C:
if (pkm.InhabitedGeneration(2))
return getRBYCompatibleMoves(LevelUpC[species].GetMoves(lvl));
break;
case GameVersion.R:
case GameVersion.S:
case GameVersion.RS:
if (pkm.InhabitedGeneration(3))
return LevelUpRS[species].GetMoves(lvl);
break;
case GameVersion.E:
if (pkm.InhabitedGeneration(3))
return LevelUpE[species].GetMoves(lvl);
break;
case GameVersion.FR:
case GameVersion.LG:
case GameVersion.FRLG:
// only difference in FR/LG is deoxys which doesn't breed.
if (pkm.InhabitedGeneration(3))
return LevelUpFR[species].GetMoves(lvl);
break;
case GameVersion.D:
case GameVersion.P:
case GameVersion.DP:
if (pkm.InhabitedGeneration(4))
return LevelUpDP[species].GetMoves(lvl);
break;
case GameVersion.Pt:
if (pkm.InhabitedGeneration(4))
return LevelUpPt[species].GetMoves(lvl);
break;
case GameVersion.HG:
case GameVersion.SS:
case GameVersion.HGSS:
if (pkm.InhabitedGeneration(4))
return LevelUpHGSS[species].GetMoves(lvl);
break;
case GameVersion.B:
case GameVersion.W:
case GameVersion.BW:
if (pkm.InhabitedGeneration(5))
return LevelUpBW[species].GetMoves(lvl);
break;
case GameVersion.B2:
case GameVersion.W2:
case GameVersion.B2W2:
if (pkm.InhabitedGeneration(5))
return LevelUpB2W2[species].GetMoves(lvl);
break;
case GameVersion.X:
case GameVersion.Y:
case GameVersion.XY:
if (pkm.InhabitedGeneration(6))
return LevelUpXY[species].GetMoves(lvl);
break;
case GameVersion.AS:
case GameVersion.OR:
case GameVersion.ORAS:
if (pkm.InhabitedGeneration(6))
return LevelUpAO[species].GetMoves(lvl);
break;
case GameVersion.SN:
case GameVersion.MN:
case GameVersion.SM:
if (species > MaxSpeciesID_7)
break;
if (pkm.InhabitedGeneration(7))
{
int index = PersonalTable.SM.GetFormeIndex(species, form);
return LevelUpSM[index].GetMoves(lvl);
}
break;
case GameVersion.US:
case GameVersion.UM:
case GameVersion.USUM:
if (pkm.InhabitedGeneration(7))
{
int index = PersonalTable.USUM.GetFormeIndex(species, form);
return LevelUpUSUM[index].GetMoves(lvl);
}
break;
case GameVersion.SW:
case GameVersion.SH:
case GameVersion.SWSH:
if (pkm.InhabitedGeneration(8))
{
int index = PersonalTable.SWSH.GetFormeIndex(species, form);
return LevelUpSWSH[index].GetMoves(lvl);
}
break;
}
return Array.Empty<int>();
}
internal static List<int> GetValidPostEvolutionMoves(PKM pkm, int species, IReadOnlyList<EvoCriteria>[] evoChains, GameVersion Version)
{
// Return moves that the pokemon could learn after evolving
var moves = new List<int>();
for (int i = 1; i < evoChains.Length; i++)
{
if (evoChains[i].Count != 0)
moves.AddRange(GetValidPostEvolutionMoves(pkm, species, evoChains[i], i, Version));
}
if (pkm.GenNumber >= 6)
moves.AddRange(pkm.RelearnMoves.Where(m => m != 0));
return moves.Distinct().ToList();
}
private static List<int> GetValidPostEvolutionMoves(PKM pkm, int species, IReadOnlyList<EvoCriteria> evoChain, int generation, GameVersion Version)
{
var evomoves = new List<int>();
var index = EvolutionChain.GetEvoChainSpeciesIndex(evoChain, species);
for (int i = 0; i <= index; i++)
{
var evo = evoChain[i];
var moves = GetMoves(pkm, evo.Species, 1, 1, evo.Level, evo.Form, moveTutor: true, Version: Version, LVL: true, specialTutors: true, Machine: true, MoveReminder: true, RemoveTransferHM: false, generation: generation);
// Moves from Species or any species after in the evolution phase
evomoves.AddRange(moves);
}
return evomoves;
}
internal static IEnumerable<int> GetExclusivePreEvolutionMoves(PKM pkm, int Species, IReadOnlyList<EvoCriteria> evoChain, int generation, GameVersion Version)
{
var preevomoves = new List<int>();
var evomoves = new List<int>();
var index = EvolutionChain.GetEvoChainSpeciesIndex(evoChain, Species);
for (int i = 0; i < evoChain.Count; i++)
{
var evo = evoChain[i];
var moves = GetMoves(pkm, evo.Species, 1, 1, evo.Level, evo.Form, moveTutor: true, Version: Version, LVL: true, specialTutors: true, Machine: true, MoveReminder: true, RemoveTransferHM: false, generation: generation);
var list = i >= index ? preevomoves : evomoves;
list.AddRange(moves);
}
return preevomoves.Except(evomoves).Distinct();
}
internal static bool GetCanBeEgg23(PKM pkm)
{
if (pkm.IsEgg)
@ -491,7 +257,7 @@ namespace PKHeX.Core
return curr.Count >= last;
}
int gen = pkm.GenNumber;
if (gen >= 3 && GetSplitBreedGeneration(gen).Contains(GetBaseSpecies(poss, 1).Species))
if (gen >= 3 && GetSplitBreedGeneration(gen).Contains(EvoBase.GetBaseSpecies(poss, 1).Species))
return curr.Count >= poss.Count - 1;
return curr.Count >= poss.Count;
}
@ -586,58 +352,19 @@ namespace PKHeX.Core
internal static bool GetCanLearnMachineMove(PKM pkm, int move, int generation, GameVersion version = GameVersion.Any)
{
return GetValidMoves(pkm, version, EvolutionChain.GetValidPreEvolutions(pkm), generation, Machine: true).Contains(move);
return MoveList.GetValidMoves(pkm, version, EvolutionChain.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, EvolutionChain.GetValidPreEvolutions(pkm), generation, LVL: true, Relearn: true).Contains(move);
return MoveList.GetValidMoves(pkm, version, EvolutionChain.GetValidPreEvolutions(pkm), generation, LVL: true, Relearn: true).Contains(move);
}
internal static bool GetCanKnowMove(PKM pkm, int move, int generation, GameVersion version = GameVersion.Any)
{
if (pkm.Species == (int)Species.Smeargle)
return !InvalidSketch.Contains(move);
return GetValidMoves(pkm, version, EvolutionChain.GetValidPreEvolutions(pkm), generation, LVL: true, Relearn: true, Tutor: true, Machine: true).Contains(move);
}
internal static EvoCriteria GetBaseEggSpecies(PKM pkm, int skipOption = 0)
{
if (pkm.Format == 1)
return GetBaseSpecies(pkm, generation: 2);
return GetBaseSpecies(pkm, skipOption);
}
internal static EvoCriteria GetBaseSpecies(PKM pkm, int skipOption = 0, int generation = -1)
{
int tree = generation != -1 ? generation : pkm.Format;
var table = EvolutionTree.GetEvolutionTree(pkm, tree);
int maxSpeciesOrigin = generation != -1 ? GetMaxSpeciesOrigin(generation) : -1;
var evos = table.GetValidPreEvolutions(pkm, maxLevel: 100, maxSpeciesOrigin: maxSpeciesOrigin, skipChecks: true);
return GetBaseSpecies(evos, skipOption);
}
private static readonly EvoCriteria Nincada = new EvoCriteria(290, 0)
{
Method = (int)EvolutionType.LevelUp,
MinLevel = 20, Level = 20,
RequiresLvlUp = true,
};
private static readonly EvoCriteria EvoEmpty = new EvoCriteria(0, 0)
{
Method = (int)EvolutionType.None,
};
internal static EvoCriteria GetBaseSpecies(IReadOnlyList<EvoCriteria> evos, int skipOption = 0)
{
int species = evos[0].Species;
if (species == (int)Species.Shedinja) // Shedinja
return Nincada; // Nincada
// skip n from end, return species if invalid index
int index = evos.Count - 1 - skipOption;
return (uint)index >= evos.Count ? EvoEmpty : evos[index];
return MoveList.GetValidMoves(pkm, version, EvolutionChain.GetValidPreEvolutions(pkm), generation, LVL: true, Relearn: true, Tutor: true, Machine: true).Contains(move);
}
private static int GetMaxLevelGeneration(PKM pkm)
@ -684,115 +411,6 @@ namespace PKHeX.Core
internal static bool IsCatchRateHeldItem(int rate) => ParseSettings.AllowGen1Tradeback && HeldItems_GSC.Contains((ushort) rate);
private static IEnumerable<int> GetValidMoves(PKM pkm, GameVersion Version, IReadOnlyList<IReadOnlyList<EvoCriteria>> vs, int minLvLG1 = 1, int minLvLG2 = 1, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false, bool MoveReminder = true, bool RemoveTransferHM = true)
{
var r = new List<int> { 0 };
if (Relearn && pkm.Format >= 6)
r.AddRange(pkm.RelearnMoves);
int start = pkm.GenNumber;
if (start < 0)
start = pkm.Format; // be generous instead of returning nothing
for (int gen = start; gen <= pkm.Format; gen++)
{
if (vs[gen].Count != 0)
r.AddRange(GetValidMoves(pkm, Version, vs[gen], gen, minLvLG1: minLvLG1, minLvLG2: minLvLG2, LVL: LVL, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder, RemoveTransferHM: RemoveTransferHM));
}
return r.Distinct();
}
private static IEnumerable<int> GetValidMoves(PKM pkm, GameVersion Version, IReadOnlyList<EvoCriteria> vs, int generation, int minLvLG1 = 1, int minLvLG2 = 1, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false, bool MoveReminder = true, bool RemoveTransferHM = true)
{
var r = new List<int> { 0 };
int species = pkm.Species;
if (FormChangeMoves.Contains(species)) // Deoxys & Shaymin & Giratina (others don't have extra but whatever)
{
// These don't evolve, so don't bother iterating for all entries in the evolution chain (should always be count==1).
int formcount;
// In gen 3 deoxys has different forms depending on the current game, in the PersonalInfo there is no alternate form info
if (pkm.Format == 3 && species == (int)Species.Deoxys)
formcount = 4;
else
formcount = pkm.PersonalInfo.FormeCount;
for (int i = 0; i < formcount; i++)
r.AddRange(GetMoves(pkm, species, minLvLG1, minLvLG2, vs[0].Level, i, Tutor, Version, LVL, Tutor, Machine, MoveReminder, RemoveTransferHM, generation));
if (Relearn)
r.AddRange(pkm.RelearnMoves);
return r.Distinct();
}
// Special Type Tutors Availability
bool moveTutor = Tutor || MoveReminder; // Usually true, except when called for move suggestions (no tutored moves)
for (var i = 0; i < vs.Count; i++)
{
var evo = vs[i];
var moves = GetEvoMoves(pkm, Version, vs, generation, minLvLG1, minLvLG2, LVL, Tutor, Machine, MoveReminder, RemoveTransferHM, moveTutor, i, evo);
r.AddRange(moves);
}
if (pkm.Format <= 3)
return r.Distinct();
if (LVL)
MoveTutor.AddSpecialFormChangeMoves(r, pkm, generation, species);
if (Tutor)
MoveTutor.AddSpecialTutorMoves(r, pkm, generation, species);
if (Relearn && generation >= 6)
r.AddRange(pkm.RelearnMoves);
return r.Distinct();
}
private static IEnumerable<int> GetEvoMoves(PKM pkm, GameVersion Version, IReadOnlyList<EvoCriteria> vs, int generation, int minLvLG1, int minLvLG2, bool LVL, bool Tutor, bool Machine, bool MoveReminder, bool RemoveTransferHM, bool moveTutor, int i, EvoCriteria evo)
{
int minlvlevo1 = GetEvoMoveMinLevel1(pkm, generation, minLvLG1, evo);
int minlvlevo2 = GetEvoMoveMinLevel2(pkm, generation, minLvLG2, evo);
var maxLevel = evo.Level;
if (i != 0 && vs[i - 1].RequiresLvlUp) // evolution
++maxLevel; // allow lvlmoves from the level it evolved to the next species
return GetMoves(pkm, evo.Species, minlvlevo1, minlvlevo2, maxLevel, evo.Form, Tutor, Version, LVL, moveTutor, Machine, MoveReminder, RemoveTransferHM, generation);
}
/// <summary>
/// Returns the minimum level the move can be learned at based on the species encounter level.
/// </summary>
private static int GetEvoMoveMinLevel1(PKM pkm, int generation, int minLvLG1, EvoCriteria evo)
{
if (generation != 1)
return 1;
// For evolutions, return the lower of the two; current level should legally be >=
if (evo.MinLevel > 1)
return Math.Min(pkm.CurrentLevel, evo.MinLevel);
return minLvLG1;
}
private static int GetEvoMoveMinLevel2(PKM pkm, int generation, int minLvLG2, EvoCriteria evo)
{
if (generation != 2 || ParseSettings.AllowGen2MoveReminder(pkm))
return 1;
// For evolutions, return the lower of the two; current level should legally be >=
if (evo.MinLevel > 1)
return Math.Min(pkm.CurrentLevel, evo.MinLevel);
return minLvLG2;
}
private static IEnumerable<int> GetMoves(PKM pkm, int species, int minlvlG1, int minlvlG2, int lvl, int form, bool moveTutor, GameVersion Version, bool LVL, bool specialTutors, bool Machine, bool MoveReminder, bool RemoveTransferHM, int generation)
{
var r = new List<int>();
if (LVL)
r.AddRange(MoveLevelUp.GetMovesLevelUp(pkm, species, minlvlG1, minlvlG2, lvl, form, Version, MoveReminder, generation));
if (Machine)
r.AddRange(MoveTechnicalMachine.GetTMHM(pkm, species, form, generation, Version, RemoveTransferHM));
if (moveTutor)
r.AddRange(MoveTutor.GetTutorMoves(pkm, species, form, specialTutors, generation));
return r.Distinct();
}
internal const GameVersion NONE = GameVersion.Invalid;
internal static readonly LearnVersion LearnNONE = new LearnVersion(-1);
@ -819,21 +437,7 @@ namespace PKHeX.Core
public static string GetG5OT_NSparkle(int lang) => lang == (int)LanguageID.Japanese ? "" : "N";
public const string Stadium1JP = "スタジアム";
public static string GetGBStadiumOTName(bool jp, GameVersion s)
{
if (jp)
return Stadium1JP;
return s == GameVersion.Stadium2 ? "Stadium" : "STADIUM";
}
public static int GetGBStadiumOTID(bool jp, GameVersion s)
{
if (jp)
return GetGBStadiumOTID_JPN(s);
return 2000;
}
public static int GetGBStadiumOTID_JPN(GameVersion s)
{
return s == GameVersion.Stadium2 ? 2000 : 1999;

View file

@ -136,7 +136,7 @@ namespace PKHeX.Core
return moves;
// Sprinkle in some default level up moves
var lvl = Legal.GetBaseEggMoves(pk, Species, Form, version, Level);
var lvl = MoveList.GetBaseEggMoves(pk, Species, Form, version, Level);
return lvl.Concat(moves).ToArray();
}
}

View file

@ -33,7 +33,7 @@ namespace PKHeX.Core
int lvl = GetEggHatchLevel(gen);
int max = GetMaxSpeciesOrigin(gen);
var e = GetBaseSpecies(vs, 0);
var e = EvoBase.GetBaseSpecies(vs, 0);
if (e.Species <= max && !NoHatchFromEggFormGen(e.Species, e.Form, ver))
{
yield return new EncounterEgg(e.Species, e.Form, lvl, gen, ver);
@ -44,7 +44,7 @@ namespace PKHeX.Core
if (!GetSplitBreedGeneration(gen).Contains(species))
yield break; // no other possible species
var o = GetBaseSpecies(vs, 1);
var o = EvoBase.GetBaseSpecies(vs, 1);
if (o.Species <= max && !NoHatchFromEggFormGen(o.Species, o.Form, ver))
{
yield return new EncounterEggSplit(o.Species, o.Form, lvl, gen, ver, e.Species);

View file

@ -41,7 +41,7 @@ namespace PKHeX.Core
private static IEnumerable<IEncounterable> GetEncounters12(PKM pkm, LegalInfo info)
{
int baseSpecies = GetBaseSpecies(pkm).Species;
int baseSpecies = EvoBase.GetBaseSpecies(pkm).Species;
if ((pkm.Format == 1 && baseSpecies > MaxSpeciesID_1) || baseSpecies > MaxSpeciesID_2)
yield break;
@ -189,10 +189,10 @@ namespace PKHeX.Core
var canBeEgg = GetCanBeEgg(pkm);
if (canBeEgg)
{
int eggspec = GetBaseEggSpecies(pkm).Species;
int species = EvoBase.GetBaseSpecies(pkm, generation: pkm.Format == 1 ? 2 : -1, maxSpeciesOrigin: MaxSpeciesID_2).Species;
if (ParseSettings.AllowGen2Crystal(pkm))
yield return new EncounterEgg(eggspec, 0, 5, 2, GameVersion.C); // gen2 egg
yield return new EncounterEgg(eggspec, 0, 5, 2, GameVersion.GS); // gen2 egg
yield return new EncounterEgg(species, 0, 5, 2, GameVersion.C); // gen2 egg
yield return new EncounterEgg(species, 0, 5, 2, GameVersion.GS); // gen2 egg
}
}

View file

@ -136,7 +136,7 @@ namespace PKHeX.Core
private static IEnumerable<int> GetMovesForGeneration(PKM pk, IReadOnlyList<EvoCriteria> dl, int generation)
{
IEnumerable<int> moves = Legal.GetValidMoves(pk, dl, generation);
IEnumerable<int> moves = MoveList.GetValidMoves(pk, dl, generation);
if (pk.Format >= 8)
{
// Shared Egg Moves via daycare

View file

@ -19,14 +19,14 @@ namespace PKHeX.Core
public ValidEncounterMoves(PKM pkm, LevelUpRestriction restrict, IEncounterable encounter)
{
var level = Legal.GetValidMovesAllGens(pkm, restrict.EvolutionChains, minLvLG1: restrict.MinimumLevelGen1, minLvLG2: restrict.MinimumLevelGen2, Tutor: false, Machine: false, RemoveTransferHM: false);
var level = MoveList.GetValidMovesAllGens(pkm, restrict.EvolutionChains, minLvLG1: restrict.MinimumLevelGen1, minLvLG2: restrict.MinimumLevelGen2, Tutor: false, Machine: false, RemoveTransferHM: false);
if (level[encounter.Generation] is List<int> x)
AddEdgeCaseMoves(x, encounter, pkm);
LevelUpMoves = level;
TMHMMoves = Legal.GetValidMovesAllGens(pkm, restrict.EvolutionChains, LVL: false, Tutor: false, MoveReminder: false, RemoveTransferHM: false);
TutorMoves = Legal.GetValidMovesAllGens(pkm, restrict.EvolutionChains, LVL: false, Machine: false, MoveReminder: false, RemoveTransferHM: false);
TMHMMoves = MoveList.GetValidMovesAllGens(pkm, restrict.EvolutionChains, LVL: false, Tutor: false, MoveReminder: false, RemoveTransferHM: false);
TutorMoves = MoveList.GetValidMovesAllGens(pkm, restrict.EvolutionChains, LVL: false, Machine: false, MoveReminder: false, RemoveTransferHM: false);
}
private static void AddEdgeCaseMoves(List<int> moves, IEncounterable encounter, PKM pkm)

View file

@ -109,11 +109,11 @@ namespace PKHeX.Core
var pi = pkm.PersonalInfo;
var AllowLevelUp = notEvent && !pi.Genderless && !(pi.OnlyMale && Legal.MixedGenderBreeding.Contains(e.Species));
int BaseLevel = AllowLevelUp ? 100 : e.LevelMin;
var LevelUp = Legal.GetBaseEggMoves(pkm, e.Species, e.Form, e.Version, BaseLevel);
var LevelUp = MoveList.GetBaseEggMoves(pkm, e.Species, e.Form, e.Version, BaseLevel);
var TradebackPreevo = pkm.Format == 2 && info.EncounterMatch.Species > 151;
var NonTradebackLvlMoves = TradebackPreevo
? Legal.GetExclusivePreEvolutionMoves(pkm, info.EncounterMatch.Species, info.EvoChainsAllGens[2], 2, e.Version).Where(m => m > Legal.MaxMoveID_1).ToArray()
? MoveList.GetExclusivePreEvolutionMoves(pkm, info.EncounterMatch.Species, info.EvoChainsAllGens[2], 2, e.Version).Where(m => m > Legal.MaxMoveID_1).ToArray()
: Array.Empty<int>();
var Egg = MoveEgg.GetEggMoves(pkm, e.Species, e.Form, e.Version);
@ -601,7 +601,7 @@ namespace PKHeX.Core
continue; // Was definitively evolved in Gen3
var maxLevel = pkm.CurrentLevel;
var ninjaskMoves = Legal.GetShedinjaEvolveMoves(pkm, gen, maxLevel);
var ninjaskMoves = MoveList.GetShedinjaEvolveMoves(pkm, gen, maxLevel);
bool native = gen == format;
for (int m = 0; m < 4; m++)
{
@ -630,7 +630,7 @@ namespace PKHeX.Core
// Double check that the Ninjask move level isn't less than any Nincada move level
int move = ShedinjaEvoMovesLearned[0];
int g = res[move].Generation;
int levelJ = Legal.GetShedinjaMoveLevel((int)Species.Ninjask, currentMoves[move], g);
int levelJ = MoveList.GetShedinjaMoveLevel((int)Species.Ninjask, currentMoves[move], g);
for (int m = 0; m < 4; m++)
{
@ -638,11 +638,11 @@ namespace PKHeX.Core
continue;
if (res[m].Source != LevelUp)
continue;
int levelS = Legal.GetShedinjaMoveLevel((int)Species.Shedinja, currentMoves[m], res[m].Generation);
int levelS = MoveList.GetShedinjaMoveLevel((int)Species.Shedinja, currentMoves[m], res[m].Generation);
if (levelS > 0)
continue;
int levelN = Legal.GetShedinjaMoveLevel((int)Species.Nincada, currentMoves[m], res[m].Generation);
int levelN = MoveList.GetShedinjaMoveLevel((int)Species.Nincada, currentMoves[m], res[m].Generation);
if (levelN > levelJ)
res[m] = new CheckMoveResult(res[m], Invalid, string.Format(LMoveEvoFHigher, SpeciesStrings[(int)Species.Nincada], SpeciesStrings[(int)Species.Ninjask]), Move);
}
@ -658,7 +658,7 @@ namespace PKHeX.Core
if (!res.All(r => r?.Valid ?? false) || currentMoves.Any(m => m == 0) || (Legal.BabyEvolutionWithMove.Contains(pkm.Species) && info.Generation <= 3))
return;
var ValidMoves = Legal.GetValidPostEvolutionMoves(pkm, pkm.Species, info.EvoChainsAllGens, GameVersion.Any);
var ValidMoves = MoveList.GetValidPostEvolutionMoves(pkm, pkm.Species, info.EvoChainsAllGens, GameVersion.Any);
// Add the evolution moves to valid moves in case some of these moves could not be learned after evolving
switch (pkm.Species)
@ -835,7 +835,7 @@ namespace PKHeX.Core
var lvlG1 = info.EncounterMatch.LevelMin + 1;
if (lvlG1 == defaultLvlG1)
return;
EncounterMoves.LevelUpMoves[1] = Legal.GetValidMoves(pkm, info.EvoChainsAllGens[1], generation: 1, minLvLG1: lvlG1, LVL: true, Tutor: false, Machine: false, MoveReminder: false).ToList();
EncounterMoves.LevelUpMoves[1] = MoveList.GetValidMoves(pkm, info.EvoChainsAllGens[1], generation: 1, minLvLG1: lvlG1, LVL: true, Tutor: false, Machine: false, MoveReminder: false).ToList();
}
private static void UpdateGen2LevelUpMoves(PKM pkm, ValidEncounterMoves EncounterMoves, int defaultLvlG2, int generation, LegalInfo info)
@ -845,7 +845,7 @@ namespace PKHeX.Core
var lvlG2 = info.EncounterMatch.LevelMin + 1;
if (lvlG2 == defaultLvlG2)
return;
EncounterMoves.LevelUpMoves[2] = Legal.GetValidMoves(pkm, info.EvoChainsAllGens[2], generation: 2, minLvLG2: defaultLvlG2, LVL: true, Tutor: false, Machine: false, MoveReminder: false).ToList();
EncounterMoves.LevelUpMoves[2] = MoveList.GetValidMoves(pkm, info.EvoChainsAllGens[2], generation: 2, minLvLG2: defaultLvlG2, LVL: true, Tutor: false, Machine: false, MoveReminder: false).ToList();
}
/// <summary>

View file

@ -27,44 +27,44 @@ namespace PKHeX.Core
};
}
private static CheckResult[] VerifyRelearnSpecifiedMoveset(PKM pkm, LegalInfo info, IReadOnlyList<int> relearn)
private static CheckResult[] VerifyRelearnSpecifiedMoveset(PKM pkm, LegalInfo info, IReadOnlyList<int> required)
{
CheckResult[] res = new CheckResult[4];
int[] RelearnMoves = pkm.RelearnMoves;
int[] relearn = pkm.RelearnMoves;
for (int i = 0; i < 4; i++)
{
res[i] = relearn[i] != RelearnMoves[i]
? new CheckResult(Severity.Invalid, string.Format(LMoveFExpect_0, MoveStrings[relearn[i]]), CheckIdentifier.RelearnMove)
res[i] = relearn[i] != required[i]
? new CheckResult(Severity.Invalid, string.Format(LMoveFExpect_0, MoveStrings[required[i]]), CheckIdentifier.RelearnMove)
: new CheckResult(CheckIdentifier.RelearnMove);
}
info.RelearnBase = relearn;
info.RelearnBase = required;
return res;
}
private static CheckResult[] VerifyRelearnDexNav(PKM pkm, LegalInfo info)
{
var result = new CheckResult[4];
int[] RelearnMoves = pkm.RelearnMoves;
int[] relearn = pkm.RelearnMoves;
// DexNav Pokémon can have 1 random egg move as a relearn move.
var baseSpec = Legal.GetBaseSpecies(pkm);
result[0] = !Legal.GetValidRelearn(pkm, baseSpec.Species, baseSpec.Form, true).Contains(RelearnMoves[0])
var baseSpec = EvoBase.GetBaseSpecies(pkm);
result[0] = !MoveList.GetValidRelearn(pkm, baseSpec.Species, baseSpec.Form, true).Contains(relearn[0])
? new CheckResult(Severity.Invalid, LMoveRelearnDexNav, CheckIdentifier.RelearnMove)
: new CheckResult(CheckIdentifier.RelearnMove);
// All other relearn moves must be empty.
for (int i = 1; i < 4; i++)
{
result[i] = RelearnMoves[i] != 0
result[i] = relearn[i] != 0
? new CheckResult(Severity.Invalid, LMoveRelearnNone, CheckIdentifier.RelearnMove)
: new CheckResult(CheckIdentifier.RelearnMove);
}
// Update the relearn base moves if the first relearn move is okay.
info.RelearnBase = result[0].Valid
? RelearnMoves
? relearn
: RelearnEmpty;
return result;
@ -96,11 +96,11 @@ namespace PKHeX.Core
bool inheritLvlMoves = Legal.GetCanInheritMoves(e.Species);
// Obtain level1 moves
var baseMoves = Legal.GetBaseEggMoves(pkm, e.Species, e.Form, e.Version, 1);
var baseMoves = MoveList.GetBaseEggMoves(pkm, e.Species, e.Form, e.Version, 1);
int baseCt = Math.Min(4, baseMoves.Length);
// Obtain Inherited moves
var inheritMoves = Legal.GetValidRelearn(pkm, e.Species, e.Form, inheritLvlMoves, e.Version).ToList();
var inheritMoves = MoveList.GetValidRelearn(pkm, e.Species, e.Form, inheritLvlMoves, e.Version).ToList();
int reqBase = GetRequiredBaseMoves(RelearnMoves, baseMoves, baseCt, inheritMoves);
// Check if the required amount of Base Egg Moves are present.
@ -112,7 +112,7 @@ namespace PKHeX.Core
// If any splitbreed moves are invalid, flag accordingly
var splitMoves = e is EncounterEggSplit s
? Legal.GetValidRelearn(pkm, s.OtherSpecies, s.Form, inheritLvlMoves, e.Version).ToList()
? MoveList.GetValidRelearn(pkm, s.OtherSpecies, s.Form, inheritLvlMoves, e.Version).ToList()
: (IReadOnlyList<int>)Array.Empty<int>();
// Inherited moves appear after the required base moves.

View file

@ -0,0 +1,44 @@
using System.Collections.Generic;
namespace PKHeX.Core
{
public static class EvoBase
{
internal static EvoCriteria GetBaseSpecies(PKM pkm, int skipOption = 0)
{
return GetBaseSpecies(pkm, -1, pkm.Format, skipOption);
}
internal static EvoCriteria GetBaseSpecies(PKM pkm, int maxSpeciesOrigin, int generation, int skipOption = 0)
{
int tree = generation;
var table = EvolutionTree.GetEvolutionTree(pkm, tree);
var evos = table.GetValidPreEvolutions(pkm, maxLevel: 100, maxSpeciesOrigin: maxSpeciesOrigin, skipChecks: true);
return GetBaseSpecies(evos, skipOption);
}
private static readonly EvoCriteria Nincada = new EvoCriteria(290, 0)
{
Method = (int)EvolutionType.LevelUp,
MinLevel = 20,
Level = 20,
RequiresLvlUp = true,
};
private static readonly EvoCriteria EvoEmpty = new EvoCriteria(0, 0)
{
Method = (int)EvolutionType.None,
};
internal static EvoCriteria GetBaseSpecies(IReadOnlyList<EvoCriteria> evolutions, int skipOption = 0)
{
int species = evolutions[0].Species;
if (species == (int)Species.Shedinja) // Shedinja
return Nincada; // Nincada
// skip n from end, return species if invalid index
int index = evolutions.Count - 1 - skipOption;
return (uint)index >= evolutions.Count ? EvoEmpty : evolutions[index];
}
}
}

View file

@ -0,0 +1,352 @@
using System;
using System.Collections.Generic;
using System.Linq;
using static PKHeX.Core.Legal;
namespace PKHeX.Core
{
public static class MoveList
{
internal static IEnumerable<int> GetValidRelearn(PKM pkm, int species, int form, bool inheritlvlmoves, GameVersion version = GameVersion.Any)
{
if (pkm.GenNumber < 6)
return Array.Empty<int>();
var r = new List<int>();
r.AddRange(MoveEgg.GetRelearnLVLMoves(pkm, species, 1, form, version));
if (pkm.Format == 6 && pkm.Species != 678)
form = 0;
r.AddRange(MoveEgg.GetEggMoves(pkm, species, form, version));
if (inheritlvlmoves)
r.AddRange(MoveEgg.GetRelearnLVLMoves(pkm, species, 100, form, version));
return r.Distinct();
}
internal static int[] GetShedinjaEvolveMoves(PKM pkm, int generation, int lvl)
{
if (pkm.Species != (int)Species.Shedinja || lvl < 20)
return Array.Empty<int>();
// If Nincada evolves into Ninjask and learns a move after evolution from Ninjask's LevelUp data, Shedinja would appear with that move.
// Only one move above level 20 is allowed; check the count of Ninjask moves elsewhere.
return generation switch
{
3 when pkm.InhabitedGeneration(3) => LevelUpE[(int)Species.Ninjask].GetMoves(lvl, 20), // Same LevelUp data in all Gen3 games
4 when pkm.InhabitedGeneration(4) => LevelUpPt[(int)Species.Ninjask].GetMoves(lvl, 20), // Same LevelUp data in all Gen4 games
_ => Array.Empty<int>(),
};
}
internal static int GetShedinjaMoveLevel(int species, int move, int generation)
{
var src = generation == 4 ? LevelUpPt : LevelUpE;
var moves = src[species];
return moves.GetLevelLearnMove(move);
}
internal static int[] GetBaseEggMoves(PKM pkm, int species, int form, GameVersion gameSource, int lvl)
{
if (gameSource == GameVersion.Any)
gameSource = (GameVersion)pkm.Version;
switch (gameSource)
{
case GameVersion.GSC:
case GameVersion.GS:
// If checking back-transfer specimen (GSC->RBY), remove moves that must be deleted prior to transfer
int[] getRBYCompatibleMoves(int[] moves) => pkm.Format == 1 ? moves.Where(m => m <= MaxMoveID_1).ToArray() : moves;
if (pkm.InhabitedGeneration(2))
return getRBYCompatibleMoves(LevelUpGS[species].GetMoves(lvl));
break;
case GameVersion.C:
if (pkm.InhabitedGeneration(2))
return getRBYCompatibleMoves(LevelUpC[species].GetMoves(lvl));
break;
case GameVersion.R:
case GameVersion.S:
case GameVersion.RS:
if (pkm.InhabitedGeneration(3))
return LevelUpRS[species].GetMoves(lvl);
break;
case GameVersion.E:
if (pkm.InhabitedGeneration(3))
return LevelUpE[species].GetMoves(lvl);
break;
case GameVersion.FR:
case GameVersion.LG:
case GameVersion.FRLG:
// The only difference in FR/LG is Deoxys, which doesn't breed.
if (pkm.InhabitedGeneration(3))
return LevelUpFR[species].GetMoves(lvl);
break;
case GameVersion.D:
case GameVersion.P:
case GameVersion.DP:
if (pkm.InhabitedGeneration(4))
return LevelUpDP[species].GetMoves(lvl);
break;
case GameVersion.Pt:
if (pkm.InhabitedGeneration(4))
return LevelUpPt[species].GetMoves(lvl);
break;
case GameVersion.HG:
case GameVersion.SS:
case GameVersion.HGSS:
if (pkm.InhabitedGeneration(4))
return LevelUpHGSS[species].GetMoves(lvl);
break;
case GameVersion.B:
case GameVersion.W:
case GameVersion.BW:
if (pkm.InhabitedGeneration(5))
return LevelUpBW[species].GetMoves(lvl);
break;
case GameVersion.B2:
case GameVersion.W2:
case GameVersion.B2W2:
if (pkm.InhabitedGeneration(5))
return LevelUpB2W2[species].GetMoves(lvl);
break;
case GameVersion.X:
case GameVersion.Y:
case GameVersion.XY:
if (pkm.InhabitedGeneration(6))
return LevelUpXY[species].GetMoves(lvl);
break;
case GameVersion.AS:
case GameVersion.OR:
case GameVersion.ORAS:
if (pkm.InhabitedGeneration(6))
return LevelUpAO[species].GetMoves(lvl);
break;
case GameVersion.SN:
case GameVersion.MN:
case GameVersion.SM:
if (species > MaxSpeciesID_7)
break;
if (pkm.InhabitedGeneration(7))
{
int index = PersonalTable.SM.GetFormeIndex(species, form);
return LevelUpSM[index].GetMoves(lvl);
}
break;
case GameVersion.US:
case GameVersion.UM:
case GameVersion.USUM:
if (pkm.InhabitedGeneration(7))
{
int index = PersonalTable.USUM.GetFormeIndex(species, form);
return LevelUpUSUM[index].GetMoves(lvl);
}
break;
case GameVersion.SW:
case GameVersion.SH:
case GameVersion.SWSH:
if (pkm.InhabitedGeneration(8))
{
int index = PersonalTable.SWSH.GetFormeIndex(species, form);
return LevelUpSWSH[index].GetMoves(lvl);
}
break;
}
return Array.Empty<int>();
}
internal static IReadOnlyList<int>[] GetValidMovesAllGens(PKM pkm, IReadOnlyList<EvoCriteria>[] evoChains, int minLvLG1 = 1, int minLvLG2 = 1, bool LVL = true, bool Tutor = true, bool Machine = true, bool MoveReminder = true, bool RemoveTransferHM = true)
{
var Moves = new IReadOnlyList<int>[evoChains.Length];
for (int i = 1; i < evoChains.Length; i++)
{
if (evoChains[i].Count != 0)
Moves[i] = GetValidMoves(pkm, evoChains[i], i, minLvLG1, minLvLG2, LVL, Tutor, Machine, MoveReminder, RemoveTransferHM).ToList();
else
Moves[i] = Array.Empty<int>();
}
return Moves;
}
internal static IEnumerable<int> GetValidMoves(PKM pkm, IReadOnlyList<EvoCriteria>[] evoChains, bool LVL = true, bool Tutor = true, bool Machine = true, bool MoveReminder = true, bool RemoveTransferHM = true)
{
GameVersion version = (GameVersion)pkm.Version;
if (!pkm.IsUntraded)
version = GameVersion.Any;
return GetValidMoves(pkm, version, evoChains, minLvLG1: 1, minLvLG2: 1, LVL: LVL, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder, RemoveTransferHM: RemoveTransferHM);
}
internal static IEnumerable<int> GetValidMoves(PKM pkm, IReadOnlyList<EvoCriteria> evoChain, int generation, int minLvLG1 = 1, int minLvLG2 = 1, bool LVL = true, bool Tutor = true, bool Machine = true, bool MoveReminder = true, bool RemoveTransferHM = true)
{
GameVersion version = (GameVersion)pkm.Version;
if (!pkm.IsUntraded)
version = GameVersion.Any;
return GetValidMoves(pkm, version, evoChain, generation, minLvLG1: minLvLG1, minLvLG2: minLvLG2, LVL: LVL, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder, RemoveTransferHM: RemoveTransferHM);
}
internal static IEnumerable<int> GetValidRelearn(PKM pkm, int species, int form, GameVersion version = GameVersion.Any)
{
return GetValidRelearn(pkm, species, form, GetCanInheritMoves(species), version);
}
internal static List<int> GetValidPostEvolutionMoves(PKM pkm, int species, IReadOnlyList<EvoCriteria>[] evoChains, GameVersion Version)
{
// Return moves that the pokemon could learn after evolving
var moves = new List<int>();
for (int i = 1; i < evoChains.Length; i++)
{
if (evoChains[i].Count != 0)
moves.AddRange(GetValidPostEvolutionMoves(pkm, species, evoChains[i], i, Version));
}
if (pkm.GenNumber >= 6)
moves.AddRange(pkm.RelearnMoves.Where(m => m != 0));
return moves.Distinct().ToList();
}
private static List<int> GetValidPostEvolutionMoves(PKM pkm, int species, IReadOnlyList<EvoCriteria> evoChain, int generation, GameVersion Version)
{
var evomoves = new List<int>();
var index = EvolutionChain.GetEvoChainSpeciesIndex(evoChain, species);
for (int i = 0; i <= index; i++)
{
var evo = evoChain[i];
var moves = GetMoves(pkm, evo.Species, 1, 1, evo.Level, evo.Form, moveTutor: true, Version: Version, LVL: true, specialTutors: true, Machine: true, MoveReminder: true, RemoveTransferHM: false, generation: generation);
// Moves from Species or any species after in the evolution phase
evomoves.AddRange(moves);
}
return evomoves;
}
internal static IEnumerable<int> GetExclusivePreEvolutionMoves(PKM pkm, int Species, IReadOnlyList<EvoCriteria> evoChain, int generation, GameVersion Version)
{
var preevomoves = new List<int>();
var evomoves = new List<int>();
var index = EvolutionChain.GetEvoChainSpeciesIndex(evoChain, Species);
for (int i = 0; i < evoChain.Count; i++)
{
var evo = evoChain[i];
var moves = GetMoves(pkm, evo.Species, 1, 1, evo.Level, evo.Form, moveTutor: true, Version: Version, LVL: true, specialTutors: true, Machine: true, MoveReminder: true, RemoveTransferHM: false, generation: generation);
var list = i >= index ? preevomoves : evomoves;
list.AddRange(moves);
}
return preevomoves.Except(evomoves).Distinct();
}
private static IEnumerable<int> GetValidMoves(PKM pkm, GameVersion version, IReadOnlyList<IReadOnlyList<EvoCriteria>> vs, int minLvLG1 = 1, int minLvLG2 = 1, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false, bool MoveReminder = true, bool RemoveTransferHM = true)
{
var r = new List<int> { 0 };
if (Relearn && pkm.Format >= 6)
r.AddRange(pkm.RelearnMoves);
int start = pkm.GenNumber;
if (start < 0)
start = pkm.Format; // be generous instead of returning nothing
for (int generation = start; generation <= pkm.Format; generation++)
{
if (vs[generation].Count != 0)
r.AddRange(GetValidMoves(pkm, version, vs[generation], generation, minLvLG1: minLvLG1, minLvLG2: minLvLG2, LVL: LVL, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder, RemoveTransferHM: RemoveTransferHM));
}
return r.Distinct();
}
internal static IEnumerable<int> GetValidMoves(PKM pkm, GameVersion version, IReadOnlyList<EvoCriteria> vs, int generation, int minLvLG1 = 1, int minLvLG2 = 1, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false, bool MoveReminder = true, bool RemoveTransferHM = true)
{
var r = new List<int> { 0 };
int species = pkm.Species;
if (FormChangeMoves.Contains(species)) // Deoxys & Shaymin & Giratina (others don't have extra but whatever)
{
// These don't evolve, so don't bother iterating for all entries in the evolution chain (should always be count==1).
int formCount;
// In gen 3 deoxys has different forms depending on the current game, in the PersonalInfo there is no alternate form info
if (pkm.Format == 3 && species == (int)Species.Deoxys)
formCount = 4;
else
formCount = pkm.PersonalInfo.FormeCount;
for (int form = 0; form < formCount; form++)
r.AddRange(GetMoves(pkm, species, minLvLG1, minLvLG2, vs[0].Level, form, Tutor, version, LVL, Tutor, Machine, MoveReminder, RemoveTransferHM, generation));
if (Relearn)
r.AddRange(pkm.RelearnMoves);
return r.Distinct();
}
// Special Type Tutors Availability
bool moveTutor = Tutor || MoveReminder; // Usually true, except when called for move suggestions (no tutored moves)
for (var i = 0; i < vs.Count; i++)
{
var evo = vs[i];
var moves = GetEvoMoves(pkm, version, vs, generation, minLvLG1, minLvLG2, LVL, Tutor, Machine, MoveReminder, RemoveTransferHM, moveTutor, i, evo);
r.AddRange(moves);
}
if (pkm.Format <= 3)
return r.Distinct();
if (LVL)
MoveTutor.AddSpecialFormChangeMoves(r, pkm, generation, species);
if (Tutor)
MoveTutor.AddSpecialTutorMoves(r, pkm, generation, species);
if (Relearn && generation >= 6)
r.AddRange(pkm.RelearnMoves);
return r.Distinct();
}
private static IEnumerable<int> GetEvoMoves(PKM pkm, GameVersion Version, IReadOnlyList<EvoCriteria> vs, int generation, int minLvLG1, int minLvLG2, bool LVL, bool Tutor, bool Machine, bool MoveReminder, bool RemoveTransferHM, bool moveTutor, int i, EvoCriteria evo)
{
int minlvlevo1 = GetEvoMoveMinLevel1(pkm, generation, minLvLG1, evo);
int minlvlevo2 = GetEvoMoveMinLevel2(pkm, generation, minLvLG2, evo);
var maxLevel = evo.Level;
if (i != 0 && vs[i - 1].RequiresLvlUp) // evolution
++maxLevel; // allow lvlmoves from the level it evolved to the next species
return GetMoves(pkm, evo.Species, minlvlevo1, minlvlevo2, maxLevel, evo.Form, Tutor, Version, LVL, moveTutor, Machine, MoveReminder, RemoveTransferHM, generation);
}
/// <summary>
/// Returns the minimum level the move can be learned at based on the species encounter level.
/// </summary>
private static int GetEvoMoveMinLevel1(PKM pkm, int generation, int minLvLG1, EvoCriteria evo)
{
if (generation != 1)
return 1;
// For evolutions, return the lower of the two; current level should legally be >=
if (evo.MinLevel > 1)
return Math.Min(pkm.CurrentLevel, evo.MinLevel);
return minLvLG1;
}
private static int GetEvoMoveMinLevel2(PKM pkm, int generation, int minLvLG2, EvoCriteria evo)
{
if (generation != 2 || ParseSettings.AllowGen2MoveReminder(pkm))
return 1;
// For evolutions, return the lower of the two; current level should legally be >=
if (evo.MinLevel > 1)
return Math.Min(pkm.CurrentLevel, evo.MinLevel);
return minLvLG2;
}
private static IEnumerable<int> GetMoves(PKM pkm, int species, int minlvlG1, int minlvlG2, int lvl, int form, bool moveTutor, GameVersion Version, bool LVL, bool specialTutors, bool Machine, bool MoveReminder, bool RemoveTransferHM, int generation)
{
var r = new List<int>();
if (LVL)
r.AddRange(MoveLevelUp.GetMovesLevelUp(pkm, species, minlvlG1, minlvlG2, lvl, form, Version, MoveReminder, generation));
if (Machine)
r.AddRange(MoveTechnicalMachine.GetTMHM(pkm, species, form, generation, Version, RemoveTransferHM));
if (moveTutor)
r.AddRange(MoveTutor.GetTutorMoves(pkm, species, form, specialTutors, generation));
return r.Distinct();
}
}
}

View file

@ -13,11 +13,11 @@ namespace PKHeX.Core
// Level up moves can only be inherited if ditto is not the mother.
bool AllowLevelUp = Legal.GetCanInheritMoves(e.Species);
Base = Legal.GetBaseEggMoves(pkm, e.Species, e.Form, e.Version, e.Level);
Base = MoveList.GetBaseEggMoves(pkm, e.Species, e.Form, e.Version, e.Level);
Egg = MoveEgg.GetEggMoves(pkm, e.Species, e.Form, e.Version);
LevelUp = AllowLevelUp
? Legal.GetBaseEggMoves(pkm, e.Species, e.Form, e.Version, 100).Except(Base).ToList()
? MoveList.GetBaseEggMoves(pkm, e.Species, e.Form, e.Version, 100).Except(Base).ToList()
: (IReadOnlyList<int>)Array.Empty<int>();
Tutor = e.Version == GameVersion.C
? MoveTutor.GetTutorMoves(pkm, e.Species, 0, false, 2).ToList()

View file

@ -302,7 +302,7 @@ namespace PKHeX
private static List<int> GetRequiredMoveCountLevel(PKM pk)
{
int species = pk.Species;
int basespecies = GetBaseSpecies(pk).Species;
int basespecies = EvoBase.GetBaseSpecies(pk).Species;
int maxlevel = 1;
int minlevel = 1;

View file

@ -149,7 +149,7 @@ namespace PKHeX.Core
private void SetMoves(PK3 pk)
{
if (Moves.Count == 0) // not completely defined
Moves = Legal.GetBaseEggMoves(pk, Species, Form, (GameVersion)pk.Version, Level);
Moves = MoveList.GetBaseEggMoves(pk, Species, Form, (GameVersion)pk.Version, Level);
if (Moves.Count != 4)
{
var moves = Moves.ToArray();

View file

@ -88,7 +88,7 @@ namespace PKHeX.Core
if (TradebackStatus != TradebackType.WasTradeback && !Legal.IsCatchRateHeldItem(Catch_Rate) && !(value == 25 && Catch_Rate == 0xA3)) // Light Ball Pikachu
{
int Rate = Catch_Rate;
int baseSpecies = Legal.GetBaseSpecies(this).Species;
int baseSpecies = EvoBase.GetBaseSpecies(this).Species;
for (int z = baseSpecies; z <= value; z++)
{
if (Rate == PersonalTable.RB[z].CatchRate && Rate == PersonalTable.Y[z].CatchRate)

View file

@ -278,10 +278,10 @@ namespace PKHeX.Core
return (ushort)((((2 * (BV + IV)) + EV) * LV / 100) + 5);
}
public override int GetMovePP(int move, int ppup)
public override int GetMovePP(int move, int ppUpCount)
{
var pp = base.GetMovePP(move, 0);
return pp + (ppup * Math.Min(7, pp / 5));
return pp + (ppUpCount * Math.Min(7, pp / 5));
}
/// <summary>