mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-26 22:10:21 +00: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:
parent
5db5f04066
commit
1d0993f852
6 changed files with 69 additions and 98 deletions
|
@ -17,10 +17,12 @@ namespace PKHeX.Core
|
|||
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 @@ namespace PKHeX.Core
|
|||
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 @@ namespace PKHeX.Core
|
|||
{
|
||||
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 @@ namespace PKHeX.Core
|
|||
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 @@ namespace PKHeX.Core
|
|||
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 @@ namespace PKHeX.Core
|
|||
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 @@ namespace PKHeX.Core
|
|||
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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue