From b2f9bf50ec03212f731acac1a6319a6c97a81ed2 Mon Sep 17 00:00:00 2001 From: Kurt Date: Mon, 20 Feb 2017 19:40:50 -0800 Subject: [PATCH] Minor refactoring Memories are only set by generation 6 games (bank i/o is a single memory). Only check for gen6 situations. Generation=2 and Format=1 is not possible, as for 1/2 it's dependent on format. Would need to detect encounters for gen2 games to determine what game it originated from. Tabs->Spaces --- PKHeX/Legality/Analysis.cs | 2 - PKHeX/Legality/Checks.cs | 35 +- PKHeX/Legality/Core.cs | 355 ++++++++++----------- PKHeX/Legality/Structures/EvolutionTree.cs | 60 ++-- PKHeX/Legality/Tables.cs | 2 +- PKHeX/Legality/Tables1.cs | 2 +- PKHeX/Legality/Tables3.cs | 2 +- PKHeX/Legality/Tables7.cs | 2 +- PKHeX/MysteryGifts/PL6.cs | 58 ++-- PKHeX/PKM/PKM.cs | 8 +- 10 files changed, 262 insertions(+), 264 deletions(-) diff --git a/PKHeX/Legality/Analysis.cs b/PKHeX/Legality/Analysis.cs index 6e3168e7e..fd3b33282 100644 --- a/PKHeX/Legality/Analysis.cs +++ b/PKHeX/Legality/Analysis.cs @@ -7,7 +7,6 @@ namespace PKHeX.Core public partial class LegalityAnalysis { private PKM pkm; - private DexLevel[] EvoChain; private DexLevel[][] EvoChainsAllGens; private readonly List Parse = new List(); @@ -143,7 +142,6 @@ private void updateEncounterChain() Encounter = verifyEncounter(); Parse.Add(Encounter); - EvoChain = Legal.getEvolutionChain(pkm, EncounterMatch); EvoChainsAllGens = Legal.getEvolutionChainsAllGens(pkm, EncounterMatch); } private void updateEncounterInfo() diff --git a/PKHeX/Legality/Checks.cs b/PKHeX/Legality/Checks.cs index 3108cb8d6..2a8b54bf8 100644 --- a/PKHeX/Legality/Checks.cs +++ b/PKHeX/Legality/Checks.cs @@ -1433,31 +1433,23 @@ private CheckResult verifyCommonMemory(int handler) resultPrefix = "HT "; 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); - if (matchingMoveMemory != -1 && pkm.Species != 235 && !Legal.getCanLearnMachineMove(pkm, Legal.MoveSpecificMemories[1][matchingMoveMemory], generations)) - { + if (matchingMoveMemory != -1 && pkm.Species != 235 && !Legal.getCanLearnMachineMove(pkm, Legal.MoveSpecificMemories[1][matchingMoveMemory], 6)) return new CheckResult(Severity.Invalid, resultPrefix + "Memory: Species cannot learn this move.", CheckIdentifier.Memory); - } + if (m == 6 && !Legal.LocationsWithPKCenter[0].Contains(t)) - { return new CheckResult(Severity.Invalid, resultPrefix + "Memory: Location doesn't have a Pokemon Center.", CheckIdentifier.Memory); - } + 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, generations)) + if (!Legal.getCanLearnMachineMove(new PK6 {Species = t, EXP = PKX.getEXP(100, t)}, 19, 6)) 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, generations, GameVersion.Any))) - { + + if ((m == 16 || m == 48) && (t == 0 || !Legal.getCanKnowMove(pkm, t, 6))) return new CheckResult(Severity.Invalid, resultPrefix + "Memory: Species cannot know this move.", CheckIdentifier.Memory); - } - 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}. - { + + if (m == 49 && (t == 0 || !Legal.getCanRelearnMove(pkm, t, 6))) // {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.Valid, resultPrefix + "Memory is valid.", CheckIdentifier.Memory); } private void verifyOTMemory() @@ -1676,11 +1668,10 @@ private void verifyForm() case 25: // Pikachu if (pkm.Format == 6 && pkm.AltForm != 0 ^ EncounterType == typeof(EncounterStatic)) { - if (EncounterType == typeof(EncounterStatic)) - AddLine(Severity.Invalid, "Cosplay Pikachu cannot have the default form.", CheckIdentifier.Form); - else - AddLine(Severity.Invalid, "Only Cosplay Pikachu can have this form.", CheckIdentifier.Form); - + string msg = EncounterType == typeof (EncounterStatic) + ? "Cosplay Pikachu cannot have the default form." + : "Only Cosplay Pikachu can have this form."; + AddLine(Severity.Invalid, msg, CheckIdentifier.Form); return; } if (pkm.Format == 7 && pkm.AltForm != 0 ^ EncounterIsMysteryGift) diff --git a/PKHeX/Legality/Core.cs b/PKHeX/Legality/Core.cs index 21afca5e9..33b6735a9 100644 --- a/PKHeX/Legality/Core.cs +++ b/PKHeX/Legality/Core.cs @@ -199,12 +199,12 @@ internal static IEnumerable getValidMoves(PKM pkm, DexLevel[][] evoChains, version = GameVersion.Any; return getValidMoves(pkm, version, evoChains, LVL: true, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder); } - internal static IEnumerable getValidMoves(PKM pkm, IEnumerable evoChain,int generation, bool Tutor = true, bool Machine = true, bool MoveReminder = true) + internal static IEnumerable getValidMoves(PKM pkm, 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); + return getValidMoves(pkm, version, evoChain, generation, LVL: true, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder); } internal static IEnumerable getValidRelearn(PKM pkm, int skipOption) { @@ -281,9 +281,9 @@ internal static EncounterStatic getValidStaticEncounter(PKM pkm, bool gen1Encoun // Get possible encounters IEnumerable poss = getStaticEncounters(pkm); - int lvl = (pkm.HasOriginalMetLocation) ? pkm.Met_Level : getMaxLevelGeneration(pkm); + int lvl = getMinLevelEncounter(pkm); if (lvl <= 0) - return null; ; + return null; // Back Check against pkm foreach (EncounterStatic e in poss) { @@ -298,11 +298,8 @@ internal static EncounterStatic getValidStaticEncounter(PKM pkm, bool gen1Encoun if (e.Level != lvl) continue; } - else - { - if (e.Level > lvl) - continue; - } + else if (e.Level > lvl) + continue; if (e.Gender != -1 && e.Gender != pkm.Gender) continue; if (e.Form != pkm.AltForm && !FormChange.Contains(pkm.Species) && !e.SkipFormCheck) @@ -316,7 +313,6 @@ internal static EncounterStatic getValidStaticEncounter(PKM pkm, bool gen1Encoun // if (e.Gift && pkm.Ball != 4) // PokéBall // continue; - // Passes all checks, valid encounter return e; } return null; @@ -329,7 +325,7 @@ internal static EncounterTrade getValidIngameTrade(PKM pkm, bool gen1Encounter = if (lang == 0 || lang == 6) return null; - int lvl = (pkm.HasOriginalMetLocation) ? pkm.Met_Level : getMaxLevelGeneration(pkm); + int lvl = getMinLevelEncounter(pkm); if (lvl <= 0) return null; // Get valid pre-evolutions @@ -421,43 +417,6 @@ private static EvolutionTree getEvolutionTable(PKM pkm) } } - internal static int getMaxSpeciesOrigin(int generation) - { - switch (generation) - { - case 1: return MaxSpeciesID_1; - case 2: return MaxSpeciesID_2; - case 3: return MaxSpeciesID_3; - case 4: return MaxSpeciesID_4; - case 5: return MaxSpeciesID_5; - case 6: return MaxSpeciesID_6; - case 7: return MaxSpeciesID_7; - default: return -1; - } - } - - 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) - { - if (pkm.Format == 1 || pkm.VC1) // Gen1 VC could not trade with gen 2 yet - return getMaxSpeciesOrigin(1); - if (pkm.Format == 2 || pkm.VC2) - return getMaxSpeciesOrigin(2); - return getMaxSpeciesOrigin(pkm.GenNumber); - } - internal static IEnumerable getValidGifts(PKM pkm) { switch (pkm.GenNumber) @@ -608,7 +567,41 @@ internal static IEnumerable getWildBalls(PKM pkm) default: return null; } - } + } + internal static int getMaxSpeciesOrigin(PKM pkm) + { + if (pkm.Format == 1 || pkm.VC1) // Gen1 VC could not trade with gen 2 yet + return getMaxSpeciesOrigin(1); + if (pkm.Format == 2 || pkm.VC2) + return getMaxSpeciesOrigin(2); + return getMaxSpeciesOrigin(pkm.GenNumber); + } + internal static int getMaxSpeciesOrigin(int generation) + { + switch (generation) + { + case 1: return MaxSpeciesID_1; + case 2: return MaxSpeciesID_2; + case 3: return MaxSpeciesID_3; + case 4: return MaxSpeciesID_4; + case 5: return MaxSpeciesID_5; + case 6: return MaxSpeciesID_6; + case 7: return MaxSpeciesID_7; + default: return -1; + } + } + internal static IEnumerable 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 bool getDexNavValid(PKM pkm) { @@ -739,52 +732,41 @@ private static bool getCanBeCaptured(int species, IEnumerable are return false; } - internal static bool getCanLearnMachineMove(PKM pkm, int move, int[] generations, GameVersion version = GameVersion.Any) + internal static bool getCanLearnMachineMove(PKM pkm, int move, IEnumerable generations, GameVersion version = GameVersion.Any) { - foreach (int generation in generations) - if (getCanLearnMachineMove(pkm, generation, move, version)) - return true; - return false; + return generations.Any(generation => getCanLearnMachineMove(pkm, generation, move, version)); } - internal static bool getCanRelearnMove(PKM pkm,int move, int[] generations, GameVersion version = GameVersion.Any) + internal static bool getCanRelearnMove(PKM pkm, int move, IEnumerable generations, GameVersion version = GameVersion.Any) { - foreach (int generation in generations) - if (getCanRelearnMove(pkm, move, generation, version)) - return true; - return false; + return generations.Any(generation => getCanRelearnMove(pkm, move, generation, version)); } - internal static bool getCanLearnMove(PKM pkm, int move, int[] generations, GameVersion version = GameVersion.Any) + internal static bool getCanLearnMove(PKM pkm, int move, IEnumerable generations, GameVersion version = GameVersion.Any) { - foreach (int generation in generations) - if (getCanLearnMove(pkm, move, generation, version)) - return true; - return false; + return generations.Any(generation => getCanLearnMove(pkm, move, generation, version)); } - internal static bool getCanKnowMove(PKM pkm, int move, int[] generations, GameVersion version = GameVersion.Any) + internal static bool getCanKnowMove(PKM pkm, int move, IEnumerable generations, GameVersion version = GameVersion.Any) { - foreach (int generation in generations) - if (getCanKnowMove(pkm, move, generation, version)) - return true; - return false; + return generations.Any(generation => getCanKnowMove(pkm, move, generation, version)); } - internal static bool getCanLearnMachineMove(PKM pkm,int move, int generation, GameVersion version = GameVersion.Any) + 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); + return getValidMoves(pkm, version, getValidPreEvolutions(pkm).ToArray(), 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); + return getValidMoves(pkm, version, getValidPreEvolutions(pkm).ToArray(), generation, LVL: true, Relearn: true).Contains(move); } - internal static bool getCanLearnMove(PKM pkm,int move, int generation, GameVersion version = GameVersion.Any) + 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); + return getValidMoves(pkm, version, getValidPreEvolutions(pkm).ToArray(), generation, Tutor: true, Machine: true).Contains(move); } - internal static bool getCanKnowMove(PKM pkm,int move, int generation, GameVersion version = GameVersion.Any) + internal static bool getCanKnowMove(PKM pkm, int move, int generation, GameVersion version = GameVersion.Any) { if (pkm.Species == 235 && !InvalidSketch.Contains(move)) return true; - return getValidMoves(pkm, version,getValidPreEvolutions(pkm), generation, LVL: true, Relearn: true, Tutor: true, Machine: true).Contains(move); + return getValidMoves(pkm, version, getValidPreEvolutions(pkm).ToArray(), generation, LVL: true, Relearn: true, Tutor: true, Machine: true).Contains(move); } + internal static int getBaseSpecies(PKM pkm, int skipOption = 0) { if (pkm.Species == 292) @@ -824,12 +806,15 @@ internal static int getMaxLevelGeneration(PKM pkm, int generation) 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; + if (!pkm.HasOriginalMetLocation) + return pkm.Met_Level; + + return pkm.CurrentLevel; + } + internal static int getMinLevelEncounter(PKM pkm) + { + return pkm.HasOriginalMetLocation ? pkm.Met_Level : getMaxLevelGeneration(pkm); } - internal static int getMinLevelGeneration(PKM pkm) { return getMinLevelGeneration(pkm, pkm.GenNumber); @@ -842,7 +827,7 @@ internal static int getMinLevelGeneration(PKM pkm, int generation) if (pkm.Format <= 2) return 2; - if(!pkm.HasOriginalMetLocation) + if (!pkm.HasOriginalMetLocation) return pkm.Met_Level; if (pkm.GenNumber <= 3) @@ -850,80 +835,86 @@ internal static int getMinLevelGeneration(PKM pkm, int generation) return 1; } + internal static DexLevel[][] getEvolutionChainsAllGens(PKM pkm, object Encounter) { - IEnumerable CompleteEvoChain = getEvolutionChain(pkm, Encounter); - DexLevel[][] GensEvoChains = new DexLevel[8][]; - for (int gen = 1; gen <= 7; gen++) + var CompleteEvoChain = getEvolutionChain(pkm, Encounter).ToArray(); + DexLevel[][] GensEvoChains = new DexLevel[pkm.Format + 1][]; + for (int gen = 1; gen <= pkm.Format; 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 + if (pkm.Species == 0 || pkm.Format > 2 && pkm.GenU) // Illegal origin or empty pokemon, return only chain for current format { - GensEvoChains[pkm.Format] = CompleteEvoChain.ToArray(); + GensEvoChains[pkm.Format] = CompleteEvoChain; 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) + // 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) { - GensEvoChains[pkm.GenNumber] = CompleteEvoChain.ToArray(); + if (getMaxSpeciesOrigin(pkm.GenNumber) >= pkm.Species) + GensEvoChains[pkm.GenNumber] = CompleteEvoChain; 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 + int lvl = 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) + 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; + if (!pkm.HasOriginalMetLocation && pkm.Format > 2 && gen <= 4 && lvl > pkm.Met_Level) + { + // Met location was lost at this point but it also means the pokemon existed in generations 1 to 4 with maximum level equals to met level + lvl = 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 + + // 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 + // Eevee requires to level one time to be Sylveon, it can be deduced in gen 5 and before it existed with maximum 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(); + lvl--; + // This is a gen 3 pokemon in a gen 4 phase evolution that requieres level up and then transfered to gen 5+ + // 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 maximum met level -1 + if (gen == 3 && pkm.Format > 4 && lvl == pkm.CurrentLevel && CompleteEvoChain.First().Species > MaxSpeciesID_3 && CompleteEvoChain.First().RequiresLvlUp) + lvl--; + // 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 && lvl == pkm.CurrentLevel && CompleteEvoChain.First().Species > MaxSpeciesID_1 && CompleteEvoChain.First().RequiresLvlUp) + lvl--; + CompleteEvoChain = CompleteEvoChain.Skip(1).ToArray(); } + + // 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).ToArray(); + + if (!CompleteEvoChain.Any()) + continue; + + GensEvoChains[gen] = getEvolutionChain(pkm, Encounter, CompleteEvoChain.First().Species, lvl); + 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 >= lvl).ToArray(); } return GensEvoChains; } internal static DexLevel[] getEvolutionChain(PKM pkm, object Encounter) { - return getEvolutionChain(pkm, Encounter,pkm.Species, 100); + return getEvolutionChain(pkm, Encounter, pkm.Species, 100); } - internal static DexLevel[] getEvolutionChain(PKM pkm, object Encounter,int maxspec, int maxlevel) + internal static DexLevel[] getEvolutionChain(PKM pkm, object Encounter, int maxspec, int maxlevel) { int minspec; DexLevel[] vs = getValidPreEvolutions(pkm).ToArray(); @@ -941,25 +932,25 @@ internal static DexLevel[] getEvolutionChain(PKM pkm, object Encounter,int maxsp int minindex = Math.Max(0, Array.FindIndex(vs, p => p.Species == minspec)); 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 + 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 + // Example Raichu in gen 2 or later, + // because Pichu requires level up Minimum 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 + // 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 + // 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; @@ -1090,22 +1081,24 @@ private static IEnumerable getValidEncounterSlots(PKM pkm, Encoun bool ignoreSlotLevel = ignoreLevel; IEnumerable slots = loc.Slots.Where(slot => vs.Any(evo => evo.Species == slot.Species && (ignoreSlotLevel || evo.Level >= slot.LevelMin - df))); - int lvl = (pkm.HasOriginalMetLocation) ? pkm.Met_Level: getMaxLevelGeneration(pkm); + int lvl = getMinLevelEncounter(pkm); if (lvl <= 0) return slotdata; int gen = pkm.GenNumber; - IEnumerable encounterSlots; - 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) + List encounterSlots; + if (ignoreLevel) + encounterSlots = slots.ToList(); + else if (pkm.HasOriginalMetLocation) + encounterSlots = slots.Where(slot => slot.LevelMin - df <= lvl && lvl <= slot.LevelMax + (slot.AllowDexNav ? dn : df)).ToList(); + else // check for any less than current level + encounterSlots = slots.Where(slot => 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 + // For gen 1 and 2 return Minimum level slot + // Minimum 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); @@ -1129,7 +1122,7 @@ private static IEnumerable getValidEncounterSlots(PKM pkm, Encoun } List eslots = encounterSlots.Where(slot => !WildForms.Contains(pkm.Species) || slot.Form == pkm.AltForm).ToList(); - if(gen <= 5) + if (gen <= 5) { slotdata.AddRange(eslots); return slotdata; @@ -1172,7 +1165,7 @@ private static IEnumerable getValidPreEvolutions(PKM pkm, int lvl = -1 if (lvl == 1 && pkm.IsEgg) return new List { - new DexLevel { Species = pkm.Species, Level = 1, MinLevel = 1 }, + new DexLevel { Species = pkm.Species, Level = 1, MinLevel = 1 }, }; if (pkm.Species == 292 && lvl >= 20 && (!pkm.HasOriginalMetLocation || pkm.Met_Level + 1 <= lvl)) return new List @@ -1189,17 +1182,19 @@ private static IEnumerable getStatic(PKM pkm, IEnumerable dl = getValidPreEvolutions(pkm, lvl); return table.Where(e => dl.Any(d => d.Species == e.Species)); } - private static IEnumerable getValidMoves(PKM pkm, GameVersion Version, DexLevel[][] vs, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false, bool MoveReminder = true) + private static IEnumerable getValidMoves(PKM pkm, GameVersion Version, IReadOnlyList vs, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false, bool MoveReminder = true) { List r = new List { 0 }; - for(int gen =1;gen<=7;gen++) - { + if (Relearn && pkm.Format >= 6) + r.AddRange(pkm.RelearnMoves); + + for (int gen = pkm.GenNumber; gen <= pkm.Format; gen++) if (vs[gen].Any()) r.AddRange(getValidMoves(pkm, Version, vs[gen], gen, LVL, Tutor, Machine, MoveReminder)); - } + return r.Distinct().ToArray(); } - private static IEnumerable getValidMoves(PKM pkm, GameVersion Version, IEnumerable vs, int Generation, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false, bool MoveReminder = true) + private static IEnumerable getValidMoves(PKM pkm, GameVersion Version, DexLevel[] vs, int Generation, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false, bool MoveReminder = true) { List r = new List { 0 }; if (!vs.Any()) @@ -1213,13 +1208,13 @@ private static IEnumerable getValidMoves(PKM pkm, GameVersion Version, IEnu { int formcount = pkm.PersonalInfo.FormeCount; for (int i = 0; i < formcount; i++) - r.AddRange(getMoves(pkm, species, vs.First().Level, i, moveTutor, Version, LVL, Tutor, Machine, Generation, MoveReminder)); + r.AddRange(getMoves(pkm, species, vs.First().Level, i, moveTutor, Version, LVL, Tutor, Machine, MoveReminder, Generation)); if (Relearn) r.AddRange(pkm.RelearnMoves); return r.Distinct().ToArray(); } foreach (DexLevel evo in vs) - r.AddRange(getMoves(pkm, evo.Species, evo.Level, pkm.AltForm, moveTutor, Version, LVL, Tutor, Machine, Generation, MoveReminder)); + r.AddRange(getMoves(pkm, evo.Species, evo.Level, pkm.AltForm, moveTutor, Version, LVL, Tutor, Machine, MoveReminder, Generation)); if (pkm.Format <= 3) return r.Distinct().ToArray(); @@ -1227,18 +1222,25 @@ private static IEnumerable getValidMoves(PKM pkm, GameVersion Version, IEnu { if (species == 479 && Generation >= 4) // Rotom r.Add(RotomMoves[pkm.AltForm]); - if (species == 648 && Generation >= 5) // Meloetta + + if (species == 718 && Generation == 7) // Zygarde + r.AddRange(ZygardeMoves); + } + if (Tutor) + { + if (species == 647) // Keldeo + r.Add(548); // Secret Sword + if (species == 648) // Meloetta r.Add(547); // Relic Song if (species == 25 && pkm.Format == 6 && Generation == 6) // Pikachu r.Add(PikachuMoves[pkm.AltForm]); - if (species == 718 && Generation == 7) // Zygarde - r.AddRange(ZygardeMoves); + if ((species == 25 || species == 26) && Generation == 7) // Pikachu/Raichu Tutor + r.Add(344); // Volt Tackle } - if ((species == 25 || species == 26) && Generation == 7 && moveTutor) // Pikachu/Raichu Tutor - r.Add(344); // Volt Tackle - if (Relearn && Generation >= 6) r.AddRange(pkm.RelearnMoves); + if (Relearn && Generation >= 6) + r.AddRange(pkm.RelearnMoves); return r.Distinct().ToArray(); } private static IEnumerable getMoves(PKM pkm, int species, int lvl, int form, bool moveTutor, GameVersion Version, bool LVL, bool specialTutors, bool Machine, bool MoveReminder) @@ -1250,16 +1252,16 @@ private static IEnumerable getMoves(PKM pkm, int species, int lvl, int form int max = pkm.Format < 3 ? 2 : 1; for (; gen <= max; gen++) if (pkm.InhabitedGeneration(gen, species)) - r.AddRange(getMoves(pkm, species, lvl, form, moveTutor, Version, LVL, specialTutors, Machine, gen, MoveReminder)); + r.AddRange(getMoves(pkm, species, lvl, form, moveTutor, Version, LVL, specialTutors, Machine, MoveReminder, gen)); gen = 7; } for (; gen <= pkm.Format; gen++) if (pkm.InhabitedGeneration(gen)) - r.AddRange(getMoves(pkm, species, lvl, form, moveTutor, Version, LVL, specialTutors, Machine, gen, MoveReminder)); + r.AddRange(getMoves(pkm, species, lvl, form, moveTutor, Version, LVL, specialTutors, Machine, MoveReminder, gen)); return r.Distinct(); } - private static IEnumerable getMoves(PKM pkm, int species, int lvl, int form, bool moveTutor, GameVersion Version, bool LVL, bool specialTutors, bool Machine, int Generation, bool MoveReminder) + private static IEnumerable getMoves(PKM pkm, int species, int lvl, int form, bool moveTutor, GameVersion Version, bool LVL, bool specialTutors, bool Machine, bool MoveReminder, int Generation) { List r = new List(); @@ -1268,16 +1270,17 @@ private static IEnumerable getMoves(PKM pkm, int species, int lvl, int form { case 1: { - if (species > MaxSpeciesID_1)//Sanity check + int index = PersonalTable.RB.getFormeIndex(species, 0); + if (index == 0) return r; - var pi_rb = (PersonalInfoG1)PersonalTable.RB[species]; - var pi_y = (PersonalInfoG1)PersonalTable.Y[species]; + var pi_rb = (PersonalInfoG1)PersonalTable.RB[index]; + var pi_y = (PersonalInfoG1)PersonalTable.Y[index]; if (LVL) { r.AddRange(pi_rb.Moves); r.AddRange(pi_y.Moves); - r.AddRange(LevelUpRB[species].getMoves(lvl)); - r.AddRange(LevelUpY[species].getMoves(lvl)); + r.AddRange(LevelUpRB[index].getMoves(lvl)); + r.AddRange(LevelUpY[index].getMoves(lvl)); } if (Machine) { @@ -1295,7 +1298,7 @@ private static IEnumerable getMoves(PKM pkm, int species, int lvl, int form case GameVersion.X: case GameVersion.Y: case GameVersion.XY: { int index = PersonalTable.XY.getFormeIndex(species, form); - PersonalInfo pi = PersonalTable.XY.getFormeEntry(species, form); + PersonalInfo pi = PersonalTable.XY[index]; if (LVL) r.AddRange(LevelUpXY[index].getMoves(lvl)); if (moveTutor) r.AddRange(getTutorMoves(pkm, species, form, specialTutors)); @@ -1309,7 +1312,7 @@ private static IEnumerable getMoves(PKM pkm, int species, int lvl, int form case GameVersion.AS: case GameVersion.OR: case GameVersion.ORAS: { int index = PersonalTable.AO.getFormeIndex(species, form); - PersonalInfo pi = PersonalTable.AO.getFormeEntry(species, form); + PersonalInfo pi = PersonalTable.AO[index]; if (LVL) r.AddRange(LevelUpAO[index].getMoves(lvl)); if (moveTutor) r.AddRange(getTutorMoves(pkm, species, form, specialTutors)); @@ -1397,10 +1400,6 @@ private static IEnumerable getTutorMoves(PKM pkm, int species, int form, bo moves.Add(Tutors_AO[i][b]); } // No tutors in G7 - - // Keldeo - Secret Sword - if (species == 647) - moves.Add(548); return moves.Distinct(); } } diff --git a/PKHeX/Legality/Structures/EvolutionTree.cs b/PKHeX/Legality/Structures/EvolutionTree.cs index 53a705483..8a834e352 100644 --- a/PKHeX/Legality/Structures/EvolutionTree.cs +++ b/PKHeX/Legality/Structures/EvolutionTree.cs @@ -153,7 +153,7 @@ private int getIndex(EvolutionMethod evo) return Personal.getFormeIndex(evolvesToSpecies, evolvesToForm); } - public IEnumerable getValidPreEvolutions(PKM pkm, int lvl,bool skipChecks = false) + public IEnumerable getValidPreEvolutions(PKM pkm, int lvl, bool skipChecks = false) { int index = getIndex(pkm); int maxSpeciesOrigin = Legal.getMaxSpeciesOrigin(pkm); @@ -354,7 +354,7 @@ public bool Valid(PKM pkm, int lvl, bool skipChecks) return false; } } - + public DexLevel GetDexLevel(int species, int lvl) { @@ -416,25 +416,7 @@ public IEnumerable getExplicitLineage(PKM pkm, int lvl, bool skipCheck continue; 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; + updateMinValues(dl, evo); int species = evo.Species; // Gen7 Personal Formes -- unmap the forme personal entry ID to the actual species ID since species are consecutive @@ -442,7 +424,7 @@ public IEnumerable getExplicitLineage(PKM pkm, int lvl, bool skipCheck species = pkm.Species - Chain.Count + i; dl.Add(evo.GetDexLevel(species, lvl)); - + if (evo.RequiresLevelUp) lvl--; break; @@ -455,11 +437,43 @@ public IEnumerable getExplicitLineage(PKM pkm, int lvl, bool skipCheck if (dl.Any(d => d.Species <= maxSpeciesOrigin) && dl.Last().Species > maxSpeciesOrigin) dl.RemoveAt(dl.Count - 1); - //Last species is the wild/hatched species, the minimun is 1 because it has not evolved from previous species + // Last species is the wild/hatched species, the minimum is 1 because it has not evolved from previous species dl.Last().MinLevel = 1; dl.Last().RequiresLvlUp = false; return dl; } + private static void updateMinValues(IReadOnlyCollection dl, EvolutionMethod evo) + { + var last = dl.Last(); + if (evo.Level == 0) // Evolutions like elemental stones, trade, etc + { + if (!evo.RequiresLevelUp) + last.MinLevel = 1; + else + { + // Evolutions like frienship, pichu -> pikachu, eevee -> umbreon, etc + last.MinLevel = 2; + + var first = dl.First(); + if (dl.Count > 1 && !first.RequiresLvlUp) + first.MinLevel = 2; // Raichu from Pikachu would have minimum level 1, but with Pichu included Raichu minimum level is 2 + } + } + else // level up evolutions + { + last.MinLevel = evo.Level; + + var first = dl.First(); + if (dl.Count > 1) + { + if (first.MinLevel < evo.Level && !first.RequiresLvlUp) + first.MinLevel = evo.Level; // Pokemon like Nidoqueen, its minimum level is Nidorina minimum level + if (first.MinLevel <= evo.Level && first.RequiresLvlUp) + first.MinLevel = evo.Level + 1; // Pokemon like Crobat, its minimum level is Golbat minimum level + 1 + } + } + last.RequiresLvlUp = evo.RequiresLevelUp; + } } public class EvolutionStage { diff --git a/PKHeX/Legality/Tables.cs b/PKHeX/Legality/Tables.cs index b03e89b6b..0ba9b6966 100644 --- a/PKHeX/Legality/Tables.cs +++ b/PKHeX/Legality/Tables.cs @@ -222,7 +222,7 @@ public static partial class Legal #region Games public static readonly int[] Games_7vc2 = { 39, 40, 41 }; // Gold, Silver, Crystal - public static readonly int[] Games_7vc1 = { 35, 36, 37, 38 }; // Red, Blue, Green, Yellow + public static readonly int[] Games_7vc1 = { 35, 36, 37, 38 }; // Red, Green, Blue, Yellow public static readonly int[] Games_7go = { 34 }; public static readonly int[] Games_7sm = { 30, 31 }; public static readonly int[] Games_6xy = { 24, 25 }; diff --git a/PKHeX/Legality/Tables1.cs b/PKHeX/Legality/Tables1.cs index 7770d500b..99b9288b5 100644 --- a/PKHeX/Legality/Tables1.cs +++ b/PKHeX/Legality/Tables1.cs @@ -120,7 +120,7 @@ public static partial class Legal 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[] + internal static readonly int[] FutureEvolutionsGen1_Gen2LevelUp = { 169,196,197,242 }; diff --git a/PKHeX/Legality/Tables3.cs b/PKHeX/Legality/Tables3.cs index 91ec69374..d661b701f 100644 --- a/PKHeX/Legality/Tables3.cs +++ b/PKHeX/Legality/Tables3.cs @@ -88,7 +88,7 @@ public static partial class Legal 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[] + internal static readonly int[] FutureEvolutionsGen3_LevelUp = { 424, 461, 462, 463, 465, 469, 470, 471, 472, 473, 476 }; diff --git a/PKHeX/Legality/Tables7.cs b/PKHeX/Legality/Tables7.cs index 2f23ff65b..55fbb84b8 100644 --- a/PKHeX/Legality/Tables7.cs +++ b/PKHeX/Legality/Tables7.cs @@ -1165,7 +1165,7 @@ public static partial class Legal new EncounterStatic { Species = 422, Relearn = new[] {124}}, // Shellos: Sludge new EncounterStatic { Species = 131, Relearn = new[] {419}}, // Lapras: Avalanche new EncounterStatic { Species = 102, Relearn = new[] {335,285,384,381,267,246}},// Exeggcute: Block, Skill Swap, Power Swap, Lucky Chant, Nature Power, Ancient Power - new EncounterStatic { Species = 123, Relearn = new[] {211,501,432,179,68}}, // Scyther: Steel Wing, Quick Guard, Defog, Reversal, Counter + new EncounterStatic { Species = 123, Relearn = new[] {211,501,432,179,68}}, // Scyther: Steel Wing, Quick Guard, Defog, Reversal, Counter new EncounterStatic { Species = 198, Relearn = new[] {375,260,195}}, // Murkrow: Psycho Shift, Flatter, Perish Song new EncounterStatic { Species = 447, Relearn = new[] {299}}, // Riolu: Blaze Kick new EncounterStatic { Species = 147, Relearn = new[] {245}}, // Dratini: Extreme Speed diff --git a/PKHeX/MysteryGifts/PL6.cs b/PKHeX/MysteryGifts/PL6.cs index 7694dcc25..53aad466a 100644 --- a/PKHeX/MysteryGifts/PL6.cs +++ b/PKHeX/MysteryGifts/PL6.cs @@ -21,31 +21,31 @@ public PL6(byte[] data = null) public bool PL_enabled { get { return PL_Flag != 0; } set { PL_Flag = (byte)(value ? 1 << 7 : 0); } } //Name of data source - public string Origin_app { + public string Origin_app { get { return Util.TrimFromZero(Encoding.Unicode.GetString(Data, 0x01, 0x6E)); } set { Encoding.Unicode.GetBytes(value.PadRight(54 + 1, '\0')).CopyTo(Data, 0x01); } } //Pokemon transfer flags? public uint PKM1_flags { - get { return BitConverter.ToUInt32(Data, 0x99); } + get { return BitConverter.ToUInt32(Data, 0x99); } set { BitConverter.GetBytes(value).CopyTo(Data, 0x99); } } public uint PKM2_flags { - get { return BitConverter.ToUInt32(Data, 0x141); } + get { return BitConverter.ToUInt32(Data, 0x141); } set { BitConverter.GetBytes(value).CopyTo(Data, 0x141); } } public uint PKM3_flags { - get { return BitConverter.ToUInt32(Data, 0x1E9); } + get { return BitConverter.ToUInt32(Data, 0x1E9); } set { BitConverter.GetBytes(value).CopyTo(Data, 0x1E9); } } public uint PKM4_flags { - get { return BitConverter.ToUInt32(Data, 0x291); } + get { return BitConverter.ToUInt32(Data, 0x291); } set { BitConverter.GetBytes(value).CopyTo(Data, 0x291); } } public uint PKM5_flags { - get { return BitConverter.ToUInt32(Data, 0x339); } + get { return BitConverter.ToUInt32(Data, 0x339); } set { BitConverter.GetBytes(value).CopyTo(Data, 0x339); } } public uint PKM6_flags { - get { return BitConverter.ToUInt32(Data, 0x3E1); } + get { return BitConverter.ToUInt32(Data, 0x3E1); } set { BitConverter.GetBytes(value).CopyTo(Data, 0x3E1); } } - public uint[] Flags + public uint[] Flags { get { return new[] {PKM1_flags, PKM2_flags, PKM3_flags, PKM4_flags, PKM5_flags, PKM6_flags}; } set @@ -58,29 +58,29 @@ public uint[] Flags if (value.Length > 5) PKM6_flags = value[5]; } } - - //Pokémon - - public PL6_PKM poke1 { - get { return new PL6_PKM(Data.Skip(0x9D).Take(PL6_PKM.Size).ToArray()); } + + //Pokémon + + public PL6_PKM poke1 { + get { return new PL6_PKM(Data.Skip(0x9D).Take(PL6_PKM.Size).ToArray()); } set { value.Data.CopyTo(Data, 0x9D); } } - public PL6_PKM poke2 { - get { return new PL6_PKM(Data.Skip(0x145).Take(PL6_PKM.Size).ToArray()); } + public PL6_PKM poke2 { + get { return new PL6_PKM(Data.Skip(0x145).Take(PL6_PKM.Size).ToArray()); } set { value.Data.CopyTo(Data, 0x145); } } - public PL6_PKM poke3 { - get { return new PL6_PKM(Data.Skip(0x1ED).Take(PL6_PKM.Size).ToArray()); } + public PL6_PKM poke3 { + get { return new PL6_PKM(Data.Skip(0x1ED).Take(PL6_PKM.Size).ToArray()); } set { value.Data.CopyTo(Data, 0x1ED); } } - public PL6_PKM poke4 { - get { return new PL6_PKM(Data.Skip(0x295).Take(PL6_PKM.Size).ToArray()); } + public PL6_PKM poke4 { + get { return new PL6_PKM(Data.Skip(0x295).Take(PL6_PKM.Size).ToArray()); } set { value.Data.CopyTo(Data, 0x295); } } - public PL6_PKM poke5 { - get { return new PL6_PKM(Data.Skip(0x33D).Take(PL6_PKM.Size).ToArray()); } + public PL6_PKM poke5 { + get { return new PL6_PKM(Data.Skip(0x33D).Take(PL6_PKM.Size).ToArray()); } set { value.Data.CopyTo(Data, 0x33D); } } - public PL6_PKM poke6 { - get { return new PL6_PKM(Data.Skip(0x3E5).Take(PL6_PKM.Size).ToArray()); } + public PL6_PKM poke6 { + get { return new PL6_PKM(Data.Skip(0x3E5).Take(PL6_PKM.Size).ToArray()); } set { value.Data.CopyTo(Data, 0x3E5); } } - public PL6_PKM[] Pokes + public PL6_PKM[] Pokes { get { return new[] {poke1, poke2, poke3, poke4, poke5, poke6}; } set @@ -132,7 +132,7 @@ public PL6_PKM[] Pokes get { return BitConverter.ToUInt16(Data, 0x49F); } set { BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x49F); } } - public int[] Items + public int[] Items { get { return new[] {Item_1, Item_2, Item_3, Item_4, Item_5, Item_6}; } set @@ -145,8 +145,8 @@ public int[] Items if (value.Length > 5) Item_6 = value[5]; } } - - public int[] Quantities + + public int[] Quantities { get { return new[] {Quantity_1, Quantity_2, Quantity_3, Quantity_4, Quantity_5, Quantity_6}; } set @@ -169,7 +169,7 @@ public int[] Quantities public int Pokemiles { get { return BitConverter.ToUInt16(Data, 0x4A3); } set { BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x4A3); } } - } + } public class PL6_PKM : IEncounterable { @@ -242,7 +242,7 @@ public PL6_PKM(byte[] data = null) public int MetLocation { get { return BitConverter.ToUInt16(Data, 0x3E); } set { BitConverter.GetBytes((ushort)value).CopyTo(Data, 0x3F); } } - public int MetLevel { + public int MetLevel { get { return Data[0x40]; } set { Data[0x40] = (byte)value; } } diff --git a/PKHeX/PKM/PKM.cs b/PKHeX/PKM/PKM.cs index 32dd885ec..f094bf6ae 100644 --- a/PKHeX/PKM/PKM.cs +++ b/PKHeX/PKM/PKM.cs @@ -453,11 +453,7 @@ public bool InhabitedGeneration(int Generation, int species = -1) if (species < 0) 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) @@ -473,8 +469,8 @@ public bool InhabitedGeneration(int Generation, int species = -1) int gen = GenNumber; switch (Generation) { - case 1: return Format == 1 || VC; - case 2: return Format <= 2 || VC2; + case 1: + case 2: return Format <= 2 || VC; case 3: return Gen3; case 4: return 3 <= gen && gen <= 4; case 5: return 3 <= gen && gen <= 5;