2022-08-27 06:43:36 +00:00
using System ;
2020-08-21 23:35:49 +00:00
2022-06-18 18:04:24 +00:00
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
2020-08-21 23:35:49 +00:00
{
/// <summary>
2022-06-18 18:04:24 +00:00
/// Gets possible evolution details for the input <see cref="pk"/>
2020-08-21 23:35:49 +00:00
/// </summary>
2022-06-18 18:04:24 +00:00
/// <param name="pk">Current state of the Pokémon</param>
2023-07-06 04:14:09 +00:00
/// <param name="generation">Original Generation</param>
2022-06-18 18:04:24 +00:00
/// <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>
2023-07-06 04:14:09 +00:00
public static EvoCriteria [ ] GetOriginChain ( PKM pk , byte generation )
2020-08-21 23:35:49 +00:00
{
2023-07-06 04:14:09 +00:00
var ( minLevel , maxLevel ) = GetMinMax ( pk , generation ) ;
var origin = new EvolutionOrigin ( pk . Species , ( byte ) pk . Version , generation , minLevel , maxLevel ) ;
return EvolutionChain . GetOriginChain ( pk , origin ) ;
2022-06-18 18:04:24 +00:00
}
/// <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 )
{
2023-07-06 04:14:09 +00:00
var ( minLevel , maxLevel ) = GetMinMaxGB ( pk ) ;
2022-06-18 18:04:24 +00:00
bool rby = gameSource = = GameVersion . RBY ;
2023-07-06 04:14:09 +00:00
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 ) ;
2022-06-18 18:04:24 +00:00
}
2020-08-21 23:35:49 +00:00
2023-07-06 04:14:09 +00:00
private static ( byte minLevel , byte maxLevel ) GetMinMax ( PKM pk , byte generation )
2022-06-18 18:04:24 +00:00
{
2023-07-06 04:14:09 +00:00
byte maxLevel = ( byte ) pk . CurrentLevel ;
byte minLevel = GetLevelOriginMin ( pk , generation ) ;
return ( minLevel , maxLevel ) ;
2022-06-18 18:04:24 +00:00
}
2023-07-06 04:14:09 +00:00
private static ( byte minLevel , byte maxLevel ) GetMinMaxGB ( PKM pk )
2022-06-18 18:04:24 +00:00
{
2023-07-06 04:14:09 +00:00
byte maxLevel = ( byte ) pk . CurrentLevel ;
byte minLevel = GetLevelOriginMinGB ( pk ) ;
return ( minLevel , maxLevel ) ;
2022-06-18 18:04:24 +00:00
}
2020-08-21 23:35:49 +00:00
2023-07-06 04:14:09 +00:00
private static byte GetLevelOriginMin ( PKM pk , byte generation ) = > generation switch
2022-06-18 18:04:24 +00:00
{
2023-07-06 04:14:09 +00:00
3 = > GetLevelOriginMin3 ( pk ) ,
4 = > GetLevelOriginMin4 ( pk ) ,
_ = > Math . Max ( ( byte ) 1 , ( byte ) pk . Met_Level ) ,
} ;
2020-08-21 23:35:49 +00:00
2023-07-06 04:14:09 +00:00
private static bool IsEggLocationNonZero ( PKM pk ) = > pk . Egg_Location ! = LocationEdits . GetNoneLocation ( pk . Context ) ;
2020-08-21 23:35:49 +00:00
2023-07-06 04:14:09 +00:00
private static byte GetLevelOriginMinGB ( PKM pk )
2022-06-18 18:04:24 +00:00
{
2023-07-06 04:14:09 +00:00
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 ;
2022-06-18 18:04:24 +00:00
}
2020-08-21 23:35:49 +00:00
2023-07-06 04:14:09 +00:00
private static byte GetLevelOriginMin3 ( PKM pk )
2022-06-18 18:04:24 +00:00
{
2023-07-06 04:14:09 +00:00
const byte EggLevel = 5 ;
const byte MinWildLevel = 2 ;
if ( pk . Format ! = 3 )
return MinWildLevel ;
if ( pk . IsEgg )
return EggLevel ;
return ( byte ) pk . Met_Level ;
}
2022-06-18 18:04:24 +00:00
2023-07-06 04:14:09 +00:00
private static byte GetLevelOriginMin4 ( PKM pk )
2022-06-18 18:04:24 +00:00
{
2023-07-06 04:14:09 +00:00
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 ;
}
2020-08-21 23:35:49 +00:00
}