mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-08-28 07:16:22 -05:00
Minor renaming/type change of passed args
Next commit will have more changes where we remove some reliance on PKM.GenNumber, in favor of the passed encounter's generation
This commit is contained in:
@@ -103,8 +103,7 @@ private static bool FilterGBSlotsCatchRate(PKM pkm, ref IReadOnlyList<EvoCriteri
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<EncounterSlot> GetFilteredSlots(PKM pkm, IEnumerable<EncounterSlot> slots,
|
||||
GameVersion Gen1Version, bool RBDragonair)
|
||||
private static IEnumerable<EncounterSlot> GetFilteredSlots(PKM pkm, IEnumerable<EncounterSlot> slots, GameVersion Gen1Version, bool RBDragonair)
|
||||
{
|
||||
int gen = pkm.GenNumber;
|
||||
switch (gen)
|
||||
|
||||
@@ -13,7 +13,7 @@ internal static class EncounterUtil
|
||||
/// </summary>
|
||||
/// <param name="source">Table of valid encounters that appear for the game pairing</param>
|
||||
/// <param name="game">Game to filter for</param>
|
||||
/// <returns>Array of encounter objects that are encounterable on the input game</returns>
|
||||
/// <returns>Array of encounter objects that can be encountered in the input game</returns>
|
||||
internal static EncounterStatic[] GetStaticEncounters(IEnumerable<EncounterStatic> source, GameVersion game)
|
||||
{
|
||||
return source.Where(s => s.Version.Contains(game)).ToArray();
|
||||
@@ -35,7 +35,7 @@ internal static T[] GetEncounterTables<T>(string ident, string resource) where T
|
||||
/// Direct fetch for <see cref="EncounterArea"/> data; can also be used to fetch supplementary encounter streams.
|
||||
/// </summary>
|
||||
/// <param name="ident">Unpacking identification ASCII characters (first two bytes of binary)</param>
|
||||
/// <param name="resource">Resource name (will be prefixed with "encounter_"</param>
|
||||
/// <param name="resource">Resource name (will be prefixed with "encounter_")</param>
|
||||
/// <returns>Array of encounter areas</returns>
|
||||
internal static T[] GetEncounterTables8<T>(string ident, string resource) where T : EncounterAreaSH, new()
|
||||
{
|
||||
@@ -61,13 +61,13 @@ internal static T[] AddExtraTableSlots<T>(params T[][] tables) where T : Encount
|
||||
/// Marks Encounter Slots for party lead's ability slot influencing.
|
||||
/// </summary>
|
||||
/// <remarks>Magnet Pull attracts Steel type slots, and Static attracts Electric</remarks>
|
||||
/// <param name="Areas">Encounter Area array for game</param>
|
||||
/// <param name="areas">Encounter Area array for game</param>
|
||||
/// <param name="t">Personal data for use with a given species' type</param>
|
||||
internal static void MarkEncountersStaticMagnetPull(IEnumerable<EncounterArea> Areas, PersonalTable t)
|
||||
internal static void MarkEncountersStaticMagnetPull(IEnumerable<EncounterArea> areas, PersonalTable t)
|
||||
{
|
||||
foreach (EncounterArea Area in Areas)
|
||||
foreach (EncounterArea area in areas)
|
||||
{
|
||||
foreach (var grp in Area.Slots.GroupBy(z => z.Type))
|
||||
foreach (var grp in area.Slots.GroupBy(z => z.Type))
|
||||
MarkEncountersStaticMagnetPull(grp, t);
|
||||
}
|
||||
}
|
||||
@@ -148,46 +148,46 @@ private static void GetStaticMagnet(PersonalTable t, IEnumerable<EncounterSlot>
|
||||
/// Sets the <see cref="EncounterSlot1.Version"/> value, for use in determining split-generation origins.
|
||||
/// </summary>
|
||||
/// <remarks>Only used for Gen 1 & 2, as <see cref="PKM.Version"/> data is not present.</remarks>
|
||||
/// <param name="Areas">Ingame encounter data</param>
|
||||
/// <param name="Version">Version ID to set</param>
|
||||
internal static void MarkEncountersVersion(IEnumerable<EncounterArea> Areas, GameVersion Version)
|
||||
/// <param name="areas">In-game encounter data</param>
|
||||
/// <param name="game">Version ID to set</param>
|
||||
internal static void MarkEncountersVersion(IEnumerable<EncounterArea> areas, GameVersion game)
|
||||
{
|
||||
foreach (EncounterArea Area in Areas)
|
||||
foreach (EncounterArea area in areas)
|
||||
{
|
||||
foreach (var Slot in Area.Slots)
|
||||
Slot.Version = Version;
|
||||
foreach (var Slot in area.Slots)
|
||||
Slot.Version = game;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="IGenerationSet.Generation"/> value.
|
||||
/// </summary>
|
||||
/// <param name="Generation">Generation number to set</param>
|
||||
/// <param name="Encounters">Ingame encounter data</param>
|
||||
internal static void MarkEncountersGeneration(int Generation, params IEnumerable<IGenerationSet>[] Encounters)
|
||||
/// <param name="generation">Generation number to set</param>
|
||||
/// <param name="encounters">In-game encounter data</param>
|
||||
internal static void MarkEncountersGeneration(int generation, params IEnumerable<IGenerationSet>[] encounters)
|
||||
{
|
||||
foreach (var table in Encounters)
|
||||
MarkEncountersGeneration(Generation, table);
|
||||
foreach (var table in encounters)
|
||||
MarkEncountersGeneration(generation, table);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the <see cref="IGenerationSet.Generation"/> value, for use in determining split-generation origins.
|
||||
/// </summary>
|
||||
/// <param name="Generation">Generation number to set</param>
|
||||
/// <param name="Areas">Ingame encounter data</param>
|
||||
internal static void MarkEncountersGeneration(int Generation, params IEnumerable<EncounterArea>[] Areas)
|
||||
/// <param name="generation">Generation number to set</param>
|
||||
/// <param name="areas">In-game encounter data</param>
|
||||
internal static void MarkEncountersGeneration(int generation, params IEnumerable<EncounterArea>[] areas)
|
||||
{
|
||||
foreach (var table in Areas)
|
||||
foreach (var table in areas)
|
||||
{
|
||||
foreach (var area in table)
|
||||
MarkEncountersGeneration(Generation, area.Slots);
|
||||
MarkEncountersGeneration(generation, area.Slots);
|
||||
}
|
||||
}
|
||||
|
||||
private static void MarkEncountersGeneration(int Generation, IEnumerable<IGenerationSet> Encounters)
|
||||
private static void MarkEncountersGeneration(int generation, IEnumerable<IGenerationSet> encounters)
|
||||
{
|
||||
foreach (var enc in Encounters)
|
||||
enc.Generation = Generation;
|
||||
foreach (var enc in encounters)
|
||||
enc.Generation = generation;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -19,7 +19,12 @@ public static class EncounterStaticGenerator
|
||||
public static IEnumerable<EncounterStatic> GetPossible(PKM pkm, GameVersion gameSource = GameVersion.Any)
|
||||
{
|
||||
int gen = pkm.GenNumber;
|
||||
int maxID = gen == 2 ? MaxSpeciesID_2 : gen == 1 ? MaxSpeciesID_1 : -1;
|
||||
int maxID = gen switch
|
||||
{
|
||||
1 => MaxSpeciesID_1,
|
||||
2 => MaxSpeciesID_2,
|
||||
_ => -1
|
||||
};
|
||||
var dl = EvolutionChain.GetValidPreEvolutions(pkm, maxID);
|
||||
return GetPossible(pkm, dl, gameSource);
|
||||
}
|
||||
|
||||
@@ -23,21 +23,21 @@ public static class VerifyCurrentMoves
|
||||
/// <returns>Validity of the <see cref="PKM.Moves"/></returns>
|
||||
public static CheckMoveResult[] VerifyMoves(PKM pkm, LegalInfo info)
|
||||
{
|
||||
int[] Moves = pkm.Moves;
|
||||
var res = ParseMovesForEncounters(pkm, info, Moves);
|
||||
var currentMoves = pkm.Moves;
|
||||
var res = ParseMovesForEncounters(pkm, info, currentMoves);
|
||||
|
||||
// Duplicate Moves Check
|
||||
VerifyNoEmptyDuplicates(Moves, res);
|
||||
if (Moves[0] == 0) // Can't have an empty moveslot for the first move.
|
||||
VerifyNoEmptyDuplicates(currentMoves, res);
|
||||
if (currentMoves[0] == 0) // Can't have an empty move slot for the first move.
|
||||
res[0] = new CheckMoveResult(res[0], Invalid, LMoveSourceEmpty, Move);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private static CheckMoveResult[] ParseMovesForEncounters(PKM pkm, LegalInfo info, int[] Moves)
|
||||
private static CheckMoveResult[] ParseMovesForEncounters(PKM pkm, LegalInfo info, IReadOnlyList<int> currentMoves)
|
||||
{
|
||||
if (pkm.Species == (int)Species.Smeargle) // special handling for Smeargle
|
||||
return ParseMovesForSmeargle(pkm, Moves, info); // Smeargle can have any moves except a few
|
||||
return ParseMovesForSmeargle(pkm, currentMoves, info); // Smeargle can have any moves except a few
|
||||
|
||||
// gather valid moves for encounter species
|
||||
var restrict = new LevelUpRestriction(pkm, info);
|
||||
@@ -64,8 +64,8 @@ private static CheckMoveResult[] ParseMovesForEncounters(PKM pkm, LegalInfo info
|
||||
}
|
||||
|
||||
var res = info.Generation < 6
|
||||
? ParseMovesPre3DS(pkm, Moves, info)
|
||||
: ParseMoves3DS(pkm, Moves, info);
|
||||
? ParseMovesPre3DS(pkm, currentMoves, info)
|
||||
: ParseMoves3DS(pkm, currentMoves, info);
|
||||
|
||||
if (res.All(x => x.Valid))
|
||||
return res;
|
||||
@@ -81,26 +81,26 @@ private static CheckMoveResult[] ParseMovesForEncounters(PKM pkm, LegalInfo info
|
||||
return res;
|
||||
}
|
||||
|
||||
private static CheckMoveResult[] ParseMovesForSmeargle(PKM pkm, int[] Moves, LegalInfo info)
|
||||
private static CheckMoveResult[] ParseMovesForSmeargle(PKM pkm, IReadOnlyList<int> currentMoves, LegalInfo info)
|
||||
{
|
||||
if (!pkm.IsEgg)
|
||||
return ParseMovesSketch(pkm, Moves);
|
||||
return ParseMovesSketch(pkm, currentMoves);
|
||||
|
||||
// can only know sketch as egg
|
||||
var levelup = new List<int>[info.EvoChainsAllGens.Length];
|
||||
levelup[pkm.Format] = new List<int>(1) {166};
|
||||
var levelup = new int[info.EvoChainsAllGens.Length][];
|
||||
levelup[pkm.Format] = new[] {166};
|
||||
info.EncounterMoves = new ValidEncounterMoves(levelup);
|
||||
var source = new MoveParseSource { CurrentMoves = pkm.Moves, };
|
||||
var source = new MoveParseSource { CurrentMoves = currentMoves, };
|
||||
return ParseMoves(pkm, source, info);
|
||||
}
|
||||
|
||||
private static CheckMoveResult[] ParseMovesIsEggPreRelearn(PKM pkm, int[] Moves, IReadOnlyList<int> SpecialMoves, EncounterEgg e)
|
||||
private static CheckMoveResult[] ParseMovesIsEggPreRelearn(PKM pkm, IReadOnlyList<int> currentMoves, EncounterEgg e)
|
||||
{
|
||||
var infoset = new EggInfoSource(pkm, SpecialMoves, e);
|
||||
return VerifyPreRelearnEggBase(pkm, Moves, infoset);
|
||||
var infoset = new EggInfoSource(pkm, e);
|
||||
return VerifyPreRelearnEggBase(pkm, currentMoves, infoset);
|
||||
}
|
||||
|
||||
private static CheckMoveResult[] ParseMovesWasEggPreRelearn(PKM pkm, int[] Moves, LegalInfo info, EncounterEgg e)
|
||||
private static CheckMoveResult[] ParseMovesWasEggPreRelearn(PKM pkm, IReadOnlyList<int> currentMoves, LegalInfo info, EncounterEgg e)
|
||||
{
|
||||
var EventEggMoves = GetSpecialMoves(info.EncounterMatch);
|
||||
bool notEvent = EventEggMoves.Count == 0;
|
||||
@@ -125,7 +125,7 @@ private static CheckMoveResult[] ParseMovesWasEggPreRelearn(PKM pkm, int[] Moves
|
||||
|
||||
var source = new MoveParseSource
|
||||
{
|
||||
CurrentMoves = Moves,
|
||||
CurrentMoves = currentMoves,
|
||||
SpecialSource = Special,
|
||||
NonTradeBackLevelUpMoves = NonTradebackLvlMoves,
|
||||
|
||||
@@ -136,12 +136,12 @@ private static CheckMoveResult[] ParseMovesWasEggPreRelearn(PKM pkm, int[] Moves
|
||||
return ParseMoves(pkm, source, info);
|
||||
}
|
||||
|
||||
private static CheckMoveResult[] ParseMovesSketch(PKM pkm, int[] Moves)
|
||||
private static CheckMoveResult[] ParseMovesSketch(PKM pkm, IReadOnlyList<int> currentMoves)
|
||||
{
|
||||
var res = new CheckMoveResult[4];
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
res[i] = Legal.InvalidSketch.Contains(Moves[i])
|
||||
res[i] = Legal.InvalidSketch.Contains(currentMoves[i])
|
||||
? new CheckMoveResult(Unknown, pkm.Format, Invalid, LMoveSourceInvalidSketch, Move)
|
||||
: new CheckMoveResult(Sketch, pkm.Format, Move);
|
||||
}
|
||||
@@ -149,39 +149,36 @@ private static CheckMoveResult[] ParseMovesSketch(PKM pkm, int[] Moves)
|
||||
return res;
|
||||
}
|
||||
|
||||
private static CheckMoveResult[] ParseMoves3DS(PKM pkm, int[] Moves, LegalInfo info)
|
||||
private static CheckMoveResult[] ParseMoves3DS(PKM pkm, IReadOnlyList<int> currentMoves, LegalInfo info)
|
||||
{
|
||||
info.EncounterMoves.Relearn = info.Generation >= 6 ? pkm.RelearnMoves : Array.Empty<int>();
|
||||
if (info.EncounterMatch is IMoveset)
|
||||
return ParseMovesSpecialMoveset(pkm, Moves, info);
|
||||
|
||||
// Everything else
|
||||
return ParseMovesRelearn(pkm, Moves, info);
|
||||
return info.EncounterMatch is IMoveset
|
||||
? ParseMovesSpecialMoveset(pkm, currentMoves, info)
|
||||
: ParseMovesRelearn(pkm, currentMoves, info);
|
||||
}
|
||||
|
||||
private static CheckMoveResult[] ParseMovesPre3DS(PKM pkm, int[] Moves, LegalInfo info)
|
||||
private static CheckMoveResult[] ParseMovesPre3DS(PKM pkm, IReadOnlyList<int> currentMoves, LegalInfo info)
|
||||
{
|
||||
if (pkm.IsEgg && info.EncounterMatch is EncounterEgg egg)
|
||||
{
|
||||
var SpecialMoves = GetSpecialMoves(info.EncounterMatch);
|
||||
return ParseMovesIsEggPreRelearn(pkm, Moves, SpecialMoves, egg);
|
||||
}
|
||||
if (info.EncounterMatch is EncounterEgg e)
|
||||
return ParseMovesWasEggPreRelearn(pkm, Moves, info, e);
|
||||
{
|
||||
return pkm.IsEgg
|
||||
? ParseMovesIsEggPreRelearn(pkm, currentMoves, e)
|
||||
: ParseMovesWasEggPreRelearn(pkm, currentMoves, info, e);
|
||||
}
|
||||
|
||||
int gen = info.EncounterMatch.Generation;
|
||||
if (gen <= 2 && (gen == 1 || (gen == 2 && !ParseSettings.AllowGen2MoveReminder(pkm)))) // fixed encounter moves without relearning
|
||||
return ParseMovesGenGB(pkm, Moves, info);
|
||||
return ParseMovesGenGB(pkm, currentMoves, info);
|
||||
|
||||
return ParseMovesSpecialMoveset(pkm, Moves, info);
|
||||
return ParseMovesSpecialMoveset(pkm, currentMoves, info);
|
||||
}
|
||||
|
||||
private static CheckMoveResult[] ParseMovesGenGB(PKM pkm, int[] Moves, LegalInfo info)
|
||||
private static CheckMoveResult[] ParseMovesGenGB(PKM pkm, IReadOnlyList<int> currentMoves, LegalInfo info)
|
||||
{
|
||||
var res = new CheckMoveResult[4];
|
||||
var G1Encounter = info.EncounterMatch;
|
||||
if (G1Encounter == null)
|
||||
return ParseMovesSpecialMoveset(pkm, Moves, info);
|
||||
return ParseMovesSpecialMoveset(pkm, currentMoves, info);
|
||||
var InitialMoves = Array.Empty<int>();
|
||||
var SpecialMoves = GetSpecialMoves(info.EncounterMatch);
|
||||
var games = info.EncounterMatch.Generation == 1 ? GBRestrictions.GetGen1Versions(info) : GBRestrictions.GetGen2Versions(info, pkm.Korean);
|
||||
@@ -193,7 +190,7 @@ private static CheckMoveResult[] ParseMovesGenGB(PKM pkm, int[] Moves, LegalInfo
|
||||
|
||||
var source = new MoveParseSource
|
||||
{
|
||||
CurrentMoves = Moves,
|
||||
CurrentMoves = currentMoves,
|
||||
SpecialSource = SpecialMoves,
|
||||
Base = VerInitialMoves,
|
||||
};
|
||||
@@ -205,11 +202,11 @@ private static CheckMoveResult[] ParseMovesGenGB(PKM pkm, int[] Moves, LegalInfo
|
||||
return res;
|
||||
}
|
||||
|
||||
private static CheckMoveResult[] ParseMovesSpecialMoveset(PKM pkm, int[] Moves, LegalInfo info)
|
||||
private static CheckMoveResult[] ParseMovesSpecialMoveset(PKM pkm, IReadOnlyList<int> currentMoves, LegalInfo info)
|
||||
{
|
||||
var source = new MoveParseSource
|
||||
{
|
||||
CurrentMoves = Moves,
|
||||
CurrentMoves = currentMoves,
|
||||
SpecialSource = GetSpecialMoves(info.EncounterMatch),
|
||||
};
|
||||
return ParseMoves(pkm, source, info);
|
||||
@@ -222,11 +219,11 @@ private static IReadOnlyList<int> GetSpecialMoves(IEncounterable EncounterMatch)
|
||||
return Array.Empty<int>();
|
||||
}
|
||||
|
||||
private static CheckMoveResult[] ParseMovesRelearn(PKM pkm, int[] Moves, LegalInfo info)
|
||||
private static CheckMoveResult[] ParseMovesRelearn(PKM pkm, IReadOnlyList<int> currentMoves, LegalInfo info)
|
||||
{
|
||||
var source = new MoveParseSource
|
||||
{
|
||||
CurrentMoves = Moves,
|
||||
CurrentMoves = currentMoves,
|
||||
SpecialSource = GetSpecialMoves(info.EncounterMatch),
|
||||
};
|
||||
|
||||
@@ -237,7 +234,7 @@ private static CheckMoveResult[] ParseMovesRelearn(PKM pkm, int[] Moves, LegalIn
|
||||
var relearn = pkm.RelearnMoves;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if ((pkm.IsEgg || res[i].Flag) && !relearn.Contains(Moves[i]))
|
||||
if ((pkm.IsEgg || res[i].Flag) && !relearn.Contains(currentMoves[i]))
|
||||
res[i] = new CheckMoveResult(res[i], Invalid, string.Format(LMoveRelearnFMiss_0, res[i].Comment), res[i].Identifier);
|
||||
}
|
||||
|
||||
@@ -372,7 +369,7 @@ private static void ParseMovesByGeneration(PKM pkm, IList<CheckMoveResult> res,
|
||||
}
|
||||
}
|
||||
|
||||
private static void ParseMovesByGeneration12(PKM pkm, CheckMoveResult[] res, int[] moves, int gen, LegalInfo info, LearnInfo learnInfo)
|
||||
private static void ParseMovesByGeneration12(PKM pkm, CheckMoveResult[] res, IReadOnlyList<int> currentMoves, int gen, LegalInfo info, LearnInfo learnInfo)
|
||||
{
|
||||
// Mark the gen 1 exclusive moves as illegal because the pokemon also have Non tradeback egg moves.
|
||||
if (learnInfo.MixedGen12NonTradeback)
|
||||
@@ -386,8 +383,8 @@ private static void ParseMovesByGeneration12(PKM pkm, CheckMoveResult[] res, int
|
||||
|
||||
if (gen == 1 && pkm.Format == 1 && pkm.Gen1_NotTradeback)
|
||||
{
|
||||
ParseRedYellowIncompatibleMoves(pkm, res, moves);
|
||||
ParseEvolutionsIncompatibleMoves(pkm, res, moves, info.EncounterMoves.TMHMMoves[1]);
|
||||
ParseRedYellowIncompatibleMoves(pkm, res, currentMoves);
|
||||
ParseEvolutionsIncompatibleMoves(pkm, res, currentMoves, info.EncounterMoves.TMHMMoves[1]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -514,19 +511,19 @@ private static void ParseEggMovesRemaining(PKM pkm, CheckMoveResult[] res, Learn
|
||||
}
|
||||
}
|
||||
|
||||
private static void ParseRedYellowIncompatibleMoves(PKM pkm, IList<CheckMoveResult> res, int[] moves)
|
||||
private static void ParseRedYellowIncompatibleMoves(PKM pkm, IList<CheckMoveResult> res, IReadOnlyList<int> currentMoves)
|
||||
{
|
||||
var incompatible = GetIncompatibleRBYMoves(pkm, moves);
|
||||
var incompatible = GetIncompatibleRBYMoves(pkm, currentMoves);
|
||||
if (incompatible.Count == 0)
|
||||
return;
|
||||
for (int m = 0; m < 4; m++)
|
||||
{
|
||||
if (incompatible.Contains(moves[m]))
|
||||
if (incompatible.Contains(currentMoves[m]))
|
||||
res[m] = new CheckMoveResult(res[m], Invalid, LG1MoveLearnSameLevel, Move);
|
||||
}
|
||||
}
|
||||
|
||||
private static IList<int> GetIncompatibleRBYMoves(PKM pkm, int[] moves)
|
||||
private static IList<int> GetIncompatibleRBYMoves(PKM pkm, IReadOnlyList<int> currentMoves)
|
||||
{
|
||||
// Check moves that are learned at the same level in Red/Blue and Yellow, these are illegal because there is no Move Reminder in Gen1.
|
||||
// There are only two incompatibilities for Gen1; there are no illegal combination in Gen2.
|
||||
@@ -535,12 +532,12 @@ private static IList<int> GetIncompatibleRBYMoves(PKM pkm, int[] moves)
|
||||
{
|
||||
// Vaporeon in Yellow learns Mist and Haze at level 42, Mist can only be learned if it leveled up in the daycare
|
||||
// Vaporeon in Red/Blue learns Acid Armor at level 42 and level 47 in Yellow
|
||||
case (int)Species.Vaporeon when pkm.CurrentLevel < 47 && moves.Contains(151):
|
||||
case (int)Species.Vaporeon when pkm.CurrentLevel < 47 && currentMoves.Contains(151):
|
||||
{
|
||||
var incompatible = new List<int>(3);
|
||||
if (moves.Contains(54))
|
||||
if (currentMoves.Contains(54))
|
||||
incompatible.Add(54);
|
||||
if (moves.Contains(114))
|
||||
if (currentMoves.Contains(114))
|
||||
incompatible.Add(114);
|
||||
if (incompatible.Count != 0)
|
||||
incompatible.Add(151);
|
||||
@@ -549,7 +546,7 @@ private static IList<int> GetIncompatibleRBYMoves(PKM pkm, int[] moves)
|
||||
|
||||
// Flareon in Yellow learns Smog at level 42
|
||||
// Flareon in Red Blue learns Leer at level 42 and level 47 in Yellow
|
||||
case (int)Species.Flareon when pkm.CurrentLevel < 47 && moves.Contains(43) && moves.Contains(123):
|
||||
case (int)Species.Flareon when pkm.CurrentLevel < 47 && currentMoves.Contains(43) && currentMoves.Contains(123):
|
||||
return new[] {43, 123};
|
||||
|
||||
default: return Array.Empty<int>();
|
||||
@@ -577,7 +574,7 @@ private static void ParseEvolutionsIncompatibleMoves(PKM pkm, IList<CheckMoveRes
|
||||
}
|
||||
}
|
||||
|
||||
private static void ParseShedinjaEvolveMoves(PKM pkm, IList<CheckMoveResult> res, int[] moves, IReadOnlyList<IReadOnlyList<EvoCriteria>> evos)
|
||||
private static void ParseShedinjaEvolveMoves(PKM pkm, IList<CheckMoveResult> res, IReadOnlyList<int> currentMoves, IReadOnlyList<IReadOnlyList<EvoCriteria>> evos)
|
||||
{
|
||||
var ShedinjaEvoMovesLearned = new List<int>();
|
||||
var format = pkm.Format;
|
||||
@@ -596,7 +593,7 @@ private static void ParseShedinjaEvolveMoves(PKM pkm, IList<CheckMoveResult> res
|
||||
if (IsCheckValid(res[m])) // already validated
|
||||
continue;
|
||||
|
||||
if (!ninjaskMoves.Contains(moves[m]))
|
||||
if (!ninjaskMoves.Contains(currentMoves[m]))
|
||||
continue;
|
||||
|
||||
var msg = native ? LMoveNincadaEvo : string.Format(LMoveNincadaEvoF_0, gen);
|
||||
@@ -618,7 +615,7 @@ private static void ParseShedinjaEvolveMoves(PKM pkm, IList<CheckMoveResult> res
|
||||
// Double check that the Ninjask move level isn't less than any Nincada move level
|
||||
int move = ShedinjaEvoMovesLearned[0];
|
||||
int g = res[move].Generation;
|
||||
int levelJ = Legal.GetShedinjaMoveLevel((int)Species.Ninjask, moves[move], g);
|
||||
int levelJ = Legal.GetShedinjaMoveLevel((int)Species.Ninjask, currentMoves[move], g);
|
||||
|
||||
for (int m = 0; m < 4; m++)
|
||||
{
|
||||
@@ -626,24 +623,24 @@ private static void ParseShedinjaEvolveMoves(PKM pkm, IList<CheckMoveResult> res
|
||||
continue;
|
||||
if (res[m].Source != LevelUp)
|
||||
continue;
|
||||
int levelS = Legal.GetShedinjaMoveLevel((int)Species.Shedinja, moves[m], res[m].Generation);
|
||||
int levelS = Legal.GetShedinjaMoveLevel((int)Species.Shedinja, currentMoves[m], res[m].Generation);
|
||||
if (levelS > 0)
|
||||
continue;
|
||||
|
||||
int levelN = Legal.GetShedinjaMoveLevel((int)Species.Nincada, moves[m], res[m].Generation);
|
||||
int levelN = Legal.GetShedinjaMoveLevel((int)Species.Nincada, currentMoves[m], res[m].Generation);
|
||||
if (levelN > levelJ)
|
||||
res[m] = new CheckMoveResult(res[m], Invalid, string.Format(LMoveEvoFHigher, SpeciesStrings[(int)Species.Nincada], SpeciesStrings[(int)Species.Ninjask]), Move);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ParseEvolutionLevelupMove(PKM pkm, IList<CheckMoveResult> res, int[] moves, LegalInfo info)
|
||||
private static void ParseEvolutionLevelupMove(PKM pkm, IList<CheckMoveResult> res, IReadOnlyList<int> currentMoves, LegalInfo info)
|
||||
{
|
||||
// Ignore if there is an invalid move or an empty move, this validation is only for 4 non-empty moves that are all valid, but invalid as a 4 combination
|
||||
// Ignore Mr. Mime and Sudowodoo from generations 1 to 3, they cant be evolved from Bonsly or Munchlax
|
||||
// Ignore if encounter species is the evolution species, the pokemon was not evolved by the player
|
||||
if (info.EncounterMatch.Species == pkm.Species)
|
||||
return;
|
||||
if (!res.All(r => r?.Valid ?? false) || moves.Any(m => m == 0) || (Legal.BabyEvolutionWithMove.Contains(pkm.Species) && info.Generation <= 3))
|
||||
if (!res.All(r => r?.Valid ?? false) || currentMoves.Any(m => m == 0) || (Legal.BabyEvolutionWithMove.Contains(pkm.Species) && info.Generation <= 3))
|
||||
return;
|
||||
|
||||
var ValidMoves = Legal.GetValidPostEvolutionMoves(pkm, pkm.Species, info.EvoChainsAllGens, GameVersion.Any);
|
||||
@@ -675,7 +672,7 @@ private static void ParseEvolutionLevelupMove(PKM pkm, IList<CheckMoveResult> re
|
||||
break;
|
||||
}
|
||||
|
||||
if (moves.Any(m => ValidMoves.Contains(m)))
|
||||
if (currentMoves.Any(m => ValidMoves.Contains(m)))
|
||||
return;
|
||||
|
||||
for (int m = 0; m < 4; m++)
|
||||
@@ -707,7 +704,7 @@ void IsHMSource(IList<bool> flags, ICollection<int> source)
|
||||
private static bool IsCheckInvalid(CheckResult chk) => !(chk?.Valid ?? false);
|
||||
private static bool IsCheckValid(CheckResult chk) => chk?.Valid ?? false;
|
||||
|
||||
private static void FlagIncompatibleTransferHMs45(CheckMoveResult[] res, int[] moves, int gen, bool[] HMLearned, bool KnowDefogWhirlpool)
|
||||
private static void FlagIncompatibleTransferHMs45(CheckMoveResult[] res, IReadOnlyList<int> currentMoves, int gen, IReadOnlyList<bool> HMLearned, bool KnowDefogWhirlpool)
|
||||
{
|
||||
// After all the moves from the generations 3 and 4,
|
||||
// including egg moves if is the origin generation because some hidden moves are also special egg moves in gen 3
|
||||
@@ -715,19 +712,19 @@ private static void FlagIncompatibleTransferHMs45(CheckMoveResult[] res, int[] m
|
||||
// the hidden move was learned in gen 3 or 4 but was not removed when transfer to 4 or 5
|
||||
if (KnowDefogWhirlpool)
|
||||
{
|
||||
int invalidCount = moves.Where((m, i) => IsDefogWhirl(m) && IsCheckValid(res[i])).Count();
|
||||
int invalidCount = currentMoves.Where((m, i) => IsDefogWhirl(m) && IsCheckValid(res[i])).Count();
|
||||
if (invalidCount == 2) // can't know both at the same time
|
||||
{
|
||||
for (int i = 0; i < 4; i++) // flag both moves
|
||||
{
|
||||
if (IsDefogWhirl(moves[i]))
|
||||
if (IsDefogWhirl(currentMoves[i]))
|
||||
res[i] = new CheckMoveResult(res[i], Invalid, LTransferMoveG4HM, Move);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Flag moves that are only legal when learned from a past-gen HM source
|
||||
for (int i = 0; i < HMLearned.Length; i++)
|
||||
for (int i = 0; i < HMLearned.Count; i++)
|
||||
{
|
||||
if (HMLearned[i] && IsCheckValid(res[i]))
|
||||
res[i] = new CheckMoveResult(res[i], Invalid, string.Format(LTransferMoveHM, gen, gen + 1), Move);
|
||||
@@ -735,18 +732,18 @@ private static void FlagIncompatibleTransferHMs45(CheckMoveResult[] res, int[] m
|
||||
}
|
||||
|
||||
/* 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 static CheckMoveResult[] VerifyPreRelearnEggBase(PKM pkm, int[] Moves, EggInfoSource infoset)
|
||||
private static CheckMoveResult[] VerifyPreRelearnEggBase(PKM pkm, IReadOnlyList<int> currentMoves, EggInfoSource infoset)
|
||||
{
|
||||
CheckMoveResult[] res = new CheckMoveResult[4];
|
||||
var gen = pkm.GenNumber;
|
||||
// Obtain level1 moves
|
||||
var reqBase = GetRequiredBaseMoveCount(Moves, infoset);
|
||||
var reqBase = GetRequiredBaseMoveCount(currentMoves, infoset);
|
||||
|
||||
var sb = new System.Text.StringBuilder();
|
||||
// Check if the required amount of Base Egg Moves are present.
|
||||
for (int i = 0; i < reqBase; i++)
|
||||
{
|
||||
if (infoset.Base.Contains(Moves[i]))
|
||||
if (infoset.Base.Contains(currentMoves[i]))
|
||||
{
|
||||
res[i] = new CheckMoveResult(Initial, gen, Valid, LMoveRelearnEgg, Move);
|
||||
continue;
|
||||
@@ -761,45 +758,22 @@ private static CheckMoveResult[] VerifyPreRelearnEggBase(PKM pkm, int[] Moves, E
|
||||
break;
|
||||
}
|
||||
|
||||
int moveoffset = reqBase;
|
||||
int endSpecial = moveoffset + infoset.Special.Count;
|
||||
// Check also if the required amount of Special Egg Moves are present, ir are after base moves
|
||||
for (int i = moveoffset; i < endSpecial; i++)
|
||||
{
|
||||
if (infoset.Special.Contains(Moves[i]))
|
||||
{
|
||||
res[i] = new CheckMoveResult(SpecialEgg, gen, Valid, LMoveSourceEggEvent, Move);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Not in special moves, mark remaining special egg moves missing
|
||||
for (int z = i; z < endSpecial; z++)
|
||||
res[z] = new CheckMoveResult(SpecialEgg, gen, Invalid, LMoveEggMissing, Move);
|
||||
|
||||
// provide the list of suggested base moves and species moves for the last required slot
|
||||
if (sb.Length == 0)
|
||||
sb.Append(string.Join(", ", GetMoveNames(infoset.Base)));
|
||||
sb.Append(", ");
|
||||
sb.Append(string.Join(", ", GetMoveNames(infoset.Special)));
|
||||
break;
|
||||
}
|
||||
|
||||
if (sb.Length != 0)
|
||||
res[reqBase > 0 ? reqBase - 1 : 0].Comment = string.Format(Environment.NewLine + LMoveFExpect_0, sb);
|
||||
|
||||
// Inherited moves appear after the required base moves.
|
||||
var AllowInheritedSeverity = infoset.AllowInherited ? Valid : Invalid;
|
||||
for (int i = reqBase + infoset.Special.Count; i < 4; i++)
|
||||
for (int i = reqBase; i < 4; i++)
|
||||
{
|
||||
if (Moves[i] == 0) // empty
|
||||
if (currentMoves[i] == 0) // empty
|
||||
res[i] = new CheckMoveResult(None, gen, Valid, LMoveSourceEmpty, Move);
|
||||
else if (infoset.Egg.Contains(Moves[i])) // inherited egg move
|
||||
else if (infoset.Egg.Contains(currentMoves[i])) // inherited egg move
|
||||
res[i] = new CheckMoveResult(EggMove, gen, AllowInheritedSeverity, infoset.AllowInherited ? LMoveEggInherited : LMoveEggInvalidEvent, Move);
|
||||
else if (infoset.LevelUp.Contains(Moves[i])) // inherited lvl moves
|
||||
else if (infoset.LevelUp.Contains(currentMoves[i])) // inherited lvl moves
|
||||
res[i] = new CheckMoveResult(InheritLevelUp, gen, AllowInheritedSeverity, infoset.AllowInherited ? LMoveEggLevelUp : LMoveEggInvalidEventLevelUp, Move);
|
||||
else if (infoset.TMHM.Contains(Moves[i])) // inherited TMHM moves
|
||||
else if (infoset.TMHM.Contains(currentMoves[i])) // inherited TMHM moves
|
||||
res[i] = new CheckMoveResult(TMHM, gen, AllowInheritedSeverity, infoset.AllowInherited ? LMoveEggTMHM : LMoveEggInvalidEventTMHM, Move);
|
||||
else if (infoset.Tutor.Contains(Moves[i])) // inherited tutor moves
|
||||
else if (infoset.Tutor.Contains(currentMoves[i])) // inherited tutor moves
|
||||
res[i] = new CheckMoveResult(Tutor, gen, AllowInheritedSeverity, infoset.AllowInherited ? LMoveEggInheritedTutor : LMoveEggInvalidEventTutor, Move);
|
||||
else // not inheritable, flag
|
||||
res[i] = new CheckMoveResult(Unknown, gen, Invalid, LMoveEggInvalid, Move);
|
||||
@@ -808,33 +782,33 @@ private static CheckMoveResult[] VerifyPreRelearnEggBase(PKM pkm, int[] Moves, E
|
||||
return res;
|
||||
}
|
||||
|
||||
private static int GetRequiredBaseMoveCount(int[] Moves, EggInfoSource infoset)
|
||||
private static int GetRequiredBaseMoveCount(IReadOnlyList<int> currentMoves, EggInfoSource infoset)
|
||||
{
|
||||
int baseCt = infoset.Base.Count;
|
||||
if (baseCt > 4) baseCt = 4;
|
||||
|
||||
// Obtain Inherited moves
|
||||
var inherited = Moves.Where(m => m != 0 && infoset.IsInherited(m)).ToList();
|
||||
var inherited = currentMoves.Where(m => m != 0 && infoset.IsInherited(m)).ToList();
|
||||
int inheritCt = inherited.Count;
|
||||
|
||||
// Get required amount of base moves
|
||||
int unique = infoset.Base.Union(inherited).Count();
|
||||
int reqBase = inheritCt == 4 || baseCt + inheritCt > 4 ? 4 - inheritCt : baseCt;
|
||||
if (Moves.Count(m => m != 0) < Math.Min(4, infoset.Base.Count))
|
||||
if (currentMoves.Count(m => m != 0) < Math.Min(4, infoset.Base.Count))
|
||||
reqBase = Math.Min(4, unique);
|
||||
return reqBase;
|
||||
}
|
||||
|
||||
private static void VerifyNoEmptyDuplicates(int[] Moves, CheckMoveResult[] res)
|
||||
private static void VerifyNoEmptyDuplicates(IReadOnlyList<int> moves, CheckMoveResult[] res)
|
||||
{
|
||||
bool emptySlot = false;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (Moves[i] == 0)
|
||||
if (moves[i] == 0)
|
||||
emptySlot = true;
|
||||
else if (emptySlot)
|
||||
res[i] = new CheckMoveResult(res[i], Invalid, LMoveSourceEmpty, res[i].Identifier);
|
||||
else if (Moves.Count(m => m == Moves[i]) > 1)
|
||||
else if (moves.Count(m => m == moves[i]) > 1)
|
||||
res[i] = new CheckMoveResult(res[i], Invalid, LMoveSourceDuplicate, res[i].Identifier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,12 +6,10 @@ namespace PKHeX.Core
|
||||
{
|
||||
internal class EggInfoSource
|
||||
{
|
||||
public EggInfoSource(PKM pkm, IReadOnlyList<int> specialMoves, EncounterEgg e)
|
||||
public EggInfoSource(PKM pkm, EncounterEgg e)
|
||||
{
|
||||
// Eggs with special moves cannot inherit levelup moves as the current moves are predefined.
|
||||
Special = specialMoves;
|
||||
bool notSpecial = Special.Count == 0;
|
||||
AllowInherited = notSpecial && !pkm.WasGiftEgg && pkm.Species != 489 && pkm.Species != 490;
|
||||
AllowInherited = e.Species != 489 && e.Species != 490;
|
||||
|
||||
// Level up moves can only be inherited if ditto is not the mother.
|
||||
bool AllowLevelUp = Legal.GetCanInheritMoves(e.Species);
|
||||
@@ -22,14 +20,14 @@ public EggInfoSource(PKM pkm, IReadOnlyList<int> specialMoves, EncounterEgg e)
|
||||
? Legal.GetBaseEggMoves(pkm, e.Species, e.Form, e.Version, 100).Except(Base).ToList()
|
||||
: (IReadOnlyList<int>)Array.Empty<int>();
|
||||
Tutor = e.Version == GameVersion.C
|
||||
? MoveTutor.GetTutorMoves(pkm, pkm.Species, pkm.AltForm, false, 2).ToList()
|
||||
? MoveTutor.GetTutorMoves(pkm, e.Species, 0, false, 2).ToList()
|
||||
: (IReadOnlyList<int>)Array.Empty<int>();
|
||||
|
||||
// Only TM/HM moves from the source game of the egg, not any other games from the same generation
|
||||
TMHM = MoveTechnicalMachine.GetTMHM(pkm, pkm.Species, pkm.AltForm, pkm.GenNumber, e.Version).ToList();
|
||||
TMHM = MoveTechnicalMachine.GetTMHM(pkm, pkm.Species, pkm.AltForm, e.Generation, e.Version).ToList();
|
||||
|
||||
// Non-Base moves that can magically appear in the regular movepool
|
||||
bool volt = notSpecial && (pkm.GenNumber > 3 || e.Version == GameVersion.E) && Legal.LightBall.Contains(pkm.Species);
|
||||
bool volt = (e.Generation > 3 || e.Version == GameVersion.E) && Legal.LightBall.Contains(pkm.Species);
|
||||
if (volt)
|
||||
{
|
||||
Egg = Egg.ToList(); // array->list
|
||||
@@ -39,7 +37,6 @@ public EggInfoSource(PKM pkm, IReadOnlyList<int> specialMoves, EncounterEgg e)
|
||||
|
||||
public bool AllowInherited { get; }
|
||||
public IReadOnlyList<int> Base { get; }
|
||||
public IReadOnlyList<int> Special { get; }
|
||||
public IList<int> Egg { get; }
|
||||
public IReadOnlyList<int> Tutor { get; }
|
||||
public IReadOnlyList<int> TMHM { get; }
|
||||
@@ -51,7 +48,7 @@ public bool IsInherited(int m)
|
||||
return false;
|
||||
if (Base.Contains(m))
|
||||
return false;
|
||||
return Special.Contains(m) || Egg.Contains(m) || LevelUp.Contains(m) || TMHM.Contains(m) || Tutor.Contains(m);
|
||||
return Egg.Contains(m) || LevelUp.Contains(m) || TMHM.Contains(m) || Tutor.Contains(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace PKHeX.Core
|
||||
internal class MoveParseSource
|
||||
{
|
||||
private static readonly int[] Empty = Array.Empty<int>();
|
||||
public int[] CurrentMoves { get; set; } = Empty;
|
||||
public IReadOnlyList<int> CurrentMoves { get; set; } = Empty;
|
||||
public IReadOnlyList<int> SpecialSource { get; set; } = Empty;
|
||||
public int[] NonTradeBackLevelUpMoves { get; set; } = Empty;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user