private static EvolutionMethod GetMethod(byte[] data, int offset) { var method = data[offset]; // other byte unnecessary int arg = BitConverter.ToUInt16(data, offset + 2); int species = BitConverter.ToUInt16(data, offset + 4); if (method == 0) { throw new ArgumentException(nameof(data)); } // To have the same structure as gen 6 // Gen 4 Method 6 is Gen 6 Method 7, G4 7 = G6 8, and so on if (method > 6) { method++; } var evo = new EvolutionMethod { Method = method, Argument = arg, Species = species, Level = arg, }; if (EvolutionSet6.EvosWithArg.Contains(method)) { evo.Level = 0; } return(evo); }
public static List <EvolutionSet> GetArray(byte[] data) { EvolutionSet[] evos = new EvolutionSet[Legal.MaxSpeciesID_3 + 1]; evos[0] = new EvolutionSet3 { PossibleEvolutions = new EvolutionMethod[0] }; for (int i = 0; i <= Legal.MaxSpeciesIndex_3; i++) { int g4species = SpeciesConverter.GetG4Species(i); if (g4species == 0) { continue; } int offset = i * 40; var m_list = new List <EvolutionMethod>(); for (int j = 0; j < 5; j++) { EvolutionMethod m = GetMethod(data, offset); if (m != null) { m_list.Add(m); } else { break; } offset += 8; } evos[g4species] = new EvolutionSet3 { PossibleEvolutions = m_list.ToArray() }; } return(evos.ToList()); }
public static List <EvolutionSet> getArray(byte[] data) { var evos = new List <EvolutionSet>(); for (int i = 0; i <= Legal.MaxSpeciesIndex_4_HGSSPt; i++) { /* 44 bytes per species, * for every species 7 evolutions with 6 bytes per evolution, * last 2 bytes of every specie is padding*/ int offset = i * 44; var m_list = new List <EvolutionMethod>(); for (int j = 0; j < 7; j++) { EvolutionMethod m = getMethod(data, offset); if (m != null) { m_list.Add(m); } else { break; } offset += 6; } evos.Add(new EvolutionSet4 { PossibleEvolutions = m_list.ToArray() }); } return(evos.ToList()); }
private static EvolutionMethod GetMethod(byte[] data, int offset) { var method = data[offset]; // other byte unnecessary int arg = BitConverter.ToUInt16(data, offset + 2); int species = BitConverter.ToUInt16(data, offset + 4); if (method == 0) { throw new ArgumentException(nameof(data)); } var evo = new EvolutionMethod { Method = method, Argument = arg, Species = species, Level = arg, }; if (EvolutionSet6.EvosWithArg.Contains(method)) { evo.Level = 0; } return(evo); }
public static List <EvolutionSet> GetArray(byte[] data) { var evos = new List <EvolutionSet>(); const int bpe = 6; // bytes per evolution entry const int entries = 7; // 7 * 6 = 42, + 2 alignment bytes const int size = 44; // bytes per species entry int count = data.Length / size; for (int i = 0; i < count; i++) { int offset = i * size; var m_list = new List <EvolutionMethod>(); for (int j = 0; j < entries; j++) { EvolutionMethod m = GetMethod(data, offset); if (m != null) { m_list.Add(m); } else { break; } offset += bpe; } evos.Add(new EvolutionSet4 { PossibleEvolutions = m_list.ToArray() }); } return(evos); }
private static EvolutionMethod GetMethod(byte[] data, int offset) { int[] argEvos = { 6, 8, 16, 17, 18, 19, 20, 21, 22 }; int method = BitConverter.ToUInt16(data, offset + 0); int arg = BitConverter.ToUInt16(data, offset + 2); int species = BitConverter.ToUInt16(data, offset + 4); if (method == 0) { return(null); } var evo = new EvolutionMethod { Method = method, Argument = arg, Species = species, Level = arg, }; if (argEvos.Contains(evo.Method)) { evo.Level = 0; } return(evo); }
public static IReadOnlyList <EvolutionMethod[]> GetArray(byte[] data, int maxSpecies) { var evos = new EvolutionMethod[maxSpecies + 1][]; int ofs = 0; const int bpe = 3; for (int i = 0; i < evos.Length; i++) { int count = data[ofs]; ofs++; if (count == 0) { evos[i] = Array.Empty <EvolutionMethod>(); continue; } var m = new EvolutionMethod[count]; for (int j = 0; j < m.Length; j++) { m[j] = GetMethod(data, ofs); ofs += bpe; } evos[i] = m; } return(evos); }
public static List <EvolutionSet> GetArray(byte[] data) { var evos = new List <EvolutionSet>(); for (int i = 0; i <= Legal.MaxSpeciesIndex_5_B2W2; i++) { /* 42 bytes per species, * for every species 7 evolutions with 6 bytes per evolution*/ int offset = i * 42; var m_list = new List <EvolutionMethod>(); for (int j = 0; j < 7; j++) { EvolutionMethod m = GetMethod(data, offset); if (m != null) { m_list.Add(m); } else { break; } offset += 6; } evos.Add(new EvolutionSet5 { PossibleEvolutions = m_list.ToArray() }); } return(evos); }
private static EvolutionMethod[] GetMethods(byte[] data) { var evos = new EvolutionMethod[data.Length / SIZE]; for (int i = 0; i < data.Length; i += SIZE) { var evo = new EvolutionMethod { Method = BitConverter.ToUInt16(data, i + 0), Argument = BitConverter.ToUInt16(data, i + 2), Species = BitConverter.ToUInt16(data, i + 4), // Copy Level = BitConverter.ToUInt16(data, i + 2), }; // Argument is used by both Level argument and Item/Move/etc. Clear if appropriate. if (EvosWithArg.Contains(evo.Method)) { evo.Level = 0; } evos[i / SIZE] = evo; } return(evos); }
public void Insert(EvolutionMethod entry) { int matchChain = -1; for (int i = 0; i < Chain.Count; i++) { if (Chain[i].StageEntryMethods.Any(e => e.Species == entry.Species)) { matchChain = i; } } if (matchChain != -1) { Chain[matchChain].StageEntryMethods.Add(entry); } else { Chain.Insert(0, new EvolutionStage { StageEntryMethods = new List <EvolutionMethod> { entry } }); } }
public EvolutionSet6(byte[] data) { if (data.Length < SIZE || data.Length % SIZE != 0) { return; } int[] argEvos = { 6, 8, 16, 17, 18, 19, 20, 21, 22, 29, 30, 31, 32, 33, 34 }; PossibleEvolutions = new EvolutionMethod[data.Length / SIZE]; for (int i = 0; i < data.Length; i += SIZE) { var evo = new EvolutionMethod { Method = BitConverter.ToUInt16(data, i + 0), Argument = BitConverter.ToUInt16(data, i + 2), Species = BitConverter.ToUInt16(data, i + 4), // Copy Level = BitConverter.ToUInt16(data, i + 2), }; // Argument is used by both Level argument and Item/Move/etc. Clear if appropriate. if (argEvos.Contains(evo.Method)) { evo.Level = 0; } PossibleEvolutions[i / SIZE] = evo; } }
private static EvolutionMethod GetMethod(byte[] data, int offset) { int[] argEvos = { 6, 8, 16, 17, 18, 19, 20, 21, 22 }; int method = BitConverter.ToUInt16(data, offset + 0); int arg = BitConverter.ToUInt16(data, offset + 2); int species = BitConverter.ToUInt16(data, offset + 4); if (method == 0) { return(null); } // To have the same estructure as gen 6 // Gen 4 Method 6 is Gen 6 Method 7, G4 7 = G6 8, and so on if (method > 6) { method++; } var evo = new EvolutionMethod { Method = method, Argument = arg, Species = species, Level = arg, }; if (argEvos.Contains(evo.Method)) { evo.Level = 0; } return(evo); }
public static IReadOnlyList <EvolutionMethod[]> GetArray(IReadOnlyList <byte[]> data) { var evos = new EvolutionMethod[data.Count][]; for (int i = 0; i < evos.Length; i++) { evos[i] = GetMethods(data[i]); } return(evos); }
private static EvolutionMethod[] GetMethods(ReadOnlySpan <byte> data) { var evos = new EvolutionMethod[data.Length / SIZE]; for (int i = 0; i < data.Length; i += SIZE) { var entry = data.Slice(i, SIZE); evos[i / SIZE] = ReadEvolution(entry); } return(evos); }
public void Insert(EvolutionMethod entry) { int matchChain = -1; for (int i = 0; i < Chain.Count; i++) { if (Chain[i].Any(e => e.Species == entry.Species)) matchChain = i; } if (matchChain != -1) Chain[matchChain].Add(entry); else Chain.Insert(0, new List<EvolutionMethod> {entry}); }
public EvolutionSet7(byte[] data) { PossibleEvolutions = new EvolutionMethod[data.Length / SIZE]; for (int i = 0; i < data.Length; i += SIZE) { PossibleEvolutions[i / SIZE] = new EvolutionMethod { Method = BitConverter.ToUInt16(data, i + 0), Argument = BitConverter.ToUInt16(data, i + 2), Species = BitConverter.ToUInt16(data, i + 4), Form = (sbyte)data[i + 6], Level = data[i + 7], }; } }
private static EvolutionMethod[] GetMethods(byte[] data) { var evos = new EvolutionMethod[data.Length / SIZE]; for (int i = 0; i < data.Length; i += SIZE) { var method = BitConverter.ToUInt16(data, i + 0); var arg = BitConverter.ToUInt16(data, i + 2); var species = BitConverter.ToUInt16(data, i + 4); var form = (sbyte)data[i + 6]; var level = data[i + 7]; evos[i / SIZE] = new EvolutionMethod(method, species, argument: arg, level: level, form: form); } return(evos); }
private static EvolutionMethod[] GetMethods(byte[] data) { var evos = new EvolutionMethod[data.Length / SIZE]; for (int i = 0; i < data.Length; i += SIZE) { evos[i / SIZE] = new EvolutionMethod { Method = BitConverter.ToUInt16(data, i + 0), Argument = BitConverter.ToUInt16(data, i + 2), Species = BitConverter.ToUInt16(data, i + 4), Form = (sbyte)data[i + 6], Level = data[i + 7], }; } return(evos); }
private static void UpdateMinValues(IReadOnlyList <EvoCriteria> dl, EvolutionMethod evo) { var last = dl[dl.Count - 1]; if (!evo.RequiresLevelUp) { // Evolutions like elemental stones, trade, etc last.MinLevel = 1; return; } if (evo.Level == 0) { // Friendship based Evolutions, Pichu -> Pikachu, Eevee -> Umbreon, etc last.MinLevel = 2; var first = dl[0]; if (dl.Count > 1 && !first.RequiresLvlUp) { first.MinLevel = 2; // Raichu from Pikachu would have a minimum level of 1; accounting for Pichu (level up required) results in a minimum level of 2 } } else // level up evolutions { last.MinLevel = evo.Level; var first = dl[0]; if (dl.Count > 1) { if (first.RequiresLvlUp) { if (first.MinLevel <= evo.Level) { first.MinLevel = evo.Level + 1; // Pokemon like Crobat, its minimum level is Golbat minimum level + 1 } } else { if (first.MinLevel < evo.Level) { first.MinLevel = evo.Level; // Pokemon like Nidoqueen who evolve with an evolution stone, minimum level is prior evolution minimum level } } } } last.RequiresLvlUp = evo.RequiresLevelUp; }
private static EvolutionMethod[] GetMethods(byte[] data) { var evos = new EvolutionMethod[data.Length / SIZE]; for (int i = 0; i < data.Length; i += SIZE) { var method = BitConverter.ToUInt16(data, i + 0); var arg = BitConverter.ToUInt16(data, i + 2); var spec = BitConverter.ToUInt16(data, i + 4); // Argument is used by both Level argument and Item/Move/etc. Clear if appropriate. var lvl = EvosWithArg.Contains(method) ? 0 : arg; evos[i / SIZE] = new EvolutionMethod(method, spec, argument: arg, level: lvl); } return(evos); }
private static EvolutionMethod GetMethod(byte[] data, int offset) { int method = data[offset]; int species = data[offset + 1]; int arg = data[offset + 2]; var obj = new EvolutionMethod { Method = method, Species = species }; if (method == 1) { obj.Level = arg; } else { obj.Argument = arg; } return(obj); }
public static IReadOnlyList <EvolutionSet> GetArray(byte[] data) { var evos = new EvolutionSet[Legal.MaxSpeciesID_3 + 1]; evos[0] = Blank; for (int i = 1; i <= Legal.MaxSpeciesIndex_3; i++) { int g4species = SpeciesConverter.GetG4Species(i); if (g4species == 0) { continue; } const int maxCount = 5; const int size = 8; int offset = i * (maxCount * size); int count = 0; for (; count < maxCount; count++) { if (data[offset + (count * size)] == 0) { break; } } if (count == 0) { evos[g4species] = Blank; continue; } var set = new EvolutionMethod[count]; for (int j = 0; j < set.Length; j++) { set[j] = GetMethod(data, offset + (j * size)); } evos[g4species] = new EvolutionSet3 { PossibleEvolutions = set }; } return(evos); }
private static void UpdateMinValues(IReadOnlyCollection <DexLevel> dl, EvolutionMethod evo) { var last = dl.Last(); if (evo.Level == 0) // Evolutions like elemental stones, trade, etc { if (!evo.RequiresLevelUp) { last.MinLevel = 1; } else { // Evolutions like frienship, pichu -> pikachu, eevee -> umbreon, etc last.MinLevel = 2; var first = dl.First(); if (dl.Count > 1 && !first.RequiresLvlUp) { first.MinLevel = 2; // Raichu from Pikachu would have minimum level 1, but with Pichu included Raichu minimum level is 2 } } } else // level up evolutions { last.MinLevel = evo.Level; var first = dl.First(); if (dl.Count > 1) { if (first.MinLevel < evo.Level && !first.RequiresLvlUp) { first.MinLevel = evo.Level; // Pokemon like Nidoqueen, its minimum level is Nidorina minimum level } if (first.MinLevel <= evo.Level && first.RequiresLvlUp) { first.MinLevel = evo.Level + 1; // Pokemon like Crobat, its minimum level is Golbat minimum level + 1 } } } last.RequiresLvlUp = evo.RequiresLevelUp; }
private void CreateLeaf(IReadOnlyList <EvolutionLineage> lineage, int i, EvolutionMethod evo) { int index = GetIndex(evo); if (index < 0) { return; } var sourceEvo = evo.Copy(i); lineage[index].Insert(sourceEvo); // If current entries has a pre-evolution, propagate to evolution as well var current = lineage[i].Chain; if (current.Count > 0) { lineage[index].Insert(current[0]); } if (index >= i) { return; } // If destination species evolves into something (ie a 'baby' Pokemon like Cleffa) // Add it to the corresponding parent chains foreach (var method in Entries[index].PossibleEvolutions) { int newIndex = GetIndex(method); if (newIndex < 0) { continue; } lineage[newIndex].Insert(sourceEvo); } }
private int GetIndex(EvolutionMethod evo) { int evolvesToSpecies = evo.Species; if (evolvesToSpecies == 0) { return(-1); } if (Personal == null) { return(evolvesToSpecies); } int evolvesToForm = evo.Form; if (evolvesToForm < 0) { evolvesToForm = 0; } return(Personal.GetFormeIndex(evolvesToSpecies, evolvesToForm)); }
private static EvolutionMethod GetMethod(byte[] data, ref int offset) { switch (data[offset]) { case 1: // Level var m1 = new EvolutionMethod { Method = 1, // Level Up Level = data[offset + 1], Species = data[offset + 2] }; offset += 3; return(m1); case 2: // Use Item var m2 = new EvolutionMethod { Method = 8, // Use Item Argument = data[offset + 1], // 1 Species = data[offset + 3], }; offset += 4; return(m2); case 3: // Trade var m3 = new EvolutionMethod { Method = 5, // Trade // 1 Species = data[offset + 2] }; offset += 3; return(m3); } return(null); }
public static IReadOnlyList <EvolutionMethod[]> GetArray(byte[] data) { const int bpe = 6; // bytes per evolution entry const int entries = 7; // amount of entries per species const int size = entries * bpe; // bytes per species entry var evos = new EvolutionMethod[data.Length / size][]; for (int i = 0; i < evos.Length; i++) { int offset = i * size; int count = 0; for (; count < entries; count++) { var methodOffset = offset + (count * bpe); var method = data[methodOffset]; if (method == 0) { break; } } if (count == 0) { evos[i] = Array.Empty <EvolutionMethod>(); continue; } var set = new EvolutionMethod[count]; for (int j = 0; j < set.Length; j++) { set[j] = GetMethod(data, offset + (j * bpe)); } evos[i] = set; } return(evos); }
public EvolutionSet6(byte[] data) { PossibleEvolutions = new EvolutionMethod[data.Length / SIZE]; for (int i = 0; i < data.Length; i += SIZE) { var evo = new EvolutionMethod { Method = BitConverter.ToUInt16(data, i + 0), Argument = BitConverter.ToUInt16(data, i + 2), Species = BitConverter.ToUInt16(data, i + 4), // Copy Level = BitConverter.ToUInt16(data, i + 2), }; // Argument is used by both Level argument and Item/Move/etc. Clear if appropriate. if (argEvos.Contains(evo.Method)) { evo.Level = 0; } PossibleEvolutions[i / SIZE] = evo; } }
private int getIndex(EvolutionMethod evo) { int evolvesToSpecies = evo.Species; if (evolvesToSpecies == 0) return -1; if (Personal == null) return evolvesToSpecies; int evolvesToForm = evo.Form; if (evolvesToForm < 0) evolvesToForm = 0; return Personal.getFormeIndex(evolvesToSpecies, evolvesToForm); }
public EvolutionSet6(byte[] data) { if (data.Length < SIZE || data.Length % SIZE != 0) return; int[] argEvos = {6, 8, 16, 17, 18, 19, 20, 21, 22, 29, 30, 31, 32, 33, 34}; PossibleEvolutions = new EvolutionMethod[data.Length / SIZE]; for (int i = 0; i < data.Length; i += SIZE) { PossibleEvolutions[i/SIZE] = new EvolutionMethod { Method = BitConverter.ToUInt16(data, i + 0), Argument = BitConverter.ToUInt16(data, i + 2), Species = BitConverter.ToUInt16(data, i + 4), // Copy Level = BitConverter.ToUInt16(data, i + 2), }; // Argument is used by both Level argument and Item/Move/etc. Clear if appropriate. if (argEvos.Contains(PossibleEvolutions[i/SIZE].Method)) PossibleEvolutions[i/SIZE].Level = 0; } }
public EvolutionSet7(byte[] data) { if (data.Length < SIZE || data.Length % SIZE != 0) return; PossibleEvolutions = new EvolutionMethod[data.Length / SIZE]; for (int i = 0; i < data.Length; i += SIZE) { PossibleEvolutions[i / SIZE] = new EvolutionMethod { Method = BitConverter.ToUInt16(data, i + 0), Argument = BitConverter.ToUInt16(data, i + 2), Species = BitConverter.ToUInt16(data, i + 4), Form = (sbyte)data[i + 6], Level = data[i + 7], }; } }
public void Insert(EvolutionMethod entry) { int matchChain = -1; for (int i = 0; i < Chain.Count; i++) if (Chain[i].StageEntryMethods.Any(e => e.Species == entry.Species)) matchChain = i; if (matchChain != -1) Chain[matchChain].StageEntryMethods.Add(entry); else Chain.Insert(0, new EvolutionStage { StageEntryMethods = new List<EvolutionMethod> {entry}}); }
private CheckResult VerifyForm(LegalityAnalysis data) { var pkm = data.pkm; var PersonalInfo = data.PersonalInfo; int count = PersonalInfo.FormCount; var form = pkm.Form; if (count <= 1 && form == 0) { return(VALID); // no forms to check } var species = pkm.Species; var enc = data.EncounterMatch; var Info = data.Info; if (!PersonalInfo.IsFormWithinRange(form) && !FormInfo.IsValidOutOfBoundsForm(species, form, Info.Generation)) { return(GetInvalid(string.Format(LFormInvalidRange, count - 1, form))); } switch (enc) { case EncounterSlot w when w.Area.Type == SlotType.FriendSafari: VerifyFormFriendSafari(data); break; case EncounterEgg e when FormInfo.IsTotemForm(species, form, e.Generation): return(GetInvalid(LFormInvalidGame)); } switch ((Species)species) { case Pikachu when Info.Generation == 6: // Cosplay bool isStatic = enc is EncounterStatic; bool validCosplay = form == (isStatic ? enc.Form : 0); if (!validCosplay) { return(GetInvalid(isStatic ? LFormPikachuCosplayInvalid : LFormPikachuCosplay)); } break; case Pikachu when Info.Generation >= 7: // Cap bool validCap = form == (enc is EncounterInvalid ? 0 : enc.Form); if (!validCap) { bool gift = enc is MysteryGift g && g.Form != form; var msg = gift ? LFormPikachuEventInvalid : LFormInvalidGame; return(GetInvalid(msg)); } break; case Unown when Info.Generation == 2 && form >= 26: return(GetInvalid(string.Format(LFormInvalidRange, "Z", form == 26 ? "!" : "?"))); case Giratina when form == 1 ^ pkm.HeldItem == 112: // Giratina, Origin form only with Griseous Orb return(GetInvalid(LFormItemInvalid)); case Arceus: { int arceus = GetArceusFormFromHeldItem(pkm.HeldItem, pkm.Format); return(arceus != form?GetInvalid(LFormItemInvalid) : GetValid(LFormItem)); } case Keldeo when pkm.Format < 8 && enc.Generation != 5: // can mismatch in gen5 via BW tutor and transfer up // can mismatch in gen8+ as the form activates in battle when knowing the move; outside of battle can be either state. bool hasSword = pkm.HasMove((int)Move.SecretSword); bool isSword = pkm.Form == 1; if (isSword != hasSword) { return(GetInvalid(LMoveKeldeoMismatch)); } break; case Genesect: { int genesect = GetGenesectFormFromHeldItem(pkm.HeldItem); return(genesect != form?GetInvalid(LFormItemInvalid) : GetValid(LFormItem)); } case Greninja: if (form > 1) // Ash Battle Bond active { return(GetInvalid(LFormBattle)); } if (form != 0 && enc is not MysteryGift) // Formes are not breedable, MysteryGift already checked { return(GetInvalid(string.Format(LFormInvalidRange, 0, form))); } break; case Scatterbug or Spewpa: if (form > 17) // Fancy & Pokéball { return(GetInvalid(LFormVivillonEventPre)); } if (pkm is not IRegionOrigin tr) { break; } if (!Vivillon3DS.IsPatternValid(form, (byte)tr.Country, (byte)tr.Region)) { data.AddLine(Get(LFormVivillonInvalid, Severity.Fishy)); } break; case Vivillon: if (form > 17) // Fancy & Pokéball { if (enc is not MysteryGift) { return(GetInvalid(LFormVivillonInvalid)); } return(GetValid(LFormVivillon)); } if (pkm is not IRegionOrigin trv) { break; } if (!Vivillon3DS.IsPatternValid(form, (byte)trv.Country, (byte)trv.Region)) { data.AddLine(Get(LFormVivillonInvalid, Severity.Fishy)); } break; case Floette when form == 5: // Floette Eternal Flower -- Never Released if (enc is not MysteryGift) { return(GetInvalid(LFormEternalInvalid)); } return(GetValid(LFormEternal)); case Meowstic when form != pkm.Gender: return(GetInvalid(LGenderInvalidNone)); case Silvally: { int silvally = GetSilvallyFormFromHeldItem(pkm.HeldItem); return(silvally != form?GetInvalid(LFormItemInvalid) : GetValid(LFormItem)); } // Form doesn't exist in SM; cannot originate from that game. case Lillipup when enc.Generation == 7 && form == 1 && pkm.SM: case Lycanroc when enc.Generation == 7 && form == 2 && pkm.SM: return(GetInvalid(LFormInvalidGame)); // Toxel encounters have already been checked for the nature-specific evolution criteria. case Toxtricity when enc.Species == (int)Toxtricity: { // The game enforces the Nature for Toxtricity encounters too! if (pkm.Form != EvolutionMethod.GetAmpLowKeyResult(pkm.Nature)) { return(GetInvalid(LFormInvalidNature)); } break; } // Impossible Egg forms case Rotom when pkm.IsEgg && form != 0: case Furfrou when pkm.IsEgg && form != 0: return(GetInvalid(LEggSpecies)); // Party Only Forms case Shaymin: case Furfrou: case Hoopa: if (form != 0 && pkm.Box > -1 && pkm.Format <= 6) // has form but stored in box { return(GetInvalid(LFormParty)); } break; } var format = pkm.Format; if (FormInfo.IsBattleOnlyForm(species, form, format)) { return(GetInvalid(LFormBattle)); } if (form == 0) { return(VALID); } // everything below here is not Form 0, so it has a form. if (format >= 7 && Info.Generation < 7) { if (species == 25 || Legal.AlolanOriginForms.Contains(species) || Legal.AlolanVariantEvolutions12.Contains(enc.Species)) { return(GetInvalid(LFormInvalidGame)); } } if (format >= 8 && Info.Generation < 8) { var orig = enc.Species; if (Legal.GalarOriginForms.Contains(species) || Legal.GalarVariantFormEvolutions.Contains(orig)) { if (species == (int)Meowth && enc.Form != 2) { // We're okay here. There's also Alolan Meowth... } else if (((Species)orig is MrMime or MimeJr) && pkm.CurrentLevel > enc.LevelMin && Info.Generation >= 4) { // We're okay with a Mime Jr. that has evolved via level up. } else if (enc.Version != GameVersion.GO) { return(GetInvalid(LFormInvalidGame)); } } }