From 8e703e17fbd613281fae363672ded5c368851bd3 Mon Sep 17 00:00:00 2001 From: javierhimura Date: Sun, 26 Mar 2017 15:09:41 +0200 Subject: [PATCH 01/15] Clean FutureGenMoves for format 1 and 2 --- PKHeX/Legality/Core.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/PKHeX/Legality/Core.cs b/PKHeX/Legality/Core.cs index 0bfed17ea..cabffcd7d 100644 --- a/PKHeX/Legality/Core.cs +++ b/PKHeX/Legality/Core.cs @@ -566,12 +566,12 @@ private static EncounterArea[] getTables2(GameVersion Version) // Moves internal static void RemoveFutureMoves(PKM pkm, DexLevel[][] evoChains, ref List[] validLevelMoves, ref List[] validTMHM, ref List[] validTutor) { + var FutureMoves = new List(); + FutureMoves.AddRange(validLevelMoves[pkm.Format]); + FutureMoves.AddRange(validTMHM[pkm.Format]); + FutureMoves.AddRange(validTutor[pkm.Format]); if (pkm.Format >= 3) { - var FutureMoves = new List(); - FutureMoves.AddRange(validLevelMoves[pkm.Format]); - FutureMoves.AddRange(validTMHM[pkm.Format]); - FutureMoves.AddRange(validTutor[pkm.Format]); if (pkm.VC1) { validLevelMoves[1]?.RemoveAll(x => FutureMoves.Contains(x)); @@ -608,10 +608,9 @@ internal static void RemoveFutureMoves(PKM pkm, DexLevel[][] evoChains, ref List else { int tradeback = pkm.Format == 2 ? 1 : 2; - var formatmoves = validLevelMoves[pkm.Format].Concat(validTMHM[pkm.Format]).Concat(validTutor[pkm.Format]).ToList(); - validLevelMoves[tradeback]?.RemoveAll(x => formatmoves.Contains(x)); - validTMHM[tradeback]?.RemoveAll(x => formatmoves.Contains(x)); - validTutor[tradeback]?.RemoveAll(x => formatmoves.Contains(x)); + validLevelMoves[tradeback]?.RemoveAll(x => FutureMoves.Contains(x)); + validTMHM[tradeback]?.RemoveAll(x => FutureMoves.Contains(x)); + validTutor[tradeback]?.RemoveAll(x => FutureMoves.Contains(x)); } } internal static List[] getValidMovesAllGens(PKM pkm, DexLevel[][] evoChains, bool LVL = true, bool Tutor = true, bool Machine = true, bool MoveReminder = true, bool RemoveTransferHM = true) From 53984c1807b1a80f8b4be8a17aebc1bd090f519e Mon Sep 17 00:00:00 2001 From: javierhimura Date: Sun, 26 Mar 2017 15:39:09 +0200 Subject: [PATCH 02/15] Verify egg moves from gen 2 to 5 pokemon inside egg with a algorithm similar to verify relearn moves. Egg moves should have fist the base egg moves and after that inherited egg moves, with base egg moves present if there are less that 4 egg moves. Also for special eggs like gift and events every special moves should be present after base egg moves but should not have any egg move that are not included in the special moves list --- PKHeX/Legality/Checks.cs | 194 +++++++++++++++++++++++-- PKHeX/Legality/Core.cs | 21 ++- PKHeX/Legality/LegalityCheckStrings.cs | 6 +- PKHeX/Legality/Tables3.cs | 9 +- 4 files changed, 211 insertions(+), 19 deletions(-) diff --git a/PKHeX/Legality/Checks.cs b/PKHeX/Legality/Checks.cs index e86258a95..aa55e2863 100644 --- a/PKHeX/Legality/Checks.cs +++ b/PKHeX/Legality/Checks.cs @@ -2070,12 +2070,24 @@ private CheckResult[] verifyMoves(GameVersion game = GameVersion.Any) Legal.RemoveFutureMoves(pkm, EvoChainsAllGens, ref validLevelMoves, ref validTMHM, ref validTutor); CheckResult[] res; int[] Moves = pkm.Moves; - if (pkm.Species == 235) // Smeargle can have any move except a few + if (pkm.IsEgg && pkm.GenNumber < 6) + { + if(EventGiftMatch?.Count > 0) + res = verifyMovesEggPreRelearnEvent(Moves); + else + { + var SpecialMoves = (EncounterMatch as MysteryGift)?.Moves ?? + (EncounterMatch as EncounterStatic)?.Moves ?? + (EncounterMatch as EncounterTrade)?.Moves ?? + null; + var allowinherited = SpecialMoves == null; + res = verifyMovesEggPreRelearn(Moves, SpecialMoves ?? new int[0], allowinherited); + } + } + else if (pkm.Species == 235) // Smeargle can have any move except a few res = parseMovesSketch(Moves); else if (EventGiftMatch?.Count > 1) // Multiple possible Mystery Gifts matched, get the best match too res = parseMovesGetGift(Moves, validLevelMoves, validTMHM, validTutor); - else if (pkm.WasEgg && pkm.GenNumber < 6) - res = verifyMovesEggPreRelearn(Moves, validLevelMoves, validTMHM, validTutor); else // Everything else res = parseMovesRegular(Moves, validLevelMoves, validTMHM, validTutor, new int[0], game); @@ -2086,11 +2098,8 @@ private CheckResult[] verifyMoves(GameVersion game = GameVersion.Any) return res; } - private CheckResult[] verifyMovesEggPreRelearn(int[] Moves, List[] validLevelMoves, List[] validTMHM, List[] validTutor) + private GameVersion[] getBaseEggGames() { - CheckResult[] res = new CheckResult[4]; - - // Some games can have different egg movepools. Have to check all situations. GameVersion[] Games = { }; switch (pkm.GenNumber) { @@ -2099,29 +2108,103 @@ private CheckResult[] verifyMovesEggPreRelearn(int[] Moves, List[] validLev Games = new[] { GameVersion.GS, GameVersion.C }; break; case 3: - Games = new[] { GameVersion.RS, GameVersion.E, GameVersion.FRLG }; + switch((GameVersion)pkm.Version) + { + case GameVersion.R: + case GameVersion.S: + Games = new[] { GameVersion.RS}; + break; + case GameVersion.E: + Games = new[] { GameVersion.E }; + break; + case GameVersion.FR: + case GameVersion.LG: + Games = new[] { GameVersion.FRLG }; + break; + } break; case 4: - Games = new[] { GameVersion.DP, GameVersion.Pt, GameVersion.HGSS }; + switch ((GameVersion)pkm.Version) + { + case GameVersion.D: + case GameVersion.P: + Games = new[] { GameVersion.DP }; + break; + case GameVersion.Pt: + Games = new[] { GameVersion.Pt }; + break; + case GameVersion.HG: + case GameVersion.SS: + Games = new[] { GameVersion.HGSS }; + break; + } break; case 5: - Games = new[] { GameVersion.BW, GameVersion.B2W2 }; + switch ((GameVersion)pkm.Version) + { + case GameVersion.B: + case GameVersion.W: + Games = new[] { GameVersion.BW }; + break; + case GameVersion.Pt: + Games = new[] { GameVersion.Pt }; + break; + case GameVersion.B2: + case GameVersion.W2: + Games = new[] { GameVersion.B2W2 }; + break; + } break; } - - int splitctr = Legal.SplitBreed.Contains(pkm.Species) ? 1 : 0; + return Games; + } + private CheckResult[] verifyMovesEggPreRelearn(int[] Moves, int[] SpecialMoves, bool allowinherited) + { + CheckResult[] res = new CheckResult[4]; + // Some games can have different egg movepools. Have to check all situations. + GameVersion[] Games = getBaseEggGames(); + int splitctr = Legal.getSplitBreedGeneration(pkm).Contains(pkm.Species) ? 1 : 0; foreach (var ver in Games) { for (int i = 0; i <= splitctr; i++) { var baseEggMoves = Legal.getBaseEggMoves(pkm, i, ver, 100)?.ToArray() ?? new int[0]; - res = parseMovesRegular(Moves, validLevelMoves, validTMHM, validTutor, baseEggMoves, ver); - if (res.All(r => r.Valid)) // moves is satisfactory - return res; + var EggMoves = Legal.getEggMoves(pkm, ver)?.ToList() ?? new List(); + if(pkm.Format > 2 || SpecialMoves.Any()) + { + // For gen 2 is not possible to difference normal eggs from event eggs + // If there is no special moves assume normal egg + res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, SpecialMoves, allowinherited, ver); + if (res.All(r => r.Valid)) // moves is satisfactory + return res; + } + if(pkm.Format == 2) + { + // For gen 2 if does not match special egg check for normal egg too + res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, new int[0], true, ver); + if (res.All(r => r.Valid)) // moves is satisfactory + return res; + } } } return res; } + private CheckResult[] verifyMovesEggPreRelearnEvent(int[] Moves) + { + foreach (MysteryGift mg in EventGiftMatch) + { + int[] SpecialMoves = mg.Moves; + CheckResult[] res = verifyMovesEggPreRelearn(Moves, SpecialMoves, false); + if (res.Any(r => !r.Valid)) + continue; + + // Match Found + EncounterMatch = mg; + return res; + } + // no Mystery Gifts matched + return verifyMovesEggPreRelearn(Moves, new int[0], false); + } private CheckResult[] parseMovesSketch(int[] Moves) { CheckResult[] res = new CheckResult[4]; @@ -2461,7 +2544,7 @@ private CheckResult[] verifyRelearnEgg() } bool checkAllGames = pkm.WasTradedEgg; - bool splitBreed = Legal.SplitBreed.Contains(pkm.Species); + bool splitBreed = Legal.getSplitBreedGeneration(pkm).Contains(pkm.Species); int iterate = (checkAllGames ? Games.Length : 1) * (splitBreed ? 2 : 1); for (int i = 0; i < iterate; i++) @@ -2537,6 +2620,85 @@ private CheckResult[] verifyRelearnEggBase(int[] RelearnMoves, int skipOption, G return res; } + /* Similar to verifyRelearnEgg but in pre relearn generation is the moves what should match the expected order + but only if the pokemon is inside an egg */ + private CheckResult[] verifyPreRelearnEggBase(int[] Moves, int[] baseMoves, List eggmoves,int[] specialmoves, bool AllowInherited, GameVersion ver) + { + CheckResult[] res = new CheckResult[4]; + + // Obtain level1 moves + int baseCt = baseMoves.Length; + if (baseCt > 4) baseCt = 4; + + // Obtain Inherited moves + var inherited = Moves.Where(m => m != 0 && (!baseMoves.Contains(m) || eggmoves.Contains(m))).ToList(); + int inheritCt = inherited.Distinct().Count(); + + // Get required amount of base moves + int unique = baseMoves.Concat(inherited).Distinct().Count(); + int reqBase = inheritCt == 4 || baseCt + inheritCt > 4 ? 4 - inheritCt : baseCt; + if (Moves.Where(m => m != 0).Count() < Math.Min(4, baseMoves.Length)) + reqBase = Math.Min(4, unique); + + reqBase = reqBase + specialmoves.Length > 4 ? reqBase - specialmoves.Length : reqBase; + + var em = string.Empty; + // Check if the required amount of Base Egg Moves are present. + for (int i = 0; i < reqBase; i++) + { + if (baseMoves.Contains(Moves[i])) + res[i] = new CheckResult(Severity.Valid, V179, CheckIdentifier.Move); + else if (specialmoves.Length > 0) + { + // mark remaining base egg moves missing + for (int z = i; z < reqBase; z++) + res[z] = new CheckResult(Severity.Invalid, V180, CheckIdentifier.Move); + + // provide the list of suggested base moves for the last required slot + em = string.Join(", ", baseMoves.Select(m => m >= movelist.Length ? V190 : movelist[m])); + break; + } + } + + // Check also if the required amount of Special Egg Moves are present, ir are after base moves + for (int i = reqBase; i < specialmoves.Length; i++) + { + if (specialmoves.Contains(Moves[i])) + res[i] = new CheckResult(Severity.Valid, V333, CheckIdentifier.Move); + else + { + // mark remaining special egg moves missing + for (int z = i; z < specialmoves.Length; z++) + res[z] = new CheckResult(Severity.Invalid, V342, CheckIdentifier.Move); + + // provide the list of suggested base moves for the last required slot + em = string.Join(", ", baseMoves.Union(specialmoves).Select(m => m >= movelist.Length ? V190 : movelist[m])); + break; + } + } + + if(!string.IsNullOrEmpty(em)) + res[reqBase > 0 ? reqBase - 1 : 0].Comment += string.Format(Environment.NewLine + V343, em); + // Non-Base moves that can magically appear in the regular movepool + if (Legal.LightBall.Contains(pkm.Species)) + eggmoves.Add(344); + + // Inherited moves appear after the required base moves. + for (int i = reqBase + specialmoves.Length; i < 4; i++) + { + if (Moves[i] == 0) // empty + res[i] = new CheckResult(Severity.Valid, V167, CheckIdentifier.Move); + else if (AllowInherited && eggmoves.Contains(Moves[i])) // inherited + res[i] = new CheckResult(Severity.Valid, V171, CheckIdentifier.Move); + else if (!AllowInherited && eggmoves.Contains(Moves[i])) // inherited in event/gift pokemon + res[i] = new CheckResult(Severity.Invalid, V341, CheckIdentifier.Move); + else // not inheritable, flag + res[i] = new CheckResult(Severity.Invalid, V340, CheckIdentifier.Move); + } + + return res; + } + private void verifyNoEmptyDuplicates(int[] Moves, CheckResult[] res) { bool emptySlot = false; diff --git a/PKHeX/Legality/Core.cs b/PKHeX/Legality/Core.cs index cabffcd7d..371ce358a 100644 --- a/PKHeX/Legality/Core.cs +++ b/PKHeX/Legality/Core.cs @@ -1371,6 +1371,25 @@ internal static int[] getWildBalls(PKM pkm) return null; } } + + internal static int[] getSplitBreedGeneration(PKM pkm) + { + return getSplitBreedGeneration(pkm.GenNumber); + } + internal static int[] getSplitBreedGeneration(int generation) + { + switch (generation) + { + case 1: return new int[0]; + case 2: return new int[0]; + case 3: return SplitBreed_3; + case 4: return SplitBreed; + case 5: return SplitBreed; + case 6: return SplitBreed; + case 7: return SplitBreed; + 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 @@ -1472,7 +1491,7 @@ internal static bool getEvolutionValid(PKM pkm) var curr = getValidPreEvolutions(pkm); var poss = getValidPreEvolutions(pkm, 100, skipChecks: true); - if (SplitBreed.Contains(getBaseSpecies(pkm, 1))) + if (getSplitBreedGeneration(pkm).Contains(getBaseSpecies(pkm, 1))) return curr.Count() >= poss.Count() - 1; return curr.Count() >= poss.Count(); } diff --git a/PKHeX/Legality/LegalityCheckStrings.cs b/PKHeX/Legality/LegalityCheckStrings.cs index ba283e673..8aef7f4fa 100644 --- a/PKHeX/Legality/LegalityCheckStrings.cs +++ b/PKHeX/Legality/LegalityCheckStrings.cs @@ -325,7 +325,11 @@ public static class LegalityCheckStrings public static string V337 {get; set;} = "Event Egg Move. Incompatible with normal egg moves."; public static string V338 {get; set;} = "Defog and whirpool. One of the two moves should have been removed before transfered to generation 5."; public static string V339 {get; set;} = "Generation {0} HM. Should have been removed before transfered to generation {1}."; + public static string V340 {get; set;} = "Not an expected egg move."; + public static string V341 {get; set;} = "Egg Move.Not expected in an event egg."; + public static string V342 {get; set;} = "Event egg move missing."; + public static string V343 {get; set;} = "Expected the following Moves: { 0}"; #endregion - } + } } diff --git a/PKHeX/Legality/Tables3.cs b/PKHeX/Legality/Tables3.cs index d3de454f8..e564499d7 100644 --- a/PKHeX/Legality/Tables3.cs +++ b/PKHeX/Legality/Tables3.cs @@ -10,7 +10,14 @@ public static partial class Legal internal const int MaxItemID_3 = 374; internal const int MaxAbilityID_3 = 77; internal const int MaxBallID_3 = 0xC; - + + public static readonly int[] SplitBreed_3 = + { + // Incense + 183, 184, // Marill + 202, // Wobbuffet + }; + #region RS internal static readonly ushort[] Pouch_Items_RS = { 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 63, 64, 65, 66, 67, 68, 69, 70, 71, 73, 74, 75, 76, 77, 78, 79, 80, 81, 83, 84, 85, 86, 93, 94, 95, 96, 97, 98, 103, 104, 106, 107, 108, 109, 110, 111, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 254, 255, 256, 257, 258 From ff6b6c5026746b65b27b1d648384bdc024f37f9b Mon Sep 17 00:00:00 2001 From: javierhimura Date: Sun, 26 Mar 2017 15:46:25 +0200 Subject: [PATCH 03/15] Base Egg Moves is not needed anymore in parseMovesRegular because if the pokemon is inside an egg base moves are already checked in verifyMovesEggPreRelearn, if the pokemon was an egg base egg moves are already included in level up moves --- PKHeX/Legality/Checks.cs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/PKHeX/Legality/Checks.cs b/PKHeX/Legality/Checks.cs index aa55e2863..8eb33afbb 100644 --- a/PKHeX/Legality/Checks.cs +++ b/PKHeX/Legality/Checks.cs @@ -2089,7 +2089,7 @@ private CheckResult[] verifyMoves(GameVersion game = GameVersion.Any) else if (EventGiftMatch?.Count > 1) // Multiple possible Mystery Gifts matched, get the best match too res = parseMovesGetGift(Moves, validLevelMoves, validTMHM, validTutor); else // Everything else - res = parseMovesRegular(Moves, validLevelMoves, validTMHM, validTutor, new int[0], game); + res = parseMovesRegular(Moves, validLevelMoves, validTMHM, validTutor, game); // Duplicate Moves Check verifyNoEmptyDuplicates(Moves, res); @@ -2220,7 +2220,7 @@ private CheckResult[] parseMovesGetGift(int[] Moves, List[] validLevelMoves foreach (MysteryGift mg in EventGiftMatch) { int[] SpecialMoves = mg.Moves; - CheckResult[] res = parseMoves(Moves, validLevelMoves, RelearnMoves, validTMHM, validTutor, SpecialMoves, new int[0], new int[0], new int[0]); + CheckResult[] res = parseMoves(Moves, validLevelMoves, RelearnMoves, validTMHM, validTutor, SpecialMoves, new int[0], new int[0]); if (res.Any(r => !r.Valid)) continue; @@ -2231,9 +2231,9 @@ private CheckResult[] parseMovesGetGift(int[] Moves, List[] validLevelMoves } // no Mystery Gifts matched - return parseMoves(Moves, validLevelMoves, RelearnMoves, validTMHM, validTutor, new int[0], new int[0], new int[0], new int[0]); + return parseMoves(Moves, validLevelMoves, RelearnMoves, validTMHM, validTutor, new int[0], new int[0], new int[0]); } - private CheckResult[] parseMovesRegular(int[] Moves, List[] validLevelMoves, List[] validTMHM, List[] validTutor, int[] baseEggMoves, GameVersion game) + private CheckResult[] parseMovesRegular(int[] Moves, List[] validLevelMoves, List[] validTMHM, List[] validTutor, GameVersion game) { int[] EggMoves = pkm.WasEgg ? Legal.getEggMoves(pkm, game).ToArray() : new int[0]; int[] EventEggMoves = pkm.WasEgg ? Legal.getSpecialEggMoves(pkm, game).ToArray() : new int[0]; @@ -2243,7 +2243,7 @@ private CheckResult[] parseMovesRegular(int[] Moves, List[] validLevelMoves (EncounterMatch as EncounterTrade)?.Moves ?? new int[0]; - CheckResult[] res = parseMoves(Moves, validLevelMoves, RelearnMoves, validTMHM, validTutor, SpecialMoves, baseEggMoves, EggMoves, EventEggMoves); + CheckResult[] res = parseMoves(Moves, validLevelMoves, RelearnMoves, validTMHM, validTutor, SpecialMoves, EggMoves, EventEggMoves); if (pkm.GenNumber < 6) return res; @@ -2254,7 +2254,7 @@ private CheckResult[] parseMovesRegular(int[] Moves, List[] validLevelMoves return res; } - private CheckResult[] parseMoves(int[] moves, List[] learn, int[] relearn, List[] tmhm, List[] tutor, int[] special, int[] baseegg, int[] egg, int[] eventegg) + private CheckResult[] parseMoves(int[] moves, List[] learn, int[] relearn, List[] tmhm, List[] tutor, int[] special, int[] egg, int[] eventegg) { CheckResult[] res = new CheckResult[4]; var Gen1MovesLearned = new List(); @@ -2308,8 +2308,6 @@ private CheckResult[] parseMoves(int[] moves, List[] learn, int[] relearn, res[m] = new CheckResult(Severity.Valid, native ? V173 : string.Format(V332, gen), CheckIdentifier.Move); else if (gen == pkm.GenNumber && special.Contains(moves[m])) res[m] = new CheckResult(Severity.Valid, V175, CheckIdentifier.Move); - else if (gen == pkm.GenNumber && baseegg.Contains(moves[m])) - res[m] = new CheckResult(Severity.Valid, V177, CheckIdentifier.Move); if (res[m] == null) continue; From 62b6f2c98d26b94f4f67718c25f8cbd74c90ff07 Mon Sep 17 00:00:00 2001 From: javierhimura Date: Sun, 26 Mar 2017 17:07:36 +0200 Subject: [PATCH 04/15] Base egg moves are not only moves from hatched level ( 5 in gen 2 and 3, 1 in gen 4 and 5) Included level up moves learned above hatched level that can be inherited from parents, unlike base egg moves this moves are optional Added to eggs machine moves and crytal tutor moves, it can be inherited too --- PKHeX/Legality/Checks.cs | 52 ++++++----- PKHeX/Legality/Core.cs | 115 ++++++++++++++++++++++++- PKHeX/Legality/LegalityCheckStrings.cs | 7 ++ 3 files changed, 153 insertions(+), 21 deletions(-) diff --git a/PKHeX/Legality/Checks.cs b/PKHeX/Legality/Checks.cs index 8eb33afbb..7a1233111 100644 --- a/PKHeX/Legality/Checks.cs +++ b/PKHeX/Legality/Checks.cs @@ -2168,20 +2168,26 @@ private CheckResult[] verifyMovesEggPreRelearn(int[] Moves, int[] SpecialMoves, { for (int i = 0; i <= splitctr; i++) { - var baseEggMoves = Legal.getBaseEggMoves(pkm, i, ver, 100)?.ToArray() ?? new int[0]; + var baseEggMoves = Legal.getBaseEggMoves(pkm, i, ver, pkm.GenNumber < 4 ? 5 : 1)?.ToList() ?? new List(); + var InheritedLvlMoves = Legal.getBaseEggMoves(pkm, i, ver, 100) ?? new List(); var EggMoves = Legal.getEggMoves(pkm, ver)?.ToList() ?? new List(); - if(pkm.Format > 2 || SpecialMoves.Any()) + var InheritedTutorMoves = (ver == GameVersion.C) ? Legal.getTutorMoves(pkm, pkm.Species, pkm.AltForm, false, 2) : new int[0]; + // Only TM Hm moves from the source game of the egg, not any other games from the same generation + var InheritedTMHMMoves = Legal.getTMHM(pkm, pkm.Species, pkm.AltForm, pkm.GenNumber, ver, false); + InheritedLvlMoves = InheritedLvlMoves.Except(baseEggMoves); + + if (pkm.Format > 2 || SpecialMoves.Any()) { // For gen 2 is not possible to difference normal eggs from event eggs // If there is no special moves assume normal egg - res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, SpecialMoves, allowinherited, ver); + res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, SpecialMoves, allowinherited, ver); if (res.All(r => r.Valid)) // moves is satisfactory return res; } if(pkm.Format == 2) { // For gen 2 if does not match special egg check for normal egg too - res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, new int[0], true, ver); + res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, new int[0], true, ver); if (res.All(r => r.Valid)) // moves is satisfactory return res; } @@ -2620,33 +2626,32 @@ private CheckResult[] verifyRelearnEggBase(int[] RelearnMoves, int skipOption, G /* Similar to verifyRelearnEgg but in pre relearn generation is the moves what should match the expected order but only if the pokemon is inside an egg */ - private CheckResult[] verifyPreRelearnEggBase(int[] Moves, int[] baseMoves, List eggmoves,int[] specialmoves, bool AllowInherited, GameVersion ver) + private CheckResult[] verifyPreRelearnEggBase(int[] Moves, List baseMoves, List eggmoves, IEnumerable lvlmoves, IEnumerable tmhmmoves, IEnumerable tutormoves, int[] specialmoves, bool AllowInherited, GameVersion ver) { CheckResult[] res = new CheckResult[4]; // Obtain level1 moves - int baseCt = baseMoves.Length; + int baseCt = baseMoves.Count; if (baseCt > 4) baseCt = 4; // Obtain Inherited moves - var inherited = Moves.Where(m => m != 0 && (!baseMoves.Contains(m) || eggmoves.Contains(m))).ToList(); - int inheritCt = inherited.Distinct().Count(); + var inherited = Moves.Where(m => m != 0 && (!baseMoves.Contains(m) || specialmoves.Contains(m) || eggmoves.Contains(m) || lvlmoves.Contains(m) || tmhmmoves.Contains(m) || tutormoves.Contains(m))).ToList(); + int inheritCt = inherited.Count; // Get required amount of base moves int unique = baseMoves.Concat(inherited).Distinct().Count(); int reqBase = inheritCt == 4 || baseCt + inheritCt > 4 ? 4 - inheritCt : baseCt; - if (Moves.Where(m => m != 0).Count() < Math.Min(4, baseMoves.Length)) + if (Moves.Where(m => m != 0).Count() < Math.Min(4, baseMoves.Count)) reqBase = Math.Min(4, unique); - reqBase = reqBase + specialmoves.Length > 4 ? reqBase - specialmoves.Length : reqBase; - var em = string.Empty; + var moveoffset = 0; // Check if the required amount of Base Egg Moves are present. - for (int i = 0; i < reqBase; i++) + for (int i = moveoffset; i < reqBase; i++) { if (baseMoves.Contains(Moves[i])) res[i] = new CheckResult(Severity.Valid, V179, CheckIdentifier.Move); - else if (specialmoves.Length > 0) + else if (specialmoves.Length == 0) { // mark remaining base egg moves missing for (int z = i; z < reqBase; z++) @@ -2657,9 +2662,11 @@ private CheckResult[] verifyPreRelearnEggBase(int[] Moves, int[] baseMoves, List break; } } - + + moveoffset += reqBase; + // Check also if the required amount of Special Egg Moves are present, ir are after base moves - for (int i = reqBase; i < specialmoves.Length; i++) + for (int i = moveoffset; i < moveoffset + specialmoves.Length; i++) { if (specialmoves.Contains(Moves[i])) res[i] = new CheckResult(Severity.Valid, V333, CheckIdentifier.Move); @@ -2678,18 +2685,23 @@ private CheckResult[] verifyPreRelearnEggBase(int[] Moves, int[] baseMoves, List if(!string.IsNullOrEmpty(em)) res[reqBase > 0 ? reqBase - 1 : 0].Comment += string.Format(Environment.NewLine + V343, em); // Non-Base moves that can magically appear in the regular movepool - if (Legal.LightBall.Contains(pkm.Species)) + if (pkm.GenNumber >=3 && Legal.LightBall.Contains(pkm.Species)) eggmoves.Add(344); // Inherited moves appear after the required base moves. + var AllowInheritedSeverity = AllowInherited ? Severity.Valid : Severity.Invalid; for (int i = reqBase + specialmoves.Length; i < 4; i++) { if (Moves[i] == 0) // empty res[i] = new CheckResult(Severity.Valid, V167, CheckIdentifier.Move); - else if (AllowInherited && eggmoves.Contains(Moves[i])) // inherited - res[i] = new CheckResult(Severity.Valid, V171, CheckIdentifier.Move); - else if (!AllowInherited && eggmoves.Contains(Moves[i])) // inherited in event/gift pokemon - res[i] = new CheckResult(Severity.Invalid, V341, CheckIdentifier.Move); + else if (eggmoves.Contains(Moves[i])) // inherited egg move + res[i] = new CheckResult(AllowInheritedSeverity, AllowInherited ? V344 : V341, CheckIdentifier.Move); + else if (lvlmoves.Contains(Moves[i])) // inherited lvl moves + res[i] = new CheckResult(AllowInheritedSeverity, AllowInherited ? V345 : V347, CheckIdentifier.Move); + else if (tmhmmoves.Contains(Moves[i])) // inherited TMHM moves + res[i] = new CheckResult(AllowInheritedSeverity, AllowInherited ? V349 : V350, CheckIdentifier.Move); + else if (tutormoves.Contains(Moves[i])) // inherited tutor moves + res[i] = new CheckResult(AllowInheritedSeverity, AllowInherited ? V346 : V348, CheckIdentifier.Move); else // not inheritable, flag res[i] = new CheckResult(Severity.Invalid, V340, CheckIdentifier.Move); } diff --git a/PKHeX/Legality/Core.cs b/PKHeX/Legality/Core.cs index 371ce358a..5f8d11bbe 100644 --- a/PKHeX/Legality/Core.cs +++ b/PKHeX/Legality/Core.cs @@ -2516,7 +2516,120 @@ private static IEnumerable getEggMoves(PKM pkm, int species, int formnum, G return new List(); } } - private static IEnumerable getTutorMoves(PKM pkm, int species, int form, bool specialTutors, int generation) + internal static IEnumerable getTMHM(PKM pkm, int species, int form, int generation, GameVersion Version = GameVersion.Any, bool RemoveTransferHM = true) + { + List moves = new List(); + 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((t, m) => pi_rb.TMHM[m])); + moves.AddRange(TMHM_RBY.Where((t, 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((t, m) => pi_c.TMHM[m])); + if (Version == GameVersion.Any) + goto case 1; + break; + case 3: + index = PersonalTable.E.getFormeIndex(species, 0); + var pi_e = PersonalTable.E[index]; + moves.AddRange(TM_3.Where((t, 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((t, 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((t, 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((t, 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((t, 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((t, 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((t, 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_oras = PersonalTable.AO[index]; + moves.AddRange(TMHM_AO.Where((t, m) => pi_oras.TMHM[m])); + break; + } + } + break; + case 7: + index = PersonalTable.SM.getFormeIndex(species, form); + PersonalInfo pi_sm = PersonalTable.SM.getFormeEntry(species, form); + moves.AddRange(TMHM_SM.Where((t, m) => pi_sm.TMHM[m])); + break; + } + return moves.Distinct(); + } + internal static IEnumerable getTutorMoves(PKM pkm, int species, int form, bool specialTutors, int generation) { List moves = new List(); PersonalInfo info; diff --git a/PKHeX/Legality/LegalityCheckStrings.cs b/PKHeX/Legality/LegalityCheckStrings.cs index 8aef7f4fa..ecee05022 100644 --- a/PKHeX/Legality/LegalityCheckStrings.cs +++ b/PKHeX/Legality/LegalityCheckStrings.cs @@ -52,6 +52,10 @@ public static class LegalityCheckStrings public static string V331 { get; set; } = "Learned by TM/HM in generation {0}."; public static string V332 { get; set; } = "Learned by Move Tutor in generation {0}."; public static string V333 { get; set; } = "Event Egg Move."; + public static string V344 { get; set; } = "Inherited egg move."; + public static string V345 { get; set; } = "Inherited move learned by Level-up."; + public static string V346 { get; set; } = "Inherited tutor move."; + public static string V349 { get; set; } = "Inherited TM/HM move."; #endregion @@ -329,6 +333,9 @@ public static class LegalityCheckStrings public static string V341 {get; set;} = "Egg Move.Not expected in an event egg."; public static string V342 {get; set;} = "Event egg move missing."; public static string V343 {get; set;} = "Expected the following Moves: { 0}"; + public static string V347 {get; set;} = "Inherited move learned by Level-up.Not expected in an event egg."; + public static string V348 {get; set;} = "Inherited tutor move. Not expected in an event egg."; + public static string V350 {get; set;} = "Inherited TM/HM move. Not expected in an event egg."; #endregion } From 813e68e0d6ce48ba4884dc3e6e2e92e400416849 Mon Sep 17 00:00:00 2001 From: javierhimura Date: Sun, 26 Mar 2017 17:20:55 +0200 Subject: [PATCH 05/15] Reverted base egg moves deletion from parseMovesRegular when pokemon was an egg but adapted to check that moves after all the normal moves and before egg moves, also checking if base egg moves are non tradeback moves --- PKHeX/Legality/Checks.cs | 77 +++++++++++++++++++++++++++++++++------- 1 file changed, 65 insertions(+), 12 deletions(-) diff --git a/PKHeX/Legality/Checks.cs b/PKHeX/Legality/Checks.cs index 7a1233111..366d256c0 100644 --- a/PKHeX/Legality/Checks.cs +++ b/PKHeX/Legality/Checks.cs @@ -2081,15 +2081,17 @@ private CheckResult[] verifyMoves(GameVersion game = GameVersion.Any) (EncounterMatch as EncounterTrade)?.Moves ?? null; var allowinherited = SpecialMoves == null; - res = verifyMovesEggPreRelearn(Moves, SpecialMoves ?? new int[0], allowinherited); + res = verifyMovesIsEggPreRelearn(Moves, SpecialMoves ?? new int[0], allowinherited); } } + else if (pkm.WasEgg && pkm.GenNumber < 6) + res = verifyMovesWasEggPreRelearn(Moves, validLevelMoves, validTMHM, validTutor); else if (pkm.Species == 235) // Smeargle can have any move except a few res = parseMovesSketch(Moves); else if (EventGiftMatch?.Count > 1) // Multiple possible Mystery Gifts matched, get the best match too res = parseMovesGetGift(Moves, validLevelMoves, validTMHM, validTutor); else // Everything else - res = parseMovesRegular(Moves, validLevelMoves, validTMHM, validTutor, game); + res = parseMovesRegular(Moves, validLevelMoves, validTMHM, validTutor, new int[0], game); // Duplicate Moves Check verifyNoEmptyDuplicates(Moves, res); @@ -2098,7 +2100,7 @@ private CheckResult[] verifyMoves(GameVersion game = GameVersion.Any) return res; } - private GameVersion[] getBaseEggGames() + private GameVersion[] getBaseMovesIsEggGames() { GameVersion[] Games = { }; switch (pkm.GenNumber) @@ -2158,11 +2160,11 @@ private GameVersion[] getBaseEggGames() } return Games; } - private CheckResult[] verifyMovesEggPreRelearn(int[] Moves, int[] SpecialMoves, bool allowinherited) + private CheckResult[] verifyMovesIsEggPreRelearn(int[] Moves, int[] SpecialMoves, bool allowinherited) { CheckResult[] res = new CheckResult[4]; // Some games can have different egg movepools. Have to check all situations. - GameVersion[] Games = getBaseEggGames(); + GameVersion[] Games = getBaseMovesIsEggGames(); int splitctr = Legal.getSplitBreedGeneration(pkm).Contains(pkm.Species) ? 1 : 0; foreach (var ver in Games) { @@ -2195,12 +2197,47 @@ private CheckResult[] verifyMovesEggPreRelearn(int[] Moves, int[] SpecialMoves, } return res; } + private CheckResult[] verifyMovesWasEggPreRelearn(int[] Moves, List[] validLevelMoves, List[] validTMHM, List[] validTutor) + { + CheckResult[] res = new CheckResult[4]; + + // Some games can have different egg movepools. Have to check all situations. + GameVersion[] Games = { }; + switch (pkm.GenNumber) + { + case 1: + case 2: + Games = new[] { GameVersion.GS, GameVersion.C }; + break; + case 3: // Generation 3 does not overwrite source game after pokemon hatched + Games = getBaseMovesIsEggGames(); + break; + case 4: + Games = new[] { GameVersion.DP, GameVersion.Pt, GameVersion.HGSS }; + break; + case 5: + Games = new[] { GameVersion.BW, GameVersion.B2W2 }; + break; + } + int splitctr = Legal.SplitBreed.Contains(pkm.Species) ? 1 : 0; + foreach (var ver in Games) + { + for (int i = 0; i <= splitctr; i++) + { + var baseEggMoves = Legal.getBaseEggMoves(pkm, i, ver, 100)?.ToArray() ?? new int[0]; + res = parseMovesRegular(Moves, validLevelMoves, validTMHM, validTutor, baseEggMoves, ver); + if (res.All(r => r.Valid)) // moves is satisfactory + return res; + } + } + return res; + } private CheckResult[] verifyMovesEggPreRelearnEvent(int[] Moves) { foreach (MysteryGift mg in EventGiftMatch) { int[] SpecialMoves = mg.Moves; - CheckResult[] res = verifyMovesEggPreRelearn(Moves, SpecialMoves, false); + CheckResult[] res = verifyMovesIsEggPreRelearn(Moves, SpecialMoves, false); if (res.Any(r => !r.Valid)) continue; @@ -2209,7 +2246,7 @@ private CheckResult[] verifyMovesEggPreRelearnEvent(int[] Moves) return res; } // no Mystery Gifts matched - return verifyMovesEggPreRelearn(Moves, new int[0], false); + return verifyMovesIsEggPreRelearn(Moves, new int[0], false); } private CheckResult[] parseMovesSketch(int[] Moves) { @@ -2226,7 +2263,7 @@ private CheckResult[] parseMovesGetGift(int[] Moves, List[] validLevelMoves foreach (MysteryGift mg in EventGiftMatch) { int[] SpecialMoves = mg.Moves; - CheckResult[] res = parseMoves(Moves, validLevelMoves, RelearnMoves, validTMHM, validTutor, SpecialMoves, new int[0], new int[0]); + CheckResult[] res = parseMoves(Moves, validLevelMoves, RelearnMoves, validTMHM, validTutor, SpecialMoves, new int[0], new int[0], new int[0]); if (res.Any(r => !r.Valid)) continue; @@ -2237,9 +2274,9 @@ private CheckResult[] parseMovesGetGift(int[] Moves, List[] validLevelMoves } // no Mystery Gifts matched - return parseMoves(Moves, validLevelMoves, RelearnMoves, validTMHM, validTutor, new int[0], new int[0], new int[0]); + return parseMoves(Moves, validLevelMoves, RelearnMoves, validTMHM, validTutor, new int[0], new int[0], new int[0], new int[0]); } - private CheckResult[] parseMovesRegular(int[] Moves, List[] validLevelMoves, List[] validTMHM, List[] validTutor, GameVersion game) + private CheckResult[] parseMovesRegular(int[] Moves, List[] validLevelMoves, List[] validTMHM, List[] validTutor, int[] baseEggMoves, GameVersion game) { int[] EggMoves = pkm.WasEgg ? Legal.getEggMoves(pkm, game).ToArray() : new int[0]; int[] EventEggMoves = pkm.WasEgg ? Legal.getSpecialEggMoves(pkm, game).ToArray() : new int[0]; @@ -2249,7 +2286,7 @@ private CheckResult[] parseMovesRegular(int[] Moves, List[] validLevelMoves (EncounterMatch as EncounterTrade)?.Moves ?? new int[0]; - CheckResult[] res = parseMoves(Moves, validLevelMoves, RelearnMoves, validTMHM, validTutor, SpecialMoves, EggMoves, EventEggMoves); + CheckResult[] res = parseMoves(Moves, validLevelMoves, RelearnMoves, validTMHM, validTutor, SpecialMoves, baseEggMoves, EggMoves, EventEggMoves); if (pkm.GenNumber < 6) return res; @@ -2260,7 +2297,7 @@ private CheckResult[] parseMovesRegular(int[] Moves, List[] validLevelMoves return res; } - private CheckResult[] parseMoves(int[] moves, List[] learn, int[] relearn, List[] tmhm, List[] tutor, int[] special, int[] egg, int[] eventegg) + private CheckResult[] parseMoves(int[] moves, List[] learn, int[] relearn, List[] tmhm, List[] tutor, int[] special, int[] baseegg, int[] egg, int[] eventegg) { CheckResult[] res = new CheckResult[4]; var Gen1MovesLearned = new List(); @@ -2323,6 +2360,22 @@ private CheckResult[] parseMoves(int[] moves, List[] learn, int[] relearn, if (gen == generations.Last()) { + // Check base egg moves after all the moves but just before egg moves to different it from normal level up moves + // Also check if the base egg moves is a non tradeback move + for (int m = 0; m < 4; m++) + { + if (baseegg.Contains(moves[m])) + { + if (IsGen2Pkm && Gen1MovesLearned.Any() && moves[m] > Legal.MaxMoveID_1) + { + res[m] = new CheckResult(Severity.Invalid, V334, CheckIdentifier.Move); + MixedGen1NonTradebackGen2 = true; + } + else + res[m] = new CheckResult(Severity.Valid, V345, CheckIdentifier.Move); + } + } + // Check egg moves after all the generations and all the moves, every move that can be learned in another source should have preference // the moves that can only be learned from egg moves should in the future check if the move combinations can be breed in gens 2 to 5 for (int m = 0; m < 4; m++) From e9befeae3f97c18c253e1e0e6be2e878b73e4f45 Mon Sep 17 00:00:00 2001 From: javierhimura Date: Sun, 26 Mar 2017 18:05:58 +0200 Subject: [PATCH 06/15] Fix for special moves with invalid move list order Fix for minum level for gen 3 pokemon met as egg Temporal fix for pokemon box encounters --- PKHeX/Legality/Checks.cs | 24 ++++++++++++++---------- PKHeX/Legality/Core.cs | 5 ++++- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/PKHeX/Legality/Checks.cs b/PKHeX/Legality/Checks.cs index 366d256c0..18510fa5a 100644 --- a/PKHeX/Legality/Checks.cs +++ b/PKHeX/Legality/Checks.cs @@ -2163,6 +2163,7 @@ private GameVersion[] getBaseMovesIsEggGames() private CheckResult[] verifyMovesIsEggPreRelearn(int[] Moves, int[] SpecialMoves, bool allowinherited) { CheckResult[] res = new CheckResult[4]; + var ValidSpecialMoves = SpecialMoves.Where(m => m > 0); // Some games can have different egg movepools. Have to check all situations. GameVersion[] Games = getBaseMovesIsEggGames(); int splitctr = Legal.getSplitBreedGeneration(pkm).Contains(pkm.Species) ? 1 : 0; @@ -2182,14 +2183,14 @@ private CheckResult[] verifyMovesIsEggPreRelearn(int[] Moves, int[] SpecialMoves { // For gen 2 is not possible to difference normal eggs from event eggs // If there is no special moves assume normal egg - res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, SpecialMoves, allowinherited, ver); + res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, ValidSpecialMoves, allowinherited, ver); if (res.All(r => r.Valid)) // moves is satisfactory return res; } if(pkm.Format == 2) { // For gen 2 if does not match special egg check for normal egg too - res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, new int[0], true, ver); + res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, new List(), true, ver); if (res.All(r => r.Valid)) // moves is satisfactory return res; } @@ -2679,7 +2680,7 @@ private CheckResult[] verifyRelearnEggBase(int[] RelearnMoves, int skipOption, G /* Similar to verifyRelearnEgg but in pre relearn generation is the moves what should match the expected order but only if the pokemon is inside an egg */ - private CheckResult[] verifyPreRelearnEggBase(int[] Moves, List baseMoves, List eggmoves, IEnumerable lvlmoves, IEnumerable tmhmmoves, IEnumerable tutormoves, int[] specialmoves, bool AllowInherited, GameVersion ver) + private CheckResult[] verifyPreRelearnEggBase(int[] Moves, List baseMoves, List eggmoves, IEnumerable lvlmoves, IEnumerable tmhmmoves, IEnumerable tutormoves, IEnumerable specialmoves, bool AllowInherited, GameVersion ver) { CheckResult[] res = new CheckResult[4]; @@ -2704,7 +2705,7 @@ private CheckResult[] verifyPreRelearnEggBase(int[] Moves, List baseMoves, { if (baseMoves.Contains(Moves[i])) res[i] = new CheckResult(Severity.Valid, V179, CheckIdentifier.Move); - else if (specialmoves.Length == 0) + else { // mark remaining base egg moves missing for (int z = i; z < reqBase; z++) @@ -2719,31 +2720,34 @@ private CheckResult[] verifyPreRelearnEggBase(int[] Moves, List baseMoves, moveoffset += reqBase; // Check also if the required amount of Special Egg Moves are present, ir are after base moves - for (int i = moveoffset; i < moveoffset + specialmoves.Length; i++) + for (int i = moveoffset; i < moveoffset + specialmoves.Count(); i++) { if (specialmoves.Contains(Moves[i])) res[i] = new CheckResult(Severity.Valid, V333, CheckIdentifier.Move); else { // mark remaining special egg moves missing - for (int z = i; z < specialmoves.Length; z++) + for (int z = i; z < moveoffset + specialmoves.Count(); z++) res[z] = new CheckResult(Severity.Invalid, V342, CheckIdentifier.Move); - // provide the list of suggested base moves for the last required slot - em = string.Join(", ", baseMoves.Union(specialmoves).Select(m => m >= movelist.Length ? V190 : movelist[m])); + // provide the list of suggested base moves and specia moves for the last required slot + if (!string.IsNullOrEmpty(em)) em += ","; + else + em = string.Join(", ", baseMoves.Select(m => m >= movelist.Length ? V190 : movelist[m])) + ","; + em += string.Join(", ", specialmoves.Select(m => m >= movelist.Length ? V190 : movelist[m])); break; } } if(!string.IsNullOrEmpty(em)) - res[reqBase > 0 ? reqBase - 1 : 0].Comment += string.Format(Environment.NewLine + V343, em); + res[reqBase > 0 ? reqBase - 1 : 0].Comment = string.Format(Environment.NewLine + V343, em); // Non-Base moves that can magically appear in the regular movepool if (pkm.GenNumber >=3 && Legal.LightBall.Contains(pkm.Species)) eggmoves.Add(344); // Inherited moves appear after the required base moves. var AllowInheritedSeverity = AllowInherited ? Severity.Valid : Severity.Invalid; - for (int i = reqBase + specialmoves.Length; i < 4; i++) + for (int i = reqBase + specialmoves.Count(); i < 4; i++) { if (Moves[i] == 0) // empty res[i] = new CheckResult(Severity.Valid, V167, CheckIdentifier.Move); diff --git a/PKHeX/Legality/Core.cs b/PKHeX/Legality/Core.cs index 5f8d11bbe..1501ac315 100644 --- a/PKHeX/Legality/Core.cs +++ b/PKHeX/Legality/Core.cs @@ -121,7 +121,8 @@ private static EncounterStatic[] getStaticEncounters(GameVersion Game) default: return null; } - return table?.Where(s => s.Version == GameVersion.Any || s.Version == Game).ToArray(); + // Temp until wwwwwwzx Contains extension is merged into the master branch + return table?.Where(s => s.Version == GameVersion.Any || s.Version == Game || s.Version == GameVersion.RSBOX).ToArray(); } private static EncounterArea[] getEncounterTables(GameVersion Game) { @@ -1674,6 +1675,8 @@ internal static int getMaxLevelGeneration(PKM pkm, int generation) } internal static int getMinLevelEncounter(PKM pkm) { + if (pkm.Format == 3 && pkm.WasEgg) + return 5; return pkm.HasOriginalMetLocation ? pkm.Met_Level : getMaxLevelGeneration(pkm); } internal static int getMinLevelGeneration(PKM pkm) From c4433d4436174849a2a6c3b063dee0778aed4860 Mon Sep 17 00:00:00 2001 From: javierhimura Date: Sun, 26 Mar 2017 18:06:30 +0200 Subject: [PATCH 07/15] Missing strings from new legality errors --- PKHeX/Resources/text/en/LegalityCheckStrings_en.txt | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/PKHeX/Resources/text/en/LegalityCheckStrings_en.txt b/PKHeX/Resources/text/en/LegalityCheckStrings_en.txt index 0672342f1..d706d8f3e 100644 --- a/PKHeX/Resources/text/en/LegalityCheckStrings_en.txt +++ b/PKHeX/Resources/text/en/LegalityCheckStrings_en.txt @@ -23,6 +23,10 @@ V177 = Learned by Level-up. V330 = Learned by Level-up in generation {0}. V332 = Learned by Move Tutor in generation {0}. V333 = Event Egg Move. +V344 = Inherited egg move. +V345 = Inherited move learned by Level-up. +V346 = Inherited tutor move. +V349 = Inherited TM/HM move. V203 = Genderless Pokémon should not have a gender. V201 = Encryption Constant is not set. V204 = Held item is unreleased. @@ -259,4 +263,11 @@ V335 = Generation 1 exclusive move. Incompatible with Non-tradeback egg moves. V336 = Egg Move. Incompatible with event egg moves. V337 = Event Egg Move. Incompatible with normal egg moves. V338 = Defog and whirpool. One of the two moves should have been removed before transfered to generation 5. -V339 = Generation {0} HM. Should have been removed before transfered to generation {1}. \ No newline at end of file +V339 = Generation {0} HM. Should have been removed before transfered to generation {1}. +V340 = Not an expected egg move. +V341 = Inherited Egg Move. Not expected in an event egg. +V342 = Event egg move missing. +V343 = Expected the following Moves: {0} +V347 = Inherited move learned by Level-up. Not expected in an event egg. +V348 = Inherited tutor move. Not expected in an event egg. +V350 = Inherited TM/HM move. Not expected in an event egg. \ No newline at end of file From d7156f1f421ed2ce99a94c1c67e77e01a7c7fd16 Mon Sep 17 00:00:00 2001 From: javierhimura Date: Sun, 26 Mar 2017 18:14:15 +0200 Subject: [PATCH 08/15] Fix smeargle check, should be after verifyMovesIsEggPreRelearn but before verifyMovesWasEggPreRelearn --- PKHeX/Legality/Checks.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PKHeX/Legality/Checks.cs b/PKHeX/Legality/Checks.cs index 18510fa5a..2d60aa058 100644 --- a/PKHeX/Legality/Checks.cs +++ b/PKHeX/Legality/Checks.cs @@ -2084,10 +2084,10 @@ private CheckResult[] verifyMoves(GameVersion game = GameVersion.Any) res = verifyMovesIsEggPreRelearn(Moves, SpecialMoves ?? new int[0], allowinherited); } } - else if (pkm.WasEgg && pkm.GenNumber < 6) - res = verifyMovesWasEggPreRelearn(Moves, validLevelMoves, validTMHM, validTutor); else if (pkm.Species == 235) // Smeargle can have any move except a few res = parseMovesSketch(Moves); + else if (pkm.WasEgg && pkm.GenNumber < 6) + res = verifyMovesWasEggPreRelearn(Moves, validLevelMoves, validTMHM, validTutor); else if (EventGiftMatch?.Count > 1) // Multiple possible Mystery Gifts matched, get the best match too res = parseMovesGetGift(Moves, validLevelMoves, validTMHM, validTutor); else // Everything else From aecd3f97382223ba392752ce8da43476a6558cc3 Mon Sep 17 00:00:00 2001 From: javierhimura Date: Sun, 26 Mar 2017 18:24:02 +0200 Subject: [PATCH 09/15] Fix error loading save from gen 2 when pokeball does not have elements --- PKHeX.WinForms/MainWindow/Main.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PKHeX.WinForms/MainWindow/Main.cs b/PKHeX.WinForms/MainWindow/Main.cs index 222900247..163bffadb 100644 --- a/PKHeX.WinForms/MainWindow/Main.cs +++ b/PKHeX.WinForms/MainWindow/Main.cs @@ -2904,7 +2904,7 @@ private void validateComboBox(object sender) if (cb == null) return; - if (cb.Text == "") + if (cb.Text == "" && cb.Items.Count > 0) { cb.SelectedIndex = 0; return; } if (cb.SelectedValue == null) cb.BackColor = Color.DarkSalmon; From 620df347f07e4529bf7faddd1e7919400a49c9b1 Mon Sep 17 00:00:00 2001 From: javierhimura Date: Sun, 26 Mar 2017 18:29:50 +0200 Subject: [PATCH 10/15] There is no need to check egg moves both times for gold/silver and crystal, gold/silver egg moves is a subset of crystal egg moves, every legal combination from g/s is also a legal combination in crystal --- PKHeX/Legality/Checks.cs | 90 +++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 52 deletions(-) diff --git a/PKHeX/Legality/Checks.cs b/PKHeX/Legality/Checks.cs index 2d60aa058..7cd026dda 100644 --- a/PKHeX/Legality/Checks.cs +++ b/PKHeX/Legality/Checks.cs @@ -2100,29 +2100,25 @@ private CheckResult[] verifyMoves(GameVersion game = GameVersion.Any) return res; } - private GameVersion[] getBaseMovesIsEggGames() + private GameVersion getBaseMovesIsEggGames() { - GameVersion[] Games = { }; switch (pkm.GenNumber) { case 1: case 2: - Games = new[] { GameVersion.GS, GameVersion.C }; - break; + // Every egg move from Gold/Silver is included in Crystal + return GameVersion.C ; case 3: switch((GameVersion)pkm.Version) { case GameVersion.R: case GameVersion.S: - Games = new[] { GameVersion.RS}; - break; + return GameVersion.RS; case GameVersion.E: - Games = new[] { GameVersion.E }; - break; + return GameVersion.E; case GameVersion.FR: case GameVersion.LG: - Games = new[] { GameVersion.FRLG }; - break; + return GameVersion.FRLG; } break; case 4: @@ -2130,15 +2126,12 @@ private GameVersion[] getBaseMovesIsEggGames() { case GameVersion.D: case GameVersion.P: - Games = new[] { GameVersion.DP }; - break; + return GameVersion.DP; case GameVersion.Pt: - Games = new[] { GameVersion.Pt }; - break; + return GameVersion.Pt; case GameVersion.HG: case GameVersion.SS: - Games = new[] { GameVersion.HGSS }; - break; + return GameVersion.HGSS; } break; case 5: @@ -2146,54 +2139,46 @@ private GameVersion[] getBaseMovesIsEggGames() { case GameVersion.B: case GameVersion.W: - Games = new[] { GameVersion.BW }; - break; - case GameVersion.Pt: - Games = new[] { GameVersion.Pt }; - break; + return GameVersion.BW; case GameVersion.B2: case GameVersion.W2: - Games = new[] { GameVersion.B2W2 }; - break; + return GameVersion.B2W2; } break; } - return Games; + return GameVersion.Any; } private CheckResult[] verifyMovesIsEggPreRelearn(int[] Moves, int[] SpecialMoves, bool allowinherited) { CheckResult[] res = new CheckResult[4]; var ValidSpecialMoves = SpecialMoves.Where(m => m > 0); // Some games can have different egg movepools. Have to check all situations. - GameVersion[] Games = getBaseMovesIsEggGames(); + GameVersion Game = getBaseMovesIsEggGames(); int splitctr = Legal.getSplitBreedGeneration(pkm).Contains(pkm.Species) ? 1 : 0; - foreach (var ver in Games) + for (int i = 0; i <= splitctr; i++) { - for (int i = 0; i <= splitctr; i++) - { - var baseEggMoves = Legal.getBaseEggMoves(pkm, i, ver, pkm.GenNumber < 4 ? 5 : 1)?.ToList() ?? new List(); - var InheritedLvlMoves = Legal.getBaseEggMoves(pkm, i, ver, 100) ?? new List(); - var EggMoves = Legal.getEggMoves(pkm, ver)?.ToList() ?? new List(); - var InheritedTutorMoves = (ver == GameVersion.C) ? Legal.getTutorMoves(pkm, pkm.Species, pkm.AltForm, false, 2) : new int[0]; - // Only TM Hm moves from the source game of the egg, not any other games from the same generation - var InheritedTMHMMoves = Legal.getTMHM(pkm, pkm.Species, pkm.AltForm, pkm.GenNumber, ver, false); - InheritedLvlMoves = InheritedLvlMoves.Except(baseEggMoves); + var baseEggMoves = Legal.getBaseEggMoves(pkm, i, Game, pkm.GenNumber < 4 ? 5 : 1)?.ToList() ?? new List(); + var InheritedLvlMoves = Legal.getBaseEggMoves(pkm, i, Game, 100) ?? new List(); + var EggMoves = Legal.getEggMoves(pkm, Game)?.ToList() ?? new List(); + var InheritedTutorMoves = (Game == GameVersion.C) ? Legal.getTutorMoves(pkm, pkm.Species, pkm.AltForm, false, 2) : new int[0]; + // Only TM Hm moves from the source game of the egg, not any other games from the same generation + var InheritedTMHMMoves = Legal.getTMHM(pkm, pkm.Species, pkm.AltForm, pkm.GenNumber, Game, false); + InheritedLvlMoves = InheritedLvlMoves.Except(baseEggMoves); - if (pkm.Format > 2 || SpecialMoves.Any()) - { - // For gen 2 is not possible to difference normal eggs from event eggs - // If there is no special moves assume normal egg - res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, ValidSpecialMoves, allowinherited, ver); - if (res.All(r => r.Valid)) // moves is satisfactory - return res; - } - if(pkm.Format == 2) - { - // For gen 2 if does not match special egg check for normal egg too - res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, new List(), true, ver); - if (res.All(r => r.Valid)) // moves is satisfactory - return res; - } + if (pkm.Format > 2 || SpecialMoves.Any()) + { + // For gen 2 is not possible to difference normal eggs from event eggs + // If there is no special moves assume normal egg + res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, ValidSpecialMoves, allowinherited, Game); + if (res.All(r => r.Valid)) // moves is satisfactory + return res; + } + if(pkm.Format == 2) + { + // For gen 2 if does not match special egg check for normal egg too + res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, new List(), true, Game); + if (res.All(r => r.Valid)) // moves is satisfactory + return res; } } return res; @@ -2208,10 +2193,11 @@ private CheckResult[] verifyMovesWasEggPreRelearn(int[] Moves, List[] valid { case 1: case 2: - Games = new[] { GameVersion.GS, GameVersion.C }; + // Every egg move from Gold/Silver is included in Crystal + Games = new[] { GameVersion.C }; break; case 3: // Generation 3 does not overwrite source game after pokemon hatched - Games = getBaseMovesIsEggGames(); + Games = new[] { getBaseMovesIsEggGames() }; break; case 4: Games = new[] { GameVersion.DP, GameVersion.Pt, GameVersion.HGSS }; From b950879065ecb5aab00e460a905f503c9b09c598 Mon Sep 17 00:00:00 2001 From: javierhimura Date: Sun, 26 Mar 2017 18:37:17 +0200 Subject: [PATCH 11/15] Revert "There is no need to check egg moves both times for gold/silver and crystal, gold/silver egg moves is a subset of crystal egg moves, every legal combination from g/s is also a legal combination in crystal" This reverts commit 620df347f07e4529bf7faddd1e7919400a49c9b1. --- PKHeX/Legality/Checks.cs | 90 +++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 38 deletions(-) diff --git a/PKHeX/Legality/Checks.cs b/PKHeX/Legality/Checks.cs index 7cd026dda..2d60aa058 100644 --- a/PKHeX/Legality/Checks.cs +++ b/PKHeX/Legality/Checks.cs @@ -2100,25 +2100,29 @@ private CheckResult[] verifyMoves(GameVersion game = GameVersion.Any) return res; } - private GameVersion getBaseMovesIsEggGames() + private GameVersion[] getBaseMovesIsEggGames() { + GameVersion[] Games = { }; switch (pkm.GenNumber) { case 1: case 2: - // Every egg move from Gold/Silver is included in Crystal - return GameVersion.C ; + Games = new[] { GameVersion.GS, GameVersion.C }; + break; case 3: switch((GameVersion)pkm.Version) { case GameVersion.R: case GameVersion.S: - return GameVersion.RS; + Games = new[] { GameVersion.RS}; + break; case GameVersion.E: - return GameVersion.E; + Games = new[] { GameVersion.E }; + break; case GameVersion.FR: case GameVersion.LG: - return GameVersion.FRLG; + Games = new[] { GameVersion.FRLG }; + break; } break; case 4: @@ -2126,12 +2130,15 @@ private GameVersion getBaseMovesIsEggGames() { case GameVersion.D: case GameVersion.P: - return GameVersion.DP; + Games = new[] { GameVersion.DP }; + break; case GameVersion.Pt: - return GameVersion.Pt; + Games = new[] { GameVersion.Pt }; + break; case GameVersion.HG: case GameVersion.SS: - return GameVersion.HGSS; + Games = new[] { GameVersion.HGSS }; + break; } break; case 5: @@ -2139,46 +2146,54 @@ private GameVersion getBaseMovesIsEggGames() { case GameVersion.B: case GameVersion.W: - return GameVersion.BW; + Games = new[] { GameVersion.BW }; + break; + case GameVersion.Pt: + Games = new[] { GameVersion.Pt }; + break; case GameVersion.B2: case GameVersion.W2: - return GameVersion.B2W2; + Games = new[] { GameVersion.B2W2 }; + break; } break; } - return GameVersion.Any; + return Games; } private CheckResult[] verifyMovesIsEggPreRelearn(int[] Moves, int[] SpecialMoves, bool allowinherited) { CheckResult[] res = new CheckResult[4]; var ValidSpecialMoves = SpecialMoves.Where(m => m > 0); // Some games can have different egg movepools. Have to check all situations. - GameVersion Game = getBaseMovesIsEggGames(); + GameVersion[] Games = getBaseMovesIsEggGames(); int splitctr = Legal.getSplitBreedGeneration(pkm).Contains(pkm.Species) ? 1 : 0; - for (int i = 0; i <= splitctr; i++) + foreach (var ver in Games) { - var baseEggMoves = Legal.getBaseEggMoves(pkm, i, Game, pkm.GenNumber < 4 ? 5 : 1)?.ToList() ?? new List(); - var InheritedLvlMoves = Legal.getBaseEggMoves(pkm, i, Game, 100) ?? new List(); - var EggMoves = Legal.getEggMoves(pkm, Game)?.ToList() ?? new List(); - var InheritedTutorMoves = (Game == GameVersion.C) ? Legal.getTutorMoves(pkm, pkm.Species, pkm.AltForm, false, 2) : new int[0]; - // Only TM Hm moves from the source game of the egg, not any other games from the same generation - var InheritedTMHMMoves = Legal.getTMHM(pkm, pkm.Species, pkm.AltForm, pkm.GenNumber, Game, false); - InheritedLvlMoves = InheritedLvlMoves.Except(baseEggMoves); + for (int i = 0; i <= splitctr; i++) + { + var baseEggMoves = Legal.getBaseEggMoves(pkm, i, ver, pkm.GenNumber < 4 ? 5 : 1)?.ToList() ?? new List(); + var InheritedLvlMoves = Legal.getBaseEggMoves(pkm, i, ver, 100) ?? new List(); + var EggMoves = Legal.getEggMoves(pkm, ver)?.ToList() ?? new List(); + var InheritedTutorMoves = (ver == GameVersion.C) ? Legal.getTutorMoves(pkm, pkm.Species, pkm.AltForm, false, 2) : new int[0]; + // Only TM Hm moves from the source game of the egg, not any other games from the same generation + var InheritedTMHMMoves = Legal.getTMHM(pkm, pkm.Species, pkm.AltForm, pkm.GenNumber, ver, false); + InheritedLvlMoves = InheritedLvlMoves.Except(baseEggMoves); - if (pkm.Format > 2 || SpecialMoves.Any()) - { - // For gen 2 is not possible to difference normal eggs from event eggs - // If there is no special moves assume normal egg - res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, ValidSpecialMoves, allowinherited, Game); - if (res.All(r => r.Valid)) // moves is satisfactory - return res; - } - if(pkm.Format == 2) - { - // For gen 2 if does not match special egg check for normal egg too - res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, new List(), true, Game); - if (res.All(r => r.Valid)) // moves is satisfactory - return res; + if (pkm.Format > 2 || SpecialMoves.Any()) + { + // For gen 2 is not possible to difference normal eggs from event eggs + // If there is no special moves assume normal egg + res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, ValidSpecialMoves, allowinherited, ver); + if (res.All(r => r.Valid)) // moves is satisfactory + return res; + } + if(pkm.Format == 2) + { + // For gen 2 if does not match special egg check for normal egg too + res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, new List(), true, ver); + if (res.All(r => r.Valid)) // moves is satisfactory + return res; + } } } return res; @@ -2193,11 +2208,10 @@ private CheckResult[] verifyMovesWasEggPreRelearn(int[] Moves, List[] valid { case 1: case 2: - // Every egg move from Gold/Silver is included in Crystal - Games = new[] { GameVersion.C }; + Games = new[] { GameVersion.GS, GameVersion.C }; break; case 3: // Generation 3 does not overwrite source game after pokemon hatched - Games = new[] { getBaseMovesIsEggGames() }; + Games = getBaseMovesIsEggGames(); break; case 4: Games = new[] { GameVersion.DP, GameVersion.Pt, GameVersion.HGSS }; From 59750b8cfe6daf907f4b38fa93d73c0e1e3dc7c2 Mon Sep 17 00:00:00 2001 From: javierhimura Date: Sun, 26 Mar 2017 18:42:20 +0200 Subject: [PATCH 12/15] The last commit was reverted because the change should not apply to base moves from was egg pokemon, unlike egg moves base level moves are not equal among all generations. Also for generation 2 check if pokemon have crystal location for the was egg base moves --- PKHeX/Legality/Checks.cs | 103 +++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 53 deletions(-) diff --git a/PKHeX/Legality/Checks.cs b/PKHeX/Legality/Checks.cs index 2d60aa058..11b8ccbbd 100644 --- a/PKHeX/Legality/Checks.cs +++ b/PKHeX/Legality/Checks.cs @@ -2100,29 +2100,37 @@ private CheckResult[] verifyMoves(GameVersion game = GameVersion.Any) return res; } - private GameVersion[] getBaseMovesIsEggGames() + private GameVersion[] getBaseGamesWasEggGen2() + { + if (pkm.Format != 2) + return new[] { GameVersion.GS, GameVersion.C }; + + if (pkm.HasOriginalMetLocation) + return new[] { GameVersion.C }; + if (pkm.Species > 151 && !Legal.FutureEvolutionsGen1.Contains(pkm.Species)) + return new[] { GameVersion.GS }; + + return new[] { GameVersion.GS, GameVersion.C }; + } + private GameVersion getBaseGamesWasEgg() { - GameVersion[] Games = { }; switch (pkm.GenNumber) { case 1: case 2: - Games = new[] { GameVersion.GS, GameVersion.C }; - break; + // Every egg move from Gold/Silver is included in Crystal + return GameVersion.C; case 3: - switch((GameVersion)pkm.Version) + switch ((GameVersion)pkm.Version) { case GameVersion.R: case GameVersion.S: - Games = new[] { GameVersion.RS}; - break; + return GameVersion.RS; case GameVersion.E: - Games = new[] { GameVersion.E }; - break; + return GameVersion.E; case GameVersion.FR: case GameVersion.LG: - Games = new[] { GameVersion.FRLG }; - break; + return GameVersion.FRLG; } break; case 4: @@ -2130,15 +2138,12 @@ private GameVersion[] getBaseMovesIsEggGames() { case GameVersion.D: case GameVersion.P: - Games = new[] { GameVersion.DP }; - break; + return GameVersion.DP; case GameVersion.Pt: - Games = new[] { GameVersion.Pt }; - break; + return GameVersion.Pt; case GameVersion.HG: case GameVersion.SS: - Games = new[] { GameVersion.HGSS }; - break; + return GameVersion.HGSS; } break; case 5: @@ -2146,54 +2151,46 @@ private GameVersion[] getBaseMovesIsEggGames() { case GameVersion.B: case GameVersion.W: - Games = new[] { GameVersion.BW }; - break; - case GameVersion.Pt: - Games = new[] { GameVersion.Pt }; - break; + return GameVersion.BW; case GameVersion.B2: case GameVersion.W2: - Games = new[] { GameVersion.B2W2 }; - break; + return GameVersion.B2W2; } break; } - return Games; + return GameVersion.Any; } private CheckResult[] verifyMovesIsEggPreRelearn(int[] Moves, int[] SpecialMoves, bool allowinherited) { CheckResult[] res = new CheckResult[4]; var ValidSpecialMoves = SpecialMoves.Where(m => m > 0); // Some games can have different egg movepools. Have to check all situations. - GameVersion[] Games = getBaseMovesIsEggGames(); + GameVersion ver = getBaseGamesWasEgg(); int splitctr = Legal.getSplitBreedGeneration(pkm).Contains(pkm.Species) ? 1 : 0; - foreach (var ver in Games) + for (int i = 0; i <= splitctr; i++) { - for (int i = 0; i <= splitctr; i++) - { - var baseEggMoves = Legal.getBaseEggMoves(pkm, i, ver, pkm.GenNumber < 4 ? 5 : 1)?.ToList() ?? new List(); - var InheritedLvlMoves = Legal.getBaseEggMoves(pkm, i, ver, 100) ?? new List(); - var EggMoves = Legal.getEggMoves(pkm, ver)?.ToList() ?? new List(); - var InheritedTutorMoves = (ver == GameVersion.C) ? Legal.getTutorMoves(pkm, pkm.Species, pkm.AltForm, false, 2) : new int[0]; - // Only TM Hm moves from the source game of the egg, not any other games from the same generation - var InheritedTMHMMoves = Legal.getTMHM(pkm, pkm.Species, pkm.AltForm, pkm.GenNumber, ver, false); - InheritedLvlMoves = InheritedLvlMoves.Except(baseEggMoves); + var baseEggMoves = Legal.getBaseEggMoves(pkm, i, ver, pkm.GenNumber < 4 ? 5 : 1)?.ToList() ?? new List(); + var InheritedLvlMoves = Legal.getBaseEggMoves(pkm, i, ver, 100) ?? new List(); + var EggMoves = Legal.getEggMoves(pkm, ver)?.ToList() ?? new List(); + var InheritedTutorMoves = (ver == GameVersion.C) ? Legal.getTutorMoves(pkm, pkm.Species, pkm.AltForm, false, 2) : new int[0]; + // Only TM Hm moves from the source game of the egg, not any other games from the same generation + var InheritedTMHMMoves = Legal.getTMHM(pkm, pkm.Species, pkm.AltForm, pkm.GenNumber, ver, false); + InheritedLvlMoves = InheritedLvlMoves.Except(baseEggMoves); - if (pkm.Format > 2 || SpecialMoves.Any()) - { - // For gen 2 is not possible to difference normal eggs from event eggs - // If there is no special moves assume normal egg - res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, ValidSpecialMoves, allowinherited, ver); - if (res.All(r => r.Valid)) // moves is satisfactory - return res; - } - if(pkm.Format == 2) - { - // For gen 2 if does not match special egg check for normal egg too - res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, new List(), true, ver); - if (res.All(r => r.Valid)) // moves is satisfactory - return res; - } + if (pkm.Format > 2 || SpecialMoves.Any()) + { + // For gen 2 is not possible to difference normal eggs from event eggs + // If there is no special moves assume normal egg + res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, ValidSpecialMoves, allowinherited, ver); + if (res.All(r => r.Valid)) // moves is satisfactory + return res; + } + if(pkm.Format == 2) + { + // For gen 2 if does not match special egg check for normal egg too + res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, new List(), true, ver); + if (res.All(r => r.Valid)) // moves is satisfactory + return res; } } return res; @@ -2208,10 +2205,10 @@ private CheckResult[] verifyMovesWasEggPreRelearn(int[] Moves, List[] valid { case 1: case 2: - Games = new[] { GameVersion.GS, GameVersion.C }; + Games = getBaseGamesWasEggGen2(); break; case 3: // Generation 3 does not overwrite source game after pokemon hatched - Games = getBaseMovesIsEggGames(); + Games = new[] { getBaseGamesWasEgg() }; break; case 4: Games = new[] { GameVersion.DP, GameVersion.Pt, GameVersion.HGSS }; From ca63bf2e511958684db8d7076e4da20f0cbe664d Mon Sep 17 00:00:00 2001 From: javierhimura Date: Sun, 26 Mar 2017 18:45:01 +0200 Subject: [PATCH 13/15] Names changed to avoid confusions --- PKHeX/Legality/Checks.cs | 6 +++--- PKHeX/Legality/Core.cs | 2 +- PKHeX/Legality/Tables3.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/PKHeX/Legality/Checks.cs b/PKHeX/Legality/Checks.cs index 11b8ccbbd..03482306b 100644 --- a/PKHeX/Legality/Checks.cs +++ b/PKHeX/Legality/Checks.cs @@ -2112,7 +2112,7 @@ private GameVersion[] getBaseGamesWasEggGen2() return new[] { GameVersion.GS, GameVersion.C }; } - private GameVersion getBaseGamesWasEgg() + private GameVersion getBaseGamesIsEgg() { switch (pkm.GenNumber) { @@ -2165,7 +2165,7 @@ private CheckResult[] verifyMovesIsEggPreRelearn(int[] Moves, int[] SpecialMoves CheckResult[] res = new CheckResult[4]; var ValidSpecialMoves = SpecialMoves.Where(m => m > 0); // Some games can have different egg movepools. Have to check all situations. - GameVersion ver = getBaseGamesWasEgg(); + GameVersion ver = getBaseGamesIsEgg(); int splitctr = Legal.getSplitBreedGeneration(pkm).Contains(pkm.Species) ? 1 : 0; for (int i = 0; i <= splitctr; i++) { @@ -2208,7 +2208,7 @@ private CheckResult[] verifyMovesWasEggPreRelearn(int[] Moves, List[] valid Games = getBaseGamesWasEggGen2(); break; case 3: // Generation 3 does not overwrite source game after pokemon hatched - Games = new[] { getBaseGamesWasEgg() }; + Games = new[] { getBaseGamesIsEgg() }; break; case 4: Games = new[] { GameVersion.DP, GameVersion.Pt, GameVersion.HGSS }; diff --git a/PKHeX/Legality/Core.cs b/PKHeX/Legality/Core.cs index 1501ac315..0f73d55ce 100644 --- a/PKHeX/Legality/Core.cs +++ b/PKHeX/Legality/Core.cs @@ -1665,7 +1665,7 @@ internal static int getMaxLevelGeneration(PKM pkm, int generation) 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)) + if (pkm.Gen3 && pkm.Format > 4 && pkm.Met_Level == pkm.CurrentLevel && FutureEvolutionsGen3_LevelUpGen4.Contains(pkm.Species)) return pkm.Met_Level - 1; if (!pkm.HasOriginalMetLocation) diff --git a/PKHeX/Legality/Tables3.cs b/PKHeX/Legality/Tables3.cs index e564499d7..69e4cd50f 100644 --- a/PKHeX/Legality/Tables3.cs +++ b/PKHeX/Legality/Tables3.cs @@ -96,7 +96,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 = + internal static readonly int[] FutureEvolutionsGen3_LevelUpGen4 = { 424, 461, 462, 463, 465, 469, 470, 471, 472, 473, 476 }; From d9d138d2a544b601fffa1f3f03eeeaf6bc7aa591 Mon Sep 17 00:00:00 2001 From: javierhimura Date: Sun, 26 Mar 2017 18:47:26 +0200 Subject: [PATCH 14/15] Fix getBaseGamesIsEgg, there is some cases when crystal origin can be discarted --- PKHeX/Legality/Checks.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/PKHeX/Legality/Checks.cs b/PKHeX/Legality/Checks.cs index 03482306b..64bae981d 100644 --- a/PKHeX/Legality/Checks.cs +++ b/PKHeX/Legality/Checks.cs @@ -2119,6 +2119,14 @@ private GameVersion getBaseGamesIsEgg() case 1: case 2: // Every egg move from Gold/Silver is included in Crystal + if (pkm.Format != 2) + return GameVersion.C; + + if (pkm.HasOriginalMetLocation) + return GameVersion.C; + if (pkm.Species > 151 && !Legal.FutureEvolutionsGen1.Contains(pkm.Species)) + return GameVersion.GS; + return GameVersion.C; case 3: switch ((GameVersion)pkm.Version) From d85f2444fc7df294d5793c504f985ada54f8ede7 Mon Sep 17 00:00:00 2001 From: javierhimura Date: Sun, 26 Mar 2017 19:17:30 +0200 Subject: [PATCH 15/15] Revert "The last commit was reverted because the change should not apply to base moves from was egg pokemon, unlike egg moves base level moves are not equal among all generations." Pokemon crystal does not store egg received location like generation 3 games, that means both crystal and gold/silver should be checked for base egg moves always --- PKHeX/Legality/Checks.cs | 111 +++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 58 deletions(-) diff --git a/PKHeX/Legality/Checks.cs b/PKHeX/Legality/Checks.cs index 64bae981d..2d60aa058 100644 --- a/PKHeX/Legality/Checks.cs +++ b/PKHeX/Legality/Checks.cs @@ -2100,45 +2100,29 @@ private CheckResult[] verifyMoves(GameVersion game = GameVersion.Any) return res; } - private GameVersion[] getBaseGamesWasEggGen2() - { - if (pkm.Format != 2) - return new[] { GameVersion.GS, GameVersion.C }; - - if (pkm.HasOriginalMetLocation) - return new[] { GameVersion.C }; - if (pkm.Species > 151 && !Legal.FutureEvolutionsGen1.Contains(pkm.Species)) - return new[] { GameVersion.GS }; - - return new[] { GameVersion.GS, GameVersion.C }; - } - private GameVersion getBaseGamesIsEgg() + private GameVersion[] getBaseMovesIsEggGames() { + GameVersion[] Games = { }; switch (pkm.GenNumber) { case 1: case 2: - // Every egg move from Gold/Silver is included in Crystal - if (pkm.Format != 2) - return GameVersion.C; - - if (pkm.HasOriginalMetLocation) - return GameVersion.C; - if (pkm.Species > 151 && !Legal.FutureEvolutionsGen1.Contains(pkm.Species)) - return GameVersion.GS; - - return GameVersion.C; + Games = new[] { GameVersion.GS, GameVersion.C }; + break; case 3: - switch ((GameVersion)pkm.Version) + switch((GameVersion)pkm.Version) { case GameVersion.R: case GameVersion.S: - return GameVersion.RS; + Games = new[] { GameVersion.RS}; + break; case GameVersion.E: - return GameVersion.E; + Games = new[] { GameVersion.E }; + break; case GameVersion.FR: case GameVersion.LG: - return GameVersion.FRLG; + Games = new[] { GameVersion.FRLG }; + break; } break; case 4: @@ -2146,12 +2130,15 @@ private GameVersion getBaseGamesIsEgg() { case GameVersion.D: case GameVersion.P: - return GameVersion.DP; + Games = new[] { GameVersion.DP }; + break; case GameVersion.Pt: - return GameVersion.Pt; + Games = new[] { GameVersion.Pt }; + break; case GameVersion.HG: case GameVersion.SS: - return GameVersion.HGSS; + Games = new[] { GameVersion.HGSS }; + break; } break; case 5: @@ -2159,46 +2146,54 @@ private GameVersion getBaseGamesIsEgg() { case GameVersion.B: case GameVersion.W: - return GameVersion.BW; + Games = new[] { GameVersion.BW }; + break; + case GameVersion.Pt: + Games = new[] { GameVersion.Pt }; + break; case GameVersion.B2: case GameVersion.W2: - return GameVersion.B2W2; + Games = new[] { GameVersion.B2W2 }; + break; } break; } - return GameVersion.Any; + return Games; } private CheckResult[] verifyMovesIsEggPreRelearn(int[] Moves, int[] SpecialMoves, bool allowinherited) { CheckResult[] res = new CheckResult[4]; var ValidSpecialMoves = SpecialMoves.Where(m => m > 0); // Some games can have different egg movepools. Have to check all situations. - GameVersion ver = getBaseGamesIsEgg(); + GameVersion[] Games = getBaseMovesIsEggGames(); int splitctr = Legal.getSplitBreedGeneration(pkm).Contains(pkm.Species) ? 1 : 0; - for (int i = 0; i <= splitctr; i++) + foreach (var ver in Games) { - var baseEggMoves = Legal.getBaseEggMoves(pkm, i, ver, pkm.GenNumber < 4 ? 5 : 1)?.ToList() ?? new List(); - var InheritedLvlMoves = Legal.getBaseEggMoves(pkm, i, ver, 100) ?? new List(); - var EggMoves = Legal.getEggMoves(pkm, ver)?.ToList() ?? new List(); - var InheritedTutorMoves = (ver == GameVersion.C) ? Legal.getTutorMoves(pkm, pkm.Species, pkm.AltForm, false, 2) : new int[0]; - // Only TM Hm moves from the source game of the egg, not any other games from the same generation - var InheritedTMHMMoves = Legal.getTMHM(pkm, pkm.Species, pkm.AltForm, pkm.GenNumber, ver, false); - InheritedLvlMoves = InheritedLvlMoves.Except(baseEggMoves); + for (int i = 0; i <= splitctr; i++) + { + var baseEggMoves = Legal.getBaseEggMoves(pkm, i, ver, pkm.GenNumber < 4 ? 5 : 1)?.ToList() ?? new List(); + var InheritedLvlMoves = Legal.getBaseEggMoves(pkm, i, ver, 100) ?? new List(); + var EggMoves = Legal.getEggMoves(pkm, ver)?.ToList() ?? new List(); + var InheritedTutorMoves = (ver == GameVersion.C) ? Legal.getTutorMoves(pkm, pkm.Species, pkm.AltForm, false, 2) : new int[0]; + // Only TM Hm moves from the source game of the egg, not any other games from the same generation + var InheritedTMHMMoves = Legal.getTMHM(pkm, pkm.Species, pkm.AltForm, pkm.GenNumber, ver, false); + InheritedLvlMoves = InheritedLvlMoves.Except(baseEggMoves); - if (pkm.Format > 2 || SpecialMoves.Any()) - { - // For gen 2 is not possible to difference normal eggs from event eggs - // If there is no special moves assume normal egg - res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, ValidSpecialMoves, allowinherited, ver); - if (res.All(r => r.Valid)) // moves is satisfactory - return res; - } - if(pkm.Format == 2) - { - // For gen 2 if does not match special egg check for normal egg too - res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, new List(), true, ver); - if (res.All(r => r.Valid)) // moves is satisfactory - return res; + if (pkm.Format > 2 || SpecialMoves.Any()) + { + // For gen 2 is not possible to difference normal eggs from event eggs + // If there is no special moves assume normal egg + res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, ValidSpecialMoves, allowinherited, ver); + if (res.All(r => r.Valid)) // moves is satisfactory + return res; + } + if(pkm.Format == 2) + { + // For gen 2 if does not match special egg check for normal egg too + res = verifyPreRelearnEggBase(Moves, baseEggMoves, EggMoves, InheritedLvlMoves, InheritedTMHMMoves, InheritedTutorMoves, new List(), true, ver); + if (res.All(r => r.Valid)) // moves is satisfactory + return res; + } } } return res; @@ -2213,10 +2208,10 @@ private CheckResult[] verifyMovesWasEggPreRelearn(int[] Moves, List[] valid { case 1: case 2: - Games = getBaseGamesWasEggGen2(); + Games = new[] { GameVersion.GS, GameVersion.C }; break; case 3: // Generation 3 does not overwrite source game after pokemon hatched - Games = new[] { getBaseGamesIsEgg() }; + Games = getBaseMovesIsEggGames(); break; case 4: Games = new[] { GameVersion.DP, GameVersion.Pt, GameVersion.HGSS };