2017-01-04 04:51:33 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2016-02-23 06:52:48 +00:00
|
|
|
|
using System.Linq;
|
2017-07-25 07:28:43 +00:00
|
|
|
|
using static PKHeX.Core.Encounters1;
|
|
|
|
|
using static PKHeX.Core.Encounters2;
|
|
|
|
|
using static PKHeX.Core.Encounters3;
|
|
|
|
|
using static PKHeX.Core.Encounters4;
|
|
|
|
|
using static PKHeX.Core.Encounters5;
|
|
|
|
|
using static PKHeX.Core.Encounters6;
|
|
|
|
|
using static PKHeX.Core.Encounters7;
|
2017-04-10 22:59:16 +00:00
|
|
|
|
using static PKHeX.Core.LegalityCheckStrings;
|
2016-02-23 06:52:48 +00:00
|
|
|
|
|
2017-01-08 07:54:09 +00:00
|
|
|
|
namespace PKHeX.Core
|
2016-02-23 06:52:48 +00:00
|
|
|
|
{
|
|
|
|
|
public static partial class Legal
|
|
|
|
|
{
|
2017-03-12 23:36:23 +00:00
|
|
|
|
/// <summary>Setting to specify if an analysis should permit data sourced from the physical cartridge era of GameBoy games.</summary>
|
2017-06-19 05:27:40 +00:00
|
|
|
|
public static bool AllowGBCartEra { get; set; }
|
|
|
|
|
public static bool AllowGen1Tradeback { get; set; }
|
2018-01-25 17:14:25 +00:00
|
|
|
|
public static bool AllowGen2Crystal(bool Korean) => !Korean; // Pokemon Crystal was never released in Korea
|
2017-09-23 18:46:10 +00:00
|
|
|
|
public static bool AllowGen2Crystal(PKM pkm) => AllowGen2Crystal(pkm.Korean);
|
2017-09-23 19:00:57 +00:00
|
|
|
|
public static bool AllowGen2MoveReminder(PKM pkm) => !pkm.Korean && AllowGBCartEra; // Pokemon Stadium 2 was never released in Korea
|
2016-07-03 03:24:17 +00:00
|
|
|
|
|
2017-09-06 06:31:24 +00:00
|
|
|
|
public static bool CheckWordFilter { get; set; } = true;
|
|
|
|
|
|
2017-06-19 05:27:40 +00:00
|
|
|
|
/// <summary> e-Reader Berry originates from a Japanese SaveFile </summary>
|
2018-06-19 04:56:30 +00:00
|
|
|
|
public static bool SavegameJapanese => ActiveTrainer.Language == 1;
|
2017-06-19 05:27:40 +00:00
|
|
|
|
/// <summary> e-Reader Berry is Enigma or special berry </summary>
|
|
|
|
|
public static bool EReaderBerryIsEnigma { get; set; } = true;
|
|
|
|
|
/// <summary> e-Reader Berry Name </summary>
|
|
|
|
|
public static string EReaderBerryName { get; set; } = string.Empty;
|
|
|
|
|
/// <summary> e-Reader Berry Name formatted in Title Case </summary>
|
2017-06-18 01:37:19 +00:00
|
|
|
|
public static string EReaderBerryDisplayName => string.Format(V372, Util.ToTitleCase(EReaderBerryName.ToLower()));
|
2017-06-19 05:27:40 +00:00
|
|
|
|
|
2018-06-19 04:56:30 +00:00
|
|
|
|
public static ITrainerInfo ActiveTrainer = new SimpleTrainerInfo {OT = string.Empty, Game = (int)GameVersion.Any, Language = -1};
|
|
|
|
|
public static int SavegameLanguage => ActiveTrainer.Language;
|
|
|
|
|
private static string Savegame_OT => ActiveTrainer.OT;
|
|
|
|
|
private static int Savegame_TID => ActiveTrainer.TID;
|
|
|
|
|
private static int Savegame_SID => ActiveTrainer.SID;
|
|
|
|
|
private static int Savegame_Gender => ActiveTrainer.Gender;
|
|
|
|
|
private static GameVersion Savegame_Version => (GameVersion)ActiveTrainer.Game;
|
2017-04-10 23:47:08 +00:00
|
|
|
|
|
2017-02-11 23:20:44 +00:00
|
|
|
|
// Gen 1
|
2018-03-30 08:02:22 +00:00
|
|
|
|
internal static readonly Learnset[] LevelUpRB = Learnset1.GetArray(Util.GetBinaryResource("lvlmove_rb.pkl"), MaxSpeciesID_1);
|
|
|
|
|
internal static readonly Learnset[] LevelUpY = Learnset1.GetArray(Util.GetBinaryResource("lvlmove_y.pkl"), MaxSpeciesID_1);
|
2017-02-11 23:20:44 +00:00
|
|
|
|
|
2017-02-25 20:37:01 +00:00
|
|
|
|
// Gen 2
|
2018-03-30 08:02:22 +00:00
|
|
|
|
internal static readonly EggMoves[] EggMovesGS = EggMoves2.GetArray(Util.GetBinaryResource("eggmove_gs.pkl"), MaxSpeciesID_2);
|
|
|
|
|
internal static readonly Learnset[] LevelUpGS = Learnset1.GetArray(Util.GetBinaryResource("lvlmove_gs.pkl"), MaxSpeciesID_2);
|
|
|
|
|
internal static readonly EggMoves[] EggMovesC = EggMoves2.GetArray(Util.GetBinaryResource("eggmove_c.pkl"), MaxSpeciesID_2);
|
|
|
|
|
internal static readonly Learnset[] LevelUpC = Learnset1.GetArray(Util.GetBinaryResource("lvlmove_c.pkl"), MaxSpeciesID_2);
|
2017-02-25 20:37:01 +00:00
|
|
|
|
|
2017-03-18 23:50:34 +00:00
|
|
|
|
// Gen 3
|
2018-03-30 08:02:22 +00:00
|
|
|
|
internal static readonly Learnset[] LevelUpE = Learnset6.GetArray(Data.UnpackMini(Util.GetBinaryResource("lvlmove_e.pkl"), "em"));
|
|
|
|
|
internal static readonly Learnset[] LevelUpRS = Learnset6.GetArray(Data.UnpackMini(Util.GetBinaryResource("lvlmove_rs.pkl"), "rs"));
|
|
|
|
|
internal static readonly Learnset[] LevelUpFR = Learnset6.GetArray(Data.UnpackMini(Util.GetBinaryResource("lvlmove_fr.pkl"), "fr"));
|
|
|
|
|
internal static readonly Learnset[] LevelUpLG = Learnset6.GetArray(Data.UnpackMini(Util.GetBinaryResource("lvlmove_lg.pkl"), "lg"));
|
|
|
|
|
internal static readonly EggMoves[] EggMovesRS = EggMoves6.GetArray(Data.UnpackMini(Util.GetBinaryResource("eggmove_rs.pkl"), "rs"));
|
2017-03-18 23:50:34 +00:00
|
|
|
|
|
|
|
|
|
// Gen 4
|
2018-03-30 08:02:22 +00:00
|
|
|
|
internal static readonly Learnset[] LevelUpDP = Learnset6.GetArray(Data.UnpackMini(Util.GetBinaryResource("lvlmove_dp.pkl"), "dp"));
|
|
|
|
|
internal static readonly Learnset[] LevelUpPt = Learnset6.GetArray(Data.UnpackMini(Util.GetBinaryResource("lvlmove_pt.pkl"), "pt"));
|
|
|
|
|
internal static readonly Learnset[] LevelUpHGSS = Learnset6.GetArray(Data.UnpackMini(Util.GetBinaryResource("lvlmove_hgss.pkl"), "hs"));
|
|
|
|
|
internal static readonly EggMoves[] EggMovesDPPt = EggMoves6.GetArray(Data.UnpackMini(Util.GetBinaryResource("eggmove_dppt.pkl"), "dp"));
|
|
|
|
|
internal static readonly EggMoves[] EggMovesHGSS = EggMoves6.GetArray(Data.UnpackMini(Util.GetBinaryResource("eggmove_hgss.pkl"), "hs"));
|
2017-03-18 23:50:34 +00:00
|
|
|
|
|
|
|
|
|
// Gen 5
|
2018-03-30 08:02:22 +00:00
|
|
|
|
internal static readonly Learnset[] LevelUpBW = Learnset6.GetArray(Data.UnpackMini(Util.GetBinaryResource("lvlmove_bw.pkl"), "51"));
|
|
|
|
|
internal static readonly Learnset[] LevelUpB2W2 = Learnset6.GetArray(Data.UnpackMini(Util.GetBinaryResource("lvlmove_b2w2.pkl"), "52"));
|
|
|
|
|
internal static readonly EggMoves[] EggMovesBW = EggMoves6.GetArray(Data.UnpackMini(Util.GetBinaryResource("eggmove_bw.pkl"), "bw"));
|
2017-03-18 23:50:34 +00:00
|
|
|
|
|
2016-10-24 05:03:19 +00:00
|
|
|
|
// Gen 6
|
2018-03-30 08:02:22 +00:00
|
|
|
|
internal static readonly EggMoves[] EggMovesXY = EggMoves6.GetArray(Data.UnpackMini(Util.GetBinaryResource("eggmove_xy.pkl"), "xy"));
|
|
|
|
|
internal static readonly Learnset[] LevelUpXY = Learnset6.GetArray(Data.UnpackMini(Util.GetBinaryResource("lvlmove_xy.pkl"), "xy"));
|
|
|
|
|
internal static readonly EggMoves[] EggMovesAO = EggMoves6.GetArray(Data.UnpackMini(Util.GetBinaryResource("eggmove_ao.pkl"), "ao"));
|
|
|
|
|
internal static readonly Learnset[] LevelUpAO = Learnset6.GetArray(Data.UnpackMini(Util.GetBinaryResource("lvlmove_ao.pkl"), "ao"));
|
2016-10-24 05:03:19 +00:00
|
|
|
|
|
|
|
|
|
// Gen 7
|
2018-03-30 08:02:22 +00:00
|
|
|
|
internal static readonly EggMoves[] EggMovesSM = EggMoves7.GetArray(Data.UnpackMini(Util.GetBinaryResource("eggmove_sm.pkl"), "sm"));
|
|
|
|
|
internal static readonly Learnset[] LevelUpSM = Learnset6.GetArray(Data.UnpackMini(Util.GetBinaryResource("lvlmove_sm.pkl"), "sm"));
|
|
|
|
|
internal static readonly EggMoves[] EggMovesUSUM = EggMoves7.GetArray(Data.UnpackMini(Util.GetBinaryResource("eggmove_uu.pkl"), "uu"));
|
|
|
|
|
internal static readonly Learnset[] LevelUpUSUM = Learnset6.GetArray(Data.UnpackMini(Util.GetBinaryResource("lvlmove_uu.pkl"), "uu"));
|
2016-10-24 05:03:19 +00:00
|
|
|
|
|
|
|
|
|
// Setup Help
|
2018-02-11 02:56:06 +00:00
|
|
|
|
static Legal()
|
|
|
|
|
{
|
|
|
|
|
// Misc Fixes to Data pertaining to legality constraints
|
|
|
|
|
EggMovesUSUM[198].Moves = EggMovesUSUM[198].Moves.Take(15).ToArray(); // Remove Punishment from USUM Murkrow (no species can pass it #1829)
|
|
|
|
|
}
|
2018-03-06 06:19:56 +00:00
|
|
|
|
|
|
|
|
|
public static void RefreshMGDB(string localDbPath) => EncounterEvent.RefreshMGDB(localDbPath);
|
2017-05-12 04:34:18 +00:00
|
|
|
|
|
2016-10-24 05:03:19 +00:00
|
|
|
|
// Moves
|
2018-03-09 05:18:32 +00:00
|
|
|
|
internal static int[] GetMinLevelLearnMoveG1(int species, List<int> moves)
|
Gen 1 move analysis improvement. Adapted the valid moves to take into account that move deleter and move reminder do not exits in generation 1 (#1037)
* Fix getMoves with min level, when SkipWhile and TakeWhile is used together the index i in TakeWhile is calculated from the enumerator that results of the SkipWhile function, not the index of the initial array, those giving an incorrect index to check Levels array in the TakeWhile
* Fix getMoves when levelmin or levelmax is above max level in the levels array, TakeWhile and SkipWhile return empty list if the while goes beyond the last element of the array
* Include player hatched egg in the list of possible encounters for parseMoves only if the pokemon was an egg
Also change the valur of WasEgg for gen1,2,3 pokemon if the encounter analyzed is not an egg
add the non egg encounters to the list instead of checking the non-egg encounter inside parseMovesWasEggPreRelearn
* Fix for gen3 egg encounters
Remove non-egg encounters without special moves if there is an egg encounter because egg encounter already cover every possible move combination
Do not add daycare egg encounter for gen3 unhatched egg if there is another encounter, that means is an event or gift egg, not a daycare egg
Remove duplicate encounters
* Gift egg should not allow inherited moves even it they dont have special moves
Those gift eggs are hatched only with the species base moves
* Added getEncounterMoves functions, to be used for generation 1 encounters to find what moves have a pokemon at the moment of being caught because there is no move reminder in generation 1
* Added GBEncounterData, structure for refactor the tuples used in generation 1 and 2 encounters
* Add LevelMin and LevelMax to IEncounterable to get the encounter moves by the min level of the generation 1 EncounterLink
Add iGeneration to difference generation 1 and generation 2 encounters for GB Era pokemon
* Mark generation in gen 1 and 2 encounters
There is no need to mark the generation in gen 3 to 7 encounters because in that generations it match the pokemon generation number
* Add min level for generation 1 moves in getMoves functions
Add function to return the default moves for a GB encounters, for generation 1 games that included both moves from level up table and level 1 moves from personal table
Fix getMoves with min level when the moves list is empty, like Raichu generation 1
* Add maxSpecies to getBaseSpecies function for gen1 pokemon with a gen2 egg encounter
Refactor VC Encounter changing Tuples for GBData class
* Fixed for gen 2 Checks
Also do not search for generation1 encounter if the gen2 pokemon have met location from crystal
* Fix VC wild encounters, should be stored as array or else other verifyEncounter functions wont work
* Add generation 1 parse moves function including default moves
* Clean-up get encounters
* Verify empty moves for generation 1 encounters, in generation 1 does not exits move deleter
That means when a move slot have been used by a level up move or a TM/HM/Tutor move it cant be empty again
Does not apply if generation 2 tradeback is allowed, in generation 2 there is a move deleter
* Added two edge cases for pokemon that learn in red/blue and yellow different moves at the same level, this combinations can not exits until a later level when they learn again one of the levels in the other game, only happen for flareon and vaporeon
* Check incompatible moves between evolution species, it is for species that learn a move in a level as an evolved species and a move at a upper level as a preevolution
Also added most edge cases for the min slots used for generation 1 games, i think every weird combination is already covered
* Fix gen 1 eevee and evolutions move checks
* Cleanup
* Move the code to change valid moves for generation 1 to a function
* Fix getMoveMinLevelGBEncounter
* getUsedMoveSlots, removed wild Butterfree edge case, it is not possible
* Filter the min level of the encounter by the possible games the pokemon could be originated, yellow pikachu and kadabra can be detected
2017-04-09 00:17:20 +00:00
|
|
|
|
{
|
|
|
|
|
var r = new int[moves.Count];
|
2018-06-19 04:56:30 +00:00
|
|
|
|
for (int i = 0; i < r.Length; i++)
|
|
|
|
|
r[i] = MoveLevelUp.GetIsLevelUp1(species, moves[i], 100, 0, 0).Level;
|
Gen 1 move analysis improvement. Adapted the valid moves to take into account that move deleter and move reminder do not exits in generation 1 (#1037)
* Fix getMoves with min level, when SkipWhile and TakeWhile is used together the index i in TakeWhile is calculated from the enumerator that results of the SkipWhile function, not the index of the initial array, those giving an incorrect index to check Levels array in the TakeWhile
* Fix getMoves when levelmin or levelmax is above max level in the levels array, TakeWhile and SkipWhile return empty list if the while goes beyond the last element of the array
* Include player hatched egg in the list of possible encounters for parseMoves only if the pokemon was an egg
Also change the valur of WasEgg for gen1,2,3 pokemon if the encounter analyzed is not an egg
add the non egg encounters to the list instead of checking the non-egg encounter inside parseMovesWasEggPreRelearn
* Fix for gen3 egg encounters
Remove non-egg encounters without special moves if there is an egg encounter because egg encounter already cover every possible move combination
Do not add daycare egg encounter for gen3 unhatched egg if there is another encounter, that means is an event or gift egg, not a daycare egg
Remove duplicate encounters
* Gift egg should not allow inherited moves even it they dont have special moves
Those gift eggs are hatched only with the species base moves
* Added getEncounterMoves functions, to be used for generation 1 encounters to find what moves have a pokemon at the moment of being caught because there is no move reminder in generation 1
* Added GBEncounterData, structure for refactor the tuples used in generation 1 and 2 encounters
* Add LevelMin and LevelMax to IEncounterable to get the encounter moves by the min level of the generation 1 EncounterLink
Add iGeneration to difference generation 1 and generation 2 encounters for GB Era pokemon
* Mark generation in gen 1 and 2 encounters
There is no need to mark the generation in gen 3 to 7 encounters because in that generations it match the pokemon generation number
* Add min level for generation 1 moves in getMoves functions
Add function to return the default moves for a GB encounters, for generation 1 games that included both moves from level up table and level 1 moves from personal table
Fix getMoves with min level when the moves list is empty, like Raichu generation 1
* Add maxSpecies to getBaseSpecies function for gen1 pokemon with a gen2 egg encounter
Refactor VC Encounter changing Tuples for GBData class
* Fixed for gen 2 Checks
Also do not search for generation1 encounter if the gen2 pokemon have met location from crystal
* Fix VC wild encounters, should be stored as array or else other verifyEncounter functions wont work
* Add generation 1 parse moves function including default moves
* Clean-up get encounters
* Verify empty moves for generation 1 encounters, in generation 1 does not exits move deleter
That means when a move slot have been used by a level up move or a TM/HM/Tutor move it cant be empty again
Does not apply if generation 2 tradeback is allowed, in generation 2 there is a move deleter
* Added two edge cases for pokemon that learn in red/blue and yellow different moves at the same level, this combinations can not exits until a later level when they learn again one of the levels in the other game, only happen for flareon and vaporeon
* Check incompatible moves between evolution species, it is for species that learn a move in a level as an evolved species and a move at a upper level as a preevolution
Also added most edge cases for the min slots used for generation 1 games, i think every weird combination is already covered
* Fix gen 1 eevee and evolutions move checks
* Cleanup
* Move the code to change valid moves for generation 1 to a function
* Fix getMoveMinLevelGBEncounter
* getUsedMoveSlots, removed wild Butterfree edge case, it is not possible
* Filter the min level of the encounter by the possible games the pokemon could be originated, yellow pikachu and kadabra can be detected
2017-04-09 00:17:20 +00:00
|
|
|
|
return r;
|
|
|
|
|
}
|
2018-03-09 05:18:32 +00:00
|
|
|
|
internal static int[] GetMaxLevelLearnMoveG1(int species, List<int> moves)
|
Gen 1 move analysis improvement. Adapted the valid moves to take into account that move deleter and move reminder do not exits in generation 1 (#1037)
* Fix getMoves with min level, when SkipWhile and TakeWhile is used together the index i in TakeWhile is calculated from the enumerator that results of the SkipWhile function, not the index of the initial array, those giving an incorrect index to check Levels array in the TakeWhile
* Fix getMoves when levelmin or levelmax is above max level in the levels array, TakeWhile and SkipWhile return empty list if the while goes beyond the last element of the array
* Include player hatched egg in the list of possible encounters for parseMoves only if the pokemon was an egg
Also change the valur of WasEgg for gen1,2,3 pokemon if the encounter analyzed is not an egg
add the non egg encounters to the list instead of checking the non-egg encounter inside parseMovesWasEggPreRelearn
* Fix for gen3 egg encounters
Remove non-egg encounters without special moves if there is an egg encounter because egg encounter already cover every possible move combination
Do not add daycare egg encounter for gen3 unhatched egg if there is another encounter, that means is an event or gift egg, not a daycare egg
Remove duplicate encounters
* Gift egg should not allow inherited moves even it they dont have special moves
Those gift eggs are hatched only with the species base moves
* Added getEncounterMoves functions, to be used for generation 1 encounters to find what moves have a pokemon at the moment of being caught because there is no move reminder in generation 1
* Added GBEncounterData, structure for refactor the tuples used in generation 1 and 2 encounters
* Add LevelMin and LevelMax to IEncounterable to get the encounter moves by the min level of the generation 1 EncounterLink
Add iGeneration to difference generation 1 and generation 2 encounters for GB Era pokemon
* Mark generation in gen 1 and 2 encounters
There is no need to mark the generation in gen 3 to 7 encounters because in that generations it match the pokemon generation number
* Add min level for generation 1 moves in getMoves functions
Add function to return the default moves for a GB encounters, for generation 1 games that included both moves from level up table and level 1 moves from personal table
Fix getMoves with min level when the moves list is empty, like Raichu generation 1
* Add maxSpecies to getBaseSpecies function for gen1 pokemon with a gen2 egg encounter
Refactor VC Encounter changing Tuples for GBData class
* Fixed for gen 2 Checks
Also do not search for generation1 encounter if the gen2 pokemon have met location from crystal
* Fix VC wild encounters, should be stored as array or else other verifyEncounter functions wont work
* Add generation 1 parse moves function including default moves
* Clean-up get encounters
* Verify empty moves for generation 1 encounters, in generation 1 does not exits move deleter
That means when a move slot have been used by a level up move or a TM/HM/Tutor move it cant be empty again
Does not apply if generation 2 tradeback is allowed, in generation 2 there is a move deleter
* Added two edge cases for pokemon that learn in red/blue and yellow different moves at the same level, this combinations can not exits until a later level when they learn again one of the levels in the other game, only happen for flareon and vaporeon
* Check incompatible moves between evolution species, it is for species that learn a move in a level as an evolved species and a move at a upper level as a preevolution
Also added most edge cases for the min slots used for generation 1 games, i think every weird combination is already covered
* Fix gen 1 eevee and evolutions move checks
* Cleanup
* Move the code to change valid moves for generation 1 to a function
* Fix getMoveMinLevelGBEncounter
* getUsedMoveSlots, removed wild Butterfree edge case, it is not possible
* Filter the min level of the encounter by the possible games the pokemon could be originated, yellow pikachu and kadabra can be detected
2017-04-09 00:17:20 +00:00
|
|
|
|
{
|
|
|
|
|
var r = new int[moves.Count];
|
|
|
|
|
|
2018-03-09 05:18:32 +00:00
|
|
|
|
int index = PersonalTable.RB.GetFormeIndex(species, 0);
|
|
|
|
|
if (index == 0)
|
|
|
|
|
return r;
|
Gen 1 move analysis improvement. Adapted the valid moves to take into account that move deleter and move reminder do not exits in generation 1 (#1037)
* Fix getMoves with min level, when SkipWhile and TakeWhile is used together the index i in TakeWhile is calculated from the enumerator that results of the SkipWhile function, not the index of the initial array, those giving an incorrect index to check Levels array in the TakeWhile
* Fix getMoves when levelmin or levelmax is above max level in the levels array, TakeWhile and SkipWhile return empty list if the while goes beyond the last element of the array
* Include player hatched egg in the list of possible encounters for parseMoves only if the pokemon was an egg
Also change the valur of WasEgg for gen1,2,3 pokemon if the encounter analyzed is not an egg
add the non egg encounters to the list instead of checking the non-egg encounter inside parseMovesWasEggPreRelearn
* Fix for gen3 egg encounters
Remove non-egg encounters without special moves if there is an egg encounter because egg encounter already cover every possible move combination
Do not add daycare egg encounter for gen3 unhatched egg if there is another encounter, that means is an event or gift egg, not a daycare egg
Remove duplicate encounters
* Gift egg should not allow inherited moves even it they dont have special moves
Those gift eggs are hatched only with the species base moves
* Added getEncounterMoves functions, to be used for generation 1 encounters to find what moves have a pokemon at the moment of being caught because there is no move reminder in generation 1
* Added GBEncounterData, structure for refactor the tuples used in generation 1 and 2 encounters
* Add LevelMin and LevelMax to IEncounterable to get the encounter moves by the min level of the generation 1 EncounterLink
Add iGeneration to difference generation 1 and generation 2 encounters for GB Era pokemon
* Mark generation in gen 1 and 2 encounters
There is no need to mark the generation in gen 3 to 7 encounters because in that generations it match the pokemon generation number
* Add min level for generation 1 moves in getMoves functions
Add function to return the default moves for a GB encounters, for generation 1 games that included both moves from level up table and level 1 moves from personal table
Fix getMoves with min level when the moves list is empty, like Raichu generation 1
* Add maxSpecies to getBaseSpecies function for gen1 pokemon with a gen2 egg encounter
Refactor VC Encounter changing Tuples for GBData class
* Fixed for gen 2 Checks
Also do not search for generation1 encounter if the gen2 pokemon have met location from crystal
* Fix VC wild encounters, should be stored as array or else other verifyEncounter functions wont work
* Add generation 1 parse moves function including default moves
* Clean-up get encounters
* Verify empty moves for generation 1 encounters, in generation 1 does not exits move deleter
That means when a move slot have been used by a level up move or a TM/HM/Tutor move it cant be empty again
Does not apply if generation 2 tradeback is allowed, in generation 2 there is a move deleter
* Added two edge cases for pokemon that learn in red/blue and yellow different moves at the same level, this combinations can not exits until a later level when they learn again one of the levels in the other game, only happen for flareon and vaporeon
* Check incompatible moves between evolution species, it is for species that learn a move in a level as an evolved species and a move at a upper level as a preevolution
Also added most edge cases for the min slots used for generation 1 games, i think every weird combination is already covered
* Fix gen 1 eevee and evolutions move checks
* Cleanup
* Move the code to change valid moves for generation 1 to a function
* Fix getMoveMinLevelGBEncounter
* getUsedMoveSlots, removed wild Butterfree edge case, it is not possible
* Filter the min level of the encounter by the possible games the pokemon could be originated, yellow pikachu and kadabra can be detected
2017-04-09 00:17:20 +00:00
|
|
|
|
|
2018-03-09 05:18:32 +00:00
|
|
|
|
var pi_rb = ((PersonalInfoG1)PersonalTable.RB[index]).Moves;
|
|
|
|
|
var pi_y = ((PersonalInfoG1)PersonalTable.Y[index]).Moves;
|
|
|
|
|
|
|
|
|
|
for (int m = 0; m < moves.Count; m++)
|
|
|
|
|
{
|
|
|
|
|
bool start = pi_rb.Contains(moves[m]) && pi_y.Contains(moves[m]);
|
|
|
|
|
r[m] = start ? 1 : Math.Max(GetHighest(LevelUpRB), GetHighest(LevelUpY));
|
|
|
|
|
int GetHighest(IReadOnlyList<Learnset> learn) => learn[index].GetLevelLearnMove(moves[m]);
|
Gen 1 move analysis improvement. Adapted the valid moves to take into account that move deleter and move reminder do not exits in generation 1 (#1037)
* Fix getMoves with min level, when SkipWhile and TakeWhile is used together the index i in TakeWhile is calculated from the enumerator that results of the SkipWhile function, not the index of the initial array, those giving an incorrect index to check Levels array in the TakeWhile
* Fix getMoves when levelmin or levelmax is above max level in the levels array, TakeWhile and SkipWhile return empty list if the while goes beyond the last element of the array
* Include player hatched egg in the list of possible encounters for parseMoves only if the pokemon was an egg
Also change the valur of WasEgg for gen1,2,3 pokemon if the encounter analyzed is not an egg
add the non egg encounters to the list instead of checking the non-egg encounter inside parseMovesWasEggPreRelearn
* Fix for gen3 egg encounters
Remove non-egg encounters without special moves if there is an egg encounter because egg encounter already cover every possible move combination
Do not add daycare egg encounter for gen3 unhatched egg if there is another encounter, that means is an event or gift egg, not a daycare egg
Remove duplicate encounters
* Gift egg should not allow inherited moves even it they dont have special moves
Those gift eggs are hatched only with the species base moves
* Added getEncounterMoves functions, to be used for generation 1 encounters to find what moves have a pokemon at the moment of being caught because there is no move reminder in generation 1
* Added GBEncounterData, structure for refactor the tuples used in generation 1 and 2 encounters
* Add LevelMin and LevelMax to IEncounterable to get the encounter moves by the min level of the generation 1 EncounterLink
Add iGeneration to difference generation 1 and generation 2 encounters for GB Era pokemon
* Mark generation in gen 1 and 2 encounters
There is no need to mark the generation in gen 3 to 7 encounters because in that generations it match the pokemon generation number
* Add min level for generation 1 moves in getMoves functions
Add function to return the default moves for a GB encounters, for generation 1 games that included both moves from level up table and level 1 moves from personal table
Fix getMoves with min level when the moves list is empty, like Raichu generation 1
* Add maxSpecies to getBaseSpecies function for gen1 pokemon with a gen2 egg encounter
Refactor VC Encounter changing Tuples for GBData class
* Fixed for gen 2 Checks
Also do not search for generation1 encounter if the gen2 pokemon have met location from crystal
* Fix VC wild encounters, should be stored as array or else other verifyEncounter functions wont work
* Add generation 1 parse moves function including default moves
* Clean-up get encounters
* Verify empty moves for generation 1 encounters, in generation 1 does not exits move deleter
That means when a move slot have been used by a level up move or a TM/HM/Tutor move it cant be empty again
Does not apply if generation 2 tradeback is allowed, in generation 2 there is a move deleter
* Added two edge cases for pokemon that learn in red/blue and yellow different moves at the same level, this combinations can not exits until a later level when they learn again one of the levels in the other game, only happen for flareon and vaporeon
* Check incompatible moves between evolution species, it is for species that learn a move in a level as an evolved species and a move at a upper level as a preevolution
Also added most edge cases for the min slots used for generation 1 games, i think every weird combination is already covered
* Fix gen 1 eevee and evolutions move checks
* Cleanup
* Move the code to change valid moves for generation 1 to a function
* Fix getMoveMinLevelGBEncounter
* getUsedMoveSlots, removed wild Butterfree edge case, it is not possible
* Filter the min level of the encounter by the possible games the pokemon could be originated, yellow pikachu and kadabra can be detected
2017-04-09 00:17:20 +00:00
|
|
|
|
}
|
|
|
|
|
return r;
|
|
|
|
|
}
|
2018-06-10 17:44:05 +00:00
|
|
|
|
internal static List<int>[] GetExclusiveMovesG1(int species1, int species2, IEnumerable<int> tmhm, IEnumerable<int> moves)
|
Gen 1 move analysis improvement. Adapted the valid moves to take into account that move deleter and move reminder do not exits in generation 1 (#1037)
* Fix getMoves with min level, when SkipWhile and TakeWhile is used together the index i in TakeWhile is calculated from the enumerator that results of the SkipWhile function, not the index of the initial array, those giving an incorrect index to check Levels array in the TakeWhile
* Fix getMoves when levelmin or levelmax is above max level in the levels array, TakeWhile and SkipWhile return empty list if the while goes beyond the last element of the array
* Include player hatched egg in the list of possible encounters for parseMoves only if the pokemon was an egg
Also change the valur of WasEgg for gen1,2,3 pokemon if the encounter analyzed is not an egg
add the non egg encounters to the list instead of checking the non-egg encounter inside parseMovesWasEggPreRelearn
* Fix for gen3 egg encounters
Remove non-egg encounters without special moves if there is an egg encounter because egg encounter already cover every possible move combination
Do not add daycare egg encounter for gen3 unhatched egg if there is another encounter, that means is an event or gift egg, not a daycare egg
Remove duplicate encounters
* Gift egg should not allow inherited moves even it they dont have special moves
Those gift eggs are hatched only with the species base moves
* Added getEncounterMoves functions, to be used for generation 1 encounters to find what moves have a pokemon at the moment of being caught because there is no move reminder in generation 1
* Added GBEncounterData, structure for refactor the tuples used in generation 1 and 2 encounters
* Add LevelMin and LevelMax to IEncounterable to get the encounter moves by the min level of the generation 1 EncounterLink
Add iGeneration to difference generation 1 and generation 2 encounters for GB Era pokemon
* Mark generation in gen 1 and 2 encounters
There is no need to mark the generation in gen 3 to 7 encounters because in that generations it match the pokemon generation number
* Add min level for generation 1 moves in getMoves functions
Add function to return the default moves for a GB encounters, for generation 1 games that included both moves from level up table and level 1 moves from personal table
Fix getMoves with min level when the moves list is empty, like Raichu generation 1
* Add maxSpecies to getBaseSpecies function for gen1 pokemon with a gen2 egg encounter
Refactor VC Encounter changing Tuples for GBData class
* Fixed for gen 2 Checks
Also do not search for generation1 encounter if the gen2 pokemon have met location from crystal
* Fix VC wild encounters, should be stored as array or else other verifyEncounter functions wont work
* Add generation 1 parse moves function including default moves
* Clean-up get encounters
* Verify empty moves for generation 1 encounters, in generation 1 does not exits move deleter
That means when a move slot have been used by a level up move or a TM/HM/Tutor move it cant be empty again
Does not apply if generation 2 tradeback is allowed, in generation 2 there is a move deleter
* Added two edge cases for pokemon that learn in red/blue and yellow different moves at the same level, this combinations can not exits until a later level when they learn again one of the levels in the other game, only happen for flareon and vaporeon
* Check incompatible moves between evolution species, it is for species that learn a move in a level as an evolved species and a move at a upper level as a preevolution
Also added most edge cases for the min slots used for generation 1 games, i think every weird combination is already covered
* Fix gen 1 eevee and evolutions move checks
* Cleanup
* Move the code to change valid moves for generation 1 to a function
* Fix getMoveMinLevelGBEncounter
* getUsedMoveSlots, removed wild Butterfree edge case, it is not possible
* Filter the min level of the encounter by the possible games the pokemon could be originated, yellow pikachu and kadabra can be detected
2017-04-09 00:17:20 +00:00
|
|
|
|
{
|
|
|
|
|
// Return from two species the exclusive moves that only one could learn and also the current pokemon have it in its current moveset
|
2018-06-18 04:54:04 +00:00
|
|
|
|
var moves1 = MoveLevelUp.GetMovesLevelUp1(species1, 0, 1, 100);
|
|
|
|
|
var moves2 = MoveLevelUp.GetMovesLevelUp1(species2, 0, 1, 100);
|
2017-06-18 01:37:19 +00:00
|
|
|
|
|
|
|
|
|
// Remove common moves and remove tmhm, remove not learned moves
|
|
|
|
|
var common = new HashSet<int>(moves1.Intersect(moves2).Concat(tmhm));
|
|
|
|
|
var hashMoves = new HashSet<int>(moves);
|
|
|
|
|
moves1.RemoveAll(x => !hashMoves.Contains(x) || common.Contains(x));
|
|
|
|
|
moves2.RemoveAll(x => !hashMoves.Contains(x) || common.Contains(x));
|
Gen 1 move analysis improvement. Adapted the valid moves to take into account that move deleter and move reminder do not exits in generation 1 (#1037)
* Fix getMoves with min level, when SkipWhile and TakeWhile is used together the index i in TakeWhile is calculated from the enumerator that results of the SkipWhile function, not the index of the initial array, those giving an incorrect index to check Levels array in the TakeWhile
* Fix getMoves when levelmin or levelmax is above max level in the levels array, TakeWhile and SkipWhile return empty list if the while goes beyond the last element of the array
* Include player hatched egg in the list of possible encounters for parseMoves only if the pokemon was an egg
Also change the valur of WasEgg for gen1,2,3 pokemon if the encounter analyzed is not an egg
add the non egg encounters to the list instead of checking the non-egg encounter inside parseMovesWasEggPreRelearn
* Fix for gen3 egg encounters
Remove non-egg encounters without special moves if there is an egg encounter because egg encounter already cover every possible move combination
Do not add daycare egg encounter for gen3 unhatched egg if there is another encounter, that means is an event or gift egg, not a daycare egg
Remove duplicate encounters
* Gift egg should not allow inherited moves even it they dont have special moves
Those gift eggs are hatched only with the species base moves
* Added getEncounterMoves functions, to be used for generation 1 encounters to find what moves have a pokemon at the moment of being caught because there is no move reminder in generation 1
* Added GBEncounterData, structure for refactor the tuples used in generation 1 and 2 encounters
* Add LevelMin and LevelMax to IEncounterable to get the encounter moves by the min level of the generation 1 EncounterLink
Add iGeneration to difference generation 1 and generation 2 encounters for GB Era pokemon
* Mark generation in gen 1 and 2 encounters
There is no need to mark the generation in gen 3 to 7 encounters because in that generations it match the pokemon generation number
* Add min level for generation 1 moves in getMoves functions
Add function to return the default moves for a GB encounters, for generation 1 games that included both moves from level up table and level 1 moves from personal table
Fix getMoves with min level when the moves list is empty, like Raichu generation 1
* Add maxSpecies to getBaseSpecies function for gen1 pokemon with a gen2 egg encounter
Refactor VC Encounter changing Tuples for GBData class
* Fixed for gen 2 Checks
Also do not search for generation1 encounter if the gen2 pokemon have met location from crystal
* Fix VC wild encounters, should be stored as array or else other verifyEncounter functions wont work
* Add generation 1 parse moves function including default moves
* Clean-up get encounters
* Verify empty moves for generation 1 encounters, in generation 1 does not exits move deleter
That means when a move slot have been used by a level up move or a TM/HM/Tutor move it cant be empty again
Does not apply if generation 2 tradeback is allowed, in generation 2 there is a move deleter
* Added two edge cases for pokemon that learn in red/blue and yellow different moves at the same level, this combinations can not exits until a later level when they learn again one of the levels in the other game, only happen for flareon and vaporeon
* Check incompatible moves between evolution species, it is for species that learn a move in a level as an evolved species and a move at a upper level as a preevolution
Also added most edge cases for the min slots used for generation 1 games, i think every weird combination is already covered
* Fix gen 1 eevee and evolutions move checks
* Cleanup
* Move the code to change valid moves for generation 1 to a function
* Fix getMoveMinLevelGBEncounter
* getUsedMoveSlots, removed wild Butterfree edge case, it is not possible
* Filter the min level of the encounter by the possible games the pokemon could be originated, yellow pikachu and kadabra can be detected
2017-04-09 00:17:20 +00:00
|
|
|
|
return new[] { moves1, moves2 };
|
|
|
|
|
}
|
2018-06-23 00:59:02 +00:00
|
|
|
|
internal static List<int>[] GetValidMovesAllGens(PKM pkm, IReadOnlyList<EvoCriteria>[] evoChains, int minLvLG1 = 1, int minLvLG2 = 1, bool LVL = true, bool Tutor = true, bool Machine = true, bool MoveReminder = true, bool RemoveTransferHM = true)
|
2017-03-25 12:27:42 +00:00
|
|
|
|
{
|
2018-07-04 16:15:20 +00:00
|
|
|
|
var Moves = new List<int>[evoChains.Length];
|
2017-03-25 12:27:42 +00:00
|
|
|
|
for (int i = 1; i < evoChains.Length; i++)
|
2018-07-04 16:15:20 +00:00
|
|
|
|
{
|
2018-06-23 00:59:02 +00:00
|
|
|
|
if (evoChains[i].Count != 0)
|
2017-06-18 01:37:19 +00:00
|
|
|
|
Moves[i] = GetValidMoves(pkm, evoChains[i], i, minLvLG1, minLvLG2, LVL, Tutor, Machine, MoveReminder, RemoveTransferHM).ToList();
|
2017-03-26 05:23:54 +00:00
|
|
|
|
else
|
|
|
|
|
Moves[i] = new List<int>();
|
2018-07-04 16:15:20 +00:00
|
|
|
|
}
|
2017-03-25 12:27:42 +00:00
|
|
|
|
return Moves;
|
|
|
|
|
}
|
2018-06-19 02:10:21 +00:00
|
|
|
|
internal static IEnumerable<int> GetValidMoves(PKM pkm, IReadOnlyList<EvoCriteria>[] evoChains, bool LVL = true, bool Tutor = true, bool Machine = true, bool MoveReminder = true, bool RemoveTransferHM = true)
|
2016-10-24 05:03:19 +00:00
|
|
|
|
{
|
2016-11-09 06:10:32 +00:00
|
|
|
|
GameVersion version = (GameVersion)pkm.Version;
|
2016-10-24 05:03:19 +00:00
|
|
|
|
if (!pkm.IsUntraded)
|
2016-11-09 06:10:32 +00:00
|
|
|
|
version = GameVersion.Any;
|
2018-06-09 23:04:06 +00:00
|
|
|
|
return GetValidMoves(pkm, version, evoChains, minLvLG1: 1, minLvLG2: 1, LVL: LVL, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder, RemoveTransferHM: RemoveTransferHM);
|
2017-02-15 22:33:59 +00:00
|
|
|
|
}
|
2018-06-19 02:10:21 +00:00
|
|
|
|
internal static IEnumerable<int> GetValidMoves(PKM pkm, IReadOnlyList<EvoCriteria> evoChain, int generation, int minLvLG1 = 1, int minLvLG2 = 1, bool LVL = true, bool Tutor = true, bool Machine = true, bool MoveReminder = true, bool RemoveTransferHM = true)
|
2017-02-15 22:33:59 +00:00
|
|
|
|
{
|
|
|
|
|
GameVersion version = (GameVersion)pkm.Version;
|
|
|
|
|
if (!pkm.IsUntraded)
|
|
|
|
|
version = GameVersion.Any;
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return GetValidMoves(pkm, version, evoChain, generation, minLvLG1: minLvLG1, minLvLG2: minLvLG2, LVL: LVL, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder, RemoveTransferHM: RemoveTransferHM);
|
2016-10-24 05:03:19 +00:00
|
|
|
|
}
|
2017-09-29 00:11:30 +00:00
|
|
|
|
internal static IEnumerable<int> GetValidRelearn(PKM pkm, int species, bool inheritlvlmoves, GameVersion version = GameVersion.Any)
|
2016-02-23 06:52:48 +00:00
|
|
|
|
{
|
2016-03-04 06:12:22 +00:00
|
|
|
|
List<int> r = new List<int> { 0 };
|
2017-03-18 23:50:34 +00:00
|
|
|
|
if (pkm.GenNumber < 6 || pkm.VC)
|
2017-02-12 17:52:26 +00:00
|
|
|
|
return r;
|
|
|
|
|
|
2018-06-10 17:44:05 +00:00
|
|
|
|
r.AddRange(MoveEgg.GetRelearnLVLMoves(pkm, species, 1, pkm.AltForm, version));
|
2016-11-12 06:13:40 +00:00
|
|
|
|
|
|
|
|
|
int form = pkm.AltForm;
|
|
|
|
|
if (pkm.Format == 6 && pkm.Species != 678)
|
|
|
|
|
form = 0;
|
|
|
|
|
|
2018-06-19 04:56:30 +00:00
|
|
|
|
r.AddRange(MoveEgg.GetEggMoves(pkm, species, form, version));
|
2017-06-07 03:10:05 +00:00
|
|
|
|
if (inheritlvlmoves)
|
2018-06-10 17:44:05 +00:00
|
|
|
|
r.AddRange(MoveEgg.GetRelearnLVLMoves(pkm, species, 100, pkm.AltForm, version));
|
2016-03-12 17:16:41 +00:00
|
|
|
|
return r.Distinct();
|
2016-02-23 06:52:48 +00:00
|
|
|
|
}
|
2018-02-02 03:57:02 +00:00
|
|
|
|
internal static IList<int> GetShedinjaEvolveMoves(PKM pkm, int lvl = -1, int generation = 0)
|
Shedinja evolution moves and some egg fixes (#1015)
* Add getMoves function with min level and max level, usefull for shedjina evolves moves (min level 20) and generation 1 moves ( no move reminder, min level is min encounter level + 1)
Also for gen1 encounters another function should be created to get by the encounter level the four moves that the pokemon learn by default, the last four in its movepool up until the encounter level
* getShedinjaEvolveMoves, function that return the moves that shedinja could learn from Ninjask move pool at the moment when Nincada evolves, in the same format that getValidMovesAllGens
* Add validation in parse moves for shedinja evolve moves.
Shedinja could have any gen3/4 moves from Ninjas learnset but only one is allowed
* Shedinja evolve moves text resources
* Fix egg moves pre-gen 6 validation:
Add skipoption variable to getEggMoves function from pre-gen6 games, to verify egg moves from split breed species
Flag illegal combinations of base egg moves and special egg moves
Return crystal egg moves for gen2 pokemon that can be tradeback to gen 1 games
* Fix for mix between event egg moves and base egg moves
* Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move
* Revert "Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move"
Revert the last change, i search in bulbapedia an there wasn't any nincada distributed with special moves in generation 3 nor 4, making this complicated validation unnecessary
This reverts commit 57f5ac1bbb75e32e417b575619339cae5e5d1ef2.
* Fix error
2017-04-01 00:40:30 +00:00
|
|
|
|
{
|
|
|
|
|
if (lvl == -1)
|
|
|
|
|
lvl = pkm.CurrentLevel;
|
|
|
|
|
if (pkm.Species != 292 || lvl < 20)
|
2018-02-02 03:57:02 +00:00
|
|
|
|
return new List<int>();
|
2017-04-01 01:35:43 +00:00
|
|
|
|
|
Shedinja evolution moves and some egg fixes (#1015)
* Add getMoves function with min level and max level, usefull for shedjina evolves moves (min level 20) and generation 1 moves ( no move reminder, min level is min encounter level + 1)
Also for gen1 encounters another function should be created to get by the encounter level the four moves that the pokemon learn by default, the last four in its movepool up until the encounter level
* getShedinjaEvolveMoves, function that return the moves that shedinja could learn from Ninjask move pool at the moment when Nincada evolves, in the same format that getValidMovesAllGens
* Add validation in parse moves for shedinja evolve moves.
Shedinja could have any gen3/4 moves from Ninjas learnset but only one is allowed
* Shedinja evolve moves text resources
* Fix egg moves pre-gen 6 validation:
Add skipoption variable to getEggMoves function from pre-gen6 games, to verify egg moves from split breed species
Flag illegal combinations of base egg moves and special egg moves
Return crystal egg moves for gen2 pokemon that can be tradeback to gen 1 games
* Fix for mix between event egg moves and base egg moves
* Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move
* Revert "Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move"
Revert the last change, i search in bulbapedia an there wasn't any nincada distributed with special moves in generation 3 nor 4, making this complicated validation unnecessary
This reverts commit 57f5ac1bbb75e32e417b575619339cae5e5d1ef2.
* Fix error
2017-04-01 00:40:30 +00:00
|
|
|
|
// If nincada evolves into Ninjask an learn in the evolution a move from ninjask learnset pool
|
|
|
|
|
// Shedinja would appear with that move learned. Only one move above level 20 allowed, only in generations 3 and 4
|
2017-04-01 01:35:43 +00:00
|
|
|
|
switch (generation)
|
Shedinja evolution moves and some egg fixes (#1015)
* Add getMoves function with min level and max level, usefull for shedjina evolves moves (min level 20) and generation 1 moves ( no move reminder, min level is min encounter level + 1)
Also for gen1 encounters another function should be created to get by the encounter level the four moves that the pokemon learn by default, the last four in its movepool up until the encounter level
* getShedinjaEvolveMoves, function that return the moves that shedinja could learn from Ninjask move pool at the moment when Nincada evolves, in the same format that getValidMovesAllGens
* Add validation in parse moves for shedinja evolve moves.
Shedinja could have any gen3/4 moves from Ninjas learnset but only one is allowed
* Shedinja evolve moves text resources
* Fix egg moves pre-gen 6 validation:
Add skipoption variable to getEggMoves function from pre-gen6 games, to verify egg moves from split breed species
Flag illegal combinations of base egg moves and special egg moves
Return crystal egg moves for gen2 pokemon that can be tradeback to gen 1 games
* Fix for mix between event egg moves and base egg moves
* Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move
* Revert "Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move"
Revert the last change, i search in bulbapedia an there wasn't any nincada distributed with special moves in generation 3 nor 4, making this complicated validation unnecessary
This reverts commit 57f5ac1bbb75e32e417b575619339cae5e5d1ef2.
* Fix error
2017-04-01 00:40:30 +00:00
|
|
|
|
{
|
2017-04-01 01:35:43 +00:00
|
|
|
|
case 0: // Default (both)
|
|
|
|
|
case 3: // Ninjask have the same learnset in every gen 3 games
|
|
|
|
|
if (pkm.InhabitedGeneration(3))
|
2018-02-02 03:57:02 +00:00
|
|
|
|
return LevelUpE[291].GetMoves(lvl, 20).ToList();
|
2017-04-01 01:35:43 +00:00
|
|
|
|
|
|
|
|
|
if (generation == 0)
|
|
|
|
|
goto case 4;
|
|
|
|
|
break;
|
|
|
|
|
case 4: // Ninjask have the same learnset in every gen 4 games
|
|
|
|
|
if (pkm.InhabitedGeneration(4))
|
2018-02-02 03:57:02 +00:00
|
|
|
|
return LevelUpPt[291].GetMoves(lvl, 20);
|
2017-04-01 01:35:43 +00:00
|
|
|
|
break;
|
Shedinja evolution moves and some egg fixes (#1015)
* Add getMoves function with min level and max level, usefull for shedjina evolves moves (min level 20) and generation 1 moves ( no move reminder, min level is min encounter level + 1)
Also for gen1 encounters another function should be created to get by the encounter level the four moves that the pokemon learn by default, the last four in its movepool up until the encounter level
* getShedinjaEvolveMoves, function that return the moves that shedinja could learn from Ninjask move pool at the moment when Nincada evolves, in the same format that getValidMovesAllGens
* Add validation in parse moves for shedinja evolve moves.
Shedinja could have any gen3/4 moves from Ninjas learnset but only one is allowed
* Shedinja evolve moves text resources
* Fix egg moves pre-gen 6 validation:
Add skipoption variable to getEggMoves function from pre-gen6 games, to verify egg moves from split breed species
Flag illegal combinations of base egg moves and special egg moves
Return crystal egg moves for gen2 pokemon that can be tradeback to gen 1 games
* Fix for mix between event egg moves and base egg moves
* Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move
* Revert "Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move"
Revert the last change, i search in bulbapedia an there wasn't any nincada distributed with special moves in generation 3 nor 4, making this complicated validation unnecessary
This reverts commit 57f5ac1bbb75e32e417b575619339cae5e5d1ef2.
* Fix error
2017-04-01 00:40:30 +00:00
|
|
|
|
}
|
2018-02-02 03:57:02 +00:00
|
|
|
|
return new List<int>();
|
|
|
|
|
}
|
|
|
|
|
internal static int GetShedinjaMoveLevel(int species, int move, int generation)
|
|
|
|
|
{
|
|
|
|
|
var src = generation == 4 ? LevelUpPt : LevelUpE;
|
|
|
|
|
var moves = src[species];
|
|
|
|
|
return moves.GetLevelLearnMove(move);
|
Shedinja evolution moves and some egg fixes (#1015)
* Add getMoves function with min level and max level, usefull for shedjina evolves moves (min level 20) and generation 1 moves ( no move reminder, min level is min encounter level + 1)
Also for gen1 encounters another function should be created to get by the encounter level the four moves that the pokemon learn by default, the last four in its movepool up until the encounter level
* getShedinjaEvolveMoves, function that return the moves that shedinja could learn from Ninjask move pool at the moment when Nincada evolves, in the same format that getValidMovesAllGens
* Add validation in parse moves for shedinja evolve moves.
Shedinja could have any gen3/4 moves from Ninjas learnset but only one is allowed
* Shedinja evolve moves text resources
* Fix egg moves pre-gen 6 validation:
Add skipoption variable to getEggMoves function from pre-gen6 games, to verify egg moves from split breed species
Flag illegal combinations of base egg moves and special egg moves
Return crystal egg moves for gen2 pokemon that can be tradeback to gen 1 games
* Fix for mix between event egg moves and base egg moves
* Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move
* Revert "Changes just to make if there is only shedinja evolve move that is also the only base egg move change it from base egg move to evolve move, to avoid flag illegal if also the pokemon have a special egg move"
Revert the last change, i search in bulbapedia an there wasn't any nincada distributed with special moves in generation 3 nor 4, making this complicated validation unnecessary
This reverts commit 57f5ac1bbb75e32e417b575619339cae5e5d1ef2.
* Fix error
2017-04-01 00:40:30 +00:00
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
internal static int[] GetBaseEggMoves(PKM pkm, int species, GameVersion gameSource, int lvl)
|
2016-03-06 19:19:09 +00:00
|
|
|
|
{
|
2016-10-24 05:03:19 +00:00
|
|
|
|
if (gameSource == GameVersion.Any)
|
2018-07-04 16:15:20 +00:00
|
|
|
|
gameSource = (GameVersion)pkm.Version;
|
2016-03-22 02:53:02 +00:00
|
|
|
|
|
2016-10-24 05:03:19 +00:00
|
|
|
|
switch (gameSource)
|
2016-03-22 02:53:02 +00:00
|
|
|
|
{
|
2018-06-11 14:23:48 +00:00
|
|
|
|
case GameVersion.GSC:
|
2017-03-26 02:57:38 +00:00
|
|
|
|
case GameVersion.GS:
|
2017-09-01 05:37:28 +00:00
|
|
|
|
// If checking back-transfer specimen (GSC->RBY), remove moves that must be deleted prior to transfer
|
|
|
|
|
int[] getRBYCompatibleMoves(int[] moves) => pkm.Format == 1 ? moves.Where(m => m <= MaxMoveID_1).ToArray() : moves;
|
2017-03-26 02:57:38 +00:00
|
|
|
|
if (pkm.InhabitedGeneration(2))
|
2017-09-01 05:37:28 +00:00
|
|
|
|
return getRBYCompatibleMoves(LevelUpGS[species].GetMoves(lvl));
|
2017-03-26 02:57:38 +00:00
|
|
|
|
break;
|
|
|
|
|
case GameVersion.C:
|
|
|
|
|
if (pkm.InhabitedGeneration(2))
|
2017-09-01 05:37:28 +00:00
|
|
|
|
return getRBYCompatibleMoves(LevelUpC[species].GetMoves(lvl));
|
2017-03-26 02:57:38 +00:00
|
|
|
|
break;
|
|
|
|
|
|
2017-03-18 23:50:34 +00:00
|
|
|
|
case GameVersion.R:
|
|
|
|
|
case GameVersion.S:
|
|
|
|
|
case GameVersion.RS:
|
|
|
|
|
if (pkm.InhabitedGeneration(3))
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return LevelUpRS[species].GetMoves(lvl);
|
2017-03-18 23:50:34 +00:00
|
|
|
|
break;
|
|
|
|
|
case GameVersion.E:
|
|
|
|
|
if (pkm.InhabitedGeneration(3))
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return LevelUpE[species].GetMoves(lvl);
|
2017-03-18 23:50:34 +00:00
|
|
|
|
break;
|
|
|
|
|
case GameVersion.FR:
|
|
|
|
|
case GameVersion.LG:
|
|
|
|
|
case GameVersion.FRLG:
|
|
|
|
|
// only difference in FR/LG is deoxys which doesn't breed.
|
|
|
|
|
if (pkm.InhabitedGeneration(3))
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return LevelUpFR[species].GetMoves(lvl);
|
2017-03-18 23:50:34 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GameVersion.D:
|
|
|
|
|
case GameVersion.P:
|
|
|
|
|
case GameVersion.DP:
|
|
|
|
|
if (pkm.InhabitedGeneration(4))
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return LevelUpDP[species].GetMoves(lvl);
|
2017-03-18 23:50:34 +00:00
|
|
|
|
break;
|
|
|
|
|
case GameVersion.Pt:
|
|
|
|
|
if (pkm.InhabitedGeneration(4))
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return LevelUpPt[species].GetMoves(lvl);
|
2017-03-18 23:50:34 +00:00
|
|
|
|
break;
|
|
|
|
|
case GameVersion.HG:
|
|
|
|
|
case GameVersion.SS:
|
|
|
|
|
case GameVersion.HGSS:
|
|
|
|
|
if (pkm.InhabitedGeneration(4))
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return LevelUpHGSS[species].GetMoves(lvl);
|
2017-03-25 02:24:01 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GameVersion.B:
|
|
|
|
|
case GameVersion.W:
|
|
|
|
|
case GameVersion.BW:
|
|
|
|
|
if (pkm.InhabitedGeneration(5))
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return LevelUpBW[species].GetMoves(lvl);
|
2017-03-25 02:24:01 +00:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GameVersion.B2:
|
|
|
|
|
case GameVersion.W2:
|
|
|
|
|
case GameVersion.B2W2:
|
|
|
|
|
if (pkm.InhabitedGeneration(5))
|
2018-06-11 00:55:03 +00:00
|
|
|
|
return LevelUpB2W2[species].GetMoves(lvl);
|
2017-03-18 23:50:34 +00:00
|
|
|
|
break;
|
|
|
|
|
|
2016-10-24 05:03:19 +00:00
|
|
|
|
case GameVersion.X:
|
|
|
|
|
case GameVersion.Y:
|
|
|
|
|
case GameVersion.XY:
|
|
|
|
|
if (pkm.InhabitedGeneration(6))
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return LevelUpXY[species].GetMoves(lvl);
|
2016-10-24 05:03:19 +00:00
|
|
|
|
break;
|
2016-03-05 04:43:00 +00:00
|
|
|
|
|
2016-10-24 05:03:19 +00:00
|
|
|
|
case GameVersion.AS:
|
|
|
|
|
case GameVersion.OR:
|
|
|
|
|
case GameVersion.ORAS:
|
|
|
|
|
if (pkm.InhabitedGeneration(6))
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return LevelUpAO[species].GetMoves(lvl);
|
2016-10-24 05:03:19 +00:00
|
|
|
|
break;
|
2016-03-22 02:53:02 +00:00
|
|
|
|
|
2016-10-24 05:03:19 +00:00
|
|
|
|
case GameVersion.SN:
|
|
|
|
|
case GameVersion.MN:
|
|
|
|
|
case GameVersion.SM:
|
2017-11-19 05:50:48 +00:00
|
|
|
|
if (species > MaxSpeciesID_7)
|
|
|
|
|
break;
|
2016-10-24 05:03:19 +00:00
|
|
|
|
if (pkm.InhabitedGeneration(7))
|
2017-09-01 05:37:28 +00:00
|
|
|
|
{
|
|
|
|
|
int index = PersonalTable.SM.GetFormeIndex(species, pkm.AltForm);
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return LevelUpSM[index].GetMoves(lvl);
|
2017-09-01 05:37:28 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case GameVersion.US:
|
|
|
|
|
case GameVersion.UM:
|
|
|
|
|
case GameVersion.USUM:
|
|
|
|
|
if (pkm.InhabitedGeneration(7))
|
|
|
|
|
{
|
|
|
|
|
int index = PersonalTable.USUM.GetFormeIndex(species, pkm.AltForm);
|
|
|
|
|
return LevelUpUSUM[index].GetMoves(lvl);
|
|
|
|
|
}
|
2016-10-24 05:03:19 +00:00
|
|
|
|
break;
|
2016-03-22 02:53:02 +00:00
|
|
|
|
}
|
2017-04-15 19:24:30 +00:00
|
|
|
|
return new int[0];
|
2016-03-05 04:43:00 +00:00
|
|
|
|
}
|
2018-06-23 00:59:02 +00:00
|
|
|
|
internal static List<int> GetValidPostEvolutionMoves(PKM pkm, int Species, IReadOnlyList<EvoCriteria>[] evoChains, GameVersion Version)
|
2017-04-23 12:54:52 +00:00
|
|
|
|
{
|
2018-05-12 15:13:39 +00:00
|
|
|
|
// Return moves that the pokemon could learn after evolving
|
2017-04-23 12:54:52 +00:00
|
|
|
|
var moves = new List<int>();
|
|
|
|
|
for (int i = 1; i < evoChains.Length; i++)
|
2018-06-23 00:59:02 +00:00
|
|
|
|
if (evoChains[i].Count != 0)
|
2017-06-18 01:37:19 +00:00
|
|
|
|
moves.AddRange(GetValidPostEvolutionMoves(pkm, Species, evoChains[i], i, Version));
|
2017-04-23 12:54:52 +00:00
|
|
|
|
if (pkm.GenNumber >= 6)
|
|
|
|
|
moves.AddRange(pkm.RelearnMoves.Where(m => m != 0));
|
|
|
|
|
return moves.Distinct().ToList();
|
|
|
|
|
}
|
2018-06-23 00:59:02 +00:00
|
|
|
|
private static List<int> GetValidPostEvolutionMoves(PKM pkm, int Species, IReadOnlyList<EvoCriteria> evoChain, int Generation, GameVersion Version)
|
2017-04-23 12:54:52 +00:00
|
|
|
|
{
|
|
|
|
|
var evomoves = new List<int>();
|
2018-06-23 00:59:02 +00:00
|
|
|
|
var index = EvolutionChain.GetEvoChainSpeciesIndex(evoChain, Species);
|
2017-04-23 14:48:23 +00:00
|
|
|
|
for (int i = 0; i <= index; i++)
|
2017-04-23 12:54:52 +00:00
|
|
|
|
{
|
|
|
|
|
var evo = evoChain[i];
|
2017-09-23 23:24:22 +00:00
|
|
|
|
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);
|
2017-04-23 14:48:23 +00:00
|
|
|
|
// Moves from Species or any species after in the evolution phase
|
|
|
|
|
evomoves.AddRange(moves);
|
2017-04-23 12:54:52 +00:00
|
|
|
|
}
|
|
|
|
|
return evomoves;
|
|
|
|
|
}
|
2018-06-23 00:59:02 +00:00
|
|
|
|
internal static IEnumerable<int> GetExclusivePreEvolutionMoves(PKM pkm, int Species, IReadOnlyList<EvoCriteria> evoChain, int Generation, GameVersion Version)
|
Split Breed Egg Moves improvements (#1058)
* Added method getBaseEggSpecies to get the base species when the pokemon was an egg, is needed because for format 1 pokemon with egg origin every time getBaseSpecies is called is returning the gen 1 base species obtaining invalid eggmoves and base egg moves
Also getBaseEggSpecies was using Evolves1 when format = 1 even when asking for a gen2 egg base species, returning Pikachu egg moves (empty list) instead of Pichu egg moves
* Fix ability checking for generation 3 pokemon, likea de Seadra from Issue #1011
pkm.AbilityNumber have a value assuming PID match ability like a generation 4 pokemon but the validation should be ignored if is a generation 3 pokemon with only one ability in generation 3
Also changed the validation for ingame trades with fixed abilities to check only with generation 3 abilities in the case the species has two abilities generation 3, if only one was possible any PID should be valid with the generation 3 ability
Encounter Trades
Also the check for evolution was wrong, the most evolved species is the first in the evochain, not the last
* Fix evoltuion chains for gen 3 pokemon in format 4
* Fix ability for generation 3 trades. Ability could not change if there were 2 abilities in generation 3, that means it is irrelevant if the pokemon evolved in gen 4-5, the ability number must match the encounter
* Added missing skipOption to a call to getBaseEggSpecies
* Functions to obtain moves excluvie to preevolutions, like moves that Azurill/Happiny could learn throught level up or TM but Marill/Chansey could not learn, icompatible with any Marill/Chansey egg moves
Also add functions to return egg moves and base egg moves for both possible species for split breed eggs
* Check both species from split breed egg at the same time to report moves incompatibilities
* Reduced generation 4-5 was egg game check
There is no need to check every possible generation game.
For every egg species HGSS learnset tables y egg moves table contains all the moves from the same species in DP and Pt, without any move exclusive to that games except in legendaries, and they cant breed
In generation 5 is the same with B2W2 except for Exxegutte, it have a exclusive level up move from B1W1, Psychic, but it can learn the move with TM, it wont count as an egg move
* Check incompatible split breed moves in verify relearn egg
* Fix generation 1 incompatibility moves check
SolarBeam removed from Exeggcute/Exeggutor incompatiblity, Exeggutor could learn it with a TM in generation 1
Removed Vaporeon Mist and Eevee Take Down incompatiblity, Vaporeon could learn Take Down with a TM in generation 1
2017-04-14 17:11:50 +00:00
|
|
|
|
{
|
|
|
|
|
var preevomoves = new List<int>();
|
|
|
|
|
var evomoves = new List<int>();
|
2018-06-23 00:59:02 +00:00
|
|
|
|
var index = EvolutionChain.GetEvoChainSpeciesIndex(evoChain, Species);
|
|
|
|
|
for (int i = 0; i < evoChain.Count; i++)
|
Split Breed Egg Moves improvements (#1058)
* Added method getBaseEggSpecies to get the base species when the pokemon was an egg, is needed because for format 1 pokemon with egg origin every time getBaseSpecies is called is returning the gen 1 base species obtaining invalid eggmoves and base egg moves
Also getBaseEggSpecies was using Evolves1 when format = 1 even when asking for a gen2 egg base species, returning Pikachu egg moves (empty list) instead of Pichu egg moves
* Fix ability checking for generation 3 pokemon, likea de Seadra from Issue #1011
pkm.AbilityNumber have a value assuming PID match ability like a generation 4 pokemon but the validation should be ignored if is a generation 3 pokemon with only one ability in generation 3
Also changed the validation for ingame trades with fixed abilities to check only with generation 3 abilities in the case the species has two abilities generation 3, if only one was possible any PID should be valid with the generation 3 ability
Encounter Trades
Also the check for evolution was wrong, the most evolved species is the first in the evochain, not the last
* Fix evoltuion chains for gen 3 pokemon in format 4
* Fix ability for generation 3 trades. Ability could not change if there were 2 abilities in generation 3, that means it is irrelevant if the pokemon evolved in gen 4-5, the ability number must match the encounter
* Added missing skipOption to a call to getBaseEggSpecies
* Functions to obtain moves excluvie to preevolutions, like moves that Azurill/Happiny could learn throught level up or TM but Marill/Chansey could not learn, icompatible with any Marill/Chansey egg moves
Also add functions to return egg moves and base egg moves for both possible species for split breed eggs
* Check both species from split breed egg at the same time to report moves incompatibilities
* Reduced generation 4-5 was egg game check
There is no need to check every possible generation game.
For every egg species HGSS learnset tables y egg moves table contains all the moves from the same species in DP and Pt, without any move exclusive to that games except in legendaries, and they cant breed
In generation 5 is the same with B2W2 except for Exxegutte, it have a exclusive level up move from B1W1, Psychic, but it can learn the move with TM, it wont count as an egg move
* Check incompatible split breed moves in verify relearn egg
* Fix generation 1 incompatibility moves check
SolarBeam removed from Exeggcute/Exeggutor incompatiblity, Exeggutor could learn it with a TM in generation 1
Removed Vaporeon Mist and Eevee Take Down incompatiblity, Vaporeon could learn Take Down with a TM in generation 1
2017-04-14 17:11:50 +00:00
|
|
|
|
{
|
|
|
|
|
var evo = evoChain[i];
|
2017-09-23 23:24:22 +00:00
|
|
|
|
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);
|
2017-09-02 06:45:47 +00:00
|
|
|
|
var list = i >= index ? preevomoves : evomoves;
|
|
|
|
|
list.AddRange(moves);
|
Split Breed Egg Moves improvements (#1058)
* Added method getBaseEggSpecies to get the base species when the pokemon was an egg, is needed because for format 1 pokemon with egg origin every time getBaseSpecies is called is returning the gen 1 base species obtaining invalid eggmoves and base egg moves
Also getBaseEggSpecies was using Evolves1 when format = 1 even when asking for a gen2 egg base species, returning Pikachu egg moves (empty list) instead of Pichu egg moves
* Fix ability checking for generation 3 pokemon, likea de Seadra from Issue #1011
pkm.AbilityNumber have a value assuming PID match ability like a generation 4 pokemon but the validation should be ignored if is a generation 3 pokemon with only one ability in generation 3
Also changed the validation for ingame trades with fixed abilities to check only with generation 3 abilities in the case the species has two abilities generation 3, if only one was possible any PID should be valid with the generation 3 ability
Encounter Trades
Also the check for evolution was wrong, the most evolved species is the first in the evochain, not the last
* Fix evoltuion chains for gen 3 pokemon in format 4
* Fix ability for generation 3 trades. Ability could not change if there were 2 abilities in generation 3, that means it is irrelevant if the pokemon evolved in gen 4-5, the ability number must match the encounter
* Added missing skipOption to a call to getBaseEggSpecies
* Functions to obtain moves excluvie to preevolutions, like moves that Azurill/Happiny could learn throught level up or TM but Marill/Chansey could not learn, icompatible with any Marill/Chansey egg moves
Also add functions to return egg moves and base egg moves for both possible species for split breed eggs
* Check both species from split breed egg at the same time to report moves incompatibilities
* Reduced generation 4-5 was egg game check
There is no need to check every possible generation game.
For every egg species HGSS learnset tables y egg moves table contains all the moves from the same species in DP and Pt, without any move exclusive to that games except in legendaries, and they cant breed
In generation 5 is the same with B2W2 except for Exxegutte, it have a exclusive level up move from B1W1, Psychic, but it can learn the move with TM, it wont count as an egg move
* Check incompatible split breed moves in verify relearn egg
* Fix generation 1 incompatibility moves check
SolarBeam removed from Exeggcute/Exeggutor incompatiblity, Exeggutor could learn it with a TM in generation 1
Removed Vaporeon Mist and Eevee Take Down incompatiblity, Vaporeon could learn Take Down with a TM in generation 1
2017-04-14 17:11:50 +00:00
|
|
|
|
}
|
2018-06-10 17:44:05 +00:00
|
|
|
|
return preevomoves.Except(evomoves).Distinct();
|
Split Breed Egg Moves improvements (#1058)
* Added method getBaseEggSpecies to get the base species when the pokemon was an egg, is needed because for format 1 pokemon with egg origin every time getBaseSpecies is called is returning the gen 1 base species obtaining invalid eggmoves and base egg moves
Also getBaseEggSpecies was using Evolves1 when format = 1 even when asking for a gen2 egg base species, returning Pikachu egg moves (empty list) instead of Pichu egg moves
* Fix ability checking for generation 3 pokemon, likea de Seadra from Issue #1011
pkm.AbilityNumber have a value assuming PID match ability like a generation 4 pokemon but the validation should be ignored if is a generation 3 pokemon with only one ability in generation 3
Also changed the validation for ingame trades with fixed abilities to check only with generation 3 abilities in the case the species has two abilities generation 3, if only one was possible any PID should be valid with the generation 3 ability
Encounter Trades
Also the check for evolution was wrong, the most evolved species is the first in the evochain, not the last
* Fix evoltuion chains for gen 3 pokemon in format 4
* Fix ability for generation 3 trades. Ability could not change if there were 2 abilities in generation 3, that means it is irrelevant if the pokemon evolved in gen 4-5, the ability number must match the encounter
* Added missing skipOption to a call to getBaseEggSpecies
* Functions to obtain moves excluvie to preevolutions, like moves that Azurill/Happiny could learn throught level up or TM but Marill/Chansey could not learn, icompatible with any Marill/Chansey egg moves
Also add functions to return egg moves and base egg moves for both possible species for split breed eggs
* Check both species from split breed egg at the same time to report moves incompatibilities
* Reduced generation 4-5 was egg game check
There is no need to check every possible generation game.
For every egg species HGSS learnset tables y egg moves table contains all the moves from the same species in DP and Pt, without any move exclusive to that games except in legendaries, and they cant breed
In generation 5 is the same with B2W2 except for Exxegutte, it have a exclusive level up move from B1W1, Psychic, but it can learn the move with TM, it wont count as an egg move
* Check incompatible split breed moves in verify relearn egg
* Fix generation 1 incompatibility moves check
SolarBeam removed from Exeggcute/Exeggutor incompatiblity, Exeggutor could learn it with a TM in generation 1
Removed Vaporeon Mist and Eevee Take Down incompatiblity, Vaporeon could learn Take Down with a TM in generation 1
2017-04-14 17:11:50 +00:00
|
|
|
|
}
|
2016-10-24 05:03:19 +00:00
|
|
|
|
|
|
|
|
|
// Encounter
|
2017-09-23 23:24:22 +00:00
|
|
|
|
internal static IEnumerable<GameVersion> GetGen2Versions(LegalInfo Info)
|
2017-07-06 23:03:41 +00:00
|
|
|
|
{
|
2017-09-23 23:24:22 +00:00
|
|
|
|
if (AllowGen2Crystal(Info.Korean) && Info.Game == GameVersion.C)
|
2017-09-02 06:45:47 +00:00
|
|
|
|
yield return GameVersion.C;
|
|
|
|
|
|
2017-09-04 20:48:10 +00:00
|
|
|
|
// Any encounter marked with version GSC is for pokemon with the same moves in GS and C
|
|
|
|
|
// it is sufficient to check just GS's case
|
2017-09-02 06:45:47 +00:00
|
|
|
|
yield return GameVersion.GS;
|
2017-07-06 23:03:41 +00:00
|
|
|
|
}
|
2017-09-02 06:45:47 +00:00
|
|
|
|
internal static IEnumerable<GameVersion> GetGen1Versions(LegalInfo Info)
|
2017-07-06 23:03:41 +00:00
|
|
|
|
{
|
|
|
|
|
if (Info.EncounterMatch.Species == 133 && Info.Game == GameVersion.Stadium)
|
2018-05-12 15:13:39 +00:00
|
|
|
|
{
|
2017-09-02 06:45:47 +00:00
|
|
|
|
// Stadium Eevee; check for RB and yellow initial moves
|
|
|
|
|
yield return GameVersion.RB;
|
|
|
|
|
yield return GameVersion.YW;
|
|
|
|
|
}
|
2017-09-04 20:48:10 +00:00
|
|
|
|
else if (Info.Game == GameVersion.YW)
|
2017-09-02 06:45:47 +00:00
|
|
|
|
yield return GameVersion.YW;
|
|
|
|
|
|
2018-05-12 15:13:39 +00:00
|
|
|
|
// Any encounter marked with version RBY is for pokemon with the same moves and catch rate in RB and Y,
|
2017-09-05 01:55:15 +00:00
|
|
|
|
// it is sufficient to check just RB's case
|
2017-09-02 06:45:47 +00:00
|
|
|
|
yield return GameVersion.RB;
|
Gen 1 move analysis improvement. Adapted the valid moves to take into account that move deleter and move reminder do not exits in generation 1 (#1037)
* Fix getMoves with min level, when SkipWhile and TakeWhile is used together the index i in TakeWhile is calculated from the enumerator that results of the SkipWhile function, not the index of the initial array, those giving an incorrect index to check Levels array in the TakeWhile
* Fix getMoves when levelmin or levelmax is above max level in the levels array, TakeWhile and SkipWhile return empty list if the while goes beyond the last element of the array
* Include player hatched egg in the list of possible encounters for parseMoves only if the pokemon was an egg
Also change the valur of WasEgg for gen1,2,3 pokemon if the encounter analyzed is not an egg
add the non egg encounters to the list instead of checking the non-egg encounter inside parseMovesWasEggPreRelearn
* Fix for gen3 egg encounters
Remove non-egg encounters without special moves if there is an egg encounter because egg encounter already cover every possible move combination
Do not add daycare egg encounter for gen3 unhatched egg if there is another encounter, that means is an event or gift egg, not a daycare egg
Remove duplicate encounters
* Gift egg should not allow inherited moves even it they dont have special moves
Those gift eggs are hatched only with the species base moves
* Added getEncounterMoves functions, to be used for generation 1 encounters to find what moves have a pokemon at the moment of being caught because there is no move reminder in generation 1
* Added GBEncounterData, structure for refactor the tuples used in generation 1 and 2 encounters
* Add LevelMin and LevelMax to IEncounterable to get the encounter moves by the min level of the generation 1 EncounterLink
Add iGeneration to difference generation 1 and generation 2 encounters for GB Era pokemon
* Mark generation in gen 1 and 2 encounters
There is no need to mark the generation in gen 3 to 7 encounters because in that generations it match the pokemon generation number
* Add min level for generation 1 moves in getMoves functions
Add function to return the default moves for a GB encounters, for generation 1 games that included both moves from level up table and level 1 moves from personal table
Fix getMoves with min level when the moves list is empty, like Raichu generation 1
* Add maxSpecies to getBaseSpecies function for gen1 pokemon with a gen2 egg encounter
Refactor VC Encounter changing Tuples for GBData class
* Fixed for gen 2 Checks
Also do not search for generation1 encounter if the gen2 pokemon have met location from crystal
* Fix VC wild encounters, should be stored as array or else other verifyEncounter functions wont work
* Add generation 1 parse moves function including default moves
* Clean-up get encounters
* Verify empty moves for generation 1 encounters, in generation 1 does not exits move deleter
That means when a move slot have been used by a level up move or a TM/HM/Tutor move it cant be empty again
Does not apply if generation 2 tradeback is allowed, in generation 2 there is a move deleter
* Added two edge cases for pokemon that learn in red/blue and yellow different moves at the same level, this combinations can not exits until a later level when they learn again one of the levels in the other game, only happen for flareon and vaporeon
* Check incompatible moves between evolution species, it is for species that learn a move in a level as an evolved species and a move at a upper level as a preevolution
Also added most edge cases for the min slots used for generation 1 games, i think every weird combination is already covered
* Fix gen 1 eevee and evolutions move checks
* Cleanup
* Move the code to change valid moves for generation 1 to a function
* Fix getMoveMinLevelGBEncounter
* getUsedMoveSlots, removed wild Butterfree edge case, it is not possible
* Filter the min level of the encounter by the possible games the pokemon could be originated, yellow pikachu and kadabra can be detected
2017-04-09 00:17:20 +00:00
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
internal static int GetRequiredMoveCount(PKM pk, int[] moves, LegalInfo info, int[] initialmoves)
|
Gen 1 move analysis improvement. Adapted the valid moves to take into account that move deleter and move reminder do not exits in generation 1 (#1037)
* Fix getMoves with min level, when SkipWhile and TakeWhile is used together the index i in TakeWhile is calculated from the enumerator that results of the SkipWhile function, not the index of the initial array, those giving an incorrect index to check Levels array in the TakeWhile
* Fix getMoves when levelmin or levelmax is above max level in the levels array, TakeWhile and SkipWhile return empty list if the while goes beyond the last element of the array
* Include player hatched egg in the list of possible encounters for parseMoves only if the pokemon was an egg
Also change the valur of WasEgg for gen1,2,3 pokemon if the encounter analyzed is not an egg
add the non egg encounters to the list instead of checking the non-egg encounter inside parseMovesWasEggPreRelearn
* Fix for gen3 egg encounters
Remove non-egg encounters without special moves if there is an egg encounter because egg encounter already cover every possible move combination
Do not add daycare egg encounter for gen3 unhatched egg if there is another encounter, that means is an event or gift egg, not a daycare egg
Remove duplicate encounters
* Gift egg should not allow inherited moves even it they dont have special moves
Those gift eggs are hatched only with the species base moves
* Added getEncounterMoves functions, to be used for generation 1 encounters to find what moves have a pokemon at the moment of being caught because there is no move reminder in generation 1
* Added GBEncounterData, structure for refactor the tuples used in generation 1 and 2 encounters
* Add LevelMin and LevelMax to IEncounterable to get the encounter moves by the min level of the generation 1 EncounterLink
Add iGeneration to difference generation 1 and generation 2 encounters for GB Era pokemon
* Mark generation in gen 1 and 2 encounters
There is no need to mark the generation in gen 3 to 7 encounters because in that generations it match the pokemon generation number
* Add min level for generation 1 moves in getMoves functions
Add function to return the default moves for a GB encounters, for generation 1 games that included both moves from level up table and level 1 moves from personal table
Fix getMoves with min level when the moves list is empty, like Raichu generation 1
* Add maxSpecies to getBaseSpecies function for gen1 pokemon with a gen2 egg encounter
Refactor VC Encounter changing Tuples for GBData class
* Fixed for gen 2 Checks
Also do not search for generation1 encounter if the gen2 pokemon have met location from crystal
* Fix VC wild encounters, should be stored as array or else other verifyEncounter functions wont work
* Add generation 1 parse moves function including default moves
* Clean-up get encounters
* Verify empty moves for generation 1 encounters, in generation 1 does not exits move deleter
That means when a move slot have been used by a level up move or a TM/HM/Tutor move it cant be empty again
Does not apply if generation 2 tradeback is allowed, in generation 2 there is a move deleter
* Added two edge cases for pokemon that learn in red/blue and yellow different moves at the same level, this combinations can not exits until a later level when they learn again one of the levels in the other game, only happen for flareon and vaporeon
* Check incompatible moves between evolution species, it is for species that learn a move in a level as an evolved species and a move at a upper level as a preevolution
Also added most edge cases for the min slots used for generation 1 games, i think every weird combination is already covered
* Fix gen 1 eevee and evolutions move checks
* Cleanup
* Move the code to change valid moves for generation 1 to a function
* Fix getMoveMinLevelGBEncounter
* getUsedMoveSlots, removed wild Butterfree edge case, it is not possible
* Filter the min level of the encounter by the possible games the pokemon could be originated, yellow pikachu and kadabra can be detected
2017-04-09 00:17:20 +00:00
|
|
|
|
{
|
2017-09-04 20:48:10 +00:00
|
|
|
|
if (pk.Format != 1 || !pk.Gen1_NotTradeback) // No Move Deleter in Gen 1
|
|
|
|
|
return 1; // Move Deleter exits, slots from 2 onwards can allways be empty
|
2017-04-10 00:43:05 +00:00
|
|
|
|
|
2017-06-18 01:37:19 +00:00
|
|
|
|
int required = GetRequiredMoveCount(pk, moves, info.EncounterMoves.LevelUpMoves, initialmoves);
|
2017-04-10 00:43:05 +00:00
|
|
|
|
if (required >= 4)
|
|
|
|
|
return 4;
|
|
|
|
|
|
|
|
|
|
// tm, hm and tutor moves replace a free slots if the pokemon have less than 4 moves
|
|
|
|
|
// Ignore tm, hm and tutor moves already in the learnset table
|
2017-06-18 01:37:19 +00:00
|
|
|
|
var learn = info.EncounterMoves.LevelUpMoves;
|
|
|
|
|
var tmhm = info.EncounterMoves.TMHMMoves;
|
|
|
|
|
var tutor = info.EncounterMoves.TutorMoves;
|
2017-09-05 01:55:15 +00:00
|
|
|
|
var union = initialmoves.Union(learn[1]);
|
|
|
|
|
required += moves.Count(m => m != 0 && union.All(t => t != m) && (tmhm[1].Any(t => t == m) || tutor[1].Any(t => t == m)));
|
2017-04-10 00:43:05 +00:00
|
|
|
|
|
|
|
|
|
return Math.Min(4, required);
|
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
private static int GetRequiredMoveCount(PKM pk, int[] moves, List<int>[] learn, int[] initialmoves)
|
2017-04-10 00:43:05 +00:00
|
|
|
|
{
|
|
|
|
|
if (SpecialMinMoveSlots.Contains(pk.Species))
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return GetRequiredMoveCountSpecial(pk, moves, learn);
|
2017-04-10 00:43:05 +00:00
|
|
|
|
|
|
|
|
|
// A pokemon is captured with initial moves and can't forget any until have all 4 slots used
|
|
|
|
|
// If it has learn a move before having 4 it will be in one of the free slots
|
2017-06-18 01:37:19 +00:00
|
|
|
|
int required = GetRequiredMoveSlotsRegular(pk, moves, learn, initialmoves);
|
|
|
|
|
return required != 0 ? required : GetRequiredMoveCountDecrement(pk, moves, learn, initialmoves);
|
2017-04-10 00:43:05 +00:00
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
private static int GetRequiredMoveSlotsRegular(PKM pk, int[] moves, List<int>[] learn, int[] initialmoves)
|
2017-04-10 00:43:05 +00:00
|
|
|
|
{
|
|
|
|
|
int species = pk.Species;
|
2018-07-04 16:15:20 +00:00
|
|
|
|
int catch_rate = ((PK1)pk).Catch_Rate;
|
2017-04-10 00:43:05 +00:00
|
|
|
|
// Caterpie and Metapod evolution lines have different count of possible slots available if captured in different evolutionary phases
|
|
|
|
|
// Example: a level 7 caterpie evolved into metapod will have 3 learned moves, a captured metapod will have only 1 move
|
Generation 1 and 2 legal Improvements (#1099)
* Refactor parseMovesForEncounter to gather valid moves for species encounter, some Pokemon can have valid encounters with different source species from the encounter, the valid moves change if the encounter species change because some preevolutions moves are illegal if pokemon caught already evolved.
Example, generation 1 Pikachu that can have a RBY Pikachu encounter and GSC Pichu encounter, the valid moves for the first encounters should not have any Pichu exclusive evolution moves
Also assign the encounter match from gb when parsing moves like the variable Encounter Match, to store the encounter that is valid for the pokemon moves instead the first encounter.
Store the species encounter, this will be needed to check if the evolution is valid for species that evolve leveling with a given learned move
* Add Tradeback Status to the pokemon, this variable for generations 1 and 2 use data like the catch rate to determine if trade between generations 1 and 2 was possible.
If analysis is for VC games tradeback have value NotTradeback for every gen 1 pokemon, but for cart saves some pokemon can be determine that have not been tradeback, if catch rate match species catch rate but do not match a valid generation 2 held item that means the pokemon habe been never traded to generation 2 games, that allow to discart encounters and moves from generation 2.
Also if is not tradeback catch rate is used to filter encounters, catch rate determine in what species was captured the pokemon discarting some preevolutions moves
Also add option for generation 1 cart save analysis to check legal status not allowing generation 2 games, like VC games but with Stadium allowed, like the generation 1 non tradeback rules from Smogon
Also change evolution chains to included generation 2 preevolutions for gen 1 pokemon if tradeback was possible, it is needed to avoid parsemoves to check illegal pokemon like Hitmonchan with Tyrogue level up moves
* Check legal values of generation 1 type and catch rate
Replace pokemon catch rate after changind pokemon species always if pokemon was not tradeback from generation 2, the catch rate will keep unchanged only if it can be a held item and do not match species catch rate (default item)
Also if catch rate is changed use base species catch rate to avoid legal errors if the catch rate of the evolution species if is not possible with the current moves
* Filter ingame trades and static encounters with catch rate for generation 1 non tradeback
* Fix min moves for generation 1 metapod encounter
* Clean up
* Fix encounter level for generation 1, valid moves are those with one level after the encounter level, pokemon can not learn a new move until level up
Clean up type validation
Fix generation 3 fatefull encounter eggs, the pokemon lost the fatefull mark when it hatch
* Clean-up
* Use new variable EncounterSpecies when it is needed to detect the species of the encounter, the old code wont work if the encounter is a wild slots array
* Fix generation 1 evolution chains and catch rate as default held item
* Fix Generation 1 Yellow Pikachu and Kadabra catch rates
2017-04-27 04:27:59 +00:00
|
|
|
|
if ((species == 011 || species == 012) && catch_rate == 120)
|
Gen 1 move analysis improvement. Adapted the valid moves to take into account that move deleter and move reminder do not exits in generation 1 (#1037)
* Fix getMoves with min level, when SkipWhile and TakeWhile is used together the index i in TakeWhile is calculated from the enumerator that results of the SkipWhile function, not the index of the initial array, those giving an incorrect index to check Levels array in the TakeWhile
* Fix getMoves when levelmin or levelmax is above max level in the levels array, TakeWhile and SkipWhile return empty list if the while goes beyond the last element of the array
* Include player hatched egg in the list of possible encounters for parseMoves only if the pokemon was an egg
Also change the valur of WasEgg for gen1,2,3 pokemon if the encounter analyzed is not an egg
add the non egg encounters to the list instead of checking the non-egg encounter inside parseMovesWasEggPreRelearn
* Fix for gen3 egg encounters
Remove non-egg encounters without special moves if there is an egg encounter because egg encounter already cover every possible move combination
Do not add daycare egg encounter for gen3 unhatched egg if there is another encounter, that means is an event or gift egg, not a daycare egg
Remove duplicate encounters
* Gift egg should not allow inherited moves even it they dont have special moves
Those gift eggs are hatched only with the species base moves
* Added getEncounterMoves functions, to be used for generation 1 encounters to find what moves have a pokemon at the moment of being caught because there is no move reminder in generation 1
* Added GBEncounterData, structure for refactor the tuples used in generation 1 and 2 encounters
* Add LevelMin and LevelMax to IEncounterable to get the encounter moves by the min level of the generation 1 EncounterLink
Add iGeneration to difference generation 1 and generation 2 encounters for GB Era pokemon
* Mark generation in gen 1 and 2 encounters
There is no need to mark the generation in gen 3 to 7 encounters because in that generations it match the pokemon generation number
* Add min level for generation 1 moves in getMoves functions
Add function to return the default moves for a GB encounters, for generation 1 games that included both moves from level up table and level 1 moves from personal table
Fix getMoves with min level when the moves list is empty, like Raichu generation 1
* Add maxSpecies to getBaseSpecies function for gen1 pokemon with a gen2 egg encounter
Refactor VC Encounter changing Tuples for GBData class
* Fixed for gen 2 Checks
Also do not search for generation1 encounter if the gen2 pokemon have met location from crystal
* Fix VC wild encounters, should be stored as array or else other verifyEncounter functions wont work
* Add generation 1 parse moves function including default moves
* Clean-up get encounters
* Verify empty moves for generation 1 encounters, in generation 1 does not exits move deleter
That means when a move slot have been used by a level up move or a TM/HM/Tutor move it cant be empty again
Does not apply if generation 2 tradeback is allowed, in generation 2 there is a move deleter
* Added two edge cases for pokemon that learn in red/blue and yellow different moves at the same level, this combinations can not exits until a later level when they learn again one of the levels in the other game, only happen for flareon and vaporeon
* Check incompatible moves between evolution species, it is for species that learn a move in a level as an evolved species and a move at a upper level as a preevolution
Also added most edge cases for the min slots used for generation 1 games, i think every weird combination is already covered
* Fix gen 1 eevee and evolutions move checks
* Cleanup
* Move the code to change valid moves for generation 1 to a function
* Fix getMoveMinLevelGBEncounter
* getUsedMoveSlots, removed wild Butterfree edge case, it is not possible
* Filter the min level of the encounter by the possible games the pokemon could be originated, yellow pikachu and kadabra can be detected
2017-04-09 00:17:20 +00:00
|
|
|
|
{
|
Generation 1 and 2 legal Improvements (#1099)
* Refactor parseMovesForEncounter to gather valid moves for species encounter, some Pokemon can have valid encounters with different source species from the encounter, the valid moves change if the encounter species change because some preevolutions moves are illegal if pokemon caught already evolved.
Example, generation 1 Pikachu that can have a RBY Pikachu encounter and GSC Pichu encounter, the valid moves for the first encounters should not have any Pichu exclusive evolution moves
Also assign the encounter match from gb when parsing moves like the variable Encounter Match, to store the encounter that is valid for the pokemon moves instead the first encounter.
Store the species encounter, this will be needed to check if the evolution is valid for species that evolve leveling with a given learned move
* Add Tradeback Status to the pokemon, this variable for generations 1 and 2 use data like the catch rate to determine if trade between generations 1 and 2 was possible.
If analysis is for VC games tradeback have value NotTradeback for every gen 1 pokemon, but for cart saves some pokemon can be determine that have not been tradeback, if catch rate match species catch rate but do not match a valid generation 2 held item that means the pokemon habe been never traded to generation 2 games, that allow to discart encounters and moves from generation 2.
Also if is not tradeback catch rate is used to filter encounters, catch rate determine in what species was captured the pokemon discarting some preevolutions moves
Also add option for generation 1 cart save analysis to check legal status not allowing generation 2 games, like VC games but with Stadium allowed, like the generation 1 non tradeback rules from Smogon
Also change evolution chains to included generation 2 preevolutions for gen 1 pokemon if tradeback was possible, it is needed to avoid parsemoves to check illegal pokemon like Hitmonchan with Tyrogue level up moves
* Check legal values of generation 1 type and catch rate
Replace pokemon catch rate after changind pokemon species always if pokemon was not tradeback from generation 2, the catch rate will keep unchanged only if it can be a held item and do not match species catch rate (default item)
Also if catch rate is changed use base species catch rate to avoid legal errors if the catch rate of the evolution species if is not possible with the current moves
* Filter ingame trades and static encounters with catch rate for generation 1 non tradeback
* Fix min moves for generation 1 metapod encounter
* Clean up
* Fix encounter level for generation 1, valid moves are those with one level after the encounter level, pokemon can not learn a new move until level up
Clean up type validation
Fix generation 3 fatefull encounter eggs, the pokemon lost the fatefull mark when it hatch
* Clean-up
* Use new variable EncounterSpecies when it is needed to detect the species of the encounter, the old code wont work if the encounter is a wild slots array
* Fix generation 1 evolution chains and catch rate as default held item
* Fix Generation 1 Yellow Pikachu and Kadabra catch rates
2017-04-27 04:27:59 +00:00
|
|
|
|
// Captured as Metapod without Caterpie moves
|
|
|
|
|
return initialmoves.Union(learn[1]).Distinct().Count(lm => lm != 0 && !G1CaterpieMoves.Contains(lm));
|
|
|
|
|
// There is no valid Butterfree encounter in generation 1 games
|
2017-04-10 00:43:05 +00:00
|
|
|
|
}
|
Generation 1 and 2 legal Improvements (#1099)
* Refactor parseMovesForEncounter to gather valid moves for species encounter, some Pokemon can have valid encounters with different source species from the encounter, the valid moves change if the encounter species change because some preevolutions moves are illegal if pokemon caught already evolved.
Example, generation 1 Pikachu that can have a RBY Pikachu encounter and GSC Pichu encounter, the valid moves for the first encounters should not have any Pichu exclusive evolution moves
Also assign the encounter match from gb when parsing moves like the variable Encounter Match, to store the encounter that is valid for the pokemon moves instead the first encounter.
Store the species encounter, this will be needed to check if the evolution is valid for species that evolve leveling with a given learned move
* Add Tradeback Status to the pokemon, this variable for generations 1 and 2 use data like the catch rate to determine if trade between generations 1 and 2 was possible.
If analysis is for VC games tradeback have value NotTradeback for every gen 1 pokemon, but for cart saves some pokemon can be determine that have not been tradeback, if catch rate match species catch rate but do not match a valid generation 2 held item that means the pokemon habe been never traded to generation 2 games, that allow to discart encounters and moves from generation 2.
Also if is not tradeback catch rate is used to filter encounters, catch rate determine in what species was captured the pokemon discarting some preevolutions moves
Also add option for generation 1 cart save analysis to check legal status not allowing generation 2 games, like VC games but with Stadium allowed, like the generation 1 non tradeback rules from Smogon
Also change evolution chains to included generation 2 preevolutions for gen 1 pokemon if tradeback was possible, it is needed to avoid parsemoves to check illegal pokemon like Hitmonchan with Tyrogue level up moves
* Check legal values of generation 1 type and catch rate
Replace pokemon catch rate after changind pokemon species always if pokemon was not tradeback from generation 2, the catch rate will keep unchanged only if it can be a held item and do not match species catch rate (default item)
Also if catch rate is changed use base species catch rate to avoid legal errors if the catch rate of the evolution species if is not possible with the current moves
* Filter ingame trades and static encounters with catch rate for generation 1 non tradeback
* Fix min moves for generation 1 metapod encounter
* Clean up
* Fix encounter level for generation 1, valid moves are those with one level after the encounter level, pokemon can not learn a new move until level up
Clean up type validation
Fix generation 3 fatefull encounter eggs, the pokemon lost the fatefull mark when it hatch
* Clean-up
* Use new variable EncounterSpecies when it is needed to detect the species of the encounter, the old code wont work if the encounter is a wild slots array
* Fix generation 1 evolution chains and catch rate as default held item
* Fix Generation 1 Yellow Pikachu and Kadabra catch rates
2017-04-27 04:27:59 +00:00
|
|
|
|
if ((species == 014 || species == 015) && (catch_rate == 45 || catch_rate == 120))
|
2017-04-10 00:43:05 +00:00
|
|
|
|
{
|
Generation 1 and 2 legal Improvements (#1099)
* Refactor parseMovesForEncounter to gather valid moves for species encounter, some Pokemon can have valid encounters with different source species from the encounter, the valid moves change if the encounter species change because some preevolutions moves are illegal if pokemon caught already evolved.
Example, generation 1 Pikachu that can have a RBY Pikachu encounter and GSC Pichu encounter, the valid moves for the first encounters should not have any Pichu exclusive evolution moves
Also assign the encounter match from gb when parsing moves like the variable Encounter Match, to store the encounter that is valid for the pokemon moves instead the first encounter.
Store the species encounter, this will be needed to check if the evolution is valid for species that evolve leveling with a given learned move
* Add Tradeback Status to the pokemon, this variable for generations 1 and 2 use data like the catch rate to determine if trade between generations 1 and 2 was possible.
If analysis is for VC games tradeback have value NotTradeback for every gen 1 pokemon, but for cart saves some pokemon can be determine that have not been tradeback, if catch rate match species catch rate but do not match a valid generation 2 held item that means the pokemon habe been never traded to generation 2 games, that allow to discart encounters and moves from generation 2.
Also if is not tradeback catch rate is used to filter encounters, catch rate determine in what species was captured the pokemon discarting some preevolutions moves
Also add option for generation 1 cart save analysis to check legal status not allowing generation 2 games, like VC games but with Stadium allowed, like the generation 1 non tradeback rules from Smogon
Also change evolution chains to included generation 2 preevolutions for gen 1 pokemon if tradeback was possible, it is needed to avoid parsemoves to check illegal pokemon like Hitmonchan with Tyrogue level up moves
* Check legal values of generation 1 type and catch rate
Replace pokemon catch rate after changind pokemon species always if pokemon was not tradeback from generation 2, the catch rate will keep unchanged only if it can be a held item and do not match species catch rate (default item)
Also if catch rate is changed use base species catch rate to avoid legal errors if the catch rate of the evolution species if is not possible with the current moves
* Filter ingame trades and static encounters with catch rate for generation 1 non tradeback
* Fix min moves for generation 1 metapod encounter
* Clean up
* Fix encounter level for generation 1, valid moves are those with one level after the encounter level, pokemon can not learn a new move until level up
Clean up type validation
Fix generation 3 fatefull encounter eggs, the pokemon lost the fatefull mark when it hatch
* Clean-up
* Use new variable EncounterSpecies when it is needed to detect the species of the encounter, the old code wont work if the encounter is a wild slots array
* Fix generation 1 evolution chains and catch rate as default held item
* Fix Generation 1 Yellow Pikachu and Kadabra catch rates
2017-04-27 04:27:59 +00:00
|
|
|
|
if (species == 15 && catch_rate == 45) // Captured as Beedril without Weedle and Kakuna moves
|
2017-04-10 00:43:05 +00:00
|
|
|
|
return initialmoves.Union(learn[1]).Distinct().Count(lm => lm != 0 && !G1KakunaMoves.Contains(lm));
|
2017-04-09 23:41:01 +00:00
|
|
|
|
|
Generation 1 and 2 legal Improvements (#1099)
* Refactor parseMovesForEncounter to gather valid moves for species encounter, some Pokemon can have valid encounters with different source species from the encounter, the valid moves change if the encounter species change because some preevolutions moves are illegal if pokemon caught already evolved.
Example, generation 1 Pikachu that can have a RBY Pikachu encounter and GSC Pichu encounter, the valid moves for the first encounters should not have any Pichu exclusive evolution moves
Also assign the encounter match from gb when parsing moves like the variable Encounter Match, to store the encounter that is valid for the pokemon moves instead the first encounter.
Store the species encounter, this will be needed to check if the evolution is valid for species that evolve leveling with a given learned move
* Add Tradeback Status to the pokemon, this variable for generations 1 and 2 use data like the catch rate to determine if trade between generations 1 and 2 was possible.
If analysis is for VC games tradeback have value NotTradeback for every gen 1 pokemon, but for cart saves some pokemon can be determine that have not been tradeback, if catch rate match species catch rate but do not match a valid generation 2 held item that means the pokemon habe been never traded to generation 2 games, that allow to discart encounters and moves from generation 2.
Also if is not tradeback catch rate is used to filter encounters, catch rate determine in what species was captured the pokemon discarting some preevolutions moves
Also add option for generation 1 cart save analysis to check legal status not allowing generation 2 games, like VC games but with Stadium allowed, like the generation 1 non tradeback rules from Smogon
Also change evolution chains to included generation 2 preevolutions for gen 1 pokemon if tradeback was possible, it is needed to avoid parsemoves to check illegal pokemon like Hitmonchan with Tyrogue level up moves
* Check legal values of generation 1 type and catch rate
Replace pokemon catch rate after changind pokemon species always if pokemon was not tradeback from generation 2, the catch rate will keep unchanged only if it can be a held item and do not match species catch rate (default item)
Also if catch rate is changed use base species catch rate to avoid legal errors if the catch rate of the evolution species if is not possible with the current moves
* Filter ingame trades and static encounters with catch rate for generation 1 non tradeback
* Fix min moves for generation 1 metapod encounter
* Clean up
* Fix encounter level for generation 1, valid moves are those with one level after the encounter level, pokemon can not learn a new move until level up
Clean up type validation
Fix generation 3 fatefull encounter eggs, the pokemon lost the fatefull mark when it hatch
* Clean-up
* Use new variable EncounterSpecies when it is needed to detect the species of the encounter, the old code wont work if the encounter is a wild slots array
* Fix generation 1 evolution chains and catch rate as default held item
* Fix Generation 1 Yellow Pikachu and Kadabra catch rates
2017-04-27 04:27:59 +00:00
|
|
|
|
// Captured as Kakuna without Weedle moves
|
|
|
|
|
return initialmoves.Union(learn[1]).Distinct().Count(lm => lm != 0 && !G1WeedleMoves.Contains(lm));
|
2017-04-10 00:43:05 +00:00
|
|
|
|
}
|
2017-04-09 23:41:01 +00:00
|
|
|
|
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return IsMoveCountRequired3(species, pk.CurrentLevel, moves) ? 3 : 0; // no match
|
2017-04-10 00:43:05 +00:00
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
private static bool IsMoveCountRequired3(int species, int level, int[] moves)
|
2017-04-10 00:43:05 +00:00
|
|
|
|
{
|
|
|
|
|
// Species that evolve and learn the 4th move as evolved species at a greather level than base species
|
2018-05-12 15:13:39 +00:00
|
|
|
|
// The 4th move is included in the level up table set as a preevolution move,
|
2017-04-10 00:43:05 +00:00
|
|
|
|
// it should be removed from the used slots count if is not the learn move
|
|
|
|
|
switch (species)
|
|
|
|
|
{
|
|
|
|
|
case 017: return level < 21 && !moves.Contains(018); // Pidgeotto without Whirlwind
|
|
|
|
|
case 028: return level < 27 && !moves.Contains(040); // Sandslash without Poison Sting
|
|
|
|
|
case 047: return level < 30 && !moves.Contains(147); // Parasect without Spore
|
|
|
|
|
case 055: return level < 39 && !moves.Contains(093); // Golduck without Confusion
|
|
|
|
|
case 087: return level < 44 && !moves.Contains(156); // Dewgong without Rest
|
|
|
|
|
case 093:
|
|
|
|
|
case 094: return level < 29 && !moves.Contains(095); // Haunter/Gengar without Hypnosis
|
|
|
|
|
case 110: return level < 39 && !moves.Contains(108); // Weezing without Smoke Screen
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
private static int GetRequiredMoveCountDecrement(PKM pk, int[] moves, List<int>[] learn, int[] initialmoves)
|
2017-04-10 00:43:05 +00:00
|
|
|
|
{
|
|
|
|
|
int usedslots = initialmoves.Union(learn[1]).Where(m => m != 0).Distinct().Count();
|
2017-09-04 20:48:10 +00:00
|
|
|
|
switch (pk.Species)
|
2017-04-10 00:43:05 +00:00
|
|
|
|
{
|
2017-09-04 20:48:10 +00:00
|
|
|
|
case 031: // Venonat; ignore Venomoth (by the time Venonat evolves it will always have 4 moves)
|
|
|
|
|
if (pk.CurrentLevel >= 11 && !moves.Contains(48)) // Supersonic
|
|
|
|
|
usedslots--;
|
|
|
|
|
if (pk.CurrentLevel >= 19 && !moves.Contains(93)) // Confusion
|
|
|
|
|
usedslots--;
|
|
|
|
|
break;
|
|
|
|
|
case 064: case 065: // Abra & Kadabra
|
2018-07-04 16:15:20 +00:00
|
|
|
|
int catch_rate = ((PK1)pk).Catch_Rate;
|
2017-09-04 20:48:10 +00:00
|
|
|
|
if (catch_rate != 100)// Initial Yellow Kadabra Kinesis (move 134)
|
|
|
|
|
usedslots--;
|
|
|
|
|
if (catch_rate == 200 && pk.CurrentLevel < 20) // Kadabra Disable, not learned until 20 if captured as Abra (move 50)
|
|
|
|
|
usedslots--;
|
|
|
|
|
break;
|
|
|
|
|
case 104: case 105: // Cubone & Marowak
|
2018-05-12 15:13:39 +00:00
|
|
|
|
if (!moves.Contains(39)) // Initial Yellow Tail Whip
|
2017-09-04 20:48:10 +00:00
|
|
|
|
usedslots--;
|
|
|
|
|
if (!moves.Contains(125)) // Initial Yellow Bone Club
|
|
|
|
|
usedslots--;
|
|
|
|
|
if (pk.Species == 105 && pk.CurrentLevel < 33 && !moves.Contains(116)) // Marowak evolved without Focus Energy
|
|
|
|
|
usedslots--;
|
|
|
|
|
break;
|
|
|
|
|
case 113:
|
2018-05-12 15:13:39 +00:00
|
|
|
|
if (!moves.Contains(39)) // Yellow Initial Tail Whip
|
2017-09-04 20:48:10 +00:00
|
|
|
|
usedslots--;
|
|
|
|
|
if (!moves.Contains(3)) // Yellow Lvl 12 and Initial Red/Blue Double Slap
|
|
|
|
|
usedslots--;
|
|
|
|
|
break;
|
|
|
|
|
case 056 when pk.CurrentLevel >= 9 && !moves.Contains(67): // Mankey (Low Kick)
|
|
|
|
|
case 127 when pk.CurrentLevel >= 21 && !moves.Contains(20): // Pinsir (Bind)
|
|
|
|
|
case 130 when pk.CurrentLevel < 32: // Gyarados
|
2017-04-10 00:43:05 +00:00
|
|
|
|
usedslots--;
|
2017-09-04 20:48:10 +00:00
|
|
|
|
break;
|
2017-04-10 00:43:05 +00:00
|
|
|
|
}
|
|
|
|
|
return usedslots;
|
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
private static int GetRequiredMoveCountSpecial(PKM pk, int[] moves, List<int>[] learn)
|
2017-04-10 00:43:05 +00:00
|
|
|
|
{
|
|
|
|
|
// Species with few mandatory slots, species with stone evolutions that could evolve at lower level and do not learn any more moves
|
2018-05-12 15:13:39 +00:00
|
|
|
|
// and Pikachu and Nidoran family, those only have mandatory the initial moves and a few have one level up moves,
|
2017-04-10 00:43:05 +00:00
|
|
|
|
// every other move could be avoided switching game or evolving
|
2017-09-04 20:48:10 +00:00
|
|
|
|
var mandatory = GetRequiredMoveCountLevel(pk);
|
|
|
|
|
switch (pk.Species)
|
|
|
|
|
{
|
|
|
|
|
case 103 when pk.CurrentLevel >= 28: // Exeggutor
|
|
|
|
|
// At level 28 learn different move if is a Exeggute or Exeggutor
|
|
|
|
|
if (moves.Contains(73))
|
|
|
|
|
mandatory.Add(73); // Leech Seed level 28 Exeggute
|
|
|
|
|
if (moves.Contains(23))
|
|
|
|
|
mandatory.Add(23); // Stomp level 28 Exeggutor
|
|
|
|
|
break;
|
|
|
|
|
case 25 when pk.CurrentLevel >= 33:
|
|
|
|
|
mandatory.Add(97); // Pikachu always learns Agility
|
|
|
|
|
break;
|
|
|
|
|
case 114:
|
|
|
|
|
mandatory.Add(132); // Tangela always has Constrict as Initial Move
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add to used slots the non-mandatory moves from the learnset table that the pokemon have learned
|
2017-09-05 01:55:15 +00:00
|
|
|
|
return mandatory.Count + moves.Count(m => m != 0 && mandatory.All(l => l != m) && learn[1].Any(t => t == m));
|
2017-09-04 20:48:10 +00:00
|
|
|
|
}
|
|
|
|
|
private static List<int> GetRequiredMoveCountLevel(PKM pk)
|
|
|
|
|
{
|
|
|
|
|
int species = pk.Species;
|
|
|
|
|
int basespecies = GetBaseSpecies(pk);
|
|
|
|
|
int maxlevel = 1;
|
|
|
|
|
int minlevel = 1;
|
|
|
|
|
|
|
|
|
|
if (species == 114) // Tangela moves before level 32 are different in RB vs Y
|
2017-04-10 00:43:05 +00:00
|
|
|
|
{
|
|
|
|
|
minlevel = 32;
|
|
|
|
|
maxlevel = pk.CurrentLevel;
|
Gen 1 move analysis improvement. Adapted the valid moves to take into account that move deleter and move reminder do not exits in generation 1 (#1037)
* Fix getMoves with min level, when SkipWhile and TakeWhile is used together the index i in TakeWhile is calculated from the enumerator that results of the SkipWhile function, not the index of the initial array, those giving an incorrect index to check Levels array in the TakeWhile
* Fix getMoves when levelmin or levelmax is above max level in the levels array, TakeWhile and SkipWhile return empty list if the while goes beyond the last element of the array
* Include player hatched egg in the list of possible encounters for parseMoves only if the pokemon was an egg
Also change the valur of WasEgg for gen1,2,3 pokemon if the encounter analyzed is not an egg
add the non egg encounters to the list instead of checking the non-egg encounter inside parseMovesWasEggPreRelearn
* Fix for gen3 egg encounters
Remove non-egg encounters without special moves if there is an egg encounter because egg encounter already cover every possible move combination
Do not add daycare egg encounter for gen3 unhatched egg if there is another encounter, that means is an event or gift egg, not a daycare egg
Remove duplicate encounters
* Gift egg should not allow inherited moves even it they dont have special moves
Those gift eggs are hatched only with the species base moves
* Added getEncounterMoves functions, to be used for generation 1 encounters to find what moves have a pokemon at the moment of being caught because there is no move reminder in generation 1
* Added GBEncounterData, structure for refactor the tuples used in generation 1 and 2 encounters
* Add LevelMin and LevelMax to IEncounterable to get the encounter moves by the min level of the generation 1 EncounterLink
Add iGeneration to difference generation 1 and generation 2 encounters for GB Era pokemon
* Mark generation in gen 1 and 2 encounters
There is no need to mark the generation in gen 3 to 7 encounters because in that generations it match the pokemon generation number
* Add min level for generation 1 moves in getMoves functions
Add function to return the default moves for a GB encounters, for generation 1 games that included both moves from level up table and level 1 moves from personal table
Fix getMoves with min level when the moves list is empty, like Raichu generation 1
* Add maxSpecies to getBaseSpecies function for gen1 pokemon with a gen2 egg encounter
Refactor VC Encounter changing Tuples for GBData class
* Fixed for gen 2 Checks
Also do not search for generation1 encounter if the gen2 pokemon have met location from crystal
* Fix VC wild encounters, should be stored as array or else other verifyEncounter functions wont work
* Add generation 1 parse moves function including default moves
* Clean-up get encounters
* Verify empty moves for generation 1 encounters, in generation 1 does not exits move deleter
That means when a move slot have been used by a level up move or a TM/HM/Tutor move it cant be empty again
Does not apply if generation 2 tradeback is allowed, in generation 2 there is a move deleter
* Added two edge cases for pokemon that learn in red/blue and yellow different moves at the same level, this combinations can not exits until a later level when they learn again one of the levels in the other game, only happen for flareon and vaporeon
* Check incompatible moves between evolution species, it is for species that learn a move in a level as an evolved species and a move at a upper level as a preevolution
Also added most edge cases for the min slots used for generation 1 games, i think every weird combination is already covered
* Fix gen 1 eevee and evolutions move checks
* Cleanup
* Move the code to change valid moves for generation 1 to a function
* Fix getMoveMinLevelGBEncounter
* getUsedMoveSlots, removed wild Butterfree edge case, it is not possible
* Filter the min level of the encounter by the possible games the pokemon could be originated, yellow pikachu and kadabra can be detected
2017-04-09 00:17:20 +00:00
|
|
|
|
}
|
2017-09-04 20:48:10 +00:00
|
|
|
|
else if (029 <= species && species <= 034 && pk.CurrentLevel >= 8)
|
2017-04-10 00:43:05 +00:00
|
|
|
|
{
|
2017-09-04 20:48:10 +00:00
|
|
|
|
maxlevel = 8; // Always learns a third move at level 8
|
2017-04-10 00:43:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2018-06-10 17:44:05 +00:00
|
|
|
|
if (minlevel > pk.CurrentLevel)
|
|
|
|
|
return new List<int>();
|
|
|
|
|
|
2018-06-18 04:54:04 +00:00
|
|
|
|
return MoveLevelUp.GetMovesLevelUp1(basespecies, 0, maxlevel, minlevel);
|
Gen 1 move analysis improvement. Adapted the valid moves to take into account that move deleter and move reminder do not exits in generation 1 (#1037)
* Fix getMoves with min level, when SkipWhile and TakeWhile is used together the index i in TakeWhile is calculated from the enumerator that results of the SkipWhile function, not the index of the initial array, those giving an incorrect index to check Levels array in the TakeWhile
* Fix getMoves when levelmin or levelmax is above max level in the levels array, TakeWhile and SkipWhile return empty list if the while goes beyond the last element of the array
* Include player hatched egg in the list of possible encounters for parseMoves only if the pokemon was an egg
Also change the valur of WasEgg for gen1,2,3 pokemon if the encounter analyzed is not an egg
add the non egg encounters to the list instead of checking the non-egg encounter inside parseMovesWasEggPreRelearn
* Fix for gen3 egg encounters
Remove non-egg encounters without special moves if there is an egg encounter because egg encounter already cover every possible move combination
Do not add daycare egg encounter for gen3 unhatched egg if there is another encounter, that means is an event or gift egg, not a daycare egg
Remove duplicate encounters
* Gift egg should not allow inherited moves even it they dont have special moves
Those gift eggs are hatched only with the species base moves
* Added getEncounterMoves functions, to be used for generation 1 encounters to find what moves have a pokemon at the moment of being caught because there is no move reminder in generation 1
* Added GBEncounterData, structure for refactor the tuples used in generation 1 and 2 encounters
* Add LevelMin and LevelMax to IEncounterable to get the encounter moves by the min level of the generation 1 EncounterLink
Add iGeneration to difference generation 1 and generation 2 encounters for GB Era pokemon
* Mark generation in gen 1 and 2 encounters
There is no need to mark the generation in gen 3 to 7 encounters because in that generations it match the pokemon generation number
* Add min level for generation 1 moves in getMoves functions
Add function to return the default moves for a GB encounters, for generation 1 games that included both moves from level up table and level 1 moves from personal table
Fix getMoves with min level when the moves list is empty, like Raichu generation 1
* Add maxSpecies to getBaseSpecies function for gen1 pokemon with a gen2 egg encounter
Refactor VC Encounter changing Tuples for GBData class
* Fixed for gen 2 Checks
Also do not search for generation1 encounter if the gen2 pokemon have met location from crystal
* Fix VC wild encounters, should be stored as array or else other verifyEncounter functions wont work
* Add generation 1 parse moves function including default moves
* Clean-up get encounters
* Verify empty moves for generation 1 encounters, in generation 1 does not exits move deleter
That means when a move slot have been used by a level up move or a TM/HM/Tutor move it cant be empty again
Does not apply if generation 2 tradeback is allowed, in generation 2 there is a move deleter
* Added two edge cases for pokemon that learn in red/blue and yellow different moves at the same level, this combinations can not exits until a later level when they learn again one of the levels in the other game, only happen for flareon and vaporeon
* Check incompatible moves between evolution species, it is for species that learn a move in a level as an evolved species and a move at a upper level as a preevolution
Also added most edge cases for the min slots used for generation 1 games, i think every weird combination is already covered
* Fix gen 1 eevee and evolutions move checks
* Cleanup
* Move the code to change valid moves for generation 1 to a function
* Fix getMoveMinLevelGBEncounter
* getUsedMoveSlots, removed wild Butterfree edge case, it is not possible
* Filter the min level of the encounter by the possible games the pokemon could be originated, yellow pikachu and kadabra can be detected
2017-04-09 00:17:20 +00:00
|
|
|
|
}
|
2017-04-10 00:43:05 +00:00
|
|
|
|
|
2017-06-18 01:37:19 +00:00
|
|
|
|
internal static bool GetWasEgg23(PKM pkm)
|
2017-02-28 04:57:24 +00:00
|
|
|
|
{
|
2017-03-26 22:11:09 +00:00
|
|
|
|
if (pkm.IsEgg)
|
|
|
|
|
return true;
|
2017-02-28 04:57:24 +00:00
|
|
|
|
if (pkm.Format > 2 && pkm.Ball != 4)
|
|
|
|
|
return false;
|
2017-03-26 22:11:09 +00:00
|
|
|
|
if (pkm.Format == 3)
|
|
|
|
|
return pkm.WasEgg;
|
2017-02-28 04:57:24 +00:00
|
|
|
|
|
|
|
|
|
int lvl = pkm.CurrentLevel;
|
|
|
|
|
if (lvl < 5)
|
|
|
|
|
return false;
|
|
|
|
|
|
2017-09-04 20:48:10 +00:00
|
|
|
|
if (pkm.Format > 3 && pkm.Met_Level < 5)
|
2017-03-26 22:11:09 +00:00
|
|
|
|
return false;
|
2017-03-27 19:10:30 +00:00
|
|
|
|
if (pkm.Format > 3 && pkm.FatefulEncounter)
|
|
|
|
|
return false;
|
2017-03-26 22:11:09 +00:00
|
|
|
|
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return IsEvolutionValid(pkm);
|
2017-02-28 04:57:24 +00:00
|
|
|
|
}
|
2016-03-23 05:50:54 +00:00
|
|
|
|
|
2016-10-24 05:03:19 +00:00
|
|
|
|
// Generation Specific Fetching
|
2017-09-01 05:37:28 +00:00
|
|
|
|
internal static IEnumerable<EncounterStatic> GetEncounterStaticTable(PKM pkm, GameVersion gameSource = GameVersion.Any)
|
2016-10-24 05:03:19 +00:00
|
|
|
|
{
|
2017-05-28 04:17:53 +00:00
|
|
|
|
if (gameSource == GameVersion.Any)
|
|
|
|
|
gameSource = (GameVersion)pkm.Version;
|
2017-03-18 23:50:34 +00:00
|
|
|
|
|
2017-05-28 04:17:53 +00:00
|
|
|
|
switch (gameSource)
|
2017-03-18 23:50:34 +00:00
|
|
|
|
{
|
2017-05-28 04:17:53 +00:00
|
|
|
|
case GameVersion.RBY:
|
|
|
|
|
case GameVersion.RD:
|
|
|
|
|
case GameVersion.BU:
|
|
|
|
|
case GameVersion.GN:
|
|
|
|
|
case GameVersion.YW:
|
|
|
|
|
return StaticRBY;
|
2017-03-24 06:15:49 +00:00
|
|
|
|
|
2017-05-28 04:17:53 +00:00
|
|
|
|
case GameVersion.GSC:
|
|
|
|
|
case GameVersion.GD:
|
|
|
|
|
case GameVersion.SV:
|
|
|
|
|
case GameVersion.C:
|
2017-09-01 05:37:28 +00:00
|
|
|
|
return GetEncounterStaticTableGSC(pkm);
|
2017-03-18 23:50:34 +00:00
|
|
|
|
|
2017-05-28 04:17:53 +00:00
|
|
|
|
case GameVersion.R: return StaticR;
|
|
|
|
|
case GameVersion.S: return StaticS;
|
|
|
|
|
case GameVersion.E: return StaticE;
|
|
|
|
|
case GameVersion.FR: return StaticFR;
|
|
|
|
|
case GameVersion.LG: return StaticLG;
|
|
|
|
|
case GameVersion.CXD: return Encounter_CXD;
|
2017-03-18 23:50:34 +00:00
|
|
|
|
|
2017-05-28 04:17:53 +00:00
|
|
|
|
case GameVersion.D: return StaticD;
|
|
|
|
|
case GameVersion.P: return StaticP;
|
|
|
|
|
case GameVersion.Pt: return StaticPt;
|
|
|
|
|
case GameVersion.HG: return StaticHG;
|
|
|
|
|
case GameVersion.SS: return StaticSS;
|
2017-04-01 20:54:04 +00:00
|
|
|
|
|
2017-05-28 04:17:53 +00:00
|
|
|
|
case GameVersion.B: return StaticB;
|
|
|
|
|
case GameVersion.W: return StaticW;
|
|
|
|
|
case GameVersion.B2: return StaticB2;
|
|
|
|
|
case GameVersion.W2: return StaticW2;
|
2017-04-01 20:54:04 +00:00
|
|
|
|
|
2017-05-28 04:17:53 +00:00
|
|
|
|
case GameVersion.X: return StaticX;
|
|
|
|
|
case GameVersion.Y: return StaticY;
|
|
|
|
|
case GameVersion.AS: return StaticA;
|
|
|
|
|
case GameVersion.OR: return StaticO;
|
2017-04-01 20:54:04 +00:00
|
|
|
|
|
2017-05-28 04:17:53 +00:00
|
|
|
|
case GameVersion.SN: return StaticSN;
|
|
|
|
|
case GameVersion.MN: return StaticMN;
|
2017-09-01 05:37:28 +00:00
|
|
|
|
case GameVersion.US: return StaticUS;
|
|
|
|
|
case GameVersion.UM: return StaticUM;
|
2017-04-01 20:54:04 +00:00
|
|
|
|
|
2017-11-10 06:17:55 +00:00
|
|
|
|
default: return Enumerable.Empty<EncounterStatic>();
|
2016-10-24 05:03:19 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-09-01 05:37:28 +00:00
|
|
|
|
internal static IEnumerable<EncounterArea> GetEncounterTable(PKM pkm, GameVersion gameSource = GameVersion.Any)
|
2016-11-13 21:11:53 +00:00
|
|
|
|
{
|
2017-05-28 04:17:53 +00:00
|
|
|
|
if (gameSource == GameVersion.Any)
|
|
|
|
|
gameSource = (GameVersion)pkm.Version;
|
|
|
|
|
|
|
|
|
|
switch (gameSource)
|
2016-11-13 21:11:53 +00:00
|
|
|
|
{
|
2017-05-28 04:17:53 +00:00
|
|
|
|
case GameVersion.RBY:
|
|
|
|
|
case GameVersion.RD:
|
|
|
|
|
case GameVersion.BU:
|
|
|
|
|
case GameVersion.GN:
|
|
|
|
|
case GameVersion.YW:
|
|
|
|
|
return SlotsRBY;
|
2017-04-01 20:54:04 +00:00
|
|
|
|
|
2017-05-28 04:17:53 +00:00
|
|
|
|
case GameVersion.GSC:
|
|
|
|
|
case GameVersion.GD:
|
|
|
|
|
case GameVersion.SV:
|
|
|
|
|
case GameVersion.C:
|
2017-09-01 05:37:28 +00:00
|
|
|
|
return GetEncounterTableGSC(pkm);
|
2017-05-28 04:17:53 +00:00
|
|
|
|
|
|
|
|
|
case GameVersion.R: return SlotsR;
|
|
|
|
|
case GameVersion.S: return SlotsS;
|
|
|
|
|
case GameVersion.E: return SlotsE;
|
|
|
|
|
case GameVersion.FR: return SlotsFR;
|
|
|
|
|
case GameVersion.LG: return SlotsLG;
|
|
|
|
|
case GameVersion.CXD: return SlotsXD;
|
|
|
|
|
|
|
|
|
|
case GameVersion.D: return SlotsD;
|
|
|
|
|
case GameVersion.P: return SlotsP;
|
|
|
|
|
case GameVersion.Pt: return SlotsPt;
|
|
|
|
|
case GameVersion.HG: return SlotsHG;
|
|
|
|
|
case GameVersion.SS: return SlotsSS;
|
|
|
|
|
|
|
|
|
|
case GameVersion.B: return SlotsB;
|
|
|
|
|
case GameVersion.W: return SlotsW;
|
|
|
|
|
case GameVersion.B2: return SlotsB2;
|
|
|
|
|
case GameVersion.W2: return SlotsW2;
|
|
|
|
|
|
|
|
|
|
case GameVersion.X: return SlotsX;
|
|
|
|
|
case GameVersion.Y: return SlotsY;
|
|
|
|
|
case GameVersion.AS: return SlotsA;
|
|
|
|
|
case GameVersion.OR: return SlotsO;
|
|
|
|
|
|
|
|
|
|
case GameVersion.SN: return SlotsSN;
|
|
|
|
|
case GameVersion.MN: return SlotsMN;
|
2017-09-01 05:37:28 +00:00
|
|
|
|
case GameVersion.US: return SlotsUS;
|
|
|
|
|
case GameVersion.UM: return SlotsUM;
|
2017-05-28 04:17:53 +00:00
|
|
|
|
|
2017-11-10 06:17:55 +00:00
|
|
|
|
default: return Enumerable.Empty<EncounterArea>();
|
2017-05-28 04:17:53 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-09-01 05:37:28 +00:00
|
|
|
|
private static IEnumerable<EncounterStatic> GetEncounterStaticTableGSC(PKM pkm)
|
|
|
|
|
{
|
2017-09-23 18:46:10 +00:00
|
|
|
|
if (!AllowGen2Crystal(pkm))
|
2017-09-01 05:37:28 +00:00
|
|
|
|
return StaticGS;
|
|
|
|
|
if (pkm.Format != 2)
|
|
|
|
|
return StaticGSC;
|
|
|
|
|
|
|
|
|
|
if (pkm.HasOriginalMetLocation)
|
|
|
|
|
return StaticC;
|
|
|
|
|
return StaticGSC;
|
|
|
|
|
}
|
|
|
|
|
private static IEnumerable<EncounterArea> GetEncounterTableGSC(PKM pkm)
|
|
|
|
|
{
|
2017-09-23 18:46:10 +00:00
|
|
|
|
if (!AllowGen2Crystal(pkm))
|
2017-09-01 05:37:28 +00:00
|
|
|
|
return SlotsGS;
|
|
|
|
|
|
|
|
|
|
if (pkm.Format != 2)
|
|
|
|
|
// Gen 2 met location is lost outside gen 2 games
|
|
|
|
|
return SlotsGSC;
|
|
|
|
|
|
|
|
|
|
if (pkm.HasOriginalMetLocation)
|
|
|
|
|
// Format 2 with met location, encounter should be from Crystal
|
|
|
|
|
return SlotsC;
|
|
|
|
|
|
|
|
|
|
if (pkm.Species > 151 && !FutureEvolutionsGen1.Contains(pkm.Species))
|
2018-05-12 15:13:39 +00:00
|
|
|
|
// Format 2 without met location but pokemon could not be tradeback to gen 1,
|
2017-09-01 05:37:28 +00:00
|
|
|
|
// encounter should be from gold or silver
|
|
|
|
|
return SlotsGS;
|
|
|
|
|
|
|
|
|
|
// Encounter could be any gen 2 game, it can have empty met location for have a g/s origin
|
|
|
|
|
// or it can be a Crystal pokemon that lost met location after being tradeback to gen 1 games
|
|
|
|
|
return SlotsGSC;
|
|
|
|
|
}
|
2017-05-28 04:17:53 +00:00
|
|
|
|
|
2017-09-30 21:08:35 +00:00
|
|
|
|
internal static ICollection<int> GetWildBalls(PKM pkm)
|
2016-11-08 16:43:57 +00:00
|
|
|
|
{
|
|
|
|
|
switch (pkm.GenNumber)
|
|
|
|
|
{
|
2018-06-10 21:45:25 +00:00
|
|
|
|
case 1: return WildPokeBalls1;
|
|
|
|
|
case 2: return WildPokeBalls2;
|
|
|
|
|
case 3: return WildPokeBalls3;
|
|
|
|
|
case 4: return pkm.HGSS ? WildPokeBalls4_HGSS : WildPokeBalls4_DPPt;
|
|
|
|
|
case 5: return WildPokeBalls5;
|
|
|
|
|
case 6: return WildPokeballs6;
|
|
|
|
|
case 7: return WildPokeballs7;
|
|
|
|
|
|
|
|
|
|
default: return null;
|
2016-11-08 16:43:57 +00:00
|
|
|
|
}
|
2017-02-21 03:40:50 +00:00
|
|
|
|
}
|
2018-07-04 16:15:20 +00:00
|
|
|
|
internal static int GetEggHatchLevel(PKM pkm) => GetEggHatchLevel(pkm.Format);
|
|
|
|
|
internal static int GetEggHatchLevel(int gen) => gen <= 3 ? 5 : 1;
|
|
|
|
|
|
2017-09-30 21:08:35 +00:00
|
|
|
|
internal static ICollection<int> GetSplitBreedGeneration(PKM pkm)
|
2017-03-26 13:39:09 +00:00
|
|
|
|
{
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return GetSplitBreedGeneration(pkm.GenNumber);
|
2017-03-26 13:39:09 +00:00
|
|
|
|
}
|
2017-09-30 21:08:35 +00:00
|
|
|
|
private static ICollection<int> GetSplitBreedGeneration(int generation)
|
2017-03-26 13:39:09 +00:00
|
|
|
|
{
|
|
|
|
|
switch (generation)
|
|
|
|
|
{
|
2018-06-10 21:45:25 +00:00
|
|
|
|
case 1:
|
2017-09-30 21:08:35 +00:00
|
|
|
|
case 2: return Empty;
|
2017-03-26 13:39:09 +00:00
|
|
|
|
case 3: return SplitBreed_3;
|
2018-06-22 03:13:41 +00:00
|
|
|
|
case 4:
|
|
|
|
|
case 5:
|
|
|
|
|
case 6:
|
2017-03-26 13:39:09 +00:00
|
|
|
|
case 7: return SplitBreed;
|
2017-09-30 21:08:35 +00:00
|
|
|
|
default: return Empty;
|
2017-03-26 13:39:09 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
internal static int GetMaxSpeciesOrigin(PKM pkm)
|
2017-02-21 03:40:50 +00:00
|
|
|
|
{
|
2018-06-13 01:46:31 +00:00
|
|
|
|
if (pkm.Format == 1)
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return GetMaxSpeciesOrigin(1);
|
2018-06-13 01:46:31 +00:00
|
|
|
|
if (pkm.Format == 2 || pkm.VC)
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return GetMaxSpeciesOrigin(2);
|
|
|
|
|
return GetMaxSpeciesOrigin(pkm.GenNumber);
|
2017-02-21 03:40:50 +00:00
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
internal static int GetMaxSpeciesOrigin(int generation)
|
2017-02-21 03:40:50 +00:00
|
|
|
|
{
|
|
|
|
|
switch (generation)
|
|
|
|
|
{
|
|
|
|
|
case 1: return MaxSpeciesID_1;
|
|
|
|
|
case 2: return MaxSpeciesID_2;
|
|
|
|
|
case 3: return MaxSpeciesID_3;
|
|
|
|
|
case 4: return MaxSpeciesID_4;
|
|
|
|
|
case 5: return MaxSpeciesID_5;
|
|
|
|
|
case 6: return MaxSpeciesID_6;
|
2017-10-06 05:37:45 +00:00
|
|
|
|
case 7: return MaxSpeciesID_7_USUM;
|
2017-02-21 03:40:50 +00:00
|
|
|
|
default: return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
internal static IEnumerable<int> GetFutureGenEvolutions(int generation)
|
2017-02-21 03:40:50 +00:00
|
|
|
|
{
|
|
|
|
|
switch (generation)
|
|
|
|
|
{
|
|
|
|
|
case 1: return FutureEvolutionsGen1;
|
|
|
|
|
case 2: return FutureEvolutionsGen2;
|
|
|
|
|
case 3: return FutureEvolutionsGen3;
|
|
|
|
|
case 4: return FutureEvolutionsGen4;
|
|
|
|
|
case 5: return FutureEvolutionsGen5;
|
2017-10-23 22:44:01 +00:00
|
|
|
|
default: return Enumerable.Empty<int>();
|
2017-02-21 03:40:50 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2018-01-10 23:40:33 +00:00
|
|
|
|
internal static int GetDebutGeneration(int species)
|
|
|
|
|
{
|
|
|
|
|
if (species <= MaxSpeciesID_1)
|
|
|
|
|
return 1;
|
|
|
|
|
if (species <= MaxSpeciesID_2)
|
|
|
|
|
return 2;
|
|
|
|
|
if (species <= MaxSpeciesID_3)
|
|
|
|
|
return 3;
|
|
|
|
|
if (species <= MaxSpeciesID_4)
|
|
|
|
|
return 4;
|
|
|
|
|
if (species <= MaxSpeciesID_5)
|
|
|
|
|
return 5;
|
|
|
|
|
if (species <= MaxSpeciesID_6)
|
|
|
|
|
return 6;
|
|
|
|
|
if (species <= MaxSpeciesID_7_USUM)
|
|
|
|
|
return 7;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2016-10-24 05:03:19 +00:00
|
|
|
|
|
2017-09-16 00:43:31 +00:00
|
|
|
|
internal static int GetMaxLanguageID(int generation)
|
|
|
|
|
{
|
|
|
|
|
switch (generation)
|
|
|
|
|
{
|
|
|
|
|
case 1:
|
|
|
|
|
case 3:
|
|
|
|
|
return 7; // 1-7 except 6
|
2017-09-23 18:46:10 +00:00
|
|
|
|
case 2:
|
2017-09-16 00:43:31 +00:00
|
|
|
|
case 4:
|
|
|
|
|
case 5:
|
|
|
|
|
case 6:
|
|
|
|
|
return 8;
|
2017-09-23 18:46:10 +00:00
|
|
|
|
case 7:
|
|
|
|
|
return 10;
|
2017-09-16 00:43:31 +00:00
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
private static bool[] GetReleasedHeldItems(int generation)
|
2017-02-26 19:43:26 +00:00
|
|
|
|
{
|
|
|
|
|
switch (generation)
|
|
|
|
|
{
|
|
|
|
|
case 2: return ReleasedHeldItems_2;
|
|
|
|
|
case 3: return ReleasedHeldItems_3;
|
|
|
|
|
case 4: return ReleasedHeldItems_4;
|
|
|
|
|
case 5: return ReleasedHeldItems_5;
|
|
|
|
|
case 6: return ReleasedHeldItems_6;
|
|
|
|
|
case 7: return ReleasedHeldItems_7;
|
|
|
|
|
default: return new bool[0];
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-10 21:45:25 +00:00
|
|
|
|
internal static bool IsHeldItemAllowed(PKM pkm)
|
|
|
|
|
{
|
|
|
|
|
return IsHeldItemAllowed(pkm.HeldItem, pkm.Format);
|
|
|
|
|
}
|
|
|
|
|
private static bool IsHeldItemAllowed(int item, int generation)
|
2017-02-26 19:43:26 +00:00
|
|
|
|
{
|
|
|
|
|
if (item < 0)
|
|
|
|
|
return false;
|
|
|
|
|
if (item == 0)
|
|
|
|
|
return true;
|
|
|
|
|
|
2017-06-18 01:37:19 +00:00
|
|
|
|
var items = GetReleasedHeldItems(generation);
|
2017-02-26 19:43:26 +00:00
|
|
|
|
return items.Length > item && items[item];
|
|
|
|
|
}
|
|
|
|
|
|
2017-06-18 01:37:19 +00:00
|
|
|
|
private static bool IsEvolvedFormChange(PKM pkm)
|
2017-02-02 05:59:39 +00:00
|
|
|
|
{
|
2017-02-05 21:08:25 +00:00
|
|
|
|
if (pkm.IsEgg)
|
|
|
|
|
return false;
|
|
|
|
|
|
2017-11-10 00:18:26 +00:00
|
|
|
|
if (pkm.Format >= 7 && AlolanVariantEvolutions12.Contains(pkm.Species))
|
2017-02-02 05:59:39 +00:00
|
|
|
|
return pkm.AltForm == 1;
|
|
|
|
|
if (pkm.Species == 678 && pkm.Gender == 1)
|
|
|
|
|
return pkm.AltForm == 1;
|
2017-03-03 02:28:43 +00:00
|
|
|
|
if (pkm.Species == 773)
|
|
|
|
|
return true;
|
2017-02-02 05:59:39 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
2018-06-23 00:59:02 +00:00
|
|
|
|
internal static bool IsTradeEvolved(IReadOnlyList<EvoCriteria>[] chain, int pkmFormat)
|
2016-03-23 05:50:54 +00:00
|
|
|
|
{
|
2018-07-04 16:15:20 +00:00
|
|
|
|
return chain[pkmFormat].Any(IsTradeEvolved);
|
2016-03-23 05:50:54 +00:00
|
|
|
|
}
|
2018-07-04 16:15:20 +00:00
|
|
|
|
internal static bool IsTradeEvolved(EvoCriteria z) => EvolutionMethod.TradeMethods.Contains(z.Method);
|
2018-04-18 03:06:23 +00:00
|
|
|
|
internal static bool IsEvolutionValid(PKM pkm, int minSpecies = -1, int minLevel = -1)
|
2016-04-08 01:19:21 +00:00
|
|
|
|
{
|
2018-06-20 00:14:22 +00:00
|
|
|
|
var curr = EvolutionChain.GetValidPreEvolutions(pkm);
|
2018-07-04 16:15:20 +00:00
|
|
|
|
var min = curr.FindLast(z => z.Species == minSpecies);
|
2018-04-18 03:06:23 +00:00
|
|
|
|
if (min != null && min.Level < minLevel)
|
|
|
|
|
return false;
|
2018-07-04 16:15:20 +00:00
|
|
|
|
var poss = EvolutionChain.GetValidPreEvolutions(pkm, lvl: 100, skipChecks: true);
|
2016-04-08 01:19:21 +00:00
|
|
|
|
|
2017-05-29 22:21:39 +00:00
|
|
|
|
if (minSpecies != -1)
|
2018-07-04 16:15:20 +00:00
|
|
|
|
{
|
|
|
|
|
int last = poss.FindLastIndex(z => z.Species == minSpecies);
|
|
|
|
|
return curr.Count >= last;
|
|
|
|
|
}
|
|
|
|
|
if (GetSplitBreedGeneration(pkm).Contains(GetBaseSpecies(pkm, 1)))
|
|
|
|
|
return curr.Count >= poss.Count - 1;
|
|
|
|
|
return curr.Count >= poss.Count;
|
2016-04-08 01:19:21 +00:00
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
internal static bool IsEvolutionValidWithMove(PKM pkm, LegalInfo info)
|
2017-06-07 03:10:05 +00:00
|
|
|
|
{
|
|
|
|
|
// Exclude species that do not evolve leveling with a move
|
2017-06-07 03:52:21 +00:00
|
|
|
|
// Exclude gen 1-3 formats
|
2017-06-07 03:10:05 +00:00
|
|
|
|
// Exclude Mr Mime and Snorlax for gen 1-3 games
|
|
|
|
|
if (!SpeciesEvolutionWithMove.Contains(pkm.Species) || pkm.Format <= 3 || (BabyEvolutionWithMove.Contains(pkm.Species) && pkm.GenNumber <= 3))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
var index = Array.FindIndex(SpeciesEvolutionWithMove, p => p == pkm.Species);
|
|
|
|
|
var levels = MinLevelEvolutionWithMove[index];
|
|
|
|
|
var moves = MoveEvolutionWithMove[index];
|
|
|
|
|
var allowegg = EggMoveEvolutionWithMove[index][pkm.GenNumber];
|
|
|
|
|
|
2017-06-07 03:52:21 +00:00
|
|
|
|
// Get the minimum level in any generation when the pokemon could learn the evolve move
|
2017-06-07 03:10:05 +00:00
|
|
|
|
var LearnLevel = 101;
|
2017-06-07 03:52:21 +00:00
|
|
|
|
for (int g = pkm.GenNumber; g <= pkm.Format; g++)
|
|
|
|
|
if (pkm.InhabitedGeneration(g) && levels[g] > 0)
|
2017-06-07 03:10:05 +00:00
|
|
|
|
LearnLevel = Math.Min(LearnLevel, levels[g]);
|
|
|
|
|
|
|
|
|
|
// Check also if the current encounter include the evolve move as an special move
|
|
|
|
|
// That means the pokemon have the move from the encounter level
|
2018-05-12 15:41:23 +00:00
|
|
|
|
if (info.EncounterMatch is IMoveset s && s.Moves?.Any(m => moves.Contains(m)) == true)
|
2017-06-07 03:10:05 +00:00
|
|
|
|
LearnLevel = Math.Min(LearnLevel, info.EncounterMatch.LevelMin);
|
|
|
|
|
|
|
|
|
|
// If the encounter is a player hatched egg check if the move could be an egg move or inherited level up move
|
|
|
|
|
if (info.EncounterMatch.EggEncounter && !pkm.WasGiftEgg && !pkm.WasEventEgg && allowegg)
|
|
|
|
|
{
|
2017-06-18 01:37:19 +00:00
|
|
|
|
if (IsMoveInherited(pkm, info, moves))
|
2017-06-07 23:15:13 +00:00
|
|
|
|
LearnLevel = Math.Min(LearnLevel, pkm.GenNumber < 4 ? 6 : 2);
|
2017-06-07 03:10:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-06-07 03:52:21 +00:00
|
|
|
|
// If has original met location the minimum evolution level is one level after met level
|
|
|
|
|
// Gen 3 pokemon in gen 4 games: minimum level is one level after transfer to generation 4
|
|
|
|
|
// VC pokemon: minimum level is one level after transfer to generation 7
|
2018-05-12 15:13:39 +00:00
|
|
|
|
// 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
|
2017-06-07 03:10:05 +00:00
|
|
|
|
if (pkm.HasOriginalMetLocation || pkm.Format == 4 && pkm.Gen3 || pkm.VC || pkm.Species == 700)
|
2017-06-07 23:15:13 +00:00
|
|
|
|
LearnLevel = Math.Max(pkm.Met_Level + 1, LearnLevel);
|
2017-06-07 03:10:05 +00:00
|
|
|
|
|
2017-06-07 23:15:13 +00:00
|
|
|
|
// 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;
|
2017-06-07 03:10:05 +00:00
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
private static bool IsMoveInherited(PKM pkm, LegalInfo info, int[] moves)
|
2017-06-07 03:52:21 +00:00
|
|
|
|
{
|
|
|
|
|
// In 3DS games, the inherited move must be in the relearn moves.
|
2018-07-04 16:15:20 +00:00
|
|
|
|
if (info.Generation >= 6)
|
2017-06-07 03:52:21 +00:00
|
|
|
|
return pkm.RelearnMoves.Any(moves.Contains);
|
|
|
|
|
|
|
|
|
|
// In Pre-3DS games, the move is inherited if it has the move and it can be hatched with the move.
|
|
|
|
|
if (pkm.Moves.Any(moves.Contains))
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
// If the pokemon does not have the move, it still could be an egg move that was forgotten.
|
|
|
|
|
// This requires the pokemon to not have 4 other moves identified as egg moves or inherited level up moves.
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return 4 > info.Moves.Count(m => m.Source == MoveSource.EggMove || m.Source == MoveSource.InheritLevelUp);
|
2017-06-07 03:52:21 +00:00
|
|
|
|
}
|
2018-02-04 05:12:36 +00:00
|
|
|
|
internal static bool IsFormChangeable(PKM pkm, int species)
|
2017-02-21 05:19:25 +00:00
|
|
|
|
{
|
|
|
|
|
if (FormChange.Contains(species))
|
|
|
|
|
return true;
|
2017-06-18 01:37:19 +00:00
|
|
|
|
if (IsEvolvedFormChange(pkm))
|
2017-02-21 05:19:25 +00:00
|
|
|
|
return true;
|
2018-02-04 05:12:36 +00:00
|
|
|
|
if (species == 718 && pkm.InhabitedGeneration(7) && pkm.AltForm > 1)
|
2017-02-21 05:19:25 +00:00
|
|
|
|
return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2018-05-12 15:13:39 +00:00
|
|
|
|
|
2018-06-19 04:56:30 +00:00
|
|
|
|
internal static bool GetCanInheritMoves(int species)
|
2017-09-15 01:52:31 +00:00
|
|
|
|
{
|
2018-06-19 04:56:30 +00:00
|
|
|
|
if (FixedGenderFromBiGender.Contains(species)) // Nincada -> Shedinja loses gender causing 'false', edge case
|
2017-09-15 01:52:31 +00:00
|
|
|
|
return true;
|
2018-06-19 04:56:30 +00:00
|
|
|
|
var pi = PKX.Personal[species];
|
|
|
|
|
if (!pi.Genderless && !pi.OnlyMale)
|
2017-09-15 01:52:31 +00:00
|
|
|
|
return true;
|
2018-06-19 04:56:30 +00:00
|
|
|
|
if (MixedGenderBreeding.Contains(species))
|
2017-09-15 01:52:31 +00:00
|
|
|
|
return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2017-08-29 01:12:57 +00:00
|
|
|
|
public static int GetLowestLevel(PKM pkm, int startLevel)
|
2016-12-01 06:06:41 +00:00
|
|
|
|
{
|
2017-08-29 01:12:57 +00:00
|
|
|
|
if (startLevel == -1)
|
|
|
|
|
startLevel = 100;
|
|
|
|
|
|
|
|
|
|
var table = EvolutionTree.GetEvolutionTree(pkm.Format);
|
|
|
|
|
int count = 1;
|
|
|
|
|
for (int i = 100; i >= startLevel; i--)
|
2016-12-01 06:06:41 +00:00
|
|
|
|
{
|
2018-07-04 16:15:20 +00:00
|
|
|
|
var evos = table.GetValidPreEvolutions(pkm, maxLevel: i, minLevel: startLevel, skipChecks: true);
|
2018-04-18 02:56:43 +00:00
|
|
|
|
if (evos.Count < count) // lost an evolution, prior level was minimum current level
|
2017-08-29 01:12:57 +00:00
|
|
|
|
return evos.Max(evo => evo.Level) + 1;
|
2018-04-18 02:56:43 +00:00
|
|
|
|
count = evos.Count;
|
2016-12-01 06:06:41 +00:00
|
|
|
|
}
|
2017-08-29 01:12:57 +00:00
|
|
|
|
return startLevel;
|
2016-12-01 06:06:41 +00:00
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
internal static bool GetCanBeCaptured(int species, int gen, GameVersion version = GameVersion.Any)
|
2016-05-06 03:35:18 +00:00
|
|
|
|
{
|
2016-10-24 05:03:19 +00:00
|
|
|
|
switch (gen)
|
2016-05-06 03:35:18 +00:00
|
|
|
|
{
|
2017-03-18 23:50:34 +00:00
|
|
|
|
// Capture Memory only obtainable via Gen 6.
|
2016-10-24 05:03:19 +00:00
|
|
|
|
case 6:
|
|
|
|
|
switch (version)
|
|
|
|
|
{
|
2016-11-09 06:10:32 +00:00
|
|
|
|
case GameVersion.Any:
|
2018-06-10 21:45:25 +00:00
|
|
|
|
return FriendSafari.Contains(species)
|
|
|
|
|
|| GetCanBeCaptured(species, SlotsX, StaticX)
|
|
|
|
|
|| GetCanBeCaptured(species, SlotsY, StaticY)
|
2017-06-18 01:37:19 +00:00
|
|
|
|
|| GetCanBeCaptured(species, SlotsA, StaticA)
|
|
|
|
|
|| GetCanBeCaptured(species, SlotsO, StaticO);
|
2016-11-09 06:10:32 +00:00
|
|
|
|
case GameVersion.X:
|
2018-06-10 21:45:25 +00:00
|
|
|
|
return FriendSafari.Contains(species)
|
|
|
|
|
|| GetCanBeCaptured(species, SlotsX, StaticX);
|
2016-11-09 06:10:32 +00:00
|
|
|
|
case GameVersion.Y:
|
2018-06-10 21:45:25 +00:00
|
|
|
|
return FriendSafari.Contains(species)
|
|
|
|
|
|| GetCanBeCaptured(species, SlotsY, StaticY);
|
|
|
|
|
|
2016-11-09 06:10:32 +00:00
|
|
|
|
case GameVersion.AS:
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return GetCanBeCaptured(species, SlotsA, StaticA);
|
2016-11-09 06:10:32 +00:00
|
|
|
|
case GameVersion.OR:
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return GetCanBeCaptured(species, SlotsO, StaticO);
|
2016-10-24 05:03:19 +00:00
|
|
|
|
}
|
2017-03-18 23:50:34 +00:00
|
|
|
|
break;
|
2016-05-06 03:35:18 +00:00
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2018-06-10 21:45:25 +00:00
|
|
|
|
private static bool GetCanBeCaptured(int species, IEnumerable<EncounterArea> area, IEnumerable<EncounterStatic> statics)
|
2016-10-24 05:03:19 +00:00
|
|
|
|
{
|
|
|
|
|
if (area.Any(loc => loc.Slots.Any(slot => slot.Species == species)))
|
|
|
|
|
return true;
|
|
|
|
|
if (statics.Any(enc => enc.Species == species && !enc.Gift))
|
|
|
|
|
return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
internal static bool GetCanLearnMachineMove(PKM pkm, int move, int generation, GameVersion version = GameVersion.Any)
|
2017-02-15 22:33:59 +00:00
|
|
|
|
{
|
2018-06-20 00:14:22 +00:00
|
|
|
|
return GetValidMoves(pkm, version, EvolutionChain.GetValidPreEvolutions(pkm), generation, Machine: true).Contains(move);
|
2017-02-15 22:33:59 +00:00
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
internal static bool GetCanRelearnMove(PKM pkm, int move, int generation, GameVersion version = GameVersion.Any)
|
2016-05-10 01:19:31 +00:00
|
|
|
|
{
|
2018-06-20 00:14:22 +00:00
|
|
|
|
return GetValidMoves(pkm, version, EvolutionChain.GetValidPreEvolutions(pkm), generation, LVL: true, Relearn: true).Contains(move);
|
2016-05-10 02:24:52 +00:00
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
internal static bool GetCanKnowMove(PKM pkm, int move, int generation, GameVersion version = GameVersion.Any)
|
2016-05-10 02:24:52 +00:00
|
|
|
|
{
|
2016-10-23 19:48:49 +00:00
|
|
|
|
if (pkm.Species == 235 && !InvalidSketch.Contains(move))
|
2016-05-10 16:03:51 +00:00
|
|
|
|
return true;
|
2018-06-20 00:14:22 +00:00
|
|
|
|
return GetValidMoves(pkm, version, EvolutionChain.GetValidPreEvolutions(pkm), generation, LVL: true, Relearn: true, Tutor: true, Machine: true).Contains(move);
|
2016-05-10 01:19:31 +00:00
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
internal static int GetBaseEggSpecies(PKM pkm, int skipOption = 0)
|
2017-04-13 15:48:13 +00:00
|
|
|
|
{
|
|
|
|
|
if (pkm.Format == 1)
|
2018-06-10 17:44:05 +00:00
|
|
|
|
return GetBaseSpecies(pkm, generation: 2);
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return GetBaseSpecies(pkm, skipOption);
|
2017-04-13 15:48:13 +00:00
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
internal static int GetBaseSpecies(PKM pkm, int skipOption = 0, int generation = -1)
|
2016-02-23 06:52:48 +00:00
|
|
|
|
{
|
2017-07-29 18:54:52 +00:00
|
|
|
|
int tree = generation != -1 ? generation : pkm.Format;
|
|
|
|
|
var table = EvolutionTree.GetEvolutionTree(tree);
|
2018-05-10 03:37:11 +00:00
|
|
|
|
int maxSpeciesOrigin = generation != -1 ? GetMaxSpeciesOrigin(generation) : -1;
|
|
|
|
|
var evos = table.GetValidPreEvolutions(pkm, maxLevel: 100, maxSpeciesOrigin: maxSpeciesOrigin, skipChecks: true);
|
2018-05-12 15:41:23 +00:00
|
|
|
|
return GetBaseSpecies(pkm, evos, skipOption);
|
2018-05-10 03:37:11 +00:00
|
|
|
|
}
|
2018-06-19 02:10:21 +00:00
|
|
|
|
internal static int GetBaseSpecies(PKM pkm, IReadOnlyList<DexLevel> evos, int skipOption = 0)
|
2018-05-10 03:37:11 +00:00
|
|
|
|
{
|
|
|
|
|
if (pkm.Species == 292)
|
|
|
|
|
return 290;
|
2016-02-26 15:52:08 +00:00
|
|
|
|
switch (skipOption)
|
2016-02-23 06:52:48 +00:00
|
|
|
|
{
|
2016-10-23 19:48:49 +00:00
|
|
|
|
case -1: return pkm.Species;
|
2018-04-18 02:56:43 +00:00
|
|
|
|
case 1: return evos.Count <= 1 ? pkm.Species : evos[evos.Count - 2].Species;
|
2018-07-04 16:15:20 +00:00
|
|
|
|
default: return evos.Count <= 0 ? pkm.Species : evos[evos.Count - 1].Species;
|
2016-02-23 06:52:48 +00:00
|
|
|
|
}
|
2016-02-26 15:52:08 +00:00
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
private static int GetMaxLevelGeneration(PKM pkm)
|
2017-02-16 10:59:07 +00:00
|
|
|
|
{
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return GetMaxLevelGeneration(pkm, pkm.GenNumber);
|
2017-02-16 10:59:07 +00:00
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
private static int GetMaxLevelGeneration(PKM pkm, int generation)
|
2017-02-16 10:59:07 +00:00
|
|
|
|
{
|
|
|
|
|
if (!pkm.InhabitedGeneration(generation))
|
2017-06-27 03:30:44 +00:00
|
|
|
|
return pkm.Met_Level;
|
2017-02-16 10:59:07 +00:00
|
|
|
|
|
|
|
|
|
if (pkm.Format <= 2)
|
|
|
|
|
{
|
|
|
|
|
if (generation == 1 && FutureEvolutionsGen1_Gen2LevelUp.Contains(pkm.Species))
|
|
|
|
|
return pkm.CurrentLevel - 1;
|
|
|
|
|
return pkm.CurrentLevel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (pkm.Species == 700 && generation == 5)
|
|
|
|
|
return pkm.CurrentLevel - 1;
|
|
|
|
|
|
2017-03-26 16:45:01 +00:00
|
|
|
|
if (pkm.Gen3 && pkm.Format > 4 && pkm.Met_Level == pkm.CurrentLevel && FutureEvolutionsGen3_LevelUpGen4.Contains(pkm.Species))
|
2017-02-16 10:59:07 +00:00
|
|
|
|
return pkm.Met_Level - 1;
|
|
|
|
|
|
2017-02-21 03:40:50 +00:00
|
|
|
|
if (!pkm.HasOriginalMetLocation)
|
|
|
|
|
return pkm.Met_Level;
|
2018-05-12 15:13:39 +00:00
|
|
|
|
|
2017-02-21 03:40:50 +00:00
|
|
|
|
return pkm.CurrentLevel;
|
|
|
|
|
}
|
2017-06-18 01:37:19 +00:00
|
|
|
|
internal static int GetMinLevelEncounter(PKM pkm)
|
2017-02-21 03:40:50 +00:00
|
|
|
|
{
|
2017-03-26 16:05:58 +00:00
|
|
|
|
if (pkm.Format == 3 && pkm.WasEgg)
|
2017-03-30 18:58:30 +00:00
|
|
|
|
// Only for gen 3 pokemon in format 3, after transfer to gen 4 it should return transfer level
|
2017-03-26 16:05:58 +00:00
|
|
|
|
return 5;
|
2017-11-18 06:19:23 +00:00
|
|
|
|
if (pkm.Format == 4 && pkm.Gen4 && pkm.WasEgg)
|
2017-03-30 18:58:30 +00:00
|
|
|
|
// Only for gen 4 pokemon in format 4, after transfer to gen 5 it should return transfer level
|
|
|
|
|
return 1;
|
2017-06-18 01:37:19 +00:00
|
|
|
|
return pkm.HasOriginalMetLocation ? pkm.Met_Level : GetMaxLevelGeneration(pkm);
|
2017-02-16 10:59:07 +00:00
|
|
|
|
}
|
2018-07-01 17:13:26 +00:00
|
|
|
|
private static bool GetCatchRateMatchesPreEvolution(PKM pkm, int catch_rate, IEnumerable<int> gen1)
|
2017-07-30 19:31:17 +00:00
|
|
|
|
{
|
|
|
|
|
// For species catch rate, discard any species that has no valid encounters and a different catch rate than their pre-evolutions
|
2018-07-01 17:13:26 +00:00
|
|
|
|
var Lineage = gen1.Except(Species_NotAvailable_CatchRate);
|
2018-06-09 23:04:06 +00:00
|
|
|
|
return IsCatchRateRBY(Lineage) || IsCatchRateTrade() || IsCatchRateStadium();
|
2017-07-30 19:31:17 +00:00
|
|
|
|
|
|
|
|
|
// Dragonite's Catch Rate is different than Dragonair's in Yellow, but there is no Dragonite encounter.
|
2018-06-09 23:04:06 +00:00
|
|
|
|
bool IsCatchRateRBY(IEnumerable<int> ds) => ds.Any(s => catch_rate == PersonalTable.RB[s].CatchRate || s != 149 && catch_rate == PersonalTable.Y[s].CatchRate);
|
2017-07-30 19:31:17 +00:00
|
|
|
|
// Krabby encounter trade special catch rate
|
|
|
|
|
bool IsCatchRateTrade() => (pkm.Species == 098 || pkm.Species == 099) && catch_rate == 204;
|
|
|
|
|
bool IsCatchRateStadium() => Stadium_GiftSpecies.Contains(pkm.Species) && Stadium_CatchRate.Contains(catch_rate);
|
|
|
|
|
}
|
2018-07-02 00:07:29 +00:00
|
|
|
|
internal static void SetTradebackStatusRBY(PK1 pkm)
|
2017-07-30 19:31:17 +00:00
|
|
|
|
{
|
|
|
|
|
if (!AllowGen1Tradeback)
|
|
|
|
|
{
|
|
|
|
|
pkm.TradebackStatus = TradebackType.Gen1_NotTradeback;
|
2018-07-02 00:07:29 +00:00
|
|
|
|
pkm.CatchRateIsItem = false;
|
2017-07-30 19:31:17 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Detect tradeback status by comparing the catch rate(Gen1)/held item(Gen2) to the species in the pkm's evolution chain.
|
2018-07-02 00:07:29 +00:00
|
|
|
|
var catch_rate = pkm.Catch_Rate;
|
2018-07-01 17:13:26 +00:00
|
|
|
|
var table = EvolutionTree.GetEvolutionTree(1);
|
|
|
|
|
var lineage = table.GetValidPreEvolutions(pkm, maxLevel: pkm.CurrentLevel);
|
|
|
|
|
var gen1 = lineage.Select(evolution => evolution.Species);
|
|
|
|
|
bool matchAny = GetCatchRateMatchesPreEvolution(pkm, catch_rate, gen1);
|
2017-07-30 19:31:17 +00:00
|
|
|
|
|
|
|
|
|
// If the catch rate value has been modified, the item has either been removed or swapped in Generation 2.
|
2018-07-02 00:07:29 +00:00
|
|
|
|
var HeldItemCatchRate = catch_rate == 0 || HeldItems_GSC.Contains((ushort)catch_rate);
|
2017-07-30 19:31:17 +00:00
|
|
|
|
if (HeldItemCatchRate && !matchAny)
|
|
|
|
|
pkm.TradebackStatus = TradebackType.WasTradeback;
|
|
|
|
|
else if (!HeldItemCatchRate && matchAny)
|
|
|
|
|
pkm.TradebackStatus = TradebackType.Gen1_NotTradeback;
|
|
|
|
|
else
|
|
|
|
|
pkm.TradebackStatus = TradebackType.Any;
|
|
|
|
|
|
|
|
|
|
// Update the editing settings for the PKM to acknowledge the tradeback status if the species is changed.
|
2018-07-02 00:07:29 +00:00
|
|
|
|
pkm.CatchRateIsItem = !pkm.Gen1_NotTradeback && HeldItemCatchRate && !matchAny;
|
2017-07-30 19:31:17 +00:00
|
|
|
|
}
|
2017-02-21 03:40:50 +00:00
|
|
|
|
|
2018-06-19 02:10:21 +00:00
|
|
|
|
private static IEnumerable<int> GetValidMoves(PKM pkm, GameVersion Version, IReadOnlyList<IReadOnlyList<EvoCriteria>> 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)
|
2016-05-10 02:03:58 +00:00
|
|
|
|
{
|
|
|
|
|
List<int> r = new List<int> { 0 };
|
2017-02-21 03:40:50 +00:00
|
|
|
|
if (Relearn && pkm.Format >= 6)
|
|
|
|
|
r.AddRange(pkm.RelearnMoves);
|
|
|
|
|
|
|
|
|
|
for (int gen = pkm.GenNumber; gen <= pkm.Format; gen++)
|
2018-04-18 02:56:43 +00:00
|
|
|
|
if (vs[gen].Count != 0)
|
2017-06-18 01:37:19 +00:00
|
|
|
|
r.AddRange(GetValidMoves(pkm, Version, vs[gen], gen, minLvLG1: minLvLG1, minLvLG2: minLvLG2, LVL: LVL, Relearn: false, Tutor: Tutor, Machine: Machine, MoveReminder: MoveReminder, RemoveTransferHM: RemoveTransferHM));
|
2017-02-21 03:40:50 +00:00
|
|
|
|
|
2017-10-07 04:03:23 +00:00
|
|
|
|
return r.Distinct();
|
2017-02-15 22:33:59 +00:00
|
|
|
|
}
|
2018-06-19 02:10:21 +00:00
|
|
|
|
private static IEnumerable<int> GetValidMoves(PKM pkm, GameVersion Version, IReadOnlyList<EvoCriteria> 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)
|
2017-02-15 22:33:59 +00:00
|
|
|
|
{
|
|
|
|
|
List<int> r = new List<int> { 0 };
|
2018-04-18 02:56:43 +00:00
|
|
|
|
if (vs.Count == 0)
|
2017-02-15 22:33:59 +00:00
|
|
|
|
return r;
|
2016-10-23 19:48:49 +00:00
|
|
|
|
int species = pkm.Species;
|
2016-10-24 05:03:19 +00:00
|
|
|
|
|
2016-11-12 13:56:22 +00:00
|
|
|
|
// Special Type Tutors Availability
|
2016-11-27 04:02:44 +00:00
|
|
|
|
bool moveTutor = Tutor || MoveReminder; // Usually true, except when called for move suggestions (no tutored moves)
|
2018-05-12 15:13:39 +00:00
|
|
|
|
|
2016-05-10 02:03:58 +00:00
|
|
|
|
if (FormChangeMoves.Contains(species)) // Deoxys & Shaymin & Giratina (others don't have extra but whatever)
|
|
|
|
|
{
|
2016-10-24 05:03:19 +00:00
|
|
|
|
int formcount = pkm.PersonalInfo.FormeCount;
|
2017-03-30 19:34:48 +00:00
|
|
|
|
if (species == 386 && pkm.Format == 3)
|
|
|
|
|
// In gen 3 deoxys has different forms depending on the current game, in personal info there is no alter form info
|
|
|
|
|
formcount = 4;
|
2016-05-10 02:03:58 +00:00
|
|
|
|
for (int i = 0; i < formcount; i++)
|
2017-12-05 04:16:54 +00:00
|
|
|
|
r.AddRange(GetMoves(pkm, species, minLvLG1, minLvLG2, vs[0].Level, i, moveTutor, Version, LVL, Tutor, Machine, MoveReminder, RemoveTransferHM, Generation));
|
2018-06-09 23:04:06 +00:00
|
|
|
|
if (Relearn)
|
|
|
|
|
r.AddRange(pkm.RelearnMoves);
|
2017-03-17 04:20:06 +00:00
|
|
|
|
return r.Distinct();
|
2016-05-10 02:03:58 +00:00
|
|
|
|
}
|
|
|
|
|
|
2018-04-18 02:56:43 +00:00
|
|
|
|
for (var i = 0; i < vs.Count; i++)
|
Gen 1 move analysis improvement. Adapted the valid moves to take into account that move deleter and move reminder do not exits in generation 1 (#1037)
* Fix getMoves with min level, when SkipWhile and TakeWhile is used together the index i in TakeWhile is calculated from the enumerator that results of the SkipWhile function, not the index of the initial array, those giving an incorrect index to check Levels array in the TakeWhile
* Fix getMoves when levelmin or levelmax is above max level in the levels array, TakeWhile and SkipWhile return empty list if the while goes beyond the last element of the array
* Include player hatched egg in the list of possible encounters for parseMoves only if the pokemon was an egg
Also change the valur of WasEgg for gen1,2,3 pokemon if the encounter analyzed is not an egg
add the non egg encounters to the list instead of checking the non-egg encounter inside parseMovesWasEggPreRelearn
* Fix for gen3 egg encounters
Remove non-egg encounters without special moves if there is an egg encounter because egg encounter already cover every possible move combination
Do not add daycare egg encounter for gen3 unhatched egg if there is another encounter, that means is an event or gift egg, not a daycare egg
Remove duplicate encounters
* Gift egg should not allow inherited moves even it they dont have special moves
Those gift eggs are hatched only with the species base moves
* Added getEncounterMoves functions, to be used for generation 1 encounters to find what moves have a pokemon at the moment of being caught because there is no move reminder in generation 1
* Added GBEncounterData, structure for refactor the tuples used in generation 1 and 2 encounters
* Add LevelMin and LevelMax to IEncounterable to get the encounter moves by the min level of the generation 1 EncounterLink
Add iGeneration to difference generation 1 and generation 2 encounters for GB Era pokemon
* Mark generation in gen 1 and 2 encounters
There is no need to mark the generation in gen 3 to 7 encounters because in that generations it match the pokemon generation number
* Add min level for generation 1 moves in getMoves functions
Add function to return the default moves for a GB encounters, for generation 1 games that included both moves from level up table and level 1 moves from personal table
Fix getMoves with min level when the moves list is empty, like Raichu generation 1
* Add maxSpecies to getBaseSpecies function for gen1 pokemon with a gen2 egg encounter
Refactor VC Encounter changing Tuples for GBData class
* Fixed for gen 2 Checks
Also do not search for generation1 encounter if the gen2 pokemon have met location from crystal
* Fix VC wild encounters, should be stored as array or else other verifyEncounter functions wont work
* Add generation 1 parse moves function including default moves
* Clean-up get encounters
* Verify empty moves for generation 1 encounters, in generation 1 does not exits move deleter
That means when a move slot have been used by a level up move or a TM/HM/Tutor move it cant be empty again
Does not apply if generation 2 tradeback is allowed, in generation 2 there is a move deleter
* Added two edge cases for pokemon that learn in red/blue and yellow different moves at the same level, this combinations can not exits until a later level when they learn again one of the levels in the other game, only happen for flareon and vaporeon
* Check incompatible moves between evolution species, it is for species that learn a move in a level as an evolved species and a move at a upper level as a preevolution
Also added most edge cases for the min slots used for generation 1 games, i think every weird combination is already covered
* Fix gen 1 eevee and evolutions move checks
* Cleanup
* Move the code to change valid moves for generation 1 to a function
* Fix getMoveMinLevelGBEncounter
* getUsedMoveSlots, removed wild Butterfree edge case, it is not possible
* Filter the min level of the encounter by the possible games the pokemon could be originated, yellow pikachu and kadabra can be detected
2017-04-09 00:17:20 +00:00
|
|
|
|
{
|
2018-06-19 02:10:21 +00:00
|
|
|
|
var evo = vs[i];
|
2018-06-09 23:04:06 +00:00
|
|
|
|
var moves = GetEvoMoves(pkm, Version, vs, Generation, minLvLG1, minLvLG2, LVL, Tutor, Machine, MoveReminder, RemoveTransferHM, moveTutor, i, evo);
|
|
|
|
|
r.AddRange(moves);
|
Gen 1 move analysis improvement. Adapted the valid moves to take into account that move deleter and move reminder do not exits in generation 1 (#1037)
* Fix getMoves with min level, when SkipWhile and TakeWhile is used together the index i in TakeWhile is calculated from the enumerator that results of the SkipWhile function, not the index of the initial array, those giving an incorrect index to check Levels array in the TakeWhile
* Fix getMoves when levelmin or levelmax is above max level in the levels array, TakeWhile and SkipWhile return empty list if the while goes beyond the last element of the array
* Include player hatched egg in the list of possible encounters for parseMoves only if the pokemon was an egg
Also change the valur of WasEgg for gen1,2,3 pokemon if the encounter analyzed is not an egg
add the non egg encounters to the list instead of checking the non-egg encounter inside parseMovesWasEggPreRelearn
* Fix for gen3 egg encounters
Remove non-egg encounters without special moves if there is an egg encounter because egg encounter already cover every possible move combination
Do not add daycare egg encounter for gen3 unhatched egg if there is another encounter, that means is an event or gift egg, not a daycare egg
Remove duplicate encounters
* Gift egg should not allow inherited moves even it they dont have special moves
Those gift eggs are hatched only with the species base moves
* Added getEncounterMoves functions, to be used for generation 1 encounters to find what moves have a pokemon at the moment of being caught because there is no move reminder in generation 1
* Added GBEncounterData, structure for refactor the tuples used in generation 1 and 2 encounters
* Add LevelMin and LevelMax to IEncounterable to get the encounter moves by the min level of the generation 1 EncounterLink
Add iGeneration to difference generation 1 and generation 2 encounters for GB Era pokemon
* Mark generation in gen 1 and 2 encounters
There is no need to mark the generation in gen 3 to 7 encounters because in that generations it match the pokemon generation number
* Add min level for generation 1 moves in getMoves functions
Add function to return the default moves for a GB encounters, for generation 1 games that included both moves from level up table and level 1 moves from personal table
Fix getMoves with min level when the moves list is empty, like Raichu generation 1
* Add maxSpecies to getBaseSpecies function for gen1 pokemon with a gen2 egg encounter
Refactor VC Encounter changing Tuples for GBData class
* Fixed for gen 2 Checks
Also do not search for generation1 encounter if the gen2 pokemon have met location from crystal
* Fix VC wild encounters, should be stored as array or else other verifyEncounter functions wont work
* Add generation 1 parse moves function including default moves
* Clean-up get encounters
* Verify empty moves for generation 1 encounters, in generation 1 does not exits move deleter
That means when a move slot have been used by a level up move or a TM/HM/Tutor move it cant be empty again
Does not apply if generation 2 tradeback is allowed, in generation 2 there is a move deleter
* Added two edge cases for pokemon that learn in red/blue and yellow different moves at the same level, this combinations can not exits until a later level when they learn again one of the levels in the other game, only happen for flareon and vaporeon
* Check incompatible moves between evolution species, it is for species that learn a move in a level as an evolved species and a move at a upper level as a preevolution
Also added most edge cases for the min slots used for generation 1 games, i think every weird combination is already covered
* Fix gen 1 eevee and evolutions move checks
* Cleanup
* Move the code to change valid moves for generation 1 to a function
* Fix getMoveMinLevelGBEncounter
* getUsedMoveSlots, removed wild Butterfree edge case, it is not possible
* Filter the min level of the encounter by the possible games the pokemon could be originated, yellow pikachu and kadabra can be detected
2017-04-09 00:17:20 +00:00
|
|
|
|
}
|
2016-10-24 05:03:19 +00:00
|
|
|
|
|
2017-02-14 06:49:32 +00:00
|
|
|
|
if (pkm.Format <= 3)
|
2017-03-17 04:20:06 +00:00
|
|
|
|
return r.Distinct();
|
2018-06-09 23:04:06 +00:00
|
|
|
|
|
2017-02-15 23:56:54 +00:00
|
|
|
|
if (LVL)
|
2018-06-09 23:04:06 +00:00
|
|
|
|
MoveTutor.AddSpecialFormChangeMoves(r, pkm, Generation, species);
|
2017-02-21 03:40:50 +00:00
|
|
|
|
if (Tutor)
|
2018-06-09 23:04:06 +00:00
|
|
|
|
MoveTutor.AddSpecialTutorMoves(r, pkm, Generation, species);
|
2017-02-21 03:40:50 +00:00
|
|
|
|
if (Relearn && Generation >= 6)
|
|
|
|
|
r.AddRange(pkm.RelearnMoves);
|
2017-03-17 04:20:06 +00:00
|
|
|
|
return r.Distinct();
|
2016-05-10 02:03:58 +00:00
|
|
|
|
}
|
2018-06-19 02:10:21 +00:00
|
|
|
|
private static IEnumerable<int> GetEvoMoves(PKM pkm, GameVersion Version, IReadOnlyList<EvoCriteria> vs, int Generation, int minLvLG1, int minLvLG2, bool LVL, bool Tutor, bool Machine, bool MoveReminder, bool RemoveTransferHM, bool moveTutor, int i, EvoCriteria evo)
|
2018-06-09 23:04:06 +00:00
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
minlvlevo1 = minLvLG1;
|
|
|
|
|
if (evo.MinLevel > 1)
|
|
|
|
|
minlvlevo1 = Math.Min(pkm.CurrentLevel, evo.MinLevel);
|
|
|
|
|
}
|
|
|
|
|
if (Generation == 2 && !AllowGen2MoveReminder(pkm))
|
|
|
|
|
{
|
|
|
|
|
minlvlevo2 = minLvLG2;
|
|
|
|
|
if (evo.MinLevel > 1)
|
|
|
|
|
minlvlevo2 = Math.Min(pkm.CurrentLevel, evo.MinLevel);
|
|
|
|
|
}
|
|
|
|
|
var maxLevel = evo.Level;
|
|
|
|
|
if (i != 0 && vs[i - 1].RequiresLvlUp) // evolution
|
|
|
|
|
++maxLevel; // allow lvlmoves from the level it evolved to the next species
|
|
|
|
|
return GetMoves(pkm, evo.Species, minlvlevo1, minlvlevo2, maxLevel, pkm.AltForm, moveTutor, Version, LVL, Tutor, Machine, MoveReminder, RemoveTransferHM, Generation);
|
|
|
|
|
}
|
2017-09-23 23:24:22 +00:00
|
|
|
|
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)
|
2016-10-24 05:03:19 +00:00
|
|
|
|
{
|
|
|
|
|
List<int> r = new List<int>();
|
2018-06-09 03:37:35 +00:00
|
|
|
|
if (LVL)
|
2018-06-10 21:45:25 +00:00
|
|
|
|
r.AddRange(MoveLevelUp.GetMovesLevelUp(pkm, species, minlvlG1, minlvlG2, lvl, form, Version, MoveReminder, Generation));
|
2018-06-09 03:37:35 +00:00
|
|
|
|
if (Machine)
|
|
|
|
|
r.AddRange(MoveTechnicalMachine.GetTMHM(pkm, species, form, Generation, Version, RemoveTransferHM));
|
|
|
|
|
if (moveTutor)
|
|
|
|
|
r.AddRange(MoveTutor.GetTutorMoves(pkm, species, form, specialTutors, Generation));
|
2018-06-10 17:44:05 +00:00
|
|
|
|
return r.Distinct();
|
2016-05-10 02:03:58 +00:00
|
|
|
|
}
|
2018-06-19 04:56:30 +00:00
|
|
|
|
|
2017-06-07 03:10:05 +00:00
|
|
|
|
internal static bool IsTradedKadabraG1(PKM pkm)
|
|
|
|
|
{
|
2017-06-07 03:52:21 +00:00
|
|
|
|
if (!(pkm is PK1 pk1) || pk1.Species != 64)
|
2017-06-07 03:10:05 +00:00
|
|
|
|
return false;
|
2017-06-07 03:52:21 +00:00
|
|
|
|
if (pk1.TradebackStatus == TradebackType.WasTradeback)
|
2017-06-07 03:10:05 +00:00
|
|
|
|
return true;
|
2018-04-30 04:08:49 +00:00
|
|
|
|
if (Savegame_Version == GameVersion.Any)
|
|
|
|
|
return false;
|
2017-10-23 00:11:48 +00:00
|
|
|
|
var IsYellow = Savegame_Version == GameVersion.YW;
|
2017-06-07 03:52:21 +00:00
|
|
|
|
if (pk1.TradebackStatus == TradebackType.Gen1_NotTradeback)
|
2017-06-07 03:10:05 +00:00
|
|
|
|
{
|
2017-06-07 03:52:21 +00:00
|
|
|
|
// If catch rate is Abra catch rate it wont trigger as invalid trade without evolution, it could be traded as Abra
|
|
|
|
|
var catch_rate = pk1.Catch_Rate;
|
|
|
|
|
// Yellow Kadabra catch rate in Red/Blue game, must be Alakazam
|
|
|
|
|
if (!IsYellow && catch_rate == PersonalTable.Y[64].CatchRate)
|
2017-06-07 03:10:05 +00:00
|
|
|
|
return true;
|
2017-06-07 03:52:21 +00:00
|
|
|
|
// Red/Blue Kadabra catch rate in Yellow game, must be Alakazam
|
|
|
|
|
if (IsYellow && catch_rate == PersonalTable.RB[64].CatchRate)
|
2017-06-07 03:10:05 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
if (IsYellow)
|
|
|
|
|
return false;
|
2018-05-19 02:33:11 +00:00
|
|
|
|
// Yellow only moves in Red/Blue game, must be Alakazam
|
2018-05-12 15:13:39 +00:00
|
|
|
|
if (pk1.Moves.Contains(134)) // Kinesis, yellow only move
|
2017-06-07 03:10:05 +00:00
|
|
|
|
return true;
|
2017-06-07 03:52:21 +00:00
|
|
|
|
if (pk1.CurrentLevel < 20 && pkm.Moves.Contains(50)) // Obtaining Disable below level 20 implies a yellow only move
|
2017-06-07 03:10:05 +00:00
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
Encounter Type fix and detection of pokemon that should have evolve on trade (#1105)
* Detect encounter trades that evolve on trade and have not been evolved
Detect generation 1 pokemon with special catch rates : krabby trade and Pokemon Stadium
Detect generation 1 pokemon that evolve on trade and have been traded but not evolved
Detect pokemon with tradeback status any but with only encounters from the other GB generation, that means they are WasTradeback
Detect pokemon with moves from the other GB generation, change tradebackstatus to WasTradeback
* Fix dppt surfing and fishing encounter type, is is surfing because the battle background is the same as other surfingfishing encounters
Fix headbutt encounter type, the encounter type depends on the battle background used when battle a pokemon, for headbutt it changes with the player tile, is the player is in a city it will be building encounter, in a grass tile tall grass, in water it is surfingfishing and cave inside a cave. Some locations have more than one possible encounter type, for example routes with trees near the grass, near the water and near non-combat tiles.
Also added slot type headbutt special for the special trees, those trees are all in routes and are only adjacent to non-combat tiles
* Fix encounter type for missing areas with multiple grass encounters types: Mt Coronet, Mt Silver Cave and Stark Mountain (Issue # 1095)
* Fixes and typos
* Check for non-japanese e-reader pokemon, is unreleased
2017-05-01 15:07:20 +00:00
|
|
|
|
internal static bool IsOutsider(PKM pkm)
|
|
|
|
|
{
|
2018-04-30 04:08:49 +00:00
|
|
|
|
if (Savegame_Version == GameVersion.Any)
|
|
|
|
|
return false;
|
Encounter Type fix and detection of pokemon that should have evolve on trade (#1105)
* Detect encounter trades that evolve on trade and have not been evolved
Detect generation 1 pokemon with special catch rates : krabby trade and Pokemon Stadium
Detect generation 1 pokemon that evolve on trade and have been traded but not evolved
Detect pokemon with tradeback status any but with only encounters from the other GB generation, that means they are WasTradeback
Detect pokemon with moves from the other GB generation, change tradebackstatus to WasTradeback
* Fix dppt surfing and fishing encounter type, is is surfing because the battle background is the same as other surfingfishing encounters
Fix headbutt encounter type, the encounter type depends on the battle background used when battle a pokemon, for headbutt it changes with the player tile, is the player is in a city it will be building encounter, in a grass tile tall grass, in water it is surfingfishing and cave inside a cave. Some locations have more than one possible encounter type, for example routes with trees near the grass, near the water and near non-combat tiles.
Also added slot type headbutt special for the special trees, those trees are all in routes and are only adjacent to non-combat tiles
* Fix encounter type for missing areas with multiple grass encounters types: Mt Coronet, Mt Silver Cave and Stark Mountain (Issue # 1095)
* Fixes and typos
* Check for non-japanese e-reader pokemon, is unreleased
2017-05-01 15:07:20 +00:00
|
|
|
|
var Outsider = Savegame_TID != pkm.TID || Savegame_OT != pkm.OT_Name;
|
|
|
|
|
if (pkm.Format <= 2)
|
|
|
|
|
return Outsider;
|
|
|
|
|
Outsider |= Savegame_SID != pkm.SID;
|
|
|
|
|
if (pkm.Format == 3) // Generation 3 does not check ot geneder nor pokemon version
|
|
|
|
|
return Outsider;
|
2018-07-04 16:15:20 +00:00
|
|
|
|
Outsider |= Savegame_Gender != pkm.OT_Gender || Savegame_Version != (GameVersion)pkm.Version;
|
Encounter Type fix and detection of pokemon that should have evolve on trade (#1105)
* Detect encounter trades that evolve on trade and have not been evolved
Detect generation 1 pokemon with special catch rates : krabby trade and Pokemon Stadium
Detect generation 1 pokemon that evolve on trade and have been traded but not evolved
Detect pokemon with tradeback status any but with only encounters from the other GB generation, that means they are WasTradeback
Detect pokemon with moves from the other GB generation, change tradebackstatus to WasTradeback
* Fix dppt surfing and fishing encounter type, is is surfing because the battle background is the same as other surfingfishing encounters
Fix headbutt encounter type, the encounter type depends on the battle background used when battle a pokemon, for headbutt it changes with the player tile, is the player is in a city it will be building encounter, in a grass tile tall grass, in water it is surfingfishing and cave inside a cave. Some locations have more than one possible encounter type, for example routes with trees near the grass, near the water and near non-combat tiles.
Also added slot type headbutt special for the special trees, those trees are all in routes and are only adjacent to non-combat tiles
* Fix encounter type for missing areas with multiple grass encounters types: Mt Coronet, Mt Silver Cave and Stark Mountain (Issue # 1095)
* Fixes and typos
* Check for non-japanese e-reader pokemon, is unreleased
2017-05-01 15:07:20 +00:00
|
|
|
|
return Outsider;
|
|
|
|
|
}
|
2017-07-06 23:03:41 +00:00
|
|
|
|
|
2018-06-09 03:10:41 +00:00
|
|
|
|
internal const GameVersion NONE = GameVersion.Invalid;
|
|
|
|
|
internal static readonly LearnVersion LearnNONE = new LearnVersion(-1);
|
|
|
|
|
|
|
|
|
|
internal static bool HasVisitedB2W2(this PKM pkm) => pkm.InhabitedGeneration(5);
|
|
|
|
|
internal static bool HasVisitedORAS(this PKM pkm) => pkm.InhabitedGeneration(6) && (pkm.AO || !pkm.IsUntraded);
|
|
|
|
|
internal static bool HasVisitedUSUM(this PKM pkm) => pkm.InhabitedGeneration(7) && (pkm.USUM || !pkm.IsUntraded);
|
2018-06-14 05:03:58 +00:00
|
|
|
|
internal static bool IsMovesetRestricted(this PKM pkm) => pkm.IsUntraded;
|
2018-06-09 03:10:41 +00:00
|
|
|
|
|
2018-07-02 00:07:29 +00:00
|
|
|
|
internal static bool CanInhabitGen1(this PKM pkm)
|
|
|
|
|
{
|
|
|
|
|
// Korean Gen2 games can't tradeback because there are no Gen1 Korean games released
|
|
|
|
|
if (pkm.Korean || pkm.IsEgg)
|
|
|
|
|
return false;
|
|
|
|
|
if (pkm is PK2 pk2 && pk2.CaughtData != 0)
|
|
|
|
|
return false;
|
|
|
|
|
int species = pkm.Species;
|
2018-07-10 04:59:38 +00:00
|
|
|
|
if (species > MaxSpeciesID_1 && !FutureEvolutionsGen1.Contains(species))
|
2018-07-02 00:07:29 +00:00
|
|
|
|
return false;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-30 23:31:40 +00:00
|
|
|
|
public static LanguageID GetSafeLanguage(int generation, LanguageID prefer, GameVersion game = GameVersion.Any)
|
|
|
|
|
{
|
|
|
|
|
switch (generation)
|
|
|
|
|
{
|
|
|
|
|
case 1:
|
|
|
|
|
case 2:
|
|
|
|
|
if (Languages_GB.Contains((int)prefer) && (prefer != LanguageID.Korean || game == GameVersion.C))
|
|
|
|
|
return prefer;
|
|
|
|
|
return LanguageID.English;
|
|
|
|
|
case 3:
|
2018-07-04 16:15:20 +00:00
|
|
|
|
if (Languages_3.Contains((int)prefer))
|
2018-03-30 23:31:40 +00:00
|
|
|
|
return prefer;
|
|
|
|
|
return LanguageID.English;
|
|
|
|
|
case 4:
|
|
|
|
|
case 5:
|
|
|
|
|
case 6:
|
|
|
|
|
if (Languages_46.Contains((int)prefer))
|
|
|
|
|
return prefer;
|
|
|
|
|
return LanguageID.English;
|
|
|
|
|
default:
|
|
|
|
|
if (Languages_7.Contains((int)prefer))
|
|
|
|
|
return prefer;
|
|
|
|
|
return LanguageID.English;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-05-20 17:35:58 +00:00
|
|
|
|
|
|
|
|
|
public static bool HasMetLocationUpdatedTransfer(int originalGeneration, int currentGeneration)
|
|
|
|
|
{
|
|
|
|
|
if (originalGeneration < 3)
|
|
|
|
|
return currentGeneration >= 3;
|
|
|
|
|
if (originalGeneration <= 4)
|
|
|
|
|
return currentGeneration != originalGeneration;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2018-05-26 21:40:02 +00:00
|
|
|
|
|
|
|
|
|
public static bool IsValidMissingLanguage(PKM pkm)
|
|
|
|
|
{
|
|
|
|
|
return pkm.Format == 5 && pkm.BW;
|
|
|
|
|
}
|
2018-06-23 16:49:04 +00:00
|
|
|
|
|
|
|
|
|
public static string GetG1OT_GFMew(int lang) => lang == (int)LanguageID.Japanese ? "ゲーフリ" : "GF";
|
|
|
|
|
public static string GetG5OT_NSparkle(int lang) => lang == (int)LanguageID.Japanese ? "N" : "N";
|
2016-02-23 06:52:48 +00:00
|
|
|
|
}
|
|
|
|
|
}
|