From ce667729f3c2fd6c9c7db98959c7d3c002f02e30 Mon Sep 17 00:00:00 2001 From: Kurt Date: Wed, 20 Jun 2018 21:38:56 -0700 Subject: [PATCH] More simplifications Can't have species == 0 or invalid gameversion; check for EncounterInvalid instead. Egg chain is always valid (since it is not EncounterInvalid) thus always provide the chain. Since these 2 are the same, simplify the logic to be shared. rearrange some parameters for easier flow --- .../Legality/Evolutions/EvolutionChain.cs | 64 +++++++++---------- 1 file changed, 30 insertions(+), 34 deletions(-) diff --git a/PKHeX.Core/Legality/Evolutions/EvolutionChain.cs b/PKHeX.Core/Legality/Evolutions/EvolutionChain.cs index 30788f95c..defa89dee 100644 --- a/PKHeX.Core/Legality/Evolutions/EvolutionChain.cs +++ b/PKHeX.Core/Legality/Evolutions/EvolutionChain.cs @@ -11,44 +11,44 @@ public static class EvolutionChain private static readonly EvoCriteria[] NONE = new EvoCriteria[0]; internal static EvoCriteria[][] GetEvolutionChainsAllGens(PKM pkm, IEncounterable Encounter) { - var CompleteEvoChain = GetEvolutionChain(pkm, Encounter); - int maxgen = !pkm.Gen1_NotTradeback && pkm.Format == 1 ? 2 : pkm.Format; - int mingen = !pkm.Gen2_NotTradeback && (pkm.Format == 2 || pkm.VC2) ? 1 : pkm.GenNumber; + var CompleteEvoChain = GetEvolutionChain(pkm, Encounter, pkm.Species, pkm.CurrentLevel); + if (Encounter is EncounterInvalid || pkm.IsEgg) + return GetChainSingle(pkm, CompleteEvoChain); + return GetChainAll(pkm, Encounter, CompleteEvoChain); + } + + private static EvoCriteria[][] GetChainBase(int maxgen) + { var GensEvoChains = new EvoCriteria[maxgen + 1][]; for (int i = 0; i <= maxgen; i++) GensEvoChains[i] = NONE; // default no-evolutions - - if (pkm.Species == 0 || pkm.Format > 2 && pkm.GenU) - { - // Illegal origin or empty pokemon, return only chain for current format - GensEvoChains[pkm.Format] = CompleteEvoChain; - return GensEvoChains; - } - - if (pkm.IsEgg) - { - // Skip the other checks and just return the evo chain for the Format; contains only the pokemon inside the egg - int gen = pkm.Format; - if (GetMaxSpeciesOrigin(gen) >= pkm.Species) - GensEvoChains[gen] = CompleteEvoChain; - return GensEvoChains; - } - - return TrimEvoChain(pkm, Encounter, CompleteEvoChain, maxgen, mingen, GensEvoChains); + return GensEvoChains; } - private static EvoCriteria[][] TrimEvoChain(PKM pkm, IEncounterable Encounter, EvoCriteria[] CompleteEvoChain, int maxgen, int mingen, EvoCriteria[][] GensEvoChains) + + private static EvoCriteria[][] GetChainSingle(PKM pkm, EvoCriteria[] CompleteEvoChain) { - int lvl = pkm.CurrentLevel; - int maxLevel = lvl; - int pkGen = pkm.GenNumber; + var chain = GetChainBase(pkm.Format); + chain[pkm.Format] = CompleteEvoChain; + return chain; + } + + private static EvoCriteria[][] GetChainAll(PKM pkm, IEncounterable Encounter, IEnumerable CompleteEvoChain) + { + int maxgen = pkm is PK1 && !pkm.Gen1_NotTradeback ? 2 : pkm.Format; + var GensEvoChains = GetChainBase(maxgen); var queue = new Queue(CompleteEvoChain); var mostEvolved = queue.Dequeue(); + int lvl = pkm.CurrentLevel; + int maxLevel = lvl; + int pkGen = pkm.GenNumber; + // Iterate generations backwards // Maximum level of an earlier generation (GenX) will never be greater than a later generation (GenX+Y). - for (int g = maxgen; g >= mingen; g--) + int mingen = (pkm is PK2 || pkm.VC2) && !pkm.Gen2_NotTradeback ? 1 : pkGen; + for (int g = GensEvoChains.Length - 1; g >= mingen; g--) { if (pkGen == 1 && pkm.Gen1_NotTradeback && g == 2) continue; @@ -67,6 +67,8 @@ private static EvoCriteria[][] TrimEvoChain(PKM pkm, IEncounterable Encounter, E // If the pokemon origin is illegal (e.g. Gen3 Infernape) the list will be emptied -- species lineage did not exist at any evolution stage. while (mostEvolved.Species > maxspeciesgen) { + if (queue.Count == 1) + return GensEvoChains; if (mostEvolved.RequiresLvlUp) { // Eevee requires a single levelup to be Sylveon, it can be deduced in gen 5 and before it existed with maximum one level below current @@ -83,8 +85,6 @@ private static EvoCriteria[][] TrimEvoChain(PKM pkm, IEncounterable Encounter, E else if (g == 1 && pkm.Format == 2 && lvl == maxLevel) lvl--; } - if (queue.Count == 1) - break; mostEvolved = queue.Dequeue(); } @@ -124,10 +124,10 @@ private static EvoCriteria[][] TrimEvoChain(PKM pkm, IEncounterable Encounter, E // Remove generation 2 pre-evolutions GensEvoChains[1] = GensEvoChains[1].Take(GensEvoChains[1].Length - 1).ToArray(); if (!pkm.VC1) - continue; + return GensEvoChains; // Remove generation 2 pre-evolutions from gen 7 and future generations - for (int fgen = 7; fgen <= maxgen; fgen++) + for (int fgen = 7; fgen < GensEvoChains.Length; fgen++) { var chain = GensEvoChains[fgen]; var g1Index = Array.FindIndex(chain, e => e.Species <= MaxSpeciesID_1); @@ -141,10 +141,6 @@ private static EvoCriteria[][] TrimEvoChain(PKM pkm, IEncounterable Encounter, E } return GensEvoChains; } - private static EvoCriteria[] GetEvolutionChain(PKM pkm, IEncounterable Encounter) - { - return GetEvolutionChain(pkm, Encounter, pkm.Species, 100); - } private static EvoCriteria[] GetEvolutionChain(PKM pkm, IEncounterable Encounter, int maxspec, int maxlevel) { var vs = GetValidPreEvolutions(pkm).ToArray();