mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-10 22:54:14 +00:00
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:
parent
4f7845547e
commit
645db23706
16 changed files with 444 additions and 444 deletions
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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" : "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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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.
|
||||
|
|
44
PKHeX.Core/Legality/EvoBase.cs
Normal file
44
PKHeX.Core/Legality/EvoBase.cs
Normal 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];
|
||||
}
|
||||
}
|
||||
}
|
352
PKHeX.Core/Legality/MoveList.cs
Normal file
352
PKHeX.Core/Legality/MoveList.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue