mirror of
https://github.com/kwsch/PKHeX
synced 2025-02-17 05:48:44 +00:00
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
This commit is contained in:
parent
8e703e17fb
commit
53984c1807
4 changed files with 211 additions and 19 deletions
|
@ -2070,12 +2070,24 @@ namespace PKHeX.Core
|
|||
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 @@ namespace PKHeX.Core
|
|||
|
||||
return res;
|
||||
}
|
||||
private CheckResult[] verifyMovesEggPreRelearn(int[] Moves, List<int>[] validLevelMoves, List<int>[] validTMHM, List<int>[] 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 @@ namespace PKHeX.Core
|
|||
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<int>();
|
||||
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 @@ namespace PKHeX.Core
|
|||
}
|
||||
|
||||
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 @@ namespace PKHeX.Core
|
|||
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<int> 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;
|
||||
|
|
|
@ -1371,6 +1371,25 @@ namespace PKHeX.Core
|
|||
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 @@ namespace PKHeX.Core
|
|||
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();
|
||||
}
|
||||
|
|
|
@ -325,7 +325,11 @@ namespace PKHeX.Core
|
|||
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
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,14 @@ namespace PKHeX.Core
|
|||
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
|
||||
|
|
Loading…
Add table
Reference in a new issue