Fix issue #1200 and added speculation for Gen2 VC without move reminder (#1201)

* Fix issue #1200
Minimum level for evolution moves in generation 7 is 2 thanks to the move reminder, also the evolution could be trigger at the minimum level and not the next level, except when the minimum level is the met level

* Gen 2 VC Speculation, it wont have Move Reminder because the only gen 2 move reminder was in Pokemon Stadium 2

* Missing variable

* Fix update generation 2 level moves
This commit is contained in:
javierhimura 2017-06-08 01:15:13 +02:00 committed by Kurt
parent ee2a075f52
commit f8346eb7e1
4 changed files with 78 additions and 40 deletions

View file

@ -17,6 +17,7 @@ namespace PKHeX.Core
public static bool AllowGen2VCTransfer => AllowGen1Tradeback;
public static bool AllowGen2VCCrystal = false;
public static bool AllowGen2Crystal => AllowGBCartEra || AllowGen2Crystal;
public static bool AllowGen2MoveReminder => AllowGBCartEra;
/// <summary>Setting to specify if the e-berry index item is an eningma berry or a e-reader berry and the name of the e-reader berry</summary>
public static bool EReaderBerryIsEnigma = true;
@ -1185,29 +1186,29 @@ namespace PKHeX.Core
}
return r;
}
internal static List<int>[] getValidMovesAllGens(PKM pkm, DexLevel[][] evoChains, int minLvLG1 = 1, bool LVL = true, bool Tutor = true, bool Machine = true, bool MoveReminder = true, bool RemoveTransferHM = true)
internal static List<int>[] getValidMovesAllGens(PKM pkm, DexLevel[][] evoChains, int minLvLG1 = 1, int minLvLG2 = 1, bool LVL = true, bool Tutor = true, bool Machine = true, bool MoveReminder = true, bool RemoveTransferHM = true)
{
List<int>[] Moves = new List<int>[evoChains.Length];
for (int i = 1; i < evoChains.Length; i++)
if (evoChains[i].Any())
Moves[i] = getValidMoves(pkm, evoChains[i], i, minLvLG1, LVL, Tutor, Machine, MoveReminder, RemoveTransferHM).ToList();
Moves[i] = getValidMoves(pkm, evoChains[i], i, minLvLG1, minLvLG2, LVL, Tutor, Machine, MoveReminder, RemoveTransferHM).ToList();
else
Moves[i] = new List<int>();
return Moves;
}
internal static IEnumerable<int> getValidMoves(PKM pkm, DexLevel[][] evoChains, int minLvLG1 = 1, bool LVL = true, bool Tutor = true, bool Machine = true, bool MoveReminder = true, bool RemoveTransferHM = true)
internal static IEnumerable<int> getValidMoves(PKM pkm, DexLevel[][] evoChains, int minLvLG1 = 1, int minLvLG2 = 1, bool LVL = true, bool Tutor = true, bool Machine = true, bool MoveReminder = true, bool RemoveTransferHM = true)
{
GameVersion version = (GameVersion)pkm.Version;
if (!pkm.IsUntraded)
version = GameVersion.Any;
return getValidMoves(pkm, version, evoChains, minLvLG1: minLvLG1, LVL: LVL, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder, RemoveTransferHM: RemoveTransferHM);
return getValidMoves(pkm, version, evoChains, minLvLG1: minLvLG1, minLvLG2: minLvLG2, LVL: LVL, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder, RemoveTransferHM: RemoveTransferHM);
}
internal static IEnumerable<int> getValidMoves(PKM pkm, DexLevel[] evoChain, int generation, int minLvLG1 = 1, bool LVL = true, bool Tutor = true, bool Machine = true, bool MoveReminder = true, bool RemoveTransferHM = true)
internal static IEnumerable<int> getValidMoves(PKM pkm, DexLevel[] evoChain, int generation, int minLvLG1 = 1, int minLvLG2 = 1, bool LVL = true, bool Tutor = true, bool Machine = true, bool MoveReminder = true, bool RemoveTransferHM = true)
{
GameVersion version = (GameVersion)pkm.Version;
if (!pkm.IsUntraded)
version = GameVersion.Any;
return getValidMoves(pkm, version, evoChain, generation, minLvLG1: minLvLG1, LVL: LVL, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder, RemoveTransferHM: RemoveTransferHM);
return getValidMoves(pkm, version, evoChain, generation, minLvLG1: minLvLG1, minLvLG2: minLvLG2, LVL: LVL, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder, RemoveTransferHM: RemoveTransferHM);
}
internal static IEnumerable<int> getValidRelearn(PKM pkm, int species, bool inheritlvlmoves)
{
@ -1369,7 +1370,7 @@ namespace PKHeX.Core
for (int i = 0; i <= index; i++)
{
var evo = evoChain[i];
var moves = getMoves(pkm, evo.Species, 1, evo.Level, pkm.AltForm, moveTutor: true, Version: Version, LVL: true, specialTutors: true, Machine: true, MoveReminder: true, RemoveTransferHM: false, Generation: Generation);
var moves = getMoves(pkm, evo.Species, 1, 1, evo.Level, pkm.AltForm, moveTutor: true, Version: Version, LVL: true, specialTutors: true, Machine: true, MoveReminder: true, RemoveTransferHM: false, Generation: Generation);
// Moves from Species or any species after in the evolution phase
evomoves.AddRange(moves);
}
@ -1394,7 +1395,7 @@ namespace PKHeX.Core
for (int i = 0; i < evoChain.Length; i++)
{
var evo = evoChain[i];
var moves = getMoves(pkm, evo.Species, 1, evo.Level, pkm.AltForm, moveTutor: true, Version: Version, LVL: true, specialTutors: true, Machine: true, MoveReminder: true, RemoveTransferHM: false, Generation: Generation);
var moves = getMoves(pkm, evo.Species, 1, 1, evo.Level, pkm.AltForm, moveTutor: true, Version: Version, LVL: true, specialTutors: true, Machine: true, MoveReminder: true, RemoveTransferHM: false, Generation: Generation);
if (i >= index)
// Moves from Species or any species bellow in the evolution phase
preevomoves.AddRange(moves);
@ -1407,6 +1408,10 @@ namespace PKHeX.Core
}
// Encounter
internal static GameVersion[] getGen2GameEncounter(PKM pk)
{
return AllowGen2VCCrystal ? new[] { GameVersion.GS, GameVersion.C } : new[] { GameVersion.GS};
}
internal static GameVersion[] getGen1GameEncounter(PKM pk)
{
if (pk.Format != 1 || !pk.Gen1_NotTradeback)
@ -2034,7 +2039,7 @@ namespace PKHeX.Core
if (info.EncounterMatch.EggEncounter && !pkm.WasGiftEgg && !pkm.WasEventEgg && allowegg)
{
if (getIsMoveInherited(pkm, info, moves))
LearnLevel = Math.Min(LearnLevel, pkm.GenNumber < 4 ? 5 : 1);
LearnLevel = Math.Min(LearnLevel, pkm.GenNumber < 4 ? 6 : 2);
}
// If has original met location the minimum evolution level is one level after met level
@ -2042,10 +2047,11 @@ namespace PKHeX.Core
// VC pokemon: minimum level is one level after transfer to generation 7
// Sylveon: always one level after met level, for gen 4 and 5 eevees in gen 6 games minimum for evolution is one level after transfer to generation 5
if (pkm.HasOriginalMetLocation || pkm.Format == 4 && pkm.Gen3 || pkm.VC || pkm.Species == 700)
LearnLevel = Math.Max(pkm.Met_Level, LearnLevel);
LearnLevel = Math.Max(pkm.Met_Level + 1, LearnLevel);
// Current level must be at least one level after the minimum learn level
return pkm.CurrentLevel > LearnLevel;
// Current level must be at least one the minimum learn level
// the level-up event that triggers the learning of the move also triggers evolution with no further level-up required
return pkm.CurrentLevel >= LearnLevel;
}
private static bool getIsMoveInherited(PKM pkm, LegalInfo info, int[] moves)
{
@ -2405,7 +2411,7 @@ namespace PKHeX.Core
var et = maxspeciesorigin == MaxSpeciesID_2 ? getEvolutionTable(2) : getEvolutionTable(pkm);
return et.getValidPreEvolutions(pkm, lvl: lvl, maxSpeciesOrigin: maxspeciesorigin, skipChecks: skipChecks);
}
private static IEnumerable<int> getValidMoves(PKM pkm, GameVersion Version, IReadOnlyList<DexLevel[]> vs, int minLvLG1 = 1, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false, bool MoveReminder = true, bool RemoveTransferHM = true)
private static IEnumerable<int> getValidMoves(PKM pkm, GameVersion Version, IReadOnlyList<DexLevel[]> vs, int minLvLG1 = 1, int minLvLG2 = 1, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false, bool MoveReminder = true, bool RemoveTransferHM = true)
{
List<int> r = new List<int> { 0 };
if (Relearn && pkm.Format >= 6)
@ -2413,11 +2419,11 @@ namespace PKHeX.Core
for (int gen = pkm.GenNumber; gen <= pkm.Format; gen++)
if (vs[gen].Any())
r.AddRange(getValidMoves(pkm, Version, vs[gen], gen, minLvLG1:minLvLG1, LVL: LVL, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder, RemoveTransferHM: RemoveTransferHM));
r.AddRange(getValidMoves(pkm, Version, vs[gen], gen, minLvLG1: minLvLG1, minLvLG2: minLvLG2, LVL: LVL, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder, RemoveTransferHM: RemoveTransferHM));
return r.Distinct().ToArray();
}
private static IEnumerable<int> getValidMoves(PKM pkm, GameVersion Version, DexLevel[] vs, int Generation, int minLvLG1 = 1, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false, bool MoveReminder = true, bool RemoveTransferHM = true)
private static IEnumerable<int> getValidMoves(PKM pkm, GameVersion Version, DexLevel[] vs, int Generation, int minLvLG1 = 1, int minLvLG2 = 1, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false, bool MoveReminder = true, bool RemoveTransferHM = true)
{
List<int> r = new List<int> { 0 };
if (!vs.Any())
@ -2434,23 +2440,30 @@ namespace PKHeX.Core
// In gen 3 deoxys has different forms depending on the current game, in personal info there is no alter form info
formcount = 4;
for (int i = 0; i < formcount; i++)
r.AddRange(getMoves(pkm, species, minLvLG1, vs.First().Level, i, moveTutor, Version, LVL, Tutor, Machine, MoveReminder, RemoveTransferHM, Generation));
r.AddRange(getMoves(pkm, species, minLvLG1, minLvLG2, vs.First().Level, i, moveTutor, Version, LVL, Tutor, Machine, MoveReminder, RemoveTransferHM, Generation));
if (Relearn) r.AddRange(pkm.RelearnMoves);
return r.Distinct();
}
foreach (DexLevel evo in vs)
{
var minlvlevo = 1;
var minlvlevo1 = 1;
var minlvlevo2 = 1;
if (Generation == 1)
{
// Return moves from minLvLG1 if species if the species encounters
// For evolutions return moves using evolution min level as min level
minlvlevo = minLvLG1;
minlvlevo1 = minLvLG1;
if (evo.MinLevel > 1)
minlvlevo = Math.Min(pkm.CurrentLevel, evo.MinLevel);
minlvlevo1 = Math.Min(pkm.CurrentLevel, evo.MinLevel);
}
r.AddRange(getMoves(pkm, evo.Species, minlvlevo, evo.Level, pkm.AltForm, moveTutor, Version, LVL, Tutor, Machine, MoveReminder, RemoveTransferHM, Generation));
if (Generation == 2 && !AllowGen2MoveReminder)
{
minlvlevo2 = minLvLG2;
if (evo.MinLevel > 1)
minlvlevo2 = Math.Min(pkm.CurrentLevel, evo.MinLevel);
}
r.AddRange(getMoves(pkm, evo.Species, minlvlevo1, minlvlevo2, evo.Level, pkm.AltForm, moveTutor, Version, LVL, Tutor, Machine, MoveReminder, RemoveTransferHM, Generation));
}
if (pkm.Format <= 3)
@ -2480,7 +2493,7 @@ namespace PKHeX.Core
r.AddRange(pkm.RelearnMoves);
return r.Distinct();
}
private static IEnumerable<int> getMoves(PKM pkm, int species, int minlvlG1, int lvl, int form, bool moveTutor, GameVersion Version, bool LVL, bool specialTutors, bool Machine, bool MoveReminder, bool RemoveTransferHM, int Generation)
private static IEnumerable<int> getMoves(PKM pkm, int species, int minlvlG1, int minlvlG2, int lvl, int form, bool moveTutor, GameVersion Version, bool LVL, bool specialTutors, bool Machine, bool MoveReminder, bool RemoveTransferHM, int Generation)
{
List<int> r = new List<int>();
@ -2521,9 +2534,9 @@ namespace PKHeX.Core
return r;
if (LVL)
{
r.AddRange(LevelUpGS[index].getMoves(lvl));
r.AddRange(LevelUpGS[index].getMoves(lvl, minlvlG2));
if (AllowGen2Crystal)
r.AddRange(LevelUpC[index].getMoves(lvl));
r.AddRange(LevelUpC[index].getMoves(lvl, minlvlG2));
}
if (Machine)
{

View file

@ -38,10 +38,16 @@ namespace PKHeX.Core
var EncounterMatchGen = info.EncounterMatch as IGeneration;
var defaultG1LevelMoves = info.EncounterMoves.validLevelUpMoves[1];
var defaultG2LevelMoves = pkm.InhabitedGeneration(2) ? info.EncounterMoves.validLevelUpMoves[2] : null;
var defaultTradeback = pkm.TradebackStatus;
if (EncounterMatchGen != null)
{
// Generation 1 can have different minimum level in different encounter of the same species; update valid level moves
UptateGen1LevelUpMoves(pkm, info.EncounterMoves, info.EncounterMoves.minLvlG1, EncounterMatchGen.Generation, info);
if(!Legal.AllowGen2MoveReminder && pkm.InhabitedGeneration(2))
// The same for Generation 2 if move reminder from Stadium 2 is not allowed
UptateGen2LevelUpMoves(pkm, info.EncounterMoves, info.EncounterMoves.minLvlG2, EncounterMatchGen.Generation, info);
}
var res = pre3DS
? parseMovesPre3DS(pkm, Moves, info)
@ -50,8 +56,12 @@ namespace PKHeX.Core
if (res.All(x => x.Valid))
return res;
if (EncounterMatchGen?.Generation == 1) // not valid, restore generation 1 moves
if (EncounterMatchGen?.Generation == 1 || EncounterMatchGen?.Generation == 2) // not valid, restore generation 1 and 2 moves
{
info.EncounterMoves.validLevelUpMoves[1] = defaultG1LevelMoves;
if (pkm.InhabitedGeneration(2))
info.EncounterMoves.validLevelUpMoves[2] = defaultG2LevelMoves;
}
pkm.TradebackStatus = defaultTradeback;
return res;
}
@ -142,16 +152,17 @@ namespace PKHeX.Core
var allowinherited = SpecialMoves == null && !pkm.WasGiftEgg && pkm.Species != 489 && pkm.Species != 490;
return parseMovesIsEggPreRelearn(pkm, Moves, SpecialMoves ?? new int[0], allowinherited, egg);
}
if (pkm.GenNumber <= 2 && (info.EncounterMatch as IGeneration)?.Generation == 1)
return parseMovesGen1(pkm, Moves, info);
var NoMoveReminder = (info.EncounterMatch as IGeneration)?.Generation == 1 || (info.EncounterMatch as IGeneration)?.Generation == 2 && !Legal.AllowGen2MoveReminder;
if (pkm.GenNumber <= 2 && NoMoveReminder)
return parseMovesGenGB(pkm, Moves, info);
if (info.EncounterMatch is EncounterEgg e)
return parseMovesWasEggPreRelearn(pkm, Moves, info, e);
return parseMovesSpecialMoveset(pkm, Moves, info);
}
private static CheckMoveResult[] parseMovesGen1(PKM pkm, int[] Moves, LegalInfo info)
private static CheckMoveResult[] parseMovesGenGB(PKM pkm, int[] Moves, LegalInfo info)
{
GameVersion[] games = Legal.getGen1GameEncounter(pkm);
GameVersion[] games = (info.EncounterMatch as IGeneration)?.Generation == 1 ? Legal.getGen1GameEncounter(pkm) : Legal.getGen2GameEncounter(pkm);
CheckMoveResult[] res = new CheckMoveResult[4];
var G1Encounter = info.EncounterMatch;
if (G1Encounter == null)
@ -709,7 +720,18 @@ namespace PKHeX.Core
EncounterMoves.validLevelUpMoves[1] = Legal.getValidMoves(pkm, info.EvoChainsAllGens[1], generation: 1, minLvLG1: lvlG1, LVL: true, Tutor: false, Machine: false, MoveReminder: false).ToList();
break;
}
}
private static void UptateGen2LevelUpMoves(PKM pkm, ValidEncounterMoves EncounterMoves, int defaultLvlG2, int generation, LegalInfo info)
{
switch (generation)
{
case 1:
case 2:
var lvlG2 = info.EncounterMatch?.LevelMin + 1 ?? 6;
if (lvlG2 != defaultLvlG2)
EncounterMoves.validLevelUpMoves[2] = Legal.getValidMoves(pkm, info.EvoChainsAllGens[2], generation: 2, minLvLG2: defaultLvlG2, LVL: true, Tutor: false, Machine: false, MoveReminder: false).ToList();
break;
}
}
private static int[] getGenMovesCheckOrder(PKM pkm)
{
@ -730,10 +752,11 @@ namespace PKHeX.Core
private static ValidEncounterMoves getEncounterValidMoves(PKM pkm, LegalInfo info)
{
var minLvLG1 = pkm.GenNumber <= 2 ? info.EncounterMatch.LevelMin + 1 : 0;
var minLvlG2 = Legal.AllowGen2MoveReminder ? 1 : info.EncounterMatch.LevelMin + 1;
var encounterspecies = info.EncounterMatch.Species;
var EvoChainsAllGens = info.EvoChainsAllGens;
// If encounter species is the same species from the first match, the one in variable EncounterMatch, its evolution chains is already in EvoChainsAllGens
var LevelMoves = Legal.getValidMovesAllGens(pkm, EvoChainsAllGens, minLvLG1: minLvLG1, Tutor: false, Machine: false, RemoveTransferHM: false);
var LevelMoves = Legal.getValidMovesAllGens(pkm, EvoChainsAllGens, minLvLG1: minLvLG1, minLvLG2: minLvlG2, Tutor: false, Machine: false, RemoveTransferHM: false);
var TMHMMoves = Legal.getValidMovesAllGens(pkm, EvoChainsAllGens, LVL: false, Tutor: false, MoveReminder: false, RemoveTransferHM: false);
var TutorMoves = Legal.getValidMovesAllGens(pkm, EvoChainsAllGens, LVL: false, Machine: false, MoveReminder: false, RemoveTransferHM: false);
return new ValidEncounterMoves
@ -743,7 +766,8 @@ namespace PKHeX.Core
validTMHMMoves = TMHMMoves,
validTutorMoves = TutorMoves,
EvolutionChains = EvoChainsAllGens,
minLvlG1 = minLvLG1
minLvlG1 = minLvLG1,
minLvlG2 = minLvlG2
};
}
}

View file

@ -12,6 +12,7 @@ namespace PKHeX.Core
public List<int>[] validTutorMoves { get; set; } = Empty;
public int[] Relearn = new int[0];
public int minLvlG1 { get; set; }
public int minLvlG2 { get; set; }
private const int EmptyCount = 7;
public static readonly List<int>[] Empty = new int[EmptyCount].Select(z => new List<int>()).ToArray();

View file

@ -256,23 +256,23 @@ namespace PKHeX.Core
internal static readonly int[][] MinLevelEvolutionWithMove =
{
// Mr. Mime (Mime Jr with Mimic)
new [] { 0, 0, 0, 0, 18, 15, 15, 15 },
new [] { 0, 0, 0, 0, 18, 15, 15, 2 },
// Sudowoodo (Bonsly with Mimic)
new [] { 0, 0, 0, 0, 17, 17, 15, 15 },
new [] { 0, 0, 0, 0, 17, 17, 15, 2 },
// Ambipom (Aipom with Double Hit)
new [] { 0, 0, 0, 0, 32, 32, 32, 32 },
new [] { 0, 0, 0, 0, 32, 32, 32, 2 },
// Lickilicky (Lickitung with Rollout)
new [] { 0, 0, 1, 0, 1, 33, 33, 33 },
new [] { 0, 0, 2, 0, 2, 33, 33, 2 },
// Tangrowth (Tangela with Ancient Power)
new [] { 0, 0, 0, 0, 1, 36, 38, 38 },
new [] { 0, 0, 0, 0, 2, 36, 38, 2 },
// Yanmega (Yanma with Ancient Power)
new [] { 0, 0, 0, 0, 1, 33, 33, 33 },
new [] { 0, 0, 0, 0, 2, 33, 33, 2 },
// Mamoswine (Piloswine with Ancient Power)
new [] { 0, 0, 0, 0, 1, 1, 1, 1 },
new [] { 0, 0, 0, 0, 2, 2, 2, 2 },
// Sylveon (Eevee with Fairy Move)
new [] { 0, 0, 0, 0, 0, 29, 9, 9 },
new [] { 0, 0, 0, 0, 0, 29, 9, 2 },
// Tsareena (Steenee with Stomp)
new [] { 0, 0, 0, 0, 0, 0, 0, 29 },
new [] { 0, 0, 0, 0, 0, 0, 0, 2 },
};
// True -> the pokemon could hatch from an egg with the move for evolution as an egg move
internal static readonly bool[][] EggMoveEvolutionWithMove =