mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-24 13:03:06 +00:00
Merge pull request #863 from javierhimura/master
Past generations legallity tweaks
This commit is contained in:
commit
d6574706b1
12 changed files with 373 additions and 71 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -40,6 +40,7 @@ local.properties
|
||||||
*.suo
|
*.suo
|
||||||
*.user
|
*.user
|
||||||
*.sln.docstates
|
*.sln.docstates
|
||||||
|
*.vs
|
||||||
|
|
||||||
# Build results
|
# Build results
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ namespace PKHeX.Core
|
||||||
{
|
{
|
||||||
private PKM pkm;
|
private PKM pkm;
|
||||||
private DexLevel[] EvoChain;
|
private DexLevel[] EvoChain;
|
||||||
|
private DexLevel[][] EvoChainsAllGens;
|
||||||
private readonly List<CheckResult> Parse = new List<CheckResult>();
|
private readonly List<CheckResult> Parse = new List<CheckResult>();
|
||||||
|
|
||||||
private object EncounterMatch;
|
private object EncounterMatch;
|
||||||
|
@ -143,6 +144,7 @@ namespace PKHeX.Core
|
||||||
Encounter = verifyEncounter();
|
Encounter = verifyEncounter();
|
||||||
Parse.Add(Encounter);
|
Parse.Add(Encounter);
|
||||||
EvoChain = Legal.getEvolutionChain(pkm, EncounterMatch);
|
EvoChain = Legal.getEvolutionChain(pkm, EncounterMatch);
|
||||||
|
EvoChainsAllGens = Legal.getEvolutionChainsAllGens(pkm, EncounterMatch);
|
||||||
}
|
}
|
||||||
private void updateEncounterInfo()
|
private void updateEncounterInfo()
|
||||||
{
|
{
|
||||||
|
@ -257,7 +259,7 @@ namespace PKHeX.Core
|
||||||
return null;
|
return null;
|
||||||
if (!Parsed)
|
if (!Parsed)
|
||||||
return new int[4];
|
return new int[4];
|
||||||
return Legal.getValidMoves(pkm, EvoChain, Tutor: tutor, Machine: tm, MoveReminder: reminder).Skip(1).ToArray(); // skip move 0
|
return Legal.getValidMoves(pkm, EvoChainsAllGens, Tutor: tutor, Machine: tm, MoveReminder: reminder).Skip(1).ToArray(); // skip move 0
|
||||||
}
|
}
|
||||||
|
|
||||||
public EncounterStatic getSuggestedMetInfo()
|
public EncounterStatic getSuggestedMetInfo()
|
||||||
|
|
|
@ -526,9 +526,9 @@ namespace PKHeX.Core
|
||||||
{
|
{
|
||||||
// Since encounter matching is super weak due to limited stored data in the structure
|
// Since encounter matching is super weak due to limited stored data in the structure
|
||||||
// Calculate all 3 at the same time and pick the best result (by species).
|
// Calculate all 3 at the same time and pick the best result (by species).
|
||||||
var s = Legal.getValidStaticEncounter(pkm);
|
var s = Legal.getValidStaticEncounter(pkm, gen1Encounter: true);
|
||||||
var e = Legal.getValidWildEncounters(pkm);
|
var e = Legal.getValidWildEncounters(pkm);
|
||||||
var t = Legal.getValidIngameTrade(pkm);
|
var t = Legal.getValidIngameTrade(pkm, gen1Encounter: true);
|
||||||
|
|
||||||
const byte invalid = 255;
|
const byte invalid = 255;
|
||||||
|
|
||||||
|
@ -1433,8 +1433,11 @@ namespace PKHeX.Core
|
||||||
resultPrefix = "HT ";
|
resultPrefix = "HT ";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
int[] generations = new int[1] { pkm.Format };
|
||||||
|
if (pkm.GenNumber == 6 && pkm.Format == 7)
|
||||||
|
generations = new int[2] { 6, 7 };
|
||||||
int matchingMoveMemory = Array.IndexOf(Legal.MoveSpecificMemories[0], m);
|
int matchingMoveMemory = Array.IndexOf(Legal.MoveSpecificMemories[0], m);
|
||||||
if (matchingMoveMemory != -1 && pkm.Species != 235 && !Legal.getCanLearnMachineMove(pkm, Legal.MoveSpecificMemories[1][matchingMoveMemory]))
|
if (matchingMoveMemory != -1 && pkm.Species != 235 && !Legal.getCanLearnMachineMove(pkm, Legal.MoveSpecificMemories[1][matchingMoveMemory], generations))
|
||||||
{
|
{
|
||||||
return new CheckResult(Severity.Invalid, resultPrefix + "Memory: Species cannot learn this move.", CheckIdentifier.Memory);
|
return new CheckResult(Severity.Invalid, resultPrefix + "Memory: Species cannot learn this move.", CheckIdentifier.Memory);
|
||||||
}
|
}
|
||||||
|
@ -1444,14 +1447,14 @@ namespace PKHeX.Core
|
||||||
}
|
}
|
||||||
if (m == 21) // {0} saw {2} carrying {1} on its back. {4} that {3}.
|
if (m == 21) // {0} saw {2} carrying {1} on its back. {4} that {3}.
|
||||||
{
|
{
|
||||||
if (!Legal.getCanLearnMachineMove(new PK6 {Species = t, EXP = PKX.getEXP(100, t)}, 19))
|
if (!Legal.getCanLearnMachineMove(new PK6 {Species = t, EXP = PKX.getEXP(100, t)}, 19, generations))
|
||||||
return new CheckResult(Severity.Invalid, resultPrefix + "Memory: Argument Species cannot learn Fly.", CheckIdentifier.Memory);
|
return new CheckResult(Severity.Invalid, resultPrefix + "Memory: Argument Species cannot learn Fly.", CheckIdentifier.Memory);
|
||||||
}
|
}
|
||||||
if ((m == 16 || m == 48) && (t == 0 || !Legal.getCanKnowMove(pkm, t, GameVersion.Any)))
|
if ((m == 16 || m == 48) && (t == 0 || !Legal.getCanKnowMove(pkm, t, generations, GameVersion.Any)))
|
||||||
{
|
{
|
||||||
return new CheckResult(Severity.Invalid, resultPrefix + "Memory: Species cannot know this move.", CheckIdentifier.Memory);
|
return new CheckResult(Severity.Invalid, resultPrefix + "Memory: Species cannot know this move.", CheckIdentifier.Memory);
|
||||||
}
|
}
|
||||||
if (m == 49 && (t == 0 || !Legal.getCanRelearnMove(pkm, t, GameVersion.Any))) // {0} was able to remember {2} at {1}'s instruction. {4} that {3}.
|
if (m == 49 && (t == 0 || !Legal.getCanRelearnMove(pkm, t, generations, GameVersion.Any))) // {0} was able to remember {2} at {1}'s instruction. {4} that {3}.
|
||||||
{
|
{
|
||||||
return new CheckResult(Severity.Invalid, resultPrefix + "Memory: Species cannot relearn this move.", CheckIdentifier.Memory);
|
return new CheckResult(Severity.Invalid, resultPrefix + "Memory: Species cannot relearn this move.", CheckIdentifier.Memory);
|
||||||
}
|
}
|
||||||
|
@ -1897,9 +1900,9 @@ namespace PKHeX.Core
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
res[i] = new CheckResult(CheckIdentifier.Move);
|
res[i] = new CheckResult(CheckIdentifier.Move);
|
||||||
|
|
||||||
var validMoves = Legal.getValidMoves(pkm, EvoChain, Tutor: false, Machine: false).ToArray();
|
var validMoves = Legal.getValidMoves(pkm, EvoChainsAllGens, Tutor: false, Machine: false).ToArray();
|
||||||
var validTMHM = Legal.getValidMoves(pkm, EvoChain, Tutor: false, MoveReminder: false).ToArray();
|
var validTMHM = Legal.getValidMoves(pkm, EvoChainsAllGens, Tutor: false, MoveReminder: false).ToArray();
|
||||||
var validTutor = Legal.getValidMoves(pkm, EvoChain, Machine: false, MoveReminder: false).ToArray();
|
var validTutor = Legal.getValidMoves(pkm, EvoChainsAllGens, Machine: false, MoveReminder: false).ToArray();
|
||||||
if (pkm.Species == 235) // Smeargle
|
if (pkm.Species == 235) // Smeargle
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
|
|
|
@ -192,12 +192,19 @@ namespace PKHeX.Core
|
||||||
}
|
}
|
||||||
|
|
||||||
// Moves
|
// Moves
|
||||||
internal static IEnumerable<int> getValidMoves(PKM pkm, IEnumerable<DexLevel> evoChain, bool Tutor = true, bool Machine = true, bool MoveReminder = true)
|
internal static IEnumerable<int> getValidMoves(PKM pkm, DexLevel[][] evoChains, bool Tutor = true, bool Machine = true, bool MoveReminder = true)
|
||||||
{
|
{
|
||||||
GameVersion version = (GameVersion)pkm.Version;
|
GameVersion version = (GameVersion)pkm.Version;
|
||||||
if (!pkm.IsUntraded)
|
if (!pkm.IsUntraded)
|
||||||
version = GameVersion.Any;
|
version = GameVersion.Any;
|
||||||
return getValidMoves(pkm, version, evoChain, LVL: true, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder);
|
return getValidMoves(pkm, version, evoChains, LVL: true, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder);
|
||||||
|
}
|
||||||
|
internal static IEnumerable<int> getValidMoves(PKM pkm, IEnumerable<DexLevel> evoChain,int generation, bool Tutor = true, bool Machine = true, bool MoveReminder = true)
|
||||||
|
{
|
||||||
|
GameVersion version = (GameVersion)pkm.Version;
|
||||||
|
if (!pkm.IsUntraded)
|
||||||
|
version = GameVersion.Any;
|
||||||
|
return getValidMoves(pkm, version, evoChain, generation,LVL: true, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder);
|
||||||
}
|
}
|
||||||
internal static IEnumerable<int> getValidRelearn(PKM pkm, int skipOption)
|
internal static IEnumerable<int> getValidRelearn(PKM pkm, int skipOption)
|
||||||
{
|
{
|
||||||
|
@ -269,10 +276,14 @@ namespace PKHeX.Core
|
||||||
s.AddRange(getValidEncounterSlots(pkm, area, DexNav: pkm.AO));
|
s.AddRange(getValidEncounterSlots(pkm, area, DexNav: pkm.AO));
|
||||||
return s.Any() ? s.ToArray() : null;
|
return s.Any() ? s.ToArray() : null;
|
||||||
}
|
}
|
||||||
internal static EncounterStatic getValidStaticEncounter(PKM pkm)
|
internal static EncounterStatic getValidStaticEncounter(PKM pkm, bool gen1Encounter = false)
|
||||||
{
|
{
|
||||||
// Get possible encounters
|
// Get possible encounters
|
||||||
IEnumerable<EncounterStatic> poss = getStaticEncounters(pkm);
|
IEnumerable<EncounterStatic> poss = getStaticEncounters(pkm);
|
||||||
|
|
||||||
|
int lvl = (pkm.HasOriginalMetLocation) ? pkm.Met_Level : getMaxLevelGeneration(pkm);
|
||||||
|
if (lvl <= 0)
|
||||||
|
return null; ;
|
||||||
// Back Check against pkm
|
// Back Check against pkm
|
||||||
foreach (EncounterStatic e in poss)
|
foreach (EncounterStatic e in poss)
|
||||||
{
|
{
|
||||||
|
@ -284,7 +295,12 @@ namespace PKHeX.Core
|
||||||
{
|
{
|
||||||
if (e.Location != 0 && e.Location != pkm.Met_Location)
|
if (e.Location != 0 && e.Location != pkm.Met_Location)
|
||||||
continue;
|
continue;
|
||||||
if (e.Level != pkm.Met_Level)
|
if (e.Level != lvl)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (e.Level > lvl)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (e.Gender != -1 && e.Gender != pkm.Gender)
|
if (e.Gender != -1 && e.Gender != pkm.Gender)
|
||||||
|
@ -305,7 +321,7 @@ namespace PKHeX.Core
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
internal static EncounterTrade getValidIngameTrade(PKM pkm)
|
internal static EncounterTrade getValidIngameTrade(PKM pkm, bool gen1Encounter = false)
|
||||||
{
|
{
|
||||||
if (!pkm.WasIngameTrade)
|
if (!pkm.WasIngameTrade)
|
||||||
return null;
|
return null;
|
||||||
|
@ -313,6 +329,9 @@ namespace PKHeX.Core
|
||||||
if (lang == 0 || lang == 6)
|
if (lang == 0 || lang == 6)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
int lvl = (pkm.HasOriginalMetLocation) ? pkm.Met_Level : getMaxLevelGeneration(pkm);
|
||||||
|
if (lvl <= 0)
|
||||||
|
return null;
|
||||||
// Get valid pre-evolutions
|
// Get valid pre-evolutions
|
||||||
IEnumerable<DexLevel> p = getValidPreEvolutions(pkm);
|
IEnumerable<DexLevel> p = getValidPreEvolutions(pkm);
|
||||||
|
|
||||||
|
@ -343,7 +362,9 @@ namespace PKHeX.Core
|
||||||
return null;
|
return null;
|
||||||
if (pkm.HasOriginalMetLocation && z.Location != pkm.Met_Location)
|
if (pkm.HasOriginalMetLocation && z.Location != pkm.Met_Location)
|
||||||
return null;
|
return null;
|
||||||
if (z.Level != pkm.Met_Level)
|
if (pkm.HasOriginalMetLocation && z.Level != lvl)
|
||||||
|
return null;
|
||||||
|
if (!pkm.HasOriginalMetLocation && z.Level > lvl)
|
||||||
return null;
|
return null;
|
||||||
if (z.Nature != Nature.Random && (int)z.Nature != pkm.Nature)
|
if (z.Nature != Nature.Random && (int)z.Nature != pkm.Nature)
|
||||||
return null;
|
return null;
|
||||||
|
@ -415,6 +436,19 @@ namespace PKHeX.Core
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static int[] getFutureGenEvolutions(int generation)
|
||||||
|
{
|
||||||
|
switch (generation)
|
||||||
|
{
|
||||||
|
case 1: return FutureEvolutionsGen1;
|
||||||
|
case 2: return FutureEvolutionsGen2;
|
||||||
|
case 3: return FutureEvolutionsGen3;
|
||||||
|
case 4: return FutureEvolutionsGen4;
|
||||||
|
case 5: return FutureEvolutionsGen5;
|
||||||
|
default: return new int[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal static int getMaxSpeciesOrigin(PKM pkm)
|
internal static int getMaxSpeciesOrigin(PKM pkm)
|
||||||
{
|
{
|
||||||
if (pkm.Format == 1 || pkm.VC1) // Gen1 VC could not trade with gen 2 yet
|
if (pkm.Format == 1 || pkm.VC1) // Gen1 VC could not trade with gen 2 yet
|
||||||
|
@ -705,25 +739,52 @@ namespace PKHeX.Core
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static bool getCanLearnMachineMove(PKM pkm, int move, GameVersion version = GameVersion.Any)
|
internal static bool getCanLearnMachineMove(PKM pkm, int move, int[] generations, GameVersion version = GameVersion.Any)
|
||||||
{
|
{
|
||||||
return getValidMoves(pkm, version, getValidPreEvolutions(pkm), Machine: true).Contains(move);
|
foreach (int generation in generations)
|
||||||
|
if (getCanLearnMachineMove(pkm, generation, move, version))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
internal static bool getCanRelearnMove(PKM pkm, int move, GameVersion version = GameVersion.Any)
|
internal static bool getCanRelearnMove(PKM pkm,int move, int[] generations, GameVersion version = GameVersion.Any)
|
||||||
{
|
{
|
||||||
return getValidMoves(pkm, version, getValidPreEvolutions(pkm), LVL: true, Relearn: true).Contains(move);
|
foreach (int generation in generations)
|
||||||
|
if (getCanRelearnMove(pkm, move, generation, version))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
internal static bool getCanLearnMove(PKM pkm, int move, GameVersion version = GameVersion.Any)
|
internal static bool getCanLearnMove(PKM pkm, int move, int[] generations, GameVersion version = GameVersion.Any)
|
||||||
{
|
{
|
||||||
return getValidMoves(pkm, version, getValidPreEvolutions(pkm), Tutor: true, Machine: true).Contains(move);
|
foreach (int generation in generations)
|
||||||
|
if (getCanLearnMove(pkm, move, generation, version))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
internal static bool getCanKnowMove(PKM pkm, int move, GameVersion version = GameVersion.Any)
|
internal static bool getCanKnowMove(PKM pkm, int move, int[] generations, GameVersion version = GameVersion.Any)
|
||||||
|
{
|
||||||
|
foreach (int generation in generations)
|
||||||
|
if (getCanKnowMove(pkm, move, generation, version))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
internal static bool getCanLearnMachineMove(PKM pkm,int move, int generation, GameVersion version = GameVersion.Any)
|
||||||
|
{
|
||||||
|
return getValidMoves(pkm, version, getValidPreEvolutions(pkm), generation, Machine: true).Contains(move);
|
||||||
|
}
|
||||||
|
internal static bool getCanRelearnMove(PKM pkm, int move, int generation, GameVersion version = GameVersion.Any)
|
||||||
|
{
|
||||||
|
return getValidMoves(pkm, version, getValidPreEvolutions(pkm), generation, LVL: true, Relearn: true).Contains(move);
|
||||||
|
}
|
||||||
|
internal static bool getCanLearnMove(PKM pkm,int move, int generation, GameVersion version = GameVersion.Any)
|
||||||
|
{
|
||||||
|
return getValidMoves(pkm, version, getValidPreEvolutions(pkm), generation, Tutor: true, Machine: true).Contains(move);
|
||||||
|
}
|
||||||
|
internal static bool getCanKnowMove(PKM pkm,int move, int generation, GameVersion version = GameVersion.Any)
|
||||||
{
|
{
|
||||||
if (pkm.Species == 235 && !InvalidSketch.Contains(move))
|
if (pkm.Species == 235 && !InvalidSketch.Contains(move))
|
||||||
return true;
|
return true;
|
||||||
return getValidMoves(pkm, Version: version, vs: getValidPreEvolutions(pkm), LVL: true, Relearn: true, Tutor: true, Machine: true).Contains(move);
|
return getValidMoves(pkm, version,getValidPreEvolutions(pkm), generation, LVL: true, Relearn: true, Tutor: true, Machine: true).Contains(move);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static int getBaseSpecies(PKM pkm, int skipOption = 0)
|
internal static int getBaseSpecies(PKM pkm, int skipOption = 0)
|
||||||
{
|
{
|
||||||
if (pkm.Species == 292)
|
if (pkm.Species == 292)
|
||||||
|
@ -741,10 +802,131 @@ namespace PKHeX.Core
|
||||||
default: return evos.Length <= 0 ? pkm.Species : evos.Last().Species;
|
default: return evos.Length <= 0 ? pkm.Species : evos.Last().Species;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
internal static int getMaxLevelGeneration(PKM pkm)
|
||||||
|
{
|
||||||
|
return getMaxLevelGeneration(pkm, pkm.GenNumber);
|
||||||
|
}
|
||||||
|
internal static int getMaxLevelGeneration(PKM pkm, int generation)
|
||||||
|
{
|
||||||
|
if (!pkm.InhabitedGeneration(generation))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (pkm.Format <= 2)
|
||||||
|
{
|
||||||
|
if (generation == 1 && FutureEvolutionsGen1_Gen2LevelUp.Contains(pkm.Species))
|
||||||
|
return pkm.CurrentLevel - 1;
|
||||||
|
return pkm.CurrentLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pkm.Species == 700 && generation == 5)
|
||||||
|
return pkm.CurrentLevel - 1;
|
||||||
|
|
||||||
|
if (pkm.Gen3 && pkm.Format > 4 && pkm.Met_Level == pkm.CurrentLevel && FutureEvolutionsGen3_LevelUp.Contains(pkm.Species))
|
||||||
|
return pkm.Met_Level - 1;
|
||||||
|
|
||||||
|
if(!pkm.HasOriginalMetLocation)
|
||||||
|
return pkm.Met_Level;
|
||||||
|
|
||||||
|
return pkm.CurrentLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static int getMinLevelGeneration(PKM pkm)
|
||||||
|
{
|
||||||
|
return getMinLevelGeneration(pkm, pkm.GenNumber);
|
||||||
|
}
|
||||||
|
internal static int getMinLevelGeneration(PKM pkm, int generation)
|
||||||
|
{
|
||||||
|
if (!pkm.InhabitedGeneration(generation))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (pkm.Format <= 2)
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
if(!pkm.HasOriginalMetLocation)
|
||||||
|
return pkm.Met_Level;
|
||||||
|
|
||||||
|
if (pkm.GenNumber <= 3)
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
internal static DexLevel[][] getEvolutionChainsAllGens(PKM pkm, object Encounter)
|
||||||
|
{
|
||||||
|
IEnumerable<DexLevel> CompleteEvoChain = getEvolutionChain(pkm, Encounter);
|
||||||
|
DexLevel[][] GensEvoChains = new DexLevel[8][];
|
||||||
|
for (int gen = 1; gen <= 7; gen++)
|
||||||
|
GensEvoChains[gen] = new DexLevel[0];
|
||||||
|
|
||||||
|
if((pkm.Format >2 && pkm.GenU) || pkm.Species==0)//Illegal origin or empty pokemon, return only chain for current format
|
||||||
|
{
|
||||||
|
GensEvoChains[pkm.Format] = CompleteEvoChain.ToArray();
|
||||||
|
return GensEvoChains;
|
||||||
|
}
|
||||||
|
//If is egg skip the other checks and just return the evo chain for GenNumber, that will contains only the pokemon inside the egg
|
||||||
|
//Empty list returned if is an impossible egg (like a gen 3 infernape inside an egg)
|
||||||
|
if (pkm.IsEgg && getMaxSpeciesOrigin(pkm.GenNumber) > pkm.Species)
|
||||||
|
return GensEvoChains;
|
||||||
|
else if (pkm.IsEgg)
|
||||||
|
{
|
||||||
|
GensEvoChains[pkm.GenNumber] = CompleteEvoChain.ToArray();
|
||||||
|
return GensEvoChains;
|
||||||
|
}
|
||||||
|
|
||||||
|
int currengenlevel = pkm.CurrentLevel;
|
||||||
|
int maxgen = (pkm.Format <= 2) ? 2 : pkm.Format;
|
||||||
|
int mingen = (pkm.VC2 || pkm.Format <= 2) ? 1 : pkm.GenNumber;
|
||||||
|
//Iterate generations backwards because level will be decreased from current level in each generation
|
||||||
|
for (int gen = maxgen; gen >= mingen; gen--)
|
||||||
|
{
|
||||||
|
if ((pkm.Gen1 || pkm.VC1) && pkm.Format >2 && 2 <= gen && gen <= 6)
|
||||||
|
continue;
|
||||||
|
if ((pkm.Gen2 || pkm.VC2) && 3 <= gen && gen <= 6)
|
||||||
|
continue;
|
||||||
|
if (!pkm.HasOriginalMetLocation && pkm.Format >2 && gen <= 4 && currengenlevel > pkm.Met_Level)
|
||||||
|
//Met location was lost at this point but it also means the pokemon existed in generations 1 to 4 with maximun level equals to met level
|
||||||
|
currengenlevel = pkm.Met_Level;
|
||||||
|
int maxspeciesgen = getMaxSpeciesOrigin(gen);
|
||||||
|
//Remove future gen evolutions after a few special considerations,
|
||||||
|
//it the pokemon origin is illegal like a "gen 3" Infernape the list will be emptied, it didnt existed in gen 3 in any evolution phase
|
||||||
|
while (CompleteEvoChain.Any() && CompleteEvoChain.First().Species > maxspeciesgen)
|
||||||
|
{
|
||||||
|
//Eeve requieres to level one time to be Sylveon, it can be deduced in gen 5 and before it existed with maximun one level bellow current
|
||||||
|
if (CompleteEvoChain.First().Species == 700 && gen == 5)
|
||||||
|
currengenlevel--;
|
||||||
|
//This is a gen 3 pokemon in a gen 4 phase evolution that requieres level up and then transfered to gen 5,6 or 7
|
||||||
|
//We can deduce that it existed in gen 4 until met level,
|
||||||
|
//but if current level is met level we can also deduce it existed in gen 3 until maximun met level -1
|
||||||
|
if (gen == 3 && pkm.Format>4 && currengenlevel == pkm.CurrentLevel && CompleteEvoChain.First().Species > MaxSpeciesID_3 && CompleteEvoChain.First().RequiresLvlUp)
|
||||||
|
currengenlevel--;
|
||||||
|
//The same condition for gen2 evolution of gen 1 pokemon, level of the pokemon in gen 1 games would be CurrentLevel -1 one level bellow gen 2 level
|
||||||
|
if (gen == 1 && pkm.Format == 2 && currengenlevel == pkm.CurrentLevel && CompleteEvoChain.First().Species > MaxSpeciesID_1 && CompleteEvoChain.First().RequiresLvlUp)
|
||||||
|
currengenlevel--;
|
||||||
|
CompleteEvoChain = CompleteEvoChain.Skip(1);
|
||||||
|
};
|
||||||
|
//Alolan form evolutions, remove from gens 1-6 chains
|
||||||
|
if (gen < 7 && pkm.Format >= 7 && CompleteEvoChain.Any() && CompleteEvoChain.First().Form > 0 && EvolveToAlolanForms.Contains(CompleteEvoChain.First().Species))
|
||||||
|
CompleteEvoChain = CompleteEvoChain.Skip(1);
|
||||||
|
|
||||||
|
if(CompleteEvoChain.Any())
|
||||||
|
{
|
||||||
|
GensEvoChains[gen] = getEvolutionChain(pkm, Encounter, CompleteEvoChain.First().Species, currengenlevel);
|
||||||
|
if (!pkm.HasOriginalMetLocation && gen >= pkm.GenNumber )
|
||||||
|
//Remove previous evolutions bellow transfer level
|
||||||
|
//For example a gen3 charizar in format 7 with current level 36 and met level 36
|
||||||
|
//chain level for charmander is 35, is bellow met level
|
||||||
|
GensEvoChains[gen] = GensEvoChains[gen].Where(e => e.Level >= currengenlevel).ToArray();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return GensEvoChains;
|
||||||
|
}
|
||||||
internal static DexLevel[] getEvolutionChain(PKM pkm, object Encounter)
|
internal static DexLevel[] getEvolutionChain(PKM pkm, object Encounter)
|
||||||
|
{
|
||||||
|
return getEvolutionChain(pkm, Encounter,pkm.Species, 100);
|
||||||
|
}
|
||||||
|
internal static DexLevel[] getEvolutionChain(PKM pkm, object Encounter,int maxspec, int maxlevel)
|
||||||
{
|
{
|
||||||
int minspec;
|
int minspec;
|
||||||
var vs = getValidPreEvolutions(pkm).ToArray();
|
DexLevel[] vs = getValidPreEvolutions(pkm).ToArray();
|
||||||
|
|
||||||
// Evolution chain is in reverse order (devolution)
|
// Evolution chain is in reverse order (devolution)
|
||||||
|
|
||||||
|
@ -757,8 +939,29 @@ namespace PKHeX.Core
|
||||||
else
|
else
|
||||||
minspec = vs.Last().Species;
|
minspec = vs.Last().Species;
|
||||||
|
|
||||||
int index = Math.Max(0, Array.FindIndex(vs, p => p.Species == minspec));
|
int minindex = Math.Max(0, Array.FindIndex(vs, p => p.Species == minspec));
|
||||||
Array.Resize(ref vs, index + 1);
|
Array.Resize(ref vs, minindex + 1);
|
||||||
|
if(vs.Last().MinLevel > 1) //Last entry from vs is removed, turn next entry into the wild/hatched pokemon
|
||||||
|
{
|
||||||
|
vs.Last().MinLevel = 1;
|
||||||
|
vs.Last().RequiresLvlUp = false;
|
||||||
|
if (vs.First().MinLevel == 2 && !vs.First().RequiresLvlUp)
|
||||||
|
{
|
||||||
|
//Example Raichu in gen 2 or later,
|
||||||
|
//because Pichu requires level up minimun level of Raichu would be 2
|
||||||
|
//but after removing Pichu because the origin species is Pikachu, Raichu min level should be 1
|
||||||
|
vs.First().MinLevel = 1;
|
||||||
|
vs.First().RequiresLvlUp = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Maxspec is used to remove future gen evolutions, to gather evolution chain of a pokemon in previous generations
|
||||||
|
int skip = Math.Max(0, Array.FindIndex(vs, p => p.Species == maxspec));
|
||||||
|
//Maxlevel is also used for previous generations, it removes evolutions imposible before the transfer level
|
||||||
|
//For example a fire red charizard whose current level in XY is 50 but met level is 20, it couldnt be a Charizard in gen 3 and 4 games
|
||||||
|
vs = vs.Skip(skip).Where(e=>e.MinLevel <= maxlevel).ToArray();
|
||||||
|
//Reduce the evolution chain levels to max level, because met level is the last one when the pokemon could be and learn moves in that generation
|
||||||
|
foreach (DexLevel d in vs)
|
||||||
|
d.Level = Math.Min(d.Level, maxlevel);
|
||||||
return vs;
|
return vs;
|
||||||
}
|
}
|
||||||
internal static string getEncounterTypeName(PKM pkm, object Encounter)
|
internal static string getEncounterTypeName(PKM pkm, object Encounter)
|
||||||
|
@ -887,27 +1090,34 @@ namespace PKHeX.Core
|
||||||
bool ignoreSlotLevel = ignoreLevel;
|
bool ignoreSlotLevel = ignoreLevel;
|
||||||
IEnumerable<EncounterSlot> slots = loc.Slots.Where(slot => vs.Any(evo => evo.Species == slot.Species && (ignoreSlotLevel || evo.Level >= slot.LevelMin - df)));
|
IEnumerable<EncounterSlot> slots = loc.Slots.Where(slot => vs.Any(evo => evo.Species == slot.Species && (ignoreSlotLevel || evo.Level >= slot.LevelMin - df)));
|
||||||
|
|
||||||
if (pkm.Format < 3 || pkm.VC)
|
int lvl = (pkm.HasOriginalMetLocation) ? pkm.Met_Level: getMaxLevelGeneration(pkm);
|
||||||
return slots; // no met level or special encounter considerations
|
if (lvl <= 0)
|
||||||
|
return slotdata;
|
||||||
// Filter for Met Level
|
|
||||||
int lvl = pkm.Met_Level;
|
|
||||||
int gen = pkm.GenNumber;
|
int gen = pkm.GenNumber;
|
||||||
bool ignoreMetLevel = ignoreLevel || gen <= 4 && pkm.Format != gen;
|
IEnumerable<EncounterSlot> encounterSlots;
|
||||||
var encounterSlots = slots.Where(slot => ignoreMetLevel || slot.LevelMin - df <= lvl && lvl <= slot.LevelMax + (slot.AllowDexNav ? dn : df)).ToList();
|
if(pkm.HasOriginalMetLocation)
|
||||||
|
encounterSlots = slots.Where(slot => ignoreLevel || slot.LevelMin - df <= lvl && lvl <= slot.LevelMax + (slot.AllowDexNav ? dn : df)).ToList();
|
||||||
|
else
|
||||||
|
//Those encounters with level min greater that met level are not valid for this pokemon
|
||||||
|
encounterSlots = slots.Where(slot => ignoreLevel || slot.LevelMin <= lvl).ToList();
|
||||||
|
|
||||||
|
if(gen <= 2)
|
||||||
|
{
|
||||||
|
//For gen 1 and 2 return minimun level slot
|
||||||
|
//Minimun level is needed to check available moves, because there is no move reminder in gen 1,
|
||||||
|
//There are moves in the level up table that cant be legally obtained
|
||||||
|
EncounterSlot slotMin = encounterSlots.OrderBy(slot => slot.LevelMin).FirstOrDefault();
|
||||||
|
if (slotMin != null)
|
||||||
|
slotdata.Add(slotMin);
|
||||||
|
return slotdata;
|
||||||
|
}
|
||||||
|
|
||||||
// Pressure Slot
|
// Pressure Slot
|
||||||
EncounterSlot slotMax = encounterSlots.OrderByDescending(slot => slot.LevelMax).FirstOrDefault();
|
EncounterSlot slotMax = encounterSlots.OrderByDescending(slot => slot.LevelMax).FirstOrDefault();
|
||||||
if (slotMax != null)
|
if (slotMax != null)
|
||||||
slotMax = new EncounterSlot(slotMax) { Pressure = true, Form = pkm.AltForm };
|
slotMax = new EncounterSlot(slotMax) { Pressure = true, Form = pkm.AltForm };
|
||||||
|
|
||||||
if (gen < 4)
|
if (gen >= 6 && !DexNav)
|
||||||
{
|
|
||||||
if (slotMax != null)
|
|
||||||
slotdata.Add(slotMax);
|
|
||||||
return slotdata;
|
|
||||||
}
|
|
||||||
if (!DexNav)
|
|
||||||
{
|
{
|
||||||
// Filter for Form Specific
|
// Filter for Form Specific
|
||||||
slotdata.AddRange(WildForms.Contains(pkm.Species)
|
slotdata.AddRange(WildForms.Contains(pkm.Species)
|
||||||
|
@ -919,6 +1129,11 @@ namespace PKHeX.Core
|
||||||
}
|
}
|
||||||
|
|
||||||
List<EncounterSlot> eslots = encounterSlots.Where(slot => !WildForms.Contains(pkm.Species) || slot.Form == pkm.AltForm).ToList();
|
List<EncounterSlot> eslots = encounterSlots.Where(slot => !WildForms.Contains(pkm.Species) || slot.Form == pkm.AltForm).ToList();
|
||||||
|
if(gen <= 5)
|
||||||
|
{
|
||||||
|
slotdata.AddRange(eslots);
|
||||||
|
return slotdata;
|
||||||
|
}
|
||||||
if (slotMax != null)
|
if (slotMax != null)
|
||||||
eslots.Add(slotMax);
|
eslots.Add(slotMax);
|
||||||
foreach (EncounterSlot s in eslots)
|
foreach (EncounterSlot s in eslots)
|
||||||
|
@ -957,13 +1172,13 @@ namespace PKHeX.Core
|
||||||
if (lvl == 1 && pkm.IsEgg)
|
if (lvl == 1 && pkm.IsEgg)
|
||||||
return new List<DexLevel>
|
return new List<DexLevel>
|
||||||
{
|
{
|
||||||
new DexLevel { Species = pkm.Species, Level = 1 },
|
new DexLevel { Species = pkm.Species, Level = 1, MinLevel = 1 },
|
||||||
};
|
};
|
||||||
if (pkm.Species == 292 && pkm.Met_Level + 1 <= lvl && lvl >= 20)
|
if (pkm.Species == 292 && lvl >= 20 && (!pkm.HasOriginalMetLocation || pkm.Met_Level + 1 <= lvl))
|
||||||
return new List<DexLevel>
|
return new List<DexLevel>
|
||||||
{
|
{
|
||||||
new DexLevel { Species = 292, Level = lvl },
|
new DexLevel { Species = 292, Level = lvl, MinLevel =20 },
|
||||||
new DexLevel { Species = 290, Level = lvl-1 }
|
new DexLevel { Species = 290, Level = lvl-1, MinLevel = 1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
var et = getEvolutionTable(pkm);
|
var et = getEvolutionTable(pkm);
|
||||||
|
@ -974,11 +1189,22 @@ namespace PKHeX.Core
|
||||||
IEnumerable<DexLevel> dl = getValidPreEvolutions(pkm, lvl);
|
IEnumerable<DexLevel> dl = getValidPreEvolutions(pkm, lvl);
|
||||||
return table.Where(e => dl.Any(d => d.Species == e.Species));
|
return table.Where(e => dl.Any(d => d.Species == e.Species));
|
||||||
}
|
}
|
||||||
private static IEnumerable<int> getValidMoves(PKM pkm, GameVersion Version, IEnumerable<DexLevel> vs, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false, bool MoveReminder = true)
|
private static IEnumerable<int> getValidMoves(PKM pkm, GameVersion Version, DexLevel[][] vs, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false, bool MoveReminder = true)
|
||||||
{
|
{
|
||||||
List<int> r = new List<int> { 0 };
|
List<int> r = new List<int> { 0 };
|
||||||
|
for(int gen =1;gen<=7;gen++)
|
||||||
|
{
|
||||||
|
if (vs[gen].Any())
|
||||||
|
r.AddRange(getValidMoves(pkm, Version, vs[gen], gen, LVL, Tutor, Machine, MoveReminder));
|
||||||
|
}
|
||||||
|
return r.Distinct().ToArray();
|
||||||
|
}
|
||||||
|
private static IEnumerable<int> getValidMoves(PKM pkm, GameVersion Version, IEnumerable<DexLevel> vs, int Generation, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false, bool MoveReminder = true)
|
||||||
|
{
|
||||||
|
List<int> r = new List<int> { 0 };
|
||||||
|
if (!vs.Any())
|
||||||
|
return r;
|
||||||
int species = pkm.Species;
|
int species = pkm.Species;
|
||||||
int lvl = pkm.CurrentLevel;
|
|
||||||
|
|
||||||
// Special Type Tutors Availability
|
// Special Type Tutors Availability
|
||||||
bool moveTutor = Tutor || MoveReminder; // Usually true, except when called for move suggestions (no tutored moves)
|
bool moveTutor = Tutor || MoveReminder; // Usually true, except when called for move suggestions (no tutored moves)
|
||||||
|
@ -987,33 +1213,32 @@ namespace PKHeX.Core
|
||||||
{
|
{
|
||||||
int formcount = pkm.PersonalInfo.FormeCount;
|
int formcount = pkm.PersonalInfo.FormeCount;
|
||||||
for (int i = 0; i < formcount; i++)
|
for (int i = 0; i < formcount; i++)
|
||||||
r.AddRange(getMoves(pkm, species, lvl, i, moveTutor, Version, LVL, Tutor, Machine, MoveReminder));
|
r.AddRange(getMoves(pkm, species, vs.First().Level, i, moveTutor, Version, LVL, Tutor, Machine, Generation, MoveReminder));
|
||||||
if (Relearn) r.AddRange(pkm.RelearnMoves);
|
if (Relearn) r.AddRange(pkm.RelearnMoves);
|
||||||
return r.Distinct().ToArray();
|
return r.Distinct().ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
r.AddRange(getMoves(pkm, species, lvl, pkm.AltForm, moveTutor, Version, LVL, Tutor, Machine, MoveReminder));
|
|
||||||
|
|
||||||
foreach (DexLevel evo in vs)
|
foreach (DexLevel evo in vs)
|
||||||
r.AddRange(getMoves(pkm, evo.Species, evo.Level, pkm.AltForm, moveTutor, Version, LVL, Tutor, Machine, MoveReminder));
|
r.AddRange(getMoves(pkm, evo.Species, evo.Level, pkm.AltForm, moveTutor, Version, LVL, Tutor, Machine, Generation, MoveReminder));
|
||||||
|
|
||||||
if (pkm.Format <= 3)
|
if (pkm.Format <= 3)
|
||||||
return r.Distinct().ToArray();
|
return r.Distinct().ToArray();
|
||||||
|
if (LVL)
|
||||||
|
{
|
||||||
|
if (species == 479 && Generation >= 4) // Rotom
|
||||||
|
r.Add(RotomMoves[pkm.AltForm]);
|
||||||
|
if (species == 648 && Generation >= 5) // Meloetta
|
||||||
|
r.Add(547); // Relic Song
|
||||||
|
|
||||||
if (species == 479) // Rotom
|
if (species == 25 && pkm.Format == 6 && Generation == 6) // Pikachu
|
||||||
r.Add(RotomMoves[pkm.AltForm]);
|
r.Add(PikachuMoves[pkm.AltForm]);
|
||||||
if (species == 648) // Meloetta
|
|
||||||
r.Add(547); // Relic Song
|
|
||||||
|
|
||||||
if (species == 25 && pkm.Format == 6 && pkm.GenNumber == 6) // Pikachu
|
if (species == 718 && Generation == 7) // Zygarde
|
||||||
r.Add(PikachuMoves[pkm.AltForm]);
|
r.AddRange(ZygardeMoves);
|
||||||
|
}
|
||||||
if (species == 718 && pkm.GenNumber == 7) // Zygarde
|
if ((species == 25 || species == 26) && Generation == 7 && moveTutor) // Pikachu/Raichu Tutor
|
||||||
r.AddRange(ZygardeMoves);
|
|
||||||
if ((species == 25 || species == 26) && pkm.Format == 7) // Pikachu/Raichu Tutor
|
|
||||||
r.Add(344); // Volt Tackle
|
r.Add(344); // Volt Tackle
|
||||||
|
if (Relearn && Generation >= 6) r.AddRange(pkm.RelearnMoves);
|
||||||
if (Relearn) r.AddRange(pkm.RelearnMoves);
|
|
||||||
return r.Distinct().ToArray();
|
return r.Distinct().ToArray();
|
||||||
}
|
}
|
||||||
private static IEnumerable<int> getMoves(PKM pkm, int species, int lvl, int form, bool moveTutor, GameVersion Version, bool LVL, bool specialTutors, bool Machine, bool MoveReminder)
|
private static IEnumerable<int> getMoves(PKM pkm, int species, int lvl, int form, bool moveTutor, GameVersion Version, bool LVL, bool specialTutors, bool Machine, bool MoveReminder)
|
||||||
|
@ -1043,6 +1268,8 @@ namespace PKHeX.Core
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
|
if (species > MaxSpeciesID_1)//Sanity check
|
||||||
|
return r;
|
||||||
var pi_rb = (PersonalInfoG1)PersonalTable.RB[species];
|
var pi_rb = (PersonalInfoG1)PersonalTable.RB[species];
|
||||||
var pi_y = (PersonalInfoG1)PersonalTable.Y[species];
|
var pi_y = (PersonalInfoG1)PersonalTable.Y[species];
|
||||||
if (LVL)
|
if (LVL)
|
||||||
|
|
|
@ -4,12 +4,14 @@
|
||||||
{
|
{
|
||||||
public int Species;
|
public int Species;
|
||||||
public int Level;
|
public int Level;
|
||||||
|
public int MinLevel;
|
||||||
|
public bool RequiresLvlUp;
|
||||||
public int Form = -1;
|
public int Form = -1;
|
||||||
public int Flag = -1;
|
public int Flag = -1;
|
||||||
|
|
||||||
public DexLevel Copy(int lvl)
|
public DexLevel Copy(int lvl)
|
||||||
{
|
{
|
||||||
return new DexLevel {Species = Species, Level = lvl, Form = Form, Flag = -1};
|
return new DexLevel {Species = Species, Level = lvl, MinLevel = MinLevel, RequiresLvlUp = RequiresLvlUp, Form = Form, Flag = -1};
|
||||||
}
|
}
|
||||||
public bool Matches(int species, int form)
|
public bool Matches(int species, int form)
|
||||||
{
|
{
|
||||||
|
|
|
@ -153,7 +153,7 @@ namespace PKHeX.Core
|
||||||
|
|
||||||
return Personal.getFormeIndex(evolvesToSpecies, evolvesToForm);
|
return Personal.getFormeIndex(evolvesToSpecies, evolvesToForm);
|
||||||
}
|
}
|
||||||
public IEnumerable<DexLevel> getValidPreEvolutions(PKM pkm, int lvl, bool skipChecks = false)
|
public IEnumerable<DexLevel> getValidPreEvolutions(PKM pkm, int lvl,bool skipChecks = false)
|
||||||
{
|
{
|
||||||
int index = getIndex(pkm);
|
int index = getIndex(pkm);
|
||||||
int maxSpeciesOrigin = Legal.getMaxSpeciesOrigin(pkm);
|
int maxSpeciesOrigin = Legal.getMaxSpeciesOrigin(pkm);
|
||||||
|
@ -416,6 +416,25 @@ namespace PKHeX.Core
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
oneValid = true;
|
oneValid = true;
|
||||||
|
if (evo.Level == 0 && !evo.RequiresLevelUp) //Evolutions like elemental stones, trade, etc
|
||||||
|
{
|
||||||
|
dl.Last().MinLevel = 1;
|
||||||
|
}
|
||||||
|
else if(evo.Level ==0) //Evolutions like frienship, pichu -> pikachu, eevee -> umbreon, etc
|
||||||
|
{
|
||||||
|
dl.Last().MinLevel = 2;
|
||||||
|
if (dl.Count > 1 && !dl.First().RequiresLvlUp)
|
||||||
|
dl.First().MinLevel = 2; //Raichu from Pikachu would have minimun level 1, but with Pichu included Raichu minimun level is 2
|
||||||
|
}
|
||||||
|
else //level up evolutions
|
||||||
|
{
|
||||||
|
dl.Last().MinLevel = evo.Level;
|
||||||
|
if (dl.Count > 1 && dl.First().MinLevel < evo.Level && !dl.First().RequiresLvlUp)
|
||||||
|
dl.First().MinLevel = evo.Level; //Pokemon like Nidoqueen, its minimun level is Nidorina minimun level
|
||||||
|
if (dl.Count > 1 && dl.First().MinLevel <= evo.Level && dl.First().RequiresLvlUp)
|
||||||
|
dl.First().MinLevel = evo.Level + 1; //Pokemon like Crobat, its minimun level is Golbat minimun level + 1
|
||||||
|
}
|
||||||
|
dl.Last().RequiresLvlUp = evo.RequiresLevelUp;
|
||||||
int species = evo.Species;
|
int species = evo.Species;
|
||||||
|
|
||||||
// Gen7 Personal Formes -- unmap the forme personal entry ID to the actual species ID since species are consecutive
|
// Gen7 Personal Formes -- unmap the forme personal entry ID to the actual species ID since species are consecutive
|
||||||
|
@ -436,6 +455,9 @@ namespace PKHeX.Core
|
||||||
if (dl.Any(d => d.Species <= maxSpeciesOrigin) && dl.Last().Species > maxSpeciesOrigin)
|
if (dl.Any(d => d.Species <= maxSpeciesOrigin) && dl.Last().Species > maxSpeciesOrigin)
|
||||||
dl.RemoveAt(dl.Count - 1);
|
dl.RemoveAt(dl.Count - 1);
|
||||||
|
|
||||||
|
//Last species is the wild/hatched species, the minimun is 1 because it has not evolved from previous species
|
||||||
|
dl.Last().MinLevel = 1;
|
||||||
|
dl.Last().RequiresLvlUp = false;
|
||||||
return dl;
|
return dl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,5 +114,16 @@ namespace PKHeX.Core
|
||||||
new EncounterSlot1 {Species = 118, LevelMin = 10, LevelMax = 10, Type = SlotType.Good_Rod, Rate = -1, }, // Goldeen
|
new EncounterSlot1 {Species = 118, LevelMin = 10, LevelMax = 10, Type = SlotType.Good_Rod, Rate = -1, }, // Goldeen
|
||||||
new EncounterSlot1 {Species = 060, LevelMin = 10, LevelMax = 10, Type = SlotType.Good_Rod, Rate = -1, }, // Poliwag
|
new EncounterSlot1 {Species = 060, LevelMin = 10, LevelMax = 10, Type = SlotType.Good_Rod, Rate = -1, }, // Poliwag
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
internal static readonly int[] FutureEvolutionsGen1 =
|
||||||
|
{
|
||||||
|
169,182,186,196,197,199,208,212,230,233,242,462,463,464,465,466,467,470,471,474,700
|
||||||
|
};
|
||||||
|
|
||||||
|
internal static readonly int[] FutureEvolutionsGen1_Gen2LevelUp = new int[]
|
||||||
|
{
|
||||||
|
169,196,197,242
|
||||||
|
};
|
||||||
|
//Crobat Espeon Umbreon Blissey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,5 +36,10 @@ namespace PKHeX.Core
|
||||||
10, 00, 00, 00, 00
|
10, 00, 00, 00, 00
|
||||||
};
|
};
|
||||||
internal static readonly int[] WildPokeBalls2 = { 4 };
|
internal static readonly int[] WildPokeBalls2 = { 4 };
|
||||||
|
|
||||||
|
internal static readonly int[] FutureEvolutionsGen2 =
|
||||||
|
{
|
||||||
|
424,429,430,461,462,463,464,465,466,467,468,469,470,471,472,473,474,700
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,5 +82,17 @@ namespace PKHeX.Core
|
||||||
590, 591, 592, 593
|
590, 591, 592, 593
|
||||||
};
|
};
|
||||||
internal static readonly int[] WildPokeBalls3 = {1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12};
|
internal static readonly int[] WildPokeBalls3 = {1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12};
|
||||||
|
|
||||||
|
internal static readonly int[] FutureEvolutionsGen3 =
|
||||||
|
{
|
||||||
|
407,424,429,430,461,462,463,464,465,466,467,468,469,470,471,472,473,474,475,476,477,700
|
||||||
|
};
|
||||||
|
|
||||||
|
internal static readonly int[] FutureEvolutionsGen3_LevelUp = new int[]
|
||||||
|
{
|
||||||
|
424, 461, 462, 463, 465, 469, 470, 471, 472, 473, 476
|
||||||
|
};
|
||||||
|
// Ambipom Weavile Magnezone Lickilicky Tangrowth
|
||||||
|
// Yanmega Leafeon Glaceon Mamoswine Gliscor Probopass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,5 +130,10 @@ namespace PKHeX.Core
|
||||||
17, 18, 19, 20, 21, 22,
|
17, 18, 19, 20, 21, 22,
|
||||||
// Comp Ball not usable in wild
|
// Comp Ball not usable in wild
|
||||||
};
|
};
|
||||||
|
|
||||||
|
internal static readonly int[] FutureEvolutionsGen4 =
|
||||||
|
{
|
||||||
|
700
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,5 +89,10 @@ namespace PKHeX.Core
|
||||||
// HGSS balls not usable
|
// HGSS balls not usable
|
||||||
// Dream ball not usable in wild
|
// Dream ball not usable in wild
|
||||||
};
|
};
|
||||||
|
|
||||||
|
internal static readonly int[] FutureEvolutionsGen5 =
|
||||||
|
{
|
||||||
|
700
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -277,7 +277,7 @@ namespace PKHeX.Core
|
||||||
public bool Gen3 => Version >= 1 && Version <= 5 || Version == 15;
|
public bool Gen3 => Version >= 1 && Version <= 5 || Version == 15;
|
||||||
public bool Gen2 => Version == (int)GameVersion.GSC;
|
public bool Gen2 => Version == (int)GameVersion.GSC;
|
||||||
public bool Gen1 => Version == (int)GameVersion.RBY;
|
public bool Gen1 => Version == (int)GameVersion.RBY;
|
||||||
public bool GenU => !(Gen7 || Gen6 || Gen5 || Gen4 || Gen3 || Gen2 || Gen1);
|
public bool GenU => !(Gen7 || Gen6 || Gen5 || Gen4 || Gen3 || Gen2 || Gen1 || VC);
|
||||||
public int GenNumber
|
public int GenNumber
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -453,6 +453,13 @@ namespace PKHeX.Core
|
||||||
if (species < 0)
|
if (species < 0)
|
||||||
species = Species;
|
species = Species;
|
||||||
|
|
||||||
|
if (Format == 1 && Generation ==2 && (Legal.MaxSpeciesID_2 >= species || Legal.FutureEvolutionsGen2.Contains(species)))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (Format == Generation)
|
||||||
|
//Every pokemon even those with illegal data inhabit the generation of its current format
|
||||||
|
return true;
|
||||||
|
|
||||||
if (Format < Generation)
|
if (Format < Generation)
|
||||||
return false; // Future
|
return false; // Future
|
||||||
|
|
||||||
|
@ -460,14 +467,14 @@ namespace PKHeX.Core
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Sanity Check Species ID
|
// Sanity Check Species ID
|
||||||
if (Legal.getMaxSpeciesOrigin(GenNumber) < species)
|
if (Legal.getMaxSpeciesOrigin(GenNumber) < species && !Legal.getFutureGenEvolutions(GenNumber).Contains(species))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int gen = GenNumber;
|
int gen = GenNumber;
|
||||||
switch (Generation)
|
switch (Generation)
|
||||||
{
|
{
|
||||||
case 1: return VC;
|
case 1: return Format == 1 || VC;
|
||||||
case 2: return VC;
|
case 2: return Format <= 2 || VC2;
|
||||||
case 3: return Gen3;
|
case 3: return Gen3;
|
||||||
case 4: return 3 <= gen && gen <= 4;
|
case 4: return 3 <= gen && gen <= 4;
|
||||||
case 5: return 3 <= gen && gen <= 5;
|
case 5: return 3 <= gen && gen <= 5;
|
||||||
|
|
Loading…
Reference in a new issue