Merge pull request #990 from javierhimura/master

Crossgen Moves legal analysis and pokemon box encounter
This commit is contained in:
Kurt
2017-03-25 12:26:04 -07:00
committed by GitHub
6 changed files with 2770 additions and 2495 deletions

View File

@@ -413,5 +413,23 @@ private static int getSuggestedTransferLocation(PKM pkm)
return 30001;
return -1;
}
private static int[] getGenMovesCheckOrder(PKM pkm)
{
if (pkm.Format == 1)
return new [] { 1, 2 };
else if (pkm.Format == 2)
return new [] { 2, 1 };
else if (pkm.Format == 7 && pkm.VC1)
return new [] { 7, 1 };
else if (pkm.Format == 7 && pkm.VC2)
return new [] { 7, 2, 1 };
else
{
var order = new int[pkm.Format - pkm.GenNumber + 1];
for (int i = 0; i < order.Length; i++)
order[i] = pkm.Format - i;
return order;
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -569,19 +569,69 @@ private static EncounterArea[] getTables2(GameVersion Version)
}
// Moves
internal static IEnumerable<int> getValidMoves(PKM pkm, DexLevel[][] evoChains, bool LVL = true, bool Tutor = true, bool Machine = true, bool MoveReminder = true)
internal static void RemoveFutureMoves(PKM pkm, DexLevel[][] evoChains, ref int[][] validLevelMoves, ref int[][] validTMHM, ref int[][] validTutor)
{
GameVersion version = (GameVersion)pkm.Version;
if (!pkm.IsUntraded)
version = GameVersion.Any;
return getValidMoves(pkm, version, evoChains, LVL: LVL, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder);
if (pkm.Format >= 3)
{
var FutureMoves = validLevelMoves[pkm.Format].Concat(validTMHM[pkm.Format]).Concat(validTutor[pkm.Format]);
if(pkm.VC1)
{
validLevelMoves[1] = validLevelMoves[1].Except(FutureMoves).ToArray();
validTMHM[1] = validTMHM[1].Except(FutureMoves).ToArray();
validTutor[1] = validTutor[1].Except(FutureMoves).ToArray();
}
else if (pkm.VC2)
{
for (int i = 2; i >= 1; i--)
{
validLevelMoves[i] = validLevelMoves[i]?.Except(FutureMoves).ToArray();
validTMHM[i] = validTMHM[i]?.Except(FutureMoves).ToArray();
validTutor[i] = validTutor[i]?.Except(FutureMoves).ToArray();
if(validLevelMoves[i]!=null && validTMHM[i]!= null && validTutor[i]!= null)
FutureMoves = FutureMoves.Concat(validLevelMoves[i]).Concat(validTMHM[i]).Concat(validTutor[i]);
}
}
else
{
for (int i = pkm.Format - 1; i >= pkm.GenNumber; i--)
{
validLevelMoves[i] = validLevelMoves[i].Except(FutureMoves).ToArray();
validTMHM[i] = validTMHM[i].Except(FutureMoves).ToArray();
validTutor[i] = validTutor[i].Except(FutureMoves).ToArray();
FutureMoves = FutureMoves.Concat(validLevelMoves[i]).Concat(validTMHM[i]).Concat(validTutor[i]);
}
}
}
else
{
int tradeback = (pkm.Format == 2) ? 1 : 2;
var formatmoves = validLevelMoves[pkm.Format].Concat(validTMHM[pkm.Format]).Concat(validTutor[pkm.Format]);
validLevelMoves[tradeback] = validLevelMoves[tradeback]?.Except(formatmoves).ToArray();
validTMHM[tradeback] = validTMHM[tradeback]?.Except(formatmoves).ToArray();
validTutor[tradeback] = validTutor[tradeback]?.Except(formatmoves).ToArray();
}
}
internal static IEnumerable<int> getValidMoves(PKM pkm, DexLevel[] evoChain, int generation, bool LVL = true, bool Tutor = true, bool Machine = true, bool MoveReminder = true)
internal static int[][] getValidMovesAllGens(PKM pkm, DexLevel[][] evoChains, bool LVL = true, bool Tutor = true, bool Machine = true, bool MoveReminder = true, bool RemoveTransferHM = true)
{
int[][] Moves = new int[evoChains.Length][];
for (int i = 1; i < evoChains.Length; i++)
if (evoChains[i].Any())
Moves[i] = getValidMoves(pkm, evoChains[i], i, LVL, Tutor, Machine, MoveReminder, RemoveTransferHM).ToArray();
return Moves;
}
internal static IEnumerable<int> getValidMoves(PKM pkm, DexLevel[][] evoChains, 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, LVL: LVL, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder);
return getValidMoves(pkm, version, evoChains, LVL: LVL, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder, RemoveTransferHM: RemoveTransferHM);
}
internal static IEnumerable<int> getValidMoves(PKM pkm, DexLevel[] evoChain, int generation, 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, LVL: LVL, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder, RemoveTransferHM: RemoveTransferHM);
}
internal static IEnumerable<int> getValidRelearn(PKM pkm, int skipOption)
{
@@ -685,7 +735,12 @@ internal static IEnumerable<int> getBaseEggMoves(PKM pkm, int skipOption, GameVe
internal static IEnumerable<int> getEggMoves(PKM pkm, GameVersion Version)
{
return getEggMoves(pkm, getBaseSpecies(pkm), 0, Version);
}
}
internal static IEnumerable<int> getSpecialEggMoves(PKM pkm, GameVersion Version)
{
return getSpecialEggMoves(pkm, getBaseSpecies(pkm), 0, Version);
}
// Encounter
internal static EncounterLink getValidLinkGifts(PKM pkm)
@@ -2070,7 +2125,7 @@ private static IEnumerable<EncounterStatic> getStatic(PKM pkm, IEnumerable<Encou
IEnumerable<DexLevel> dl = getValidPreEvolutions(pkm, lvl);
return table.Where(e => dl.Any(d => d.Species == e.Species));
}
private static IEnumerable<int> getValidMoves(PKM pkm, GameVersion Version, IReadOnlyList<DexLevel[]> vs, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false, bool MoveReminder = true)
private static IEnumerable<int> getValidMoves(PKM pkm, GameVersion Version, IReadOnlyList<DexLevel[]> vs, 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)
@@ -2078,11 +2133,11 @@ private static IEnumerable<int> getValidMoves(PKM pkm, GameVersion Version, IRea
for (int gen = pkm.GenNumber; gen <= pkm.Format; gen++)
if (vs[gen].Any())
r.AddRange(getValidMoves(pkm, Version, vs[gen], gen, LVL: LVL, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder));
r.AddRange(getValidMoves(pkm, Version, vs[gen], gen, 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, bool LVL = false, bool Relearn = false, bool Tutor = false, bool Machine = false, bool MoveReminder = true)
private static IEnumerable<int> getValidMoves(PKM pkm, GameVersion Version, DexLevel[] vs, int Generation, 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())
@@ -2096,13 +2151,13 @@ private static IEnumerable<int> getValidMoves(PKM pkm, GameVersion Version, DexL
{
int formcount = pkm.PersonalInfo.FormeCount;
for (int i = 0; i < formcount; i++)
r.AddRange(getMoves(pkm, species, vs.First().Level, i, moveTutor, Version, LVL, Tutor, Machine, MoveReminder, Generation));
r.AddRange(getMoves(pkm, species, 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)
r.AddRange(getMoves(pkm, evo.Species, evo.Level, pkm.AltForm, moveTutor, Version, LVL, Tutor, Machine, MoveReminder, Generation));
r.AddRange(getMoves(pkm, evo.Species, evo.Level, pkm.AltForm, moveTutor, Version, LVL, Tutor, Machine, MoveReminder, RemoveTransferHM, Generation));
if (pkm.Format <= 3)
return r.Distinct();
@@ -2131,7 +2186,7 @@ private static IEnumerable<int> getValidMoves(PKM pkm, GameVersion Version, DexL
r.AddRange(pkm.RelearnMoves);
return r.Distinct();
}
private static IEnumerable<int> getMoves(PKM pkm, int species, int lvl, int form, bool moveTutor, GameVersion Version, bool LVL, bool specialTutors, bool Machine, bool MoveReminder)
private static IEnumerable<int> getMoves(PKM pkm, int species, int lvl, int form, bool moveTutor, GameVersion Version, bool LVL, bool specialTutors, bool Machine, bool MoveReminder, bool RemoveTransferHM)
{
List<int> r = new List<int> { 0 };
int gen = pkm.GenNumber;
@@ -2140,16 +2195,16 @@ private static IEnumerable<int> getMoves(PKM pkm, int species, int lvl, int form
int max = pkm.Format < 3 ? 2 : 1;
for (; gen <= max; gen++)
if (pkm.InhabitedGeneration(gen, species))
r.AddRange(getMoves(pkm, species, lvl, form, moveTutor, Version, LVL, specialTutors, Machine, MoveReminder, gen));
r.AddRange(getMoves(pkm, species, lvl, form, moveTutor, Version, LVL, specialTutors, Machine, MoveReminder, RemoveTransferHM, gen));
gen = 7;
}
for (; gen <= pkm.Format; gen++)
if (pkm.InhabitedGeneration(gen))
r.AddRange(getMoves(pkm, species, lvl, form, moveTutor, Version, LVL, specialTutors, Machine, MoveReminder, gen));
r.AddRange(getMoves(pkm, species, lvl, form, moveTutor, Version, LVL, specialTutors, Machine, MoveReminder, RemoveTransferHM, gen));
return r.Distinct();
}
private static IEnumerable<int> getMoves(PKM pkm, int species, int lvl, int form, bool moveTutor, GameVersion Version, bool LVL, bool specialTutors, bool Machine, bool MoveReminder, int Generation)
private static IEnumerable<int> getMoves(PKM pkm, int species, 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>();
@@ -2226,12 +2281,12 @@ private static IEnumerable<int> getMoves(PKM pkm, int species, int lvl, int form
{
var pi_c = PersonalTable.E[index];
r.AddRange(TM_3.Where((t, m) => pi_c.TMHM[m]));
if (pkm.Format == 3) // HM moves must be removed for 3->4, only give if current format.
if (!RemoveTransferHM || pkm.Format == 3) // HM moves must be removed for 3->4, only give if current format.
r.AddRange(HM_3.Where((t, m) => pi_c.TMHM[m+50]));
}
if (moveTutor)
r.AddRange(getTutorMoves(pkm, species, form, specialTutors, Generation));
if (pkm.Format > 3) //Remove HM
if (RemoveTransferHM && pkm.Format > 3) //Remove HM
r = r.Except(HM_3).ToList();
break;
}
@@ -2251,7 +2306,7 @@ private static IEnumerable<int> getMoves(PKM pkm, int species, int lvl, int form
var pi_hgss = PersonalTable.HGSS[index];
var pi_dppt = PersonalTable.Pt[index];
r.AddRange(TM_4.Where((t, m) => pi_hgss.TMHM[m]));
if (pkm.Format > 4)
if (RemoveTransferHM && pkm.Format > 4)
{
// 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
@@ -2268,7 +2323,7 @@ private static IEnumerable<int> getMoves(PKM pkm, int species, int lvl, int form
}
if (moveTutor)
r.AddRange(getTutorMoves(pkm, species, form, specialTutors, Generation));
if (pkm.Format > 4) //Remove HM
if (RemoveTransferHM && pkm.Format > 4) //Remove HM
r = r.Except(HM_4_RemovePokeTransfer).ToList();
break;
}
@@ -2364,6 +2419,22 @@ private static IEnumerable<int> getMoves(PKM pkm, int species, int lvl, int form
}
return r;
}
private static IEnumerable<int> getSpecialEggMoves(PKM pkm, int species, int alform, GameVersion Version = GameVersion.Any)
{
if (!pkm.InhabitedGeneration(pkm.GenNumber, species))
return new List<int>();
switch (pkm.GenNumber)
{
case 3:
{
var boxencounter = Encounter_Box.Where(e => e.Species == species).FirstOrDefault();
if (boxencounter != null)
return boxencounter.Moves;
break;
}
}
return new List<int>();
}
private static IEnumerable<int> getEggMoves(PKM pkm, int species, int formnum, GameVersion Version = GameVersion.Any)
{
if (!pkm.InhabitedGeneration(pkm.GenNumber, species))
@@ -2373,15 +2444,13 @@ private static IEnumerable<int> getEggMoves(PKM pkm, int species, int formnum, G
{
case 1:
case 2:
switch (Version)
{
case GameVersion.GS:
return EggMovesGS[species].Moves;
case GameVersion.C:
return EggMovesC[species].Moves;
default:
return new List<int>();
}
if (pkm.Format != 2)
return EggMovesC[species].Moves;
if (pkm.HasOriginalMetLocation)
return EggMovesC[species].Moves;
if (pkm.Species > 151 && !FutureEvolutionsGen1.Contains(pkm.Species))
return EggMovesGS[species].Moves;
return new List<int>();
case 3:
return EggMovesRS[species].Moves;
case 4:

View File

@@ -37,6 +37,10 @@ public static class LegalityCheckStrings
public static string V174 { get; set; } = "Learned by Move Tutor.";
public static string V175 { get; set; } = "Special Non-Relearn Move.";
public static string V177 { get; set; } = "Learned by Level-up.";
public static string V330 { get; set; } = "Learned by Level-up in generation {0}.";
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.";
#endregion
@@ -304,6 +308,12 @@ public static class LegalityCheckStrings
public static string V327 {get; set;} = "Special ingame N's Sparkle flag should not be checked.";
public static string V328 {get; set;} = "Version Specific evolution requires a trade to opposite version. A Handling Trainer is required.";
public static string V334 {get; set;} = "Non-tradeback egg move. Incompatible with generation 1 exclusive moves.";
public static string V335 {get; set;} = "Generation 1 exclusive move. Incompatible with Non-tradeback egg moves.";
public static string V336 {get; set;} = "Egg Move. Incompatible with event egg moves.";
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}.";
#endregion
}

View File

@@ -202,6 +202,13 @@ public static partial class Legal
36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
46, 47, 48, 49,
};
internal static readonly EncounterStatic[] Encounter_Box =
{
new EncounterStatic { Species = 333, Level = 05, EggLocation = 255, Version = GameVersion.RSBOX, Moves = new[]{206} }, // Swablu Egg with False Swipe
new EncounterStatic { Species = 263, Level = 05, EggLocation = 255, Version = GameVersion.RSBOX, Moves = new[]{245} }, // Zigzagoon Egg with Extreme Speed
new EncounterStatic { Species = 300, Level = 05, EggLocation = 255, Version = GameVersion.RSBOX, Moves = new[]{6} }, // Skitty Egg with Pay Day
new EncounterStatic { Species = 172, Level = 05, EggLocation = 255, Version = GameVersion.RSBOX, Moves = new[]{57} }, // Pichu Egg with Surf
};
internal static readonly EncounterStatic[] Encounter_RSE_Roam =
{
@@ -303,8 +310,8 @@ public static partial class Legal
new EncounterStatic { Species = 386, Level = 30, Location = 187, Version = GameVersion.LG, Form = 2 }, // Deoxys @ Birth Island
};
internal static readonly EncounterStatic[] Encounter_RSE = Encounter_RSE_Roam.SelectMany(e => e.Clone(Roaming_MetLocation_RSE)).Concat(Encounter_RSE_Regular).ToArray();
internal static readonly EncounterStatic[] Encounter_FRLG = Encounter_FRLG_Roam.SelectMany(e => e.Clone(Roaming_MetLocation_FRLG)).Concat(Encounter_FRLG_Stationary).ToArray();
internal static readonly EncounterStatic[] Encounter_RSE = Encounter_RSE_Roam.SelectMany(e => e.Clone(Roaming_MetLocation_RSE)).Concat(Encounter_RSE_Regular).Concat(Encounter_Box).ToArray();
internal static readonly EncounterStatic[] Encounter_FRLG = Encounter_FRLG_Roam.SelectMany(e => e.Clone(Roaming_MetLocation_FRLG)).Concat(Encounter_FRLG_Stationary).Concat(Encounter_Box).ToArray();
private static readonly int[] TradeContest_Cool = {30, 05, 05, 05, 05, 10};
private static readonly int[] TradeContest_Beauty = {05, 30, 05, 05, 05, 10};
@@ -480,7 +487,18 @@ public static partial class Legal
},}
};
#endregion
internal static readonly int[] ValidEggMet_RSE =
{
32, //Route 117
253, //Ingame egg gift
255 // event/pokemon box
};
internal static readonly int[] ValidEggMet_FRLG =
{
146, //Four Island
253, //Ingame egg gift
255 // event/pokemon box
};
// 064 is an unused location for metor falls
// 084 is Inside of a truck, no possible pokemon can be hatched there
internal static readonly int[] ValidMet_RS =

View File

@@ -15,6 +15,9 @@ V173 = Learned by TM/HM.
V174 = Learned by Move Tutor.
V175 = Special Non-Relearn Move.
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.
V203 = Genderless Pokémon should not have a gender.
V201 = Encryption Constant is not set.
V204 = Held item is unreleased.
@@ -245,4 +248,10 @@ V324 = Special ingame Fateful Encounter flag missing.
V325 = Fateful Encounter should not be checked.
V326 = Special ingame N's Sparkle flag missing.
V327 = Special ingame N's Sparkle flag should not be checked.
V328 = Version Specific evolution requires a trade to opposite version. A Handling Trainer is required.
V328 = Version Specific evolution requires a trade to opposite version. A Handling Trainer is required.
V334 = Non-tradeback egg move. Incompatible with generation 1 exclusive moves.
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}.