mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-23 20:43:07 +00:00
dcc0e79435
Like move validation, evolutions are the earliest thing we wish to traverse when determining what encounters may have originated the current Pokémon. To determine the permitted species-form-levels a Pokémon could originate with, we must devolve a Pokémon by traveling down-generation to origin. Once we have an encounter, we can then evolve it to the current species, traversing upwards from origin to the current format.
95 lines
3.6 KiB
C#
95 lines
3.6 KiB
C#
using System;
|
|
|
|
namespace PKHeX.Core;
|
|
|
|
/// <summary>
|
|
/// Contains logic that calculates the evolution chain of a <see cref="PKM"/>, only considering the generation it originated in.
|
|
/// </summary>
|
|
public static class EncounterOrigin
|
|
{
|
|
/// <summary>
|
|
/// Gets possible evolution details for the input <see cref="pk"/>
|
|
/// </summary>
|
|
/// <param name="pk">Current state of the Pokémon</param>
|
|
/// <param name="generation">Original Generation</param>
|
|
/// <returns>Possible origin species-form-levels to match against encounter data.</returns>
|
|
/// <remarks>Use <see cref="GetOriginChain12"/> if the <see cref="pk"/> originated from Generation 1 or 2.</remarks>
|
|
public static EvoCriteria[] GetOriginChain(PKM pk, byte generation)
|
|
{
|
|
var (minLevel, maxLevel) = GetMinMax(pk, generation);
|
|
var origin = new EvolutionOrigin(pk.Species, (byte)pk.Version, generation, minLevel, maxLevel);
|
|
return EvolutionChain.GetOriginChain(pk, origin);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets possible evolution details for the input <see cref="pk"/> originating from Generation 1 or 2.
|
|
/// </summary>
|
|
/// <param name="pk">Current state of the Pokémon</param>
|
|
/// <param name="gameSource">Game/group the <see cref="pk"/> originated from. If <see cref="GameVersion.RBY"/>, it assumes Gen 1, otherwise Gen 2.</param>
|
|
/// <returns>Possible origin species-form-levels to match against encounter data.</returns>
|
|
public static EvoCriteria[] GetOriginChain12(PKM pk, GameVersion gameSource)
|
|
{
|
|
var (minLevel, maxLevel) = GetMinMaxGB(pk);
|
|
bool rby = gameSource == GameVersion.RBY;
|
|
byte ver = rby ? (byte)GameVersion.RBY : (byte)GameVersion.GSC;
|
|
byte gen = rby ? (byte)1 : (byte)2;
|
|
var origin = new EvolutionOrigin(pk.Species, ver, gen, minLevel, maxLevel);
|
|
return EvolutionChain.GetOriginChain(pk, origin);
|
|
}
|
|
|
|
private static (byte minLevel, byte maxLevel) GetMinMax(PKM pk, byte generation)
|
|
{
|
|
byte maxLevel = (byte)pk.CurrentLevel;
|
|
byte minLevel = GetLevelOriginMin(pk, generation);
|
|
return (minLevel, maxLevel);
|
|
}
|
|
|
|
private static (byte minLevel, byte maxLevel) GetMinMaxGB(PKM pk)
|
|
{
|
|
byte maxLevel = (byte)pk.CurrentLevel;
|
|
byte minLevel = GetLevelOriginMinGB(pk);
|
|
return (minLevel, maxLevel);
|
|
}
|
|
|
|
private static byte GetLevelOriginMin(PKM pk, byte generation) => generation switch
|
|
{
|
|
3 => GetLevelOriginMin3(pk),
|
|
4 => GetLevelOriginMin4(pk),
|
|
_ => Math.Max((byte)1, (byte)pk.Met_Level),
|
|
};
|
|
|
|
private static bool IsEggLocationNonZero(PKM pk) => pk.Egg_Location != LocationEdits.GetNoneLocation(pk.Context);
|
|
|
|
private static byte GetLevelOriginMinGB(PKM pk)
|
|
{
|
|
const byte EggLevel = 5;
|
|
const byte MinWildLevel = 2;
|
|
if (pk.IsEgg)
|
|
return EggLevel;
|
|
if (pk is not ICaughtData2 { CaughtData: not 0 } pk2)
|
|
return MinWildLevel;
|
|
return (byte)pk2.Met_Level;
|
|
}
|
|
|
|
private static byte GetLevelOriginMin3(PKM pk)
|
|
{
|
|
const byte EggLevel = 5;
|
|
const byte MinWildLevel = 2;
|
|
if (pk.Format != 3)
|
|
return MinWildLevel;
|
|
if (pk.IsEgg)
|
|
return EggLevel;
|
|
return (byte)pk.Met_Level;
|
|
}
|
|
|
|
private static byte GetLevelOriginMin4(PKM pk)
|
|
{
|
|
const byte EggLevel = 1;
|
|
const byte MinWildLevel = 2;
|
|
if (pk.Format != 4)
|
|
return IsEggLocationNonZero(pk) ? EggLevel : MinWildLevel;
|
|
if (pk.IsEgg || IsEggLocationNonZero(pk))
|
|
return EggLevel;
|
|
return (byte)pk.Met_Level;
|
|
}
|
|
}
|