mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-09-13 01:25:22 -05:00
Remove EvoBase, relocate functions to call sites
Utilize FormInfo to remap battle forms into hatch forms so the encounter matches something valid, and is flagged later in FormVerifier
This commit is contained in:
@@ -17,10 +17,12 @@ public static IEnumerable<EncounterEgg> GenerateEggs(PKM pkm, int generation, bo
|
||||
public static IEnumerable<EncounterEgg> GenerateEggs(PKM pkm, IReadOnlyList<EvoCriteria> chain, int generation, bool all = false)
|
||||
{
|
||||
System.Diagnostics.Debug.Assert(generation >= 3); // if generating Gen2 eggs, use the other generator.
|
||||
int species = pkm.Species;
|
||||
if (!Breeding.CanHatchAsEgg(species))
|
||||
int currentSpecies = pkm.Species;
|
||||
if (!Breeding.CanHatchAsEgg(currentSpecies))
|
||||
yield break;
|
||||
if (!Breeding.CanHatchAsEgg(species, pkm.Form, generation))
|
||||
|
||||
var currentForm = pkm.Form;
|
||||
if (!Breeding.CanHatchAsEgg(currentSpecies, currentForm, generation))
|
||||
yield break; // can't originate from eggs
|
||||
|
||||
// version is a true indicator for all generation 3-5 origins
|
||||
@@ -31,26 +33,39 @@ public static IEnumerable<EncounterEgg> GenerateEggs(PKM pkm, IReadOnlyList<EvoC
|
||||
int lvl = EggStateLegality.GetEggLevel(generation);
|
||||
int max = GetMaxSpeciesOrigin(generation);
|
||||
|
||||
var e = EvoBase.GetBaseSpecies(chain, 0);
|
||||
if (e.Species <= max && Breeding.CanHatchAsEgg(e.Species, e.Form, ver))
|
||||
var (species, form) = GetBaseSpecies(chain, 0);
|
||||
if ((uint)species <= max)
|
||||
{
|
||||
yield return new EncounterEgg(e.Species, e.Form, lvl, generation, ver);
|
||||
if (generation > 5 && (pkm.WasTradedEgg || all) && HasOtherGamePair(ver))
|
||||
yield return new EncounterEgg(e.Species, e.Form, lvl, generation, GetOtherTradePair(ver));
|
||||
// NOTE: THE SPLIT-BREED SECTION OF CODE SHOULD BE EXACTLY THE SAME AS THE BELOW SECTION
|
||||
if (FormInfo.IsBattleOnlyForm(species, form, generation))
|
||||
form = FormInfo.GetOutOfBattleForm(species, form, generation);
|
||||
if (Breeding.CanHatchAsEgg(species, form, ver))
|
||||
{
|
||||
yield return new EncounterEgg(species, form, lvl, generation, ver);
|
||||
if (generation > 5 && (pkm.WasTradedEgg || all) && HasOtherGamePair(ver))
|
||||
yield return new EncounterEgg(species, form, lvl, generation, GetOtherTradePair(ver));
|
||||
}
|
||||
}
|
||||
|
||||
if (!Breeding.GetSplitBreedGeneration(generation).Contains(species))
|
||||
if (!Breeding.GetSplitBreedGeneration(generation).Contains(currentSpecies))
|
||||
yield break; // no other possible species
|
||||
|
||||
var o = EvoBase.GetBaseSpecies(chain, 1);
|
||||
if (o.Species == e.Species)
|
||||
var otherSplit = species;
|
||||
(species, form) = GetBaseSpecies(chain, 1);
|
||||
if ((uint)species == otherSplit)
|
||||
yield break;
|
||||
|
||||
if (o.Species <= max && Breeding.CanHatchAsEgg(o.Species, o.Form, ver))
|
||||
if (species <= max)
|
||||
{
|
||||
yield return new EncounterEgg(o.Species, o.Form, lvl, generation, ver);
|
||||
if (generation > 5 && (pkm.WasTradedEgg || all) && HasOtherGamePair(ver))
|
||||
yield return new EncounterEgg(o.Species, o.Form, lvl, generation, GetOtherTradePair(ver));
|
||||
// NOTE: THIS SECTION OF CODE SHOULD BE EXACTLY THE SAME AS THE ABOVE SECTION
|
||||
if (FormInfo.IsBattleOnlyForm(species, form, generation))
|
||||
form = FormInfo.GetOutOfBattleForm(species, form, generation);
|
||||
if (Breeding.CanHatchAsEgg(species, form, ver))
|
||||
{
|
||||
yield return new EncounterEgg(species, form, lvl, generation, ver);
|
||||
if (generation > 5 && (pkm.WasTradedEgg || all) && HasOtherGamePair(ver))
|
||||
yield return new EncounterEgg(species, form, lvl, generation, GetOtherTradePair(ver));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,5 +81,19 @@ private static bool HasOtherGamePair(GameVersion ver)
|
||||
{
|
||||
return ver < GameVersion.GP; // lgpe and sw/sh don't have a sister pair
|
||||
}
|
||||
|
||||
private static (int Species, int Form) GetBaseSpecies(IReadOnlyList<EvoCriteria> evolutions, int skipOption)
|
||||
{
|
||||
int species = evolutions[0].Species;
|
||||
if (species == (int)Species.Shedinja) // Shedinja
|
||||
return ((int)Species.Nincada, 0); // Nincada
|
||||
|
||||
// skip n from end, return empty if invalid index
|
||||
int index = evolutions.Count - 1 - skipOption;
|
||||
if ((uint)index >= evolutions.Count)
|
||||
return (-1, 0);
|
||||
var evo = evolutions[index];
|
||||
return (evo.Species, evo.Form);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,14 @@
|
||||
namespace PKHeX.Core
|
||||
namespace PKHeX.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Small general purpose value passing object with misc data pertaining to an encountered Species.
|
||||
/// </summary>
|
||||
public record DexLevel(int Species, int Form) : ISpeciesForm
|
||||
{
|
||||
/// <summary>
|
||||
/// Small general purpose value passing object with misc data pertaining to an encountered Species.
|
||||
/// Maximum Level
|
||||
/// </summary>
|
||||
public class DexLevel
|
||||
{
|
||||
public readonly int Species;
|
||||
public readonly int Form;
|
||||
public int Level { get; set; }
|
||||
|
||||
public int Level { get; set; }
|
||||
|
||||
protected DexLevel(int species, int form)
|
||||
{
|
||||
Species = species;
|
||||
Form = form;
|
||||
}
|
||||
|
||||
public override string ToString() => $"{(Species) Species} [{Level}]";
|
||||
}
|
||||
}
|
||||
public override string ToString() => $"{(Species)Species}{(Form == 0 ? "" : $"-{Form}")} [{Level}]";
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Logic for determining the least-evolved species (baby/seed).
|
||||
/// </summary>
|
||||
internal static class EvoBase
|
||||
{
|
||||
internal static EvoCriteria GetBaseSpecies(PKM pkm, int skipOption = 0)
|
||||
{
|
||||
return GetBaseSpecies(pkm, -1, pkm.Format, skipOption);
|
||||
}
|
||||
|
||||
internal static EvoCriteria GetBaseSpecies(PKM pkm, int maxSpeciesOrigin, int generation, int skipOption = 0)
|
||||
{
|
||||
int tree = generation;
|
||||
var table = EvolutionTree.GetEvolutionTree(pkm, tree);
|
||||
var evos = table.GetValidPreEvolutions(pkm, maxLevel: 100, maxSpeciesOrigin: maxSpeciesOrigin, skipChecks: true);
|
||||
return GetBaseSpecies(evos, skipOption);
|
||||
}
|
||||
|
||||
private static readonly EvoCriteria Nincada = new(290, 0)
|
||||
{
|
||||
Method = (int)EvolutionType.LevelUp,
|
||||
MinLevel = 20,
|
||||
Level = 20,
|
||||
RequiresLvlUp = true,
|
||||
};
|
||||
|
||||
private static readonly EvoCriteria EvoEmpty = new(0, 0)
|
||||
{
|
||||
Method = (int)EvolutionType.None,
|
||||
};
|
||||
|
||||
internal static EvoCriteria GetBaseSpecies(IReadOnlyList<EvoCriteria> evolutions, int skipOption = 0)
|
||||
{
|
||||
int species = evolutions[0].Species;
|
||||
if (species == (int)Species.Shedinja) // Shedinja
|
||||
return Nincada; // Nincada
|
||||
|
||||
// skip n from end, return empty if invalid index
|
||||
int index = evolutions.Count - 1 - skipOption;
|
||||
return (uint)index >= evolutions.Count ? EvoEmpty : evolutions[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,12 @@
|
||||
namespace PKHeX.Core
|
||||
namespace PKHeX.Core;
|
||||
|
||||
public sealed record EvoCriteria(int Species, int Form) : DexLevel(Species, Form)
|
||||
{
|
||||
public sealed class EvoCriteria : DexLevel
|
||||
{
|
||||
public EvoCriteria(int species, int form) : base(species, form)
|
||||
{
|
||||
}
|
||||
public int MinLevel { get; set; }
|
||||
public bool RequiresLvlUp { get; set; }
|
||||
public int Method { get; init; } = -1;
|
||||
|
||||
public int MinLevel { get; set; }
|
||||
public bool RequiresLvlUp { get; set; }
|
||||
public int Method { get; init; } = -1;
|
||||
public bool IsTradeRequired => ((EvolutionType) Method).IsTrade();
|
||||
|
||||
public bool IsTradeRequired => ((EvolutionType) Method).IsTrade();
|
||||
|
||||
public override string ToString() => $"{(Species) Species}{(Form != 0 ? $"-{Form}" : "")}}} [{MinLevel},{Level}] via {(EvolutionType) Method}";
|
||||
}
|
||||
public override string ToString() => $"{(Species) Species}{(Form != 0 ? $"-{Form}" : "")}}} [{MinLevel},{Level}] via {(EvolutionType) Method}";
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ internal static int GetRequiredMoveCount(PK1 pk, IReadOnlyList<int> moves, Legal
|
||||
private static int GetRequiredMoveCount(PK1 pk, IReadOnlyList<int> moves, IReadOnlyList<int>[] learn, IReadOnlyList<int> initialmoves, int originalSpecies)
|
||||
{
|
||||
if (SpecialMinMoveSlots.Contains(pk.Species))
|
||||
return GetRequiredMoveCountSpecial(pk, moves, learn);
|
||||
return GetRequiredMoveCountSpecial(pk, moves, learn, originalSpecies);
|
||||
|
||||
// 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
|
||||
@@ -319,12 +319,12 @@ private static int GetRequiredMoveCountDecrement(PKM pk, IReadOnlyList<int> move
|
||||
return usedslots;
|
||||
}
|
||||
|
||||
private static int GetRequiredMoveCountSpecial(PKM pk, IReadOnlyList<int> moves, IReadOnlyList<int>[] learn)
|
||||
private static int GetRequiredMoveCountSpecial(PKM pk, IReadOnlyList<int> moves, IReadOnlyList<int>[] learn, int originalSpecies)
|
||||
{
|
||||
// Species with few mandatory slots, species with stone evolutions that could evolve at lower level and do not learn any more moves
|
||||
// and Pikachu and Nidoran family, those only have mandatory the initial moves and a few have one level up moves,
|
||||
// every other move could be avoided switching game or evolving
|
||||
var mandatory = GetRequiredMoveCountLevel(pk);
|
||||
var mandatory = GetRequiredMoveCountLevel(pk, originalSpecies);
|
||||
switch (pk.Species)
|
||||
{
|
||||
case (int)Exeggutor when pk.CurrentLevel >= 28: // Exeggutor
|
||||
@@ -346,10 +346,9 @@ private static int GetRequiredMoveCountSpecial(PKM pk, IReadOnlyList<int> moves,
|
||||
return mandatory.Distinct().Count(z => z != 0) + moves.Where(m => m != 0).Count(m => !mandatory.Contains(m) && learn[1].Contains(m));
|
||||
}
|
||||
|
||||
private static List<int> GetRequiredMoveCountLevel(PKM pk)
|
||||
private static List<int> GetRequiredMoveCountLevel(PKM pk, int basespecies)
|
||||
{
|
||||
int species = pk.Species;
|
||||
int basespecies = EvoBase.GetBaseSpecies(pk).Species;
|
||||
int maxlevel = 1;
|
||||
int minlevel = 1;
|
||||
|
||||
|
||||
@@ -107,7 +107,9 @@ private void SetSpeciesValues(int value)
|
||||
if (value == (int)Core.Species.Pikachu && rate == 0xA3) // Light Ball (starter)
|
||||
return;
|
||||
|
||||
int baseSpecies = EvoBase.GetBaseSpecies(this).Species;
|
||||
var table = EvolutionTree.GetEvolutionTree(1);
|
||||
var evos = table.GetValidPreEvolutions(this, maxLevel: 100, maxSpeciesOrigin: -1, skipChecks: true);
|
||||
var baseSpecies = evos[^1].Species;
|
||||
if (IsCatchRatePreEvolutionRate(baseSpecies, value, rate))
|
||||
return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user