internal static int GetBaseSpecies(PKM pkm, int skipOption = 0, int generation = -1) { int tree = generation != -1 ? generation : pkm.Format; var table = EvolutionTree.GetEvolutionTree(pkm, tree); int maxSpeciesOrigin = generation != -1 ? GetMaxSpeciesOrigin(generation) : -1; var evos = table.GetValidPreEvolutions(pkm, maxLevel: 100, maxSpeciesOrigin: maxSpeciesOrigin, skipChecks: true); return(GetBaseSpecies(pkm, evos, skipOption)); }
/// <summary> /// Gets possible encounters that allow all moves requested to be learned. /// </summary> /// <param name="pk">Rough Pokémon data which contains the requested species, gender, and form.</param> /// <param name="moves">Moves that the resulting <see cref="IEncounterable"/> must be able to learn.</param> /// <param name="version">Specific version to iterate for.</param> /// <returns>A consumable <see cref="IEncounterable"/> list of possible encounters.</returns> public static IEnumerable <IEncounterable> GenerateVersionEncounters(PKM pk, IEnumerable <int> moves, GameVersion version) { pk.Version = (int)version; var et = EvolutionTree.GetEvolutionTree(pk.Format); var dl = et.GetValidPreEvolutions(pk, maxLevel: 100, skipChecks: true); int[] needs = GetNeededMoves(pk, moves, dl); return(PriorityList.SelectMany(type => GetPossibleOfType(pk, needs, version, type))); }
/// <summary> /// Gets possible encounters that allow all moves requested to be learned. /// </summary> /// <param name="pk">Rough Pokémon data which contains the requested species, gender, and form.</param> /// <param name="moves">Moves that the resulting <see cref="IEncounterable"/> must be able to learn.</param> /// <param name="version">Specific version to iterate for.</param> /// <returns>A consumable <see cref="IEncounterable"/> list of possible encounters.</returns> public static IEnumerable <IEncounterable> GenerateVersionEncounters(PKM pk, IEnumerable <int> moves, GameVersion version) { pk.Version = (int)version; var et = EvolutionTree.GetEvolutionTree(pk, pk.Species <= Legal.MaxSpeciesID_7_USUM ? 7 : PKX.Generation); // temp workaround as G8 doesn't have all evolutions var dl = et.GetValidPreEvolutions(pk, maxLevel: 100, skipChecks: true); int[] needs = GetNeededMoves(pk, moves, dl); return(PriorityList.SelectMany(type => GetPossibleOfType(pk, needs, version, type))); }
/// <summary> /// Gets possible encounters that allow all moves requested to be learned. /// </summary> /// <param name="pk">Rough Pokémon data which contains the requested species, gender, and form.</param> /// <param name="moves">Moves that the resulting <see cref="IEncounterable"/> must be able to learn.</param> /// <param name="version">Specific version to iterate for.</param> /// <returns>A consumable <see cref="IEncounterable"/> list of possible encounters.</returns> public static IEnumerable <IEncounterable> GenerateVersionEncounters(PKM pk, IEnumerable <int> moves, GameVersion version) { pk.Version = (int)version; var et = EvolutionTree.GetEvolutionTree(PKX.Generation); var dl = et.GetValidPreEvolutions(pk, maxLevel: 100, skipChecks: true); int[] needs = GetNeededMoves(pk, moves, dl); foreach (var enc in GetPossible(pk, needs, version)) { yield return(enc); } }
/// <summary> /// Gets an enumerable list of species IDs from the possible lineage of the <see cref="pkm"/> based on its current format. /// </summary> /// <param name="pkm">Pokémon to fetch the lineage for.</param> internal static IEnumerable <int> GetLineage(PKM pkm) { if (pkm.IsEgg) { return new[] { pkm.Species } } ; var table = EvolutionTree.GetEvolutionTree(pkm.Format); var lineage = table.GetValidPreEvolutions(pkm, maxLevel: pkm.CurrentLevel); return(lineage.Select(evolution => evolution.Species)); } }
/// <summary> /// Gets possible encounters that allow all moves requested to be learned. /// </summary> /// <param name="pk">Rough Pokémon data which contains the requested species, gender, and form.</param> /// <param name="moves">Moves that the resulting <see cref="IEncounterable"/> must be able to learn.</param> /// <param name="version">Specific version to iterate for.</param> /// <returns>A consumable <see cref="IEncounterable"/> list of possible encounters.</returns> public static IEnumerable <IEncounterable> GenerateVersionEncounters(PKM pk, IEnumerable <int> moves, GameVersion version) { pk.Version = (int)version; if (version == GameVersion.GO && pk.Format >= 8) { pk.Met_Location = Locations.GO8; // needed to yield the GO->HOME table instead of GO->LGPE. HOME is a superset of LGPE's possible encounters. } var et = EvolutionTree.GetEvolutionTree(pk.Format); var chain = et.GetValidPreEvolutions(pk, maxLevel: 100, skipChecks: true); int[] needs = GetNeededMoves(pk, moves, chain); return(PriorityList.SelectMany(type => GetPossibleOfType(pk, needs, version, type, chain))); }
/// <summary> /// Gets possible encounters that allow all moves requested to be learned. /// </summary> /// <param name="pk">Rough Pokémon data which contains the requested species, gender, and form.</param> /// <param name="moves">Moves that the resulting <see cref="IEncounterable"/> must be able to learn.</param> /// <param name="version">Specific version to iterate for.</param> /// <returns>A consumable <see cref="IEncounterable"/> list of possible encounters.</returns> public static IEnumerable <IEncounterable> GenerateVersionEncounters(PKM pk, IEnumerable <int> moves, GameVersion version) { pk.Version = (int)version; var et = EvolutionTree.GetEvolutionTree(PKX.Generation); var dl = et.GetValidPreEvolutions(pk, maxLevel: 100, skipChecks: true); var gens = VerifyCurrentMoves.GetGenMovesCheckOrder(pk); var canlearn = gens.SelectMany(z => Legal.GetValidMoves(pk, dl, z)); var needs = moves.Except(canlearn).ToArray(); foreach (var enc in GetPossible(pk, needs, version)) { yield return(enc); } }
static EvolutionTree() { // Evolution tables need Personal Tables initialized beforehand, hence why the EvolutionTree data is initialized here. byte[] get(string resource) => Util.GetBinaryResource($"evos_{resource}.pkl"); byte[][] unpack(string resource) => Data.UnpackMini(get(resource), resource); Evolves1 = new EvolutionTree(new[] { get("rby") }, GameVersion.RBY, PersonalTable.Y, Legal.MaxSpeciesID_1); Evolves2 = new EvolutionTree(new[] { get("gsc") }, GameVersion.GSC, PersonalTable.C, Legal.MaxSpeciesID_2); Evolves3 = new EvolutionTree(new[] { get("g3") }, GameVersion.RS, PersonalTable.RS, Legal.MaxSpeciesID_3); Evolves4 = new EvolutionTree(new[] { get("g4") }, GameVersion.DP, PersonalTable.DP, Legal.MaxSpeciesID_4); Evolves5 = new EvolutionTree(new[] { get("g5") }, GameVersion.BW, PersonalTable.BW, Legal.MaxSpeciesID_5); Evolves6 = new EvolutionTree(unpack("ao"), GameVersion.ORAS, PersonalTable.AO, Legal.MaxSpeciesID_6); Evolves7 = new EvolutionTree(unpack("sm"), GameVersion.SM, PersonalTable.SM, Legal.MaxSpeciesID_7); }
/// <summary> /// Gets possible encounters that allow all moves requested to be learned. /// </summary> /// <param name="pk">Rough Pokémon data which contains the requested species, gender, and form.</param> /// <param name="moves">Moves that the resulting <see cref="IEncounterable"/> must be able to learn.</param> /// <param name="version">Specific version to iterate for.</param> /// <returns>A consumable <see cref="IEncounterable"/> list of possible encounters.</returns> public static IEnumerable <IEncounterable> GenerateVersionEncounters(PKM pk, IEnumerable <int> moves, GameVersion version) { pk.Version = (int)version; var format = pk.Format; if (format is 2 && version is GameVersion.RD or GameVersion.GN or GameVersion.BU or GameVersion.YW) { format = 1; // try excluding baby pokemon from our evolution chain, for move learning purposes. } var et = EvolutionTree.GetEvolutionTree(format); var chain = et.GetValidPreEvolutions(pk, maxLevel: 100, skipChecks: true); int[] needs = GetNeededMoves(pk, moves, chain); return(PriorityList.SelectMany(type => GetPossibleOfType(pk, needs, version, type, chain))); }
internal static List <EvoCriteria> GetValidPreEvolutions(PKM pkm, int maxspeciesorigin = -1, int lvl = -1, int minLevel = 1, bool skipChecks = false) { if (lvl < 0) { lvl = pkm.CurrentLevel; } if (maxspeciesorigin == -1 && pkm.InhabitedGeneration(2) && pkm.Format <= 2 && pkm.GenNumber == 1) { maxspeciesorigin = MaxSpeciesID_2; } int tree = Math.Max(2, pkm.Format); var et = EvolutionTree.GetEvolutionTree(pkm, tree); return(et.GetValidPreEvolutions(pkm, maxLevel: lvl, maxSpeciesOrigin: maxspeciesorigin, skipChecks: skipChecks, minLevel: minLevel)); }
private static int GetDexSizeOffset(DexSizeType group, int index) => 0x3978 + (index * 6) + ((int)group * 0x45C); // blockofs + 0xF78 + ([186*6]*n) + x*6 private void SetSizeData(PB7 pkm, DexSizeType group) { var tree = EvolutionTree.GetEvolutionTree(pkm, 7); int species = pkm.Species; int form = pkm.AltForm; int height = pkm.HeightScalar; int weight = pkm.WeightScalar; // update for all species in potential lineage var allspec = tree.GetEvolutionsAndPreEvolutions(species, form); foreach (var s in allspec) { SetSizeData(group, s, form, height, weight); } }
static EvolutionTree() { // Evolution tables need Personal Tables initialized beforehand, hence why the EvolutionTree data is initialized here. byte[] get(string resource) => Util.GetBinaryResource($"evos_{resource}.pkl"); byte[][] unpack(string resource) => Data.UnpackMini(get(resource), resource); Evolves1 = new EvolutionTree(new[] { get("rby") }, GameVersion.Gen1, PersonalTable.Y, Legal.MaxSpeciesID_1); Evolves2 = new EvolutionTree(new[] { get("gsc") }, GameVersion.Gen2, PersonalTable.C, Legal.MaxSpeciesID_2); Evolves3 = new EvolutionTree(new[] { get("g3") }, GameVersion.Gen3, PersonalTable.RS, Legal.MaxSpeciesID_3); Evolves4 = new EvolutionTree(new[] { get("g4") }, GameVersion.Gen4, PersonalTable.DP, Legal.MaxSpeciesID_4); Evolves5 = new EvolutionTree(new[] { get("g5") }, GameVersion.Gen5, PersonalTable.BW, Legal.MaxSpeciesID_5); Evolves6 = new EvolutionTree(unpack("ao"), GameVersion.Gen6, PersonalTable.AO, Legal.MaxSpeciesID_6); Evolves7 = new EvolutionTree(unpack("uu"), GameVersion.Gen7, PersonalTable.USUM, Legal.MaxSpeciesID_7_USUM); // There's always oddballs. Evolves7.FixEvoTreeSM(); }
internal static List <EvoCriteria> GetValidPreEvolutions(PKM pkm, int maxspeciesorigin = -1, int lvl = -1, int minLevel = 1, bool skipChecks = false) { if (lvl < 0) { lvl = pkm.CurrentLevel; } if (pkm.IsEgg && !skipChecks) { return(new List <EvoCriteria>(1) { new EvoCriteria(pkm.Species, pkm.AltForm) { Level = lvl, MinLevel = lvl }, }); } // Shedinja's evolution case can be a little tricky; hard-code handling. if (pkm.Species == (int)Species.Shedinja && lvl >= 20 && (!pkm.HasOriginalMetLocation || pkm.Met_Level + 1 <= lvl)) { return(new List <EvoCriteria>(2) { new EvoCriteria((int)Species.Shedinja, 0) { Level = lvl, MinLevel = 20 }, new EvoCriteria((int)Species.Nincada, 0) { Level = lvl, MinLevel = 1 }, }); } if (maxspeciesorigin == -1 && pkm.InhabitedGeneration(2) && pkm.Format <= 2 && pkm.GenNumber == 1) { maxspeciesorigin = MaxSpeciesID_2; } int tree = Math.Max(2, pkm.Format); var et = EvolutionTree.GetEvolutionTree(pkm, tree); return(et.GetValidPreEvolutions(pkm, maxLevel: lvl, maxSpeciesOrigin: maxspeciesorigin, skipChecks: skipChecks, minLevel: minLevel)); }
/// <summary> /// Gets possible encounters that allow all moves requested to be learned. /// </summary> /// <param name="pk">Rough Pokémon data which contains the requested species, gender, and form.</param> /// <param name="moves">Moves that the resulting <see cref="IEncounterable"/> must be able to learn.</param> /// <param name="version">Specific version to iterate for.</param> /// <returns>A consumable <see cref="IEncounterable"/> list of possible encounters.</returns> public static IEnumerable <IEncounterable> GenerateVersionEncounters(PKM pk, IEnumerable <int> moves, GameVersion version) { if (pk.Species == 0) // can enter this method after failing to set a species ID that cannot exist in the format { return(Array.Empty <IEncounterable>()); } pk.Version = (int)version; var format = pk.Format; if (format is 2 && version is GameVersion.RD or GameVersion.GN or GameVersion.BU or GameVersion.YW) { format = 1; // try excluding baby pokemon from our evolution chain, for move learning purposes. } var et = EvolutionTree.GetEvolutionTree(pk, format); var chain = et.GetValidPreEvolutions(pk, maxLevel: 100, skipChecks: true); int[] needs = GetNeededMoves(pk, moves, chain); return(PriorityList.SelectMany(type => GetPossibleOfType(pk, needs, version, type, chain))); }
public static int GetLowestLevel(PKM pkm, int startLevel) { if (startLevel == -1) { startLevel = 100; } var table = EvolutionTree.GetEvolutionTree(pkm.Format); int count = 1; for (int i = 100; i >= startLevel; i--) { var evos = table.GetValidPreEvolutions(pkm, maxLevel: i, minLevel: startLevel, skipChecks: true); if (evos.Count < count) // lost an evolution, prior level was minimum current level { return(evos.Max(evo => evo.Level) + 1); } count = evos.Count; } return(startLevel); }
internal static List <EvoCriteria> GetValidPreEvolutions(PKM pkm, int maxspeciesorigin = -1, int lvl = -1, bool skipChecks = false) { if (lvl < 0) { lvl = pkm.CurrentLevel; } if (pkm.IsEgg && !skipChecks) { return new List <EvoCriteria> { new EvoCriteria { Species = pkm.Species, Level = lvl, MinLevel = lvl }, } } ; if (pkm.Species == 292 && lvl >= 20 && (!pkm.HasOriginalMetLocation || pkm.Met_Level + 1 <= lvl)) { return new List <EvoCriteria> { new EvoCriteria { Species = 292, Level = lvl, MinLevel = 20 }, new EvoCriteria { Species = 290, Level = pkm.GenNumber < 5 ? lvl : lvl - 1, MinLevel = 1 } // Shedinja spawns after evolving, which is after level up moves were prompted. Not for future generations. } } ; if (maxspeciesorigin == -1 && pkm.InhabitedGeneration(2) && pkm.Format <= 2 && pkm.GenNumber == 1) { maxspeciesorigin = MaxSpeciesID_2; } int tree = maxspeciesorigin == MaxSpeciesID_2 ? 2 : pkm.Format; var et = EvolutionTree.GetEvolutionTree(tree); return(et.GetValidPreEvolutions(pkm, maxLevel: lvl, maxSpeciesOrigin: maxspeciesorigin, skipChecks: skipChecks)); }
static Legal() // Setup { // Gen 6 { StaticX = getStaticEncounters(GameVersion.X); StaticY = getStaticEncounters(GameVersion.Y); StaticA = getStaticEncounters(GameVersion.AS); StaticO = getStaticEncounters(GameVersion.OR); var XSlots = getEncounterTables(GameVersion.X); var YSlots = getEncounterTables(GameVersion.Y); MarkG6XYSlots(ref XSlots); MarkG6XYSlots(ref YSlots); SlotsX = addExtraTableSlots(XSlots, SlotsXYAlt); SlotsY = addExtraTableSlots(YSlots, SlotsXYAlt); SlotsA = getEncounterTables(GameVersion.AS); SlotsO = getEncounterTables(GameVersion.OR); MarkG6AOSlots(ref SlotsA); MarkG6AOSlots(ref SlotsO); Evolves6 = new EvolutionTree(Data.unpackMini(Properties.Resources.evos_ao, "ao"), GameVersion.ORAS, PersonalTable.AO, 721); } // Gen 7 { StaticSN = getStaticEncounters(GameVersion.SN); StaticMN = getStaticEncounters(GameVersion.MN); var REG_SN = getEncounterTables(GameVersion.SN); var REG_MN = getEncounterTables(GameVersion.MN); var SOS_SN = getEncounterTables(Properties.Resources.encounter_sn_sos, "sm"); var SOS_MN = getEncounterTables(Properties.Resources.encounter_mn_sos, "sm"); MarkG7SMSlots(ref SOS_SN); MarkG7SMSlots(ref SOS_MN); SlotsSN = addExtraTableSlots(REG_SN, SOS_SN).Concat(Encounter_SM_Pelago).ToArray(); SlotsMN = addExtraTableSlots(REG_MN, SOS_MN).Concat(Encounter_SM_Pelago).ToArray(); Evolves7 = new EvolutionTree(Data.unpackMini(Properties.Resources.evos_sm, "sm"), GameVersion.SM, PersonalTable.SM, 802); } }
internal static List <EvoCriteria> GetValidPreEvolutions(PKM pkm, int maxspeciesorigin = -1, int lvl = -1, int minLevel = 1, bool skipChecks = false) { if (lvl < 0) { lvl = pkm.CurrentLevel; } if (pkm.IsEgg && !skipChecks) { return(new List <EvoCriteria>(1) { new EvoCriteria { Species = pkm.Species, Level = lvl, MinLevel = lvl }, }); } if (pkm.Species == 292 && lvl >= 20 && (!pkm.HasOriginalMetLocation || pkm.Met_Level + 1 <= lvl)) { return(new List <EvoCriteria>(2) { new EvoCriteria { Species = 292, Level = lvl, MinLevel = 20 }, new EvoCriteria { Species = 290, Level = lvl, MinLevel = 1 } }); } if (maxspeciesorigin == -1 && pkm.InhabitedGeneration(2) && pkm.Format <= 2 && pkm.GenNumber == 1) { maxspeciesorigin = MaxSpeciesID_2; } int tree = maxspeciesorigin == MaxSpeciesID_2 ? 2 : pkm.Format; var et = EvolutionTree.GetEvolutionTree(pkm, tree); return(et.GetValidPreEvolutions(pkm, maxLevel: lvl, maxSpeciesOrigin: maxspeciesorigin, skipChecks: skipChecks, minLevel: minLevel)); }