mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-08-27 09:54:44 -05:00
Refactoring
pull out some move data fetching to separate class add methods to quickly fetch if the move is learnable via that method eventual plan is this: replace 'fetch all possible moves then look within' move validation with: 'peek if learnable, and get info how' move validation advantages: - returns game the move was learned in and the level (if appropriate) - infinitely less object creation (garbage collection) - only looks for a given move, doesn't have to fetch everything before checking - faster than full fetch, can be made even faster by optimizing lookups. subject to change :)
This commit is contained in:
@@ -1982,186 +1982,11 @@ private static int[] GetEggMoves(int gen, int species, int formnum, GameVersion
|
||||
|
||||
internal static IEnumerable<int> GetTMHM(PKM pkm, int species, int form, int generation, GameVersion Version = GameVersion.Any, bool RemoveTransferHM = true)
|
||||
{
|
||||
List<int> moves = new List<int>();
|
||||
int index;
|
||||
switch (generation)
|
||||
{
|
||||
case 1:
|
||||
index = PersonalTable.RB.GetFormeIndex(species, 0);
|
||||
if (index == 0)
|
||||
return moves;
|
||||
var pi_rb = (PersonalInfoG1)PersonalTable.RB[index];
|
||||
var pi_y = (PersonalInfoG1)PersonalTable.Y[index];
|
||||
moves.AddRange(TMHM_RBY.Where((_, m) => pi_rb.TMHM[m]));
|
||||
moves.AddRange(TMHM_RBY.Where((_, m) => pi_y.TMHM[m]));
|
||||
break;
|
||||
case 2:
|
||||
index = PersonalTable.C.GetFormeIndex(species, 0);
|
||||
if (index == 0)
|
||||
return moves;
|
||||
var pi_c = (PersonalInfoG2)PersonalTable.C[index];
|
||||
moves.AddRange(TMHM_GSC.Where((_, m) => pi_c.TMHM[m]));
|
||||
if (Version == GameVersion.Any)
|
||||
goto case 1; // rby
|
||||
break;
|
||||
case 3:
|
||||
index = PersonalTable.E.GetFormeIndex(species, 0);
|
||||
var pi_e = PersonalTable.E[index];
|
||||
moves.AddRange(TM_3.Where((_, m) => pi_e.TMHM[m]));
|
||||
if (!RemoveTransferHM || pkm.Format == 3) // HM moves must be removed for 3->4, only give if current format.
|
||||
moves.AddRange(HM_3.Where((_, m) => pi_e.TMHM[m + 50]));
|
||||
break;
|
||||
case 4:
|
||||
index = PersonalTable.HGSS.GetFormeIndex(species, 0);
|
||||
if (index == 0)
|
||||
return moves;
|
||||
var pi_hgss = PersonalTable.HGSS[index];
|
||||
var pi_dppt = PersonalTable.Pt[index];
|
||||
moves.AddRange(TM_4.Where((_, m) => pi_hgss.TMHM[m]));
|
||||
// The combination of both these moves is illegal, it should be checked that the pokemon only learn one
|
||||
// except if it can learn any of these moves in gen 5 or later
|
||||
if (Version == GameVersion.Any || Version == GameVersion.DP || Version == GameVersion.D || Version == GameVersion.P || Version == GameVersion.Pt)
|
||||
{
|
||||
if (RemoveTransferHM && pkm.Format > 4)
|
||||
{
|
||||
if (pi_dppt.TMHM[96])
|
||||
moves.Add(432); // Defog
|
||||
}
|
||||
else
|
||||
{
|
||||
moves.AddRange(HM_DPPt.Where((_, m) => pi_dppt.TMHM[m + 92]));
|
||||
}
|
||||
}
|
||||
if (Version == GameVersion.Any || Version == GameVersion.HGSS || Version == GameVersion.HG || Version == GameVersion.SS)
|
||||
{
|
||||
if (RemoveTransferHM && pkm.Format > 4)
|
||||
{
|
||||
if (pi_hgss.TMHM[96])
|
||||
moves.Add(432); // Defog
|
||||
}
|
||||
else
|
||||
{
|
||||
moves.AddRange(HM_HGSS.Where((_, m) => pi_dppt.TMHM[m + 92]));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
index = PersonalTable.B2W2.GetFormeIndex(species, 0);
|
||||
if (index == 0)
|
||||
return moves;
|
||||
|
||||
var pi_bw = PersonalTable.B2W2[index];
|
||||
moves.AddRange(TMHM_BW.Where((_, m) => pi_bw.TMHM[m]));
|
||||
break;
|
||||
case 6:
|
||||
switch (Version)
|
||||
{
|
||||
case GameVersion.Any: // Start at the top, hit every table
|
||||
case GameVersion.X:
|
||||
case GameVersion.Y:
|
||||
case GameVersion.XY:
|
||||
{
|
||||
index = PersonalTable.XY.GetFormeIndex(species, form);
|
||||
if (index == 0)
|
||||
return moves;
|
||||
|
||||
PersonalInfo pi_xy = PersonalTable.XY[index];
|
||||
moves.AddRange(TMHM_XY.Where((_, m) => pi_xy.TMHM[m]));
|
||||
|
||||
if (Version == GameVersion.Any) // Fall Through
|
||||
goto case GameVersion.ORAS;
|
||||
break;
|
||||
}
|
||||
case GameVersion.AS:
|
||||
case GameVersion.OR:
|
||||
case GameVersion.ORAS:
|
||||
{
|
||||
index = PersonalTable.AO.GetFormeIndex(species, form);
|
||||
if (index == 0)
|
||||
return moves;
|
||||
|
||||
PersonalInfo pi_ao = PersonalTable.AO[index];
|
||||
moves.AddRange(TMHM_AO.Where((_, m) => pi_ao.TMHM[m]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
index = PersonalTable.USUM.GetFormeIndex(species, form);
|
||||
if (index == 0)
|
||||
return moves;
|
||||
|
||||
PersonalInfo pi_sm = PersonalTable.USUM[index];
|
||||
moves.AddRange(TMHM_SM.Where((_, m) => pi_sm.TMHM[m]));
|
||||
break;
|
||||
}
|
||||
return moves.Distinct();
|
||||
return MoveTechnicalMachine.GetTMHM(pkm, species, form, generation, Version, RemoveTransferHM);
|
||||
}
|
||||
internal static IEnumerable<int> GetTutorMoves(PKM pkm, int species, int form, bool specialTutors, int generation)
|
||||
{
|
||||
List<int> moves = new List<int>();
|
||||
PersonalInfo info;
|
||||
switch (generation)
|
||||
{
|
||||
case 1:
|
||||
if (AllowGBCartEra && pkm.Format < 3 && (pkm.Species == 25 || pkm.Species == 26)) // Surf Pikachu via Stadium
|
||||
moves.Add(57);
|
||||
break;
|
||||
case 2:
|
||||
if (!AllowGen2Crystal(pkm))
|
||||
break;
|
||||
info = PersonalTable.C[species];
|
||||
moves.AddRange(Tutors_GSC.Where((_, i) => info.TMHM[57 + i]));
|
||||
goto case 1;
|
||||
case 3:
|
||||
// E Tutors (Free)
|
||||
// E Tutors (BP)
|
||||
info = PersonalTable.E[species];
|
||||
moves.AddRange(Tutor_E.Where((_, i) => info.TypeTutors[i]));
|
||||
// FRLG Tutors
|
||||
// Only special tutor moves, normal tutor moves are already included in Emerald data
|
||||
moves.AddRange(SpecialTutors_FRLG.Where((_, i) => SpecialTutors_Compatibility_FRLG[i].Any(e => e == species)));
|
||||
// XD
|
||||
moves.AddRange(SpecialTutors_XD_Exclusive.Where((_, i) => SpecialTutors_Compatibility_XD_Exclusive[i].Any(e => e == species)));
|
||||
// XD (Mew)
|
||||
if (species == 151)
|
||||
moves.AddRange(Tutor_3Mew);
|
||||
|
||||
break;
|
||||
case 4:
|
||||
info = PersonalTable.HGSS.GetFormeEntry(species, form);
|
||||
moves.AddRange(Tutors_4.Where((_, i) => info.TypeTutors[i]));
|
||||
moves.AddRange(SpecialTutors_4.Where((_, i) => SpecialTutors_Compatibility_4[i].Any(e => e == species)));
|
||||
break;
|
||||
case 5:
|
||||
info = PersonalTable.B2W2[species];
|
||||
moves.AddRange(TypeTutor6.Where((_, i) => info.TypeTutors[i]));
|
||||
if (pkm.InhabitedGeneration(5) && specialTutors)
|
||||
moves.AddRange(GetTutors(PersonalTable.B2W2, Tutors_B2W2));
|
||||
break;
|
||||
case 6:
|
||||
info = PersonalTable.AO[species];
|
||||
moves.AddRange(TypeTutor6.Where((_, i) => info.TypeTutors[i]));
|
||||
if (pkm.InhabitedGeneration(6) && specialTutors && (pkm.AO || !pkm.IsUntraded))
|
||||
moves.AddRange(GetTutors(PersonalTable.AO, Tutors_AO));
|
||||
break;
|
||||
case 7:
|
||||
info = PersonalTable.USUM.GetFormeEntry(species, form);
|
||||
moves.AddRange(TypeTutor6.Where((_, i) => info.TypeTutors[i]));
|
||||
if (pkm.InhabitedGeneration(7) && specialTutors && (pkm.USUM || !pkm.IsUntraded))
|
||||
moves.AddRange(GetTutors(PersonalTable.USUM, Tutors_USUM));
|
||||
break;
|
||||
}
|
||||
return moves.Distinct();
|
||||
|
||||
IEnumerable<int> GetTutors(PersonalTable t, params int[][] tutors)
|
||||
{
|
||||
var pi = t.GetFormeEntry(species, form);
|
||||
for (int i = 0; i < tutors.Length; i++)
|
||||
for (int b = 0; b < tutors[i].Length; b++)
|
||||
if (pi.SpecialTutors[i][b])
|
||||
yield return tutors[i][b];
|
||||
}
|
||||
return MoveTutor.GetTutorMoves(pkm, species, form, specialTutors, generation);
|
||||
}
|
||||
internal static bool IsTradedKadabraG1(PKM pkm)
|
||||
{
|
||||
@@ -2207,6 +2032,13 @@ internal static bool IsOutsider(PKM pkm)
|
||||
return Outsider;
|
||||
}
|
||||
|
||||
internal const GameVersion NONE = GameVersion.Invalid;
|
||||
internal static readonly LearnVersion LearnNONE = new LearnVersion(-1);
|
||||
|
||||
internal static bool HasVisitedB2W2(this PKM pkm) => pkm.InhabitedGeneration(5);
|
||||
internal static bool HasVisitedORAS(this PKM pkm) => pkm.InhabitedGeneration(6) && (pkm.AO || !pkm.IsUntraded);
|
||||
internal static bool HasVisitedUSUM(this PKM pkm) => pkm.InhabitedGeneration(7) && (pkm.USUM || !pkm.IsUntraded);
|
||||
|
||||
internal static TreeEncounterAvailable GetGSCHeadbuttAvailability(EncounterSlot encounter, int TID)
|
||||
{
|
||||
var Area = Array.Find(HeadbuttTreesC, a => a.Location == encounter.Location);
|
||||
|
||||
@@ -84,5 +84,23 @@ public int GetLevelLearnMove(int move)
|
||||
{
|
||||
return (Learn ?? (Learn = GetDictionary())).TryGetValue(move, out var level) ? level : -1;
|
||||
}
|
||||
|
||||
/// <summary>Returns the level that a Pokémon can learn the specified move.</summary>
|
||||
/// <param name="move">Move ID</param>
|
||||
/// <param name="min">Minimum level to start looking at.</param>
|
||||
/// <returns>Level the move is learned at. If the result is below 0, it cannot be learned by levelup.</returns>
|
||||
public int GetLevelLearnMove(int move, int min)
|
||||
{
|
||||
for (int i = 0; i < Moves.Length; i++)
|
||||
{
|
||||
if (move != Moves[i])
|
||||
continue;
|
||||
|
||||
var lv = Levels[i];
|
||||
if (lv >= min)
|
||||
return lv;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
@@ -19,4 +20,15 @@ public LearnInfo(PKM pkm)
|
||||
IsGen2Pkm = pkm.Format == 2 || pkm.VC2;
|
||||
}
|
||||
}
|
||||
|
||||
public struct LearnVersion
|
||||
{
|
||||
public readonly GameVersion Game;
|
||||
public readonly int Level;
|
||||
public LearnVersion(int lv, GameVersion game = GameVersion.Any)
|
||||
{
|
||||
Game = game;
|
||||
Level = lv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
430
PKHeX.Core/Legality/Moves/MoveLevelUp.cs
Normal file
430
PKHeX.Core/Legality/Moves/MoveLevelUp.cs
Normal file
@@ -0,0 +1,430 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using static PKHeX.Core.Legal;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
internal static class MoveLevelUp
|
||||
{
|
||||
public static LearnVersion GetIsLevelUpMove(PKM pkm, int species, int minlvlG1, int minlvlG2, int lvl, int form, int Generation, int move, GameVersion Version = GameVersion.Any)
|
||||
{
|
||||
switch (Generation)
|
||||
{
|
||||
case 1: return GetIsLevelUp1(species, move, lvl, minlvlG1);
|
||||
case 2: return GetIsLevelUp2(species, move, lvl, minlvlG2, pkm.Korean);
|
||||
case 3: return GetIsLevelUp3(species, move, lvl, form);
|
||||
case 4: return GetIsLevelUp4(species, move, lvl, form);
|
||||
case 5: return GetIsLevelUp5(species, move, lvl, form);
|
||||
case 6: return GetIsLevelUp6(species, move, lvl, form, Version);
|
||||
case 7: return GetIsLevelUp7(species, move, form, Version);
|
||||
}
|
||||
return LearnNONE;
|
||||
}
|
||||
|
||||
private static LearnVersion GetIsLevelUp1(int species, int move, int max, int min)
|
||||
{
|
||||
int index = PersonalTable.RB.GetFormeIndex(species, 0);
|
||||
if (index == 0)
|
||||
return LearnNONE;
|
||||
|
||||
if (min == 1)
|
||||
{
|
||||
var pi_rb = (PersonalInfoG1)PersonalTable.RB[index];
|
||||
var pi_y = (PersonalInfoG1)PersonalTable.Y[index];
|
||||
if (pi_rb.Moves.Contains(move))
|
||||
return new LearnVersion(0, GameVersion.RB);
|
||||
if (pi_y.Moves.Contains(move))
|
||||
return new LearnVersion(0, GameVersion.YW);
|
||||
}
|
||||
|
||||
// No relearner -- have to be learned on levelup
|
||||
var lv = LevelUpRB[index].GetLevelLearnMove(move, min);
|
||||
if (lv >= 0 && lv <= max)
|
||||
return new LearnVersion(lv, GameVersion.RB);
|
||||
|
||||
// No relearner -- have to be learned on levelup
|
||||
lv = LevelUpY[index].GetLevelLearnMove(move, min);
|
||||
if (lv >= 0 && lv <= max)
|
||||
return new LearnVersion(lv, GameVersion.YW);
|
||||
|
||||
return LearnNONE;
|
||||
}
|
||||
private static LearnVersion GetIsLevelUp2(int species, int move, int max, int min, bool korean)
|
||||
{
|
||||
if (move > MaxMoveID_1)
|
||||
return LearnNONE;
|
||||
|
||||
int index = PersonalTable.C.GetFormeIndex(species, 0);
|
||||
if (index == 0)
|
||||
return LearnNONE;
|
||||
|
||||
// No relearner -- have to be learned on levelup
|
||||
var lv = LevelUpGS[index].GetLevelLearnMove(move, min);
|
||||
if (lv >= 0 && lv <= max)
|
||||
return new LearnVersion(lv, GameVersion.GS);
|
||||
|
||||
if (korean) // No Korean Crystal
|
||||
return LearnNONE;
|
||||
|
||||
// No relearner -- have to be learned on levelup
|
||||
lv = LevelUpC[index].GetLevelLearnMove(move, min);
|
||||
if (lv >= 0 && lv <= max)
|
||||
return new LearnVersion(lv, GameVersion.C);
|
||||
|
||||
return LearnNONE;
|
||||
}
|
||||
private static LearnVersion GetIsLevelUp3(int species, int move, int lvl, int form)
|
||||
{
|
||||
|
||||
int index = PersonalTable.E.GetFormeIndex(species, 0);
|
||||
if (index == 0)
|
||||
return LearnNONE;
|
||||
if (index == 386)
|
||||
return GetIsLevelUp3Deoxys(form, move, lvl);
|
||||
|
||||
// Emerald level up table are equals to R/S level up tables
|
||||
var lv = LevelUpE[index].GetLevelLearnMove(move);
|
||||
if (lv >= 0 && lv <= lvl)
|
||||
return new LearnVersion(lv, GameVersion.RSE);
|
||||
|
||||
// fire red and leaf green are equals between each other but different than RSE
|
||||
// Do not use FR Levelup table. It have 67 moves for charmander but Leaf Green moves table is correct
|
||||
lv = LevelUpLG[index].GetLevelLearnMove(move);
|
||||
if (lv >= 0 && lv <= lvl)
|
||||
return new LearnVersion(lv, GameVersion.FRLG);
|
||||
|
||||
return LearnNONE;
|
||||
}
|
||||
private static LearnVersion GetIsLevelUp4(int species, int move, int lvl, int form)
|
||||
{
|
||||
int index = PersonalTable.HGSS.GetFormeIndex(species, form);
|
||||
if (index == 0)
|
||||
return LearnNONE;
|
||||
|
||||
var lv = LevelUpDP[index].GetLevelLearnMove(move);
|
||||
if (lv >= 0 && lv <= lvl)
|
||||
return new LearnVersion(lv, GameVersion.DP);
|
||||
|
||||
lv = LevelUpPt[index].GetLevelLearnMove(move);
|
||||
if (lv >= 0 && lv <= lvl)
|
||||
return new LearnVersion(lv, GameVersion.Pt);
|
||||
|
||||
lv = LevelUpHGSS[index].GetLevelLearnMove(move);
|
||||
if (lv >= 0 && lv <= lvl)
|
||||
return new LearnVersion(lv, GameVersion.HGSS);
|
||||
|
||||
return LearnNONE;
|
||||
}
|
||||
private static LearnVersion GetIsLevelUp5(int species, int form, int move, int lvl)
|
||||
{
|
||||
int index1 = PersonalTable.BW.GetFormeIndex(species, form);
|
||||
int index2 = PersonalTable.B2W2.GetFormeIndex(species, form);
|
||||
if (index1 == 0 && index2 == 0)
|
||||
return LearnNONE;
|
||||
if (index1 != 0)
|
||||
{
|
||||
var lv = LevelUpBW[index1].GetLevelLearnMove(move);
|
||||
if (lv >= 0 && lv <= lvl)
|
||||
return new LearnVersion(lv, GameVersion.BW);
|
||||
}
|
||||
if (index2 != 0)
|
||||
{
|
||||
var lv = LevelUpB2W2[index2].GetLevelLearnMove(move);
|
||||
if (lv >= 0 && lv <= lvl)
|
||||
return new LearnVersion(lv, GameVersion.B2W2);
|
||||
}
|
||||
return LearnNONE;
|
||||
}
|
||||
private static LearnVersion GetIsLevelUp6(int species, int move, int lvl, int form, GameVersion ver)
|
||||
{
|
||||
switch (ver)
|
||||
{
|
||||
case GameVersion.SN:
|
||||
case GameVersion.MN:
|
||||
case GameVersion.SM:
|
||||
return GetIsLevelUp6XY(species, form, move, lvl);
|
||||
case GameVersion.Any:
|
||||
case GameVersion.US:
|
||||
case GameVersion.UM:
|
||||
case GameVersion.USUM:
|
||||
return GetIsLevelUp6AO(species, form, move, lvl);
|
||||
}
|
||||
return LearnNONE;
|
||||
}
|
||||
private static LearnVersion GetIsLevelUp7(int species, int move, int form, GameVersion ver)
|
||||
{
|
||||
switch (ver)
|
||||
{
|
||||
case GameVersion.SN:
|
||||
case GameVersion.MN:
|
||||
case GameVersion.SM:
|
||||
return GetIsLevelUp7SM(species, form, move);
|
||||
case GameVersion.Any:
|
||||
case GameVersion.US:
|
||||
case GameVersion.UM:
|
||||
case GameVersion.USUM:
|
||||
return GetIsLevelUp7USUM(species, form, move);
|
||||
}
|
||||
return LearnNONE;
|
||||
}
|
||||
|
||||
private static LearnVersion GetIsLevelUp3Deoxys(int form, int move, int lvl)
|
||||
{
|
||||
var moveset = GetDeoxysLearn3(form);
|
||||
if (moveset == null)
|
||||
return LearnNONE;
|
||||
var lv = moveset.GetLevelLearnMove(move);
|
||||
if (lv >= 0 && lv <= lvl)
|
||||
return new LearnVersion(lv, GetDeoxysGameVersion3(form));
|
||||
return LearnNONE;
|
||||
}
|
||||
private static LearnVersion GetIsLevelUp6XY(int species, int form, int move, int lvl)
|
||||
{
|
||||
int index = PersonalTable.XY.GetFormeIndex(species, form);
|
||||
if (index == 0)
|
||||
return LearnNONE;
|
||||
|
||||
var lv = LevelUpXY[index].GetLevelLearnMove(move);
|
||||
if (lv >= 0 && lv <= lvl)
|
||||
return new LearnVersion(lv, GameVersion.XY);
|
||||
|
||||
return LearnNONE;
|
||||
}
|
||||
private static LearnVersion GetIsLevelUp6AO(int species, int form, int move, int lvl)
|
||||
{
|
||||
int index = PersonalTable.AO.GetFormeIndex(species, form);
|
||||
if (index == 0)
|
||||
return LearnNONE;
|
||||
|
||||
var lv = LevelUpAO[index].GetLevelLearnMove(move);
|
||||
if (lv >= 0 && lv <= lvl)
|
||||
return new LearnVersion(lv, GameVersion.ORAS);
|
||||
|
||||
return GetIsLevelUp7SM(species, form, move);
|
||||
}
|
||||
private static LearnVersion GetIsLevelUp7SM(int species, int form, int move)
|
||||
{
|
||||
if (species > MaxSpeciesID_7)
|
||||
return LearnNONE;
|
||||
int index = PersonalTable.SM.GetFormeIndex(species, form);
|
||||
if (index == 0)
|
||||
return LearnNONE;
|
||||
|
||||
var lv = LevelUpSM[index].GetLevelLearnMove(move);
|
||||
if (lv >= 0)
|
||||
return new LearnVersion(lv, GameVersion.SM);
|
||||
|
||||
return LearnNONE;
|
||||
}
|
||||
private static LearnVersion GetIsLevelUp7USUM(int species, int form, int move)
|
||||
{
|
||||
if (species > MaxSpeciesID_7_USUM)
|
||||
return LearnNONE;
|
||||
int index = PersonalTable.USUM.GetFormeIndex(species, form);
|
||||
if (index == 0)
|
||||
return LearnNONE;
|
||||
|
||||
var lv = LevelUpUSUM[index].GetLevelLearnMove(move);
|
||||
if (lv >= 0)
|
||||
return new LearnVersion(lv, GameVersion.USUM);
|
||||
|
||||
return GetIsLevelUp7SM(species, form, move);
|
||||
}
|
||||
|
||||
private static GameVersion GetDeoxysGameVersion3(int form)
|
||||
{
|
||||
switch (form)
|
||||
{
|
||||
case 0: return GameVersion.RS;
|
||||
case 1: return GameVersion.FR;
|
||||
case 2: return GameVersion.LG;
|
||||
case 3: return GameVersion.E;
|
||||
default:
|
||||
return GameVersion.Invalid;
|
||||
}
|
||||
}
|
||||
private static Learnset GetDeoxysLearn3(int form)
|
||||
{
|
||||
switch (form)
|
||||
{
|
||||
case 0: return LevelUpRS[386]; // Normal
|
||||
case 1: return LevelUpFR[386]; // Attack
|
||||
case 2: return LevelUpLG[386]; // Defense
|
||||
case 3: return LevelUpE[386]; // Speed
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<int> GetLevelUpMoves(PKM pkm, int species, int minlvlG1, int minlvlG2, int lvl, int form, GameVersion version, bool MoveReminder, int Generation)
|
||||
{
|
||||
switch (Generation)
|
||||
{
|
||||
case 1: return AddMovesLevelUp1(species, lvl, minlvlG1);
|
||||
case 2: return AddMovesLevelUp2(species, lvl, minlvlG2, pkm.Korean, pkm.Format);
|
||||
case 3: return AddMovesLevelUp3(species, lvl, form);
|
||||
case 4: return AddMovesLevelUp4(species, lvl, form);
|
||||
case 5: return AddMovesLevelUp5(species, lvl, form);
|
||||
case 6: return AddMovesLevelUp6(species, lvl, form, version);
|
||||
case 7: return AddMovesLevelUp7(species, lvl, form, version, MoveReminder);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static List<int> AddMovesLevelUp1(int species, int max, int min)
|
||||
{
|
||||
List<int> moves = new List<int>();
|
||||
int index = PersonalTable.RB.GetFormeIndex(species, 0);
|
||||
if (index == 0)
|
||||
return moves;
|
||||
|
||||
if (min == 1)
|
||||
{
|
||||
var pi_rb = (PersonalInfoG1)PersonalTable.RB[index];
|
||||
var pi_y = (PersonalInfoG1)PersonalTable.Y[index];
|
||||
moves.AddRange(pi_rb.Moves);
|
||||
moves.AddRange(pi_y.Moves);
|
||||
}
|
||||
moves.AddRange(LevelUpRB[index].GetMoves(max, min));
|
||||
moves.AddRange(LevelUpY[index].GetMoves(max, min));
|
||||
return moves;
|
||||
}
|
||||
private static List<int> AddMovesLevelUp2(int species, int max, int min, bool korean, int format)
|
||||
{
|
||||
var r = new List<int>();
|
||||
int index = PersonalTable.C.GetFormeIndex(species, 0);
|
||||
if (index == 0)
|
||||
return r;
|
||||
r.AddRange(LevelUpGS[index].GetMoves(max, min));
|
||||
if (!korean)
|
||||
r.AddRange(LevelUpC[index].GetMoves(max, min));
|
||||
if (format == 1) //tradeback gen 2 -> gen 1
|
||||
r = r.Where(m => m <= MaxMoveID_1).ToList();
|
||||
return r;
|
||||
}
|
||||
private static List<int> AddMovesLevelUp3(int species, int lvl, int form)
|
||||
{
|
||||
var moves = new List<int>();
|
||||
if (species == 386)
|
||||
{
|
||||
var learn = GetDeoxysLearn3(form);
|
||||
if (learn != null)
|
||||
moves.AddRange(learn.GetMoves(lvl));
|
||||
return moves;
|
||||
}
|
||||
|
||||
int index = PersonalTable.E.GetFormeIndex(species, 0);
|
||||
if (index == 0)
|
||||
return moves;
|
||||
|
||||
// Emerald level up table are equals to R/S level up tables
|
||||
moves.AddRange(LevelUpE[index].GetMoves(lvl));
|
||||
// fire red and leaf green are equals between each other but different than RSE
|
||||
// Do not use FR Levelup table. It have 67 moves for charmander but Leaf Green moves table is correct
|
||||
moves.AddRange(LevelUpLG[index].GetMoves(lvl));
|
||||
return moves;
|
||||
}
|
||||
private static List<int> AddMovesLevelUp4(int species, int lvl, int form)
|
||||
{
|
||||
var moves = new List<int>();
|
||||
int index = PersonalTable.HGSS.GetFormeIndex(species, form);
|
||||
if (index == 0)
|
||||
return moves;
|
||||
if (index < LevelUpDP.Length)
|
||||
moves.AddRange(LevelUpDP[index].GetMoves(lvl));
|
||||
moves.AddRange(LevelUpPt[index].GetMoves(lvl));
|
||||
moves.AddRange(LevelUpHGSS[index].GetMoves(lvl));
|
||||
return moves;
|
||||
}
|
||||
private static List<int> AddMovesLevelUp5(int species, int lvl, int form)
|
||||
{
|
||||
var moves = new List<int>();
|
||||
int index1 = PersonalTable.BW.GetFormeIndex(species, form);
|
||||
if (index1 != 0)
|
||||
moves.AddRange(LevelUpBW[index1].GetMoves(lvl));
|
||||
|
||||
int index2 = PersonalTable.B2W2.GetFormeIndex(species, form);
|
||||
if (index2 != 0)
|
||||
moves.AddRange(LevelUpB2W2[index2].GetMoves(lvl));
|
||||
return moves;
|
||||
}
|
||||
private static List<int> AddMovesLevelUp6(int species, int lvl, int form, GameVersion ver)
|
||||
{
|
||||
var moves = new List<int>();
|
||||
switch (ver)
|
||||
{
|
||||
case GameVersion.Any:
|
||||
AddMovesLevelUp6XY(moves, species, lvl, form);
|
||||
AddMovesLevelUp6AO(moves, species, lvl, form);
|
||||
break;
|
||||
case GameVersion.X:
|
||||
case GameVersion.Y:
|
||||
case GameVersion.XY:
|
||||
AddMovesLevelUp6XY(moves, species, lvl, form);
|
||||
break;
|
||||
case GameVersion.AS:
|
||||
case GameVersion.OR:
|
||||
case GameVersion.ORAS:
|
||||
AddMovesLevelUp6AO(moves, species, lvl, form);
|
||||
break;
|
||||
}
|
||||
return moves;
|
||||
}
|
||||
private static void AddMovesLevelUp6XY(List<int> moves, int species, int lvl, int form)
|
||||
{
|
||||
int index = PersonalTable.XY.GetFormeIndex(species, form);
|
||||
if (index == 0)
|
||||
return;
|
||||
moves.AddRange(LevelUpXY[index].GetMoves(lvl));
|
||||
}
|
||||
private static void AddMovesLevelUp6AO(List<int> moves, int species, int lvl, int form)
|
||||
{
|
||||
int index = PersonalTable.AO.GetFormeIndex(species, form);
|
||||
if (index == 0)
|
||||
return;
|
||||
moves.AddRange(LevelUpAO[index].GetMoves(lvl));
|
||||
}
|
||||
private static List<int> AddMovesLevelUp7(int species, int lvl, int form, GameVersion ver, bool MoveReminder)
|
||||
{
|
||||
var moves = new List<int>();
|
||||
switch (ver)
|
||||
{
|
||||
case GameVersion.Any:
|
||||
AddMovesLevelUp7SM(moves, species, lvl, form, MoveReminder);
|
||||
AddMovesLevelUp7USUM(moves, species, lvl, form, MoveReminder);
|
||||
break;
|
||||
case GameVersion.SN:
|
||||
case GameVersion.MN:
|
||||
case GameVersion.SM:
|
||||
AddMovesLevelUp7SM(moves, species, lvl, form, MoveReminder);
|
||||
break;
|
||||
case GameVersion.US:
|
||||
case GameVersion.UM:
|
||||
case GameVersion.USUM:
|
||||
AddMovesLevelUp7USUM(moves, species, lvl, form, MoveReminder);
|
||||
break;
|
||||
}
|
||||
return moves;
|
||||
}
|
||||
private static void AddMovesLevelUp7SM(List<int> moves, int species, int lvl, int form, bool MoveReminder)
|
||||
{
|
||||
if (species > MaxSpeciesID_7)
|
||||
return;
|
||||
int index = PersonalTable.SM.GetFormeIndex(species, form);
|
||||
if (MoveReminder)
|
||||
lvl = 100; // Move reminder can teach any level in movepool now!
|
||||
|
||||
moves.AddRange(LevelUpSM[index].GetMoves(lvl));
|
||||
}
|
||||
private static void AddMovesLevelUp7USUM(List<int> moves, int species, int lvl, int form, bool MoveReminder)
|
||||
{
|
||||
if (species > MaxSpeciesID_7_USUM)
|
||||
return;
|
||||
int index = PersonalTable.USUM.GetFormeIndex(species, form);
|
||||
if (MoveReminder)
|
||||
lvl = 100; // Move reminder can teach any level in movepool now!
|
||||
|
||||
moves.AddRange(LevelUpUSUM[index].GetMoves(lvl));
|
||||
}
|
||||
}
|
||||
}
|
||||
307
PKHeX.Core/Legality/Moves/MoveTechnicalMachine.cs
Normal file
307
PKHeX.Core/Legality/Moves/MoveTechnicalMachine.cs
Normal file
@@ -0,0 +1,307 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
internal static class MoveTechnicalMachine
|
||||
{
|
||||
internal static GameVersion GetIsMachineMove(PKM pkm, int species, int form, int generation, int move, GameVersion ver = GameVersion.Any, bool RemoveTransfer = false)
|
||||
{
|
||||
switch (generation)
|
||||
{
|
||||
case 1: return GetIsMachine1(species, move);
|
||||
case 2: return GetIsMachine2(species, move);
|
||||
case 3: return GetIsMachine3(species, move, pkm.Format, RemoveTransfer);
|
||||
case 4: return GetIsMachine4(species, move, pkm.Format, RemoveTransfer, form);
|
||||
case 5: return GetIsMachine5(species, move, form);
|
||||
case 6: return GetIsMachine6(species, move, form, ver);
|
||||
case 7: return GetIsMachine7(species, move, form, ver);
|
||||
default:
|
||||
return Legal.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
private static GameVersion GetIsMachine1(int species, int move)
|
||||
{
|
||||
for (int i = 0; i < Legal.TMHM_RBY.Length; i++)
|
||||
if (Legal.TMHM_RBY[i] == move)
|
||||
{
|
||||
if (PersonalTable.RB[species].TMHM[i])
|
||||
return GameVersion.RB;
|
||||
if (PersonalTable.Y[species].TMHM[i])
|
||||
return GameVersion.Y;
|
||||
}
|
||||
|
||||
return Legal.NONE;
|
||||
}
|
||||
private static GameVersion GetIsMachine2(int species, int move)
|
||||
{
|
||||
for (int i = 0; i < Legal.TMHM_GSC.Length; i++)
|
||||
if (Legal.TMHM_GSC[i] == move && PersonalTable.C[species].TMHM[i])
|
||||
return GameVersion.GS;
|
||||
|
||||
return Legal.NONE;
|
||||
}
|
||||
private static GameVersion GetIsMachine3(int species, int move, int format, bool RemoveTransfer)
|
||||
{
|
||||
for (int i = 0; i < Legal.TM_3.Length; i++)
|
||||
if (Legal.TM_3[i] == move && PersonalTable.E[species].TMHM[i])
|
||||
return GameVersion.Gen3;
|
||||
|
||||
if (!RemoveTransfer && format <= 3)
|
||||
return GetIsMachine3HM(species, move);
|
||||
|
||||
return Legal.NONE;
|
||||
}
|
||||
private static GameVersion GetIsMachine3HM(int species, int move)
|
||||
{
|
||||
int x = 0;
|
||||
foreach (var m in Legal.HM_3)
|
||||
{
|
||||
if (m == move && PersonalTable.E[species].TMHM[x + 50])
|
||||
return GameVersion.Gen3;
|
||||
x++;
|
||||
}
|
||||
return Legal.NONE;
|
||||
}
|
||||
private static GameVersion GetIsMachine4(int species, int move, int format, bool RemoveTransfer, int form)
|
||||
{
|
||||
for (int i = 0; i < Legal.TM_3.Length; i++)
|
||||
if (Legal.TM_4[i] == move && PersonalTable.HGSS.GetFormeEntry(species, form).TMHM[i])
|
||||
return GameVersion.Gen4;
|
||||
|
||||
if (RemoveTransfer && format > 4)
|
||||
return GetIsMachine4HMTransfer(species, move, form);
|
||||
|
||||
return GetIsMachine4HM(species, move, form);
|
||||
}
|
||||
private static GameVersion GetIsMachine4HMTransfer(int species, int move, int form)
|
||||
{
|
||||
// The combination of both these moves is illegal, it should be checked that the pokemon only learn one
|
||||
// except if it can learn any of these moves in gen 5 or later
|
||||
switch (move)
|
||||
{
|
||||
case 250: // Whirlpool
|
||||
if (PersonalTable.HGSS.GetFormeEntry(species, form).TMHM[96])
|
||||
return GameVersion.HGSS;
|
||||
break;
|
||||
case 432: // Defog
|
||||
if (PersonalTable.Pt.GetFormeEntry(species, form).TMHM[96])
|
||||
return GameVersion.DPPt;
|
||||
break;
|
||||
}
|
||||
return Legal.NONE;
|
||||
}
|
||||
private static GameVersion GetIsMachine4HM(int species, int move, int form)
|
||||
{
|
||||
{
|
||||
int i = 0;
|
||||
foreach (var m in Legal.HM_DPPt)
|
||||
{
|
||||
if (m == move)
|
||||
{
|
||||
if (PersonalTable.Pt.GetFormeEntry(species, form).TMHM[i + 92])
|
||||
return GameVersion.DPPt;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
foreach (var m in Legal.HM_HGSS)
|
||||
{
|
||||
if (m == move)
|
||||
{
|
||||
if (PersonalTable.HGSS.GetFormeEntry(species, form).TMHM[i + 92])
|
||||
return GameVersion.HGSS;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return Legal.NONE;
|
||||
}
|
||||
private static GameVersion GetIsMachine5(int species, int move, int form)
|
||||
{
|
||||
for (int i = 0; i < Legal.TMHM_BW.Length; i++)
|
||||
if (Legal.TMHM_BW[i] == move)
|
||||
return PersonalTable.B2W2.GetFormeEntry(species, form).TMHM[i] ? GameVersion.Gen5 : Legal.NONE;
|
||||
return Legal.NONE;
|
||||
}
|
||||
private static GameVersion GetIsMachine6(int species, int move, int form, GameVersion ver)
|
||||
{
|
||||
if (GameVersion.XY.Contains(ver))
|
||||
for (int i = 0; i < Legal.TMHM_XY.Length; i++)
|
||||
if (Legal.TMHM_XY[i] == move)
|
||||
{
|
||||
if (PersonalTable.XY.GetFormeEntry(species, form).TMHM[i])
|
||||
return GameVersion.XY;
|
||||
break;
|
||||
}
|
||||
if (GameVersion.ORAS.Contains(ver))
|
||||
for (int i = 0; i < Legal.TMHM_AO.Length; i++)
|
||||
if (Legal.TMHM_AO[i] == move)
|
||||
{
|
||||
if (PersonalTable.AO.GetFormeEntry(species, form).TMHM[i])
|
||||
return GameVersion.ORAS;
|
||||
break;
|
||||
}
|
||||
return Legal.NONE;
|
||||
}
|
||||
private static GameVersion GetIsMachine7(int species, int move, int form, GameVersion ver)
|
||||
{
|
||||
if (GameVersion.SM.Contains(ver) && species <= Legal.MaxSpeciesID_7)
|
||||
for (int i = 0; i < Legal.TMHM_XY.Length; i++)
|
||||
if (Legal.TMHM_XY[i] == move)
|
||||
{
|
||||
if (PersonalTable.SM.GetFormeEntry(species, form).TMHM[i])
|
||||
return GameVersion.SM;
|
||||
break;
|
||||
}
|
||||
if (GameVersion.ORAS.Contains(ver) && species <= Legal.MaxSpeciesID_7_USUM)
|
||||
for (int i = 0; i < Legal.TMHM_SM.Length; i++)
|
||||
if (Legal.TMHM_SM[i] == move)
|
||||
{
|
||||
if (PersonalTable.USUM.GetFormeEntry(species, form).TMHM[i])
|
||||
return GameVersion.USUM;
|
||||
break;
|
||||
}
|
||||
return Legal.NONE;
|
||||
}
|
||||
|
||||
|
||||
internal static IEnumerable<int> GetTMHM(PKM pkm, int species, int form, int generation, GameVersion ver = GameVersion.Any, bool RemoveTransfer = true)
|
||||
{
|
||||
List<int> r = new List<int>();
|
||||
|
||||
switch (generation)
|
||||
{
|
||||
case 1: AddMachine1(r, species); break;
|
||||
case 2: AddMachine2(r, species); break;
|
||||
case 3: AddMachine3(r, species, pkm.Format, RemoveTransfer); break;
|
||||
case 4: AddMachine4(r, species, pkm.Format, RemoveTransfer, form); break;
|
||||
case 5: AddMachine5(r, species, form); break;
|
||||
case 6: AddMachine6(r, species, form, ver); break;
|
||||
case 7: AddMachine7(r, species, form, ver); break;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
private static void AddMachine1(List<int> r, int species)
|
||||
{
|
||||
int index = PersonalTable.RB.GetFormeIndex(species, 0);
|
||||
if (index == 0)
|
||||
return;
|
||||
var pi_rb = (PersonalInfoG1)PersonalTable.RB[index];
|
||||
var pi_y = (PersonalInfoG1)PersonalTable.Y[index];
|
||||
r.AddRange(Legal.TMHM_RBY.Where((_, m) => pi_rb.TMHM[m]));
|
||||
r.AddRange(Legal.TMHM_RBY.Where((_, m) => pi_y.TMHM[m]));
|
||||
}
|
||||
private static void AddMachine2(List<int> r, int species)
|
||||
{
|
||||
int index = PersonalTable.C.GetFormeIndex(species, 0);
|
||||
if (index == 0)
|
||||
return;
|
||||
var pi_c = PersonalTable.C[index];
|
||||
r.AddRange(Legal.TMHM_GSC.Where((_, m) => pi_c.TMHM[m]));
|
||||
}
|
||||
private static void AddMachine3(List<int> r, int species, int format, bool RemoveTransfer)
|
||||
{
|
||||
int index = PersonalTable.E.GetFormeIndex(species, 0);
|
||||
if (index == 0)
|
||||
return;
|
||||
var pi_c = PersonalTable.E[index];
|
||||
r.AddRange(Legal.TM_3.Where((_, m) => pi_c.TMHM[m]));
|
||||
|
||||
if (!RemoveTransfer || format == 3) // HM moves must be removed for 3->4, only give if current format.
|
||||
r.AddRange(Legal.HM_3.Where((_, m) => pi_c.TMHM[m + 50]));
|
||||
else if (format > 3) //Remove HM
|
||||
r.AddRange(Legal.HM_3.Where((_, m) => pi_c.TMHM[m + 50]).Except(Legal.HM_3));
|
||||
}
|
||||
private static void AddMachine4(List<int> r, int species, int format, bool RemoveTransfer, int form)
|
||||
{
|
||||
var pi_hgss = PersonalTable.HGSS.GetFormeEntry(species, form);
|
||||
var pi_dppt = PersonalTable.Pt.GetFormeEntry(species, form);
|
||||
r.AddRange(Legal.TM_4.Where((_, m) => pi_hgss.TMHM[m]));
|
||||
|
||||
if (RemoveTransfer && format > 4)
|
||||
{
|
||||
// The combination of both these moves is illegal, it should be checked that the pokemon only learn one
|
||||
// except if it can learn any of these moves in gen 5 or later
|
||||
if (pi_hgss.TMHM[96])
|
||||
r.Add(250); // Whirlpool
|
||||
if (pi_dppt.TMHM[96])
|
||||
r.Add(432); // Defog
|
||||
}
|
||||
else
|
||||
{
|
||||
r.AddRange(Legal.HM_DPPt.Where((_, m) => pi_dppt.TMHM[m + 92]));
|
||||
r.AddRange(Legal.HM_HGSS.Where((_, m) => pi_hgss.TMHM[m + 92]));
|
||||
}
|
||||
}
|
||||
private static void AddMachine5(List<int> r, int species, int form)
|
||||
{
|
||||
var pi = PersonalTable.B2W2.GetFormeEntry(species, form);
|
||||
r.AddRange(Legal.TMHM_BW.Where((_, m) => pi.TMHM[m]));
|
||||
}
|
||||
private static void AddMachine6(List<int> r, int species, int form, GameVersion ver = GameVersion.Any)
|
||||
{
|
||||
switch (ver)
|
||||
{
|
||||
case GameVersion.Any: // Start at the top, hit every table
|
||||
case GameVersion.X:
|
||||
case GameVersion.Y:
|
||||
case GameVersion.XY:
|
||||
AddMachine6XY(r, species, form);
|
||||
if (ver == GameVersion.Any) // Fall Through
|
||||
AddMachine6AO(r, species, form);
|
||||
break;
|
||||
case GameVersion.AS:
|
||||
case GameVersion.OR:
|
||||
case GameVersion.ORAS:
|
||||
AddMachine6AO(r, species, form);
|
||||
break;
|
||||
}
|
||||
}
|
||||
private static void AddMachine7(List<int> r, int species, int form, GameVersion ver = GameVersion.Any)
|
||||
{
|
||||
switch (ver)
|
||||
{
|
||||
case GameVersion.SN:
|
||||
case GameVersion.MN:
|
||||
case GameVersion.SM:
|
||||
if (species <= Legal.MaxSpeciesID_7)
|
||||
AddMachineSM(r, species, form);
|
||||
return;
|
||||
case GameVersion.Any:
|
||||
case GameVersion.US:
|
||||
case GameVersion.UM:
|
||||
case GameVersion.USUM:
|
||||
AddMachineUSUM(r, species, form);
|
||||
if (ver == GameVersion.Any) // Fall Through
|
||||
AddMachineSM(r, species, form);
|
||||
return;
|
||||
}
|
||||
}
|
||||
private static void AddMachine6XY(List<int> r, int species, int form)
|
||||
{
|
||||
var pi = PersonalTable.XY.GetFormeEntry(species, form);
|
||||
r.AddRange(Legal.TMHM_XY.Where((_, m) => pi.TMHM[m]));
|
||||
}
|
||||
private static void AddMachine6AO(List<int> r, int species, int form)
|
||||
{
|
||||
var pi = PersonalTable.AO.GetFormeEntry(species, form);
|
||||
r.AddRange(Legal.TMHM_AO.Where((_, m) => pi.TMHM[m]));
|
||||
}
|
||||
private static void AddMachineSM(List<int> r, int species, int form)
|
||||
{
|
||||
if (species > Legal.MaxSpeciesID_7)
|
||||
return;
|
||||
var pi = PersonalTable.SM.GetFormeEntry(species, form);
|
||||
r.AddRange(Legal.TMHM_SM.Where((_, m) => pi.TMHM[m]));
|
||||
}
|
||||
private static void AddMachineUSUM(List<int> r, int species, int form)
|
||||
{
|
||||
var pi = PersonalTable.USUM.GetFormeEntry(species, form);
|
||||
r.AddRange(Legal.TMHM_SM.Where((_, m) => pi.TMHM[m]));
|
||||
}
|
||||
}
|
||||
}
|
||||
215
PKHeX.Core/Legality/Moves/MoveTutor.cs
Normal file
215
PKHeX.Core/Legality/Moves/MoveTutor.cs
Normal file
@@ -0,0 +1,215 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using static PKHeX.Core.Legal;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
public static class MoveTutor
|
||||
{
|
||||
public static GameVersion GetIsTutorMove(PKM pkm, int species, int form, int generation, int move, bool specialTutors = true)
|
||||
{
|
||||
switch (generation)
|
||||
{
|
||||
case 1: return GetIsTutor1(pkm, species, move);
|
||||
case 2: return GetIsTutor2(pkm, species, move);
|
||||
case 3: return GetIsTutor3(species, move);
|
||||
case 4: return GetIsTutor4(species, form, move);
|
||||
case 5: return GetIsTutor5(pkm, species, form, specialTutors, move);
|
||||
case 6: return GetIsTutor6(pkm, species, form, specialTutors, move);
|
||||
case 7: return GetIsTutor7(pkm, species, form, specialTutors, move);
|
||||
default:
|
||||
return NONE;
|
||||
}
|
||||
}
|
||||
|
||||
private static GameVersion GetIsTutor1(PKM pkm, int species, int move)
|
||||
{
|
||||
// Surf Pikachu via Stadium
|
||||
if (move != 57 || AllowGBCartEra)
|
||||
return NONE;
|
||||
if (pkm.Format < 3 && (species == 25 || species == 26))
|
||||
return GameVersion.Stadium;
|
||||
return NONE;
|
||||
}
|
||||
private static GameVersion GetIsTutor2(PKM pkm, int species, int move)
|
||||
{
|
||||
if (!AllowGen2Crystal(pkm))
|
||||
return NONE;
|
||||
var info = PersonalTable.C[species];
|
||||
for (int i = 0; i < Tutors_GSC.Length; i++)
|
||||
{
|
||||
if (Tutors_GSC[i] == move)
|
||||
return info.TMHM[57 + i] ? GameVersion.C : NONE;
|
||||
}
|
||||
return GetIsTutor1(pkm, species, move);
|
||||
}
|
||||
private static GameVersion GetIsTutor3(int species, int move)
|
||||
{
|
||||
// E Tutors (Free)
|
||||
// E Tutors (BP)
|
||||
var info = PersonalTable.E[species];
|
||||
for (int i = 0; i < Tutor_E.Length; i++)
|
||||
if (Tutor_E[i] == move && info.TypeTutors[i])
|
||||
return GameVersion.E;
|
||||
|
||||
// FRLG Tutors
|
||||
// Only special tutor moves, normal tutor moves are already included in Emerald data
|
||||
for (int i = 0; i < SpecialTutors_FRLG.Length; i++)
|
||||
{
|
||||
if (Tutor_FRLG[i] == move && species == SpecialTutors_Compatibility_FRLG[i])
|
||||
return GameVersion.FRLG;
|
||||
}
|
||||
|
||||
// XD
|
||||
for (int i = 0; i < SpecialTutors_XD_Exclusive.Length; i++)
|
||||
{
|
||||
if (SpecialTutors_XD_Exclusive[i] == move && SpecialTutors_Compatibility_XD_Exclusive[i].Any(e => e == species))
|
||||
return GameVersion.XD;
|
||||
}
|
||||
|
||||
// XD (Mew)
|
||||
if (species == 151 && Tutor_3Mew.Contains(move))
|
||||
return GameVersion.XD;
|
||||
|
||||
return NONE;
|
||||
}
|
||||
private static GameVersion GetIsTutor4(int species, int form, int move)
|
||||
{
|
||||
var pi = PersonalTable.HGSS.GetFormeEntry(species, form);
|
||||
for (int i = 0; i < Tutors_4.Length; i++)
|
||||
if (Tutors_4[i] == move && pi.TypeTutors[i])
|
||||
return GameVersion.Gen4;
|
||||
|
||||
for (int i = 0; i < SpecialTutors_4.Length; i++)
|
||||
if (SpecialTutors_4[i] == move && SpecialTutors_Compatibility_4[i].Any(e => e == species))
|
||||
return GameVersion.HGSS;
|
||||
|
||||
return NONE;
|
||||
}
|
||||
private static GameVersion GetIsTutor5(PKM pkm, int species, int form, bool specialTutors, int move)
|
||||
{
|
||||
var pi = PersonalTable.B2W2.GetFormeEntry(species, form);
|
||||
for (int i = 0; i < TypeTutor6.Length; i++)
|
||||
if (TypeTutor6[i] == move && pi.TypeTutors[i])
|
||||
return GameVersion.Gen5;
|
||||
|
||||
if (specialTutors && pkm.HasVisitedB2W2())
|
||||
for (int i = 0; i < Tutors_B2W2.Length; i++)
|
||||
for (int j = 0; j < Tutors_B2W2[i].Length; j++)
|
||||
if (Tutors_B2W2[i][j] == move && pi.SpecialTutors[i][j])
|
||||
return GameVersion.B2W2;
|
||||
|
||||
return NONE;
|
||||
}
|
||||
private static GameVersion GetIsTutor6(PKM pkm, int species, int form, bool specialTutors, int move)
|
||||
{
|
||||
var pi = PersonalTable.AO.GetFormeEntry(species, form);
|
||||
for (int i = 0; i < TypeTutor6.Length; i++)
|
||||
if (TypeTutor6[i] == move && pi.TypeTutors[i])
|
||||
return GameVersion.Gen6;
|
||||
|
||||
if (specialTutors && pkm.HasVisitedORAS())
|
||||
for (int i = 0; i < Tutors_AO.Length; i++)
|
||||
for (int j = 0; j < Tutors_AO[i].Length; j++)
|
||||
if (Tutors_AO[i][j] == move && pi.SpecialTutors[i][j])
|
||||
return GameVersion.ORAS;
|
||||
|
||||
return NONE;
|
||||
}
|
||||
private static GameVersion GetIsTutor7(PKM pkm, int species, int form, bool specialTutors, int move)
|
||||
{
|
||||
var pi = PersonalTable.USUM.GetFormeEntry(species, form);
|
||||
for (int i = 0; i < TypeTutor6.Length; i++)
|
||||
if (TypeTutor6[i] == move && pi.TypeTutors[i])
|
||||
return GameVersion.Gen7;
|
||||
|
||||
if (specialTutors && pkm.HasVisitedUSUM())
|
||||
for (int i = 0; i < Tutors_USUM.Length; i++)
|
||||
if (Tutors_USUM[i] == move && pi.SpecialTutors[0][i])
|
||||
return GameVersion.USUM;
|
||||
|
||||
return NONE;
|
||||
}
|
||||
|
||||
public static IEnumerable<int> GetTutorMoves(PKM pkm, int species, int form, bool specialTutors, int generation)
|
||||
{
|
||||
List<int> moves = new List<int>();
|
||||
switch (generation)
|
||||
{
|
||||
case 1: AddMovesTutor1(moves, species, pkm.Format); break;
|
||||
case 2: AddMovesTutor2(moves, species, pkm.Format, pkm.Korean); break;
|
||||
case 3: AddMovesTutor3(moves, species); break;
|
||||
case 4: AddMovesTutor4(moves, species, form); break;
|
||||
case 5: AddMovesTutor5(moves, species, form, pkm, specialTutors); break;
|
||||
case 6: AddMovesTutor6(moves, species, form, pkm, specialTutors); break;
|
||||
case 7: AddMovesTutor7(moves, species, form, pkm, specialTutors); break;
|
||||
}
|
||||
return moves.Distinct();
|
||||
}
|
||||
|
||||
private static void AddMovesTutor1(List<int> moves, int species, int format)
|
||||
{
|
||||
if (AllowGBCartEra && format < 3 && (species == 25 || species == 26)) // Surf Pikachu via Stadium
|
||||
moves.Add(57);
|
||||
}
|
||||
private static void AddMovesTutor2(List<int> moves, int species, int format, bool korean = false)
|
||||
{
|
||||
if (korean)
|
||||
return;
|
||||
var pi = PersonalTable.C[species];
|
||||
moves.AddRange(Tutors_GSC.Where((_, i) => pi.TMHM[57 + i]));
|
||||
AddMovesTutor1(moves, species, format);
|
||||
}
|
||||
private static void AddMovesTutor3(List<int> moves, int species)
|
||||
{
|
||||
// E Tutors (Free)
|
||||
// E Tutors (BP)
|
||||
var pi = PersonalTable.E[species];
|
||||
moves.AddRange(Tutor_E.Where((_, i) => pi.TypeTutors[i]));
|
||||
// FRLG Tutors
|
||||
// Only special tutor moves, normal tutor moves are already included in Emerald data
|
||||
moves.AddRange(SpecialTutors_FRLG.Where((_, i) => SpecialTutors_Compatibility_FRLG[i] == species));
|
||||
// XD
|
||||
moves.AddRange(SpecialTutors_XD_Exclusive.Where((_, i) => SpecialTutors_Compatibility_XD_Exclusive[i].Any(e => e == species)));
|
||||
// XD (Mew)
|
||||
if (species == 151)
|
||||
moves.AddRange(Tutor_3Mew);
|
||||
}
|
||||
private static void AddMovesTutor4(List<int> moves, int species, int form)
|
||||
{
|
||||
var pi = PersonalTable.HGSS.GetFormeEntry(species, form);
|
||||
moves.AddRange(Tutors_4.Where((_, i) => pi.TypeTutors[i]));
|
||||
moves.AddRange(SpecialTutors_4.Where((_, i) => SpecialTutors_Compatibility_4[i].Any(e => e == species)));
|
||||
}
|
||||
private static void AddMovesTutor5(List<int> moves, int species, int form, PKM pkm, bool specialTutors)
|
||||
{
|
||||
var pi = PersonalTable.B2W2[species];
|
||||
moves.AddRange(TypeTutor6.Where((_, i) => pi.TypeTutors[i]));
|
||||
if (pkm.InhabitedGeneration(5) && specialTutors)
|
||||
moves.AddRange(GetTutors(PersonalTable.B2W2.GetFormeEntry(species, form), Tutors_B2W2));
|
||||
}
|
||||
private static void AddMovesTutor6(List<int> moves, int species, int form, PKM pkm, bool specialTutors)
|
||||
{
|
||||
var pi = PersonalTable.AO[species];
|
||||
moves.AddRange(TypeTutor6.Where((_, i) => pi.TypeTutors[i]));
|
||||
if (specialTutors && pkm.HasVisitedORAS())
|
||||
moves.AddRange(GetTutors(PersonalTable.AO.GetFormeEntry(species, form), Tutors_AO));
|
||||
}
|
||||
private static void AddMovesTutor7(List<int> moves, int species, int form, PKM pkm, bool specialTutors)
|
||||
{
|
||||
var pi = PersonalTable.USUM.GetFormeEntry(species, form);
|
||||
moves.AddRange(TypeTutor6.Where((_, i) => pi.TypeTutors[i]));
|
||||
if (specialTutors && pkm.HasVisitedUSUM())
|
||||
moves.AddRange(GetTutors(PersonalTable.USUM.GetFormeEntry(species, form), Tutors_USUM));
|
||||
}
|
||||
|
||||
private static IEnumerable<int> GetTutors(PersonalInfo pi, params int[][] tutors)
|
||||
{
|
||||
for (int i = 0; i < tutors.Length; i++)
|
||||
for (int b = 0; b < tutors[i].Length; b++)
|
||||
if (pi.SpecialTutors[i][b])
|
||||
yield return tutors[i][b];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -186,12 +186,7 @@ public static partial class Legal
|
||||
307, 308, 338
|
||||
};
|
||||
|
||||
internal static readonly int[][] SpecialTutors_Compatibility_FRLG =
|
||||
{
|
||||
new[] { 6 },
|
||||
new[] { 9 },
|
||||
new[] { 3 },
|
||||
};
|
||||
internal static readonly int[] SpecialTutors_Compatibility_FRLG = { 6, 9, 3 };
|
||||
|
||||
// Tutor moves from XD that can be learned as tutor moves in emerald
|
||||
// For this moves compatibility data is the same in XD and Emerald
|
||||
@@ -230,7 +225,7 @@ public static partial class Legal
|
||||
|
||||
internal static readonly HashSet<int> ValidEggMet_RSE = new HashSet<int>
|
||||
{
|
||||
32, //Route 117
|
||||
32, //Route 117
|
||||
253, //Ingame egg gift
|
||||
255 // event/pokemon box
|
||||
};
|
||||
|
||||
@@ -486,7 +486,7 @@ public static partial class Legal
|
||||
200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232,
|
||||
};
|
||||
|
||||
private static readonly int[] TMHM_SM =
|
||||
internal static readonly int[] TMHM_SM =
|
||||
{
|
||||
526, 337, 473, 347, 046, 092, 258, 339, 474, 237,
|
||||
241, 269, 058, 059, 063, 113, 182, 240, 355, 219,
|
||||
|
||||
Reference in New Issue
Block a user