2021-01-01 23:01:22 +00:00
using static PKHeX . Core . GameVersion ;
using static PKHeX . Core . Species ;
2020-12-08 04:54:55 +00:00
2022-06-18 18:04:24 +00:00
namespace PKHeX.Core ;
/// <summary>
/// Logic related to breeding.
/// </summary>
public static class Breeding
2020-12-08 04:54:55 +00:00
{
/// <summary>
2022-06-18 18:04:24 +00:00
/// Checks if the game has a Daycare, and returns true if it does.
/// </summary>
/// <param name="game">Version ID to check for.</param>
2023-07-08 19:46:46 +00:00
public static bool CanGameGenerateEggs ( GameVersion game ) = > game switch
2022-06-18 18:04:24 +00:00
{
2023-07-08 19:46:46 +00:00
R or S or E or FR or LG = > true ,
D or P or Pt or HG or SS = > true ,
B or W or B2 or W2 = > true ,
X or Y or OR or AS = > true ,
SN or MN or US or UM = > true ,
GD or SI or C = > true ,
SW or SH or BD or SP = > true ,
SL or VL = > true ,
GS = > true ,
_ = > false ,
2022-06-18 18:04:24 +00:00
} ;
/// <summary>
/// Species that have special handling for breeding.
/// </summary>
2023-07-08 19:46:46 +00:00
private static bool IsMixedGenderBreed ( ushort species ) = > species switch
2022-06-18 18:04:24 +00:00
{
2023-07-08 19:46:46 +00:00
( int ) NidoranF = > true ,
( int ) NidoranM = > true ,
( int ) Volbeat = > true ,
( int ) Illumise = > true ,
2022-06-18 18:04:24 +00:00
2023-07-08 19:46:46 +00:00
( int ) Indeedee = > true , // male/female
2022-06-18 18:04:24 +00:00
2023-07-08 19:46:46 +00:00
_ = > false ,
2022-06-18 18:04:24 +00:00
} ;
/// <summary>
/// Checks if the <see cref="species"/> can be born with inherited moves from the parents.
/// </summary>
/// <param name="species">Entity species ID</param>
/// <returns>True if can inherit moves, false if cannot.</returns>
2022-08-27 06:43:36 +00:00
internal static bool GetCanInheritMoves ( ushort species )
2022-06-18 18:04:24 +00:00
{
var pi = PKX . Personal [ species ] ;
2023-01-22 04:02:33 +00:00
if ( pi is { Genderless : false , OnlyMale : false } )
2022-06-18 18:04:24 +00:00
return true ;
2023-07-08 19:46:46 +00:00
if ( IsMixedGenderBreed ( species ) )
2022-06-18 18:04:24 +00:00
return true ;
return false ;
}
/// <summary>
/// Species that can yield a different baby species when bred.
/// </summary>
2023-07-08 19:46:46 +00:00
public static bool IsSplitBreedNotBabySpecies ( ushort species , int generation )
2022-06-18 18:04:24 +00:00
{
2023-07-08 19:46:46 +00:00
if ( generation = = 3 )
return IsSplitBreedNotBabySpecies3 ( species ) ;
if ( generation is 4 or 5 or 6 or 7 or 8 )
return IsSplitBreedNotBabySpecies4 ( species ) ;
// Gen9 does not have split-breed egg generation.
return false ;
}
2022-06-18 18:04:24 +00:00
2023-07-08 19:46:46 +00:00
/// <summary>
/// Checks if the species can yield a different baby species when bred via incense in Generation 3.
/// </summary>
/// <remarks>
/// This is a special case for Marill and Wobbuffet, which can be bred with incense to yield Azurill and Wynaut respectively.
/// </remarks>
public static bool IsSplitBreedNotBabySpecies3 ( ushort species ) = > species is ( ushort ) Marill or ( ushort ) Wobbuffet ;
/// <summary>
/// Checks if the species can yield a different baby species when bred via incense in Generation 4-8.
/// </summary>
public static bool IsSplitBreedNotBabySpecies4 ( ushort species ) = > species switch
2022-06-18 18:04:24 +00:00
{
2023-07-08 19:46:46 +00:00
( int ) Marill = > true ,
( int ) Wobbuffet = > true ,
( int ) Chansey = > true ,
( int ) MrMime = > true ,
( int ) Snorlax = > true ,
( int ) Sudowoodo = > true ,
( int ) Mantine = > true ,
( int ) Roselia = > true ,
( int ) Chimecho = > true ,
_ = > false ,
2022-06-18 18:04:24 +00:00
} ;
/// <summary>
/// Checks if the <see cref="species"/> can be obtained from a daycare egg.
/// </summary>
/// <remarks>Chained with the other 2 overloads for incremental checks with different parameters.</remarks>
/// <param name="species">Current species</param>
2023-07-08 19:46:46 +00:00
public static bool CanHatchAsEgg ( ushort species ) = > IsAbleToHatchFromEgg ( species ) ;
2022-06-18 18:04:24 +00:00
/// <summary>
2023-01-22 04:02:33 +00:00
/// Checks if the <see cref="species"/>-<see cref="form"/> can exist as a hatched egg in the requested <see cref="context"/>.
2022-06-18 18:04:24 +00:00
/// </summary>
/// <remarks>Chained with the other 2 overloads for incremental checks with different parameters.</remarks>
/// <param name="species">Current species</param>
/// <param name="form">Current form</param>
2022-12-18 08:16:29 +00:00
/// <param name="context">Generation of origin</param>
public static bool CanHatchAsEgg ( ushort species , byte form , EntityContext context )
2022-06-18 18:04:24 +00:00
{
if ( form = = 0 )
return true ;
2022-12-18 08:16:29 +00:00
if ( FormInfo . IsTotemForm ( species , form , context ) )
2022-06-18 18:04:24 +00:00
return false ;
2022-12-18 08:16:29 +00:00
if ( FormInfo . IsLordForm ( species , form , context ) )
2022-06-18 18:04:24 +00:00
return false ;
return IsBreedableForm ( species , form ) ;
}
/// <summary>
2023-01-22 04:02:33 +00:00
/// Some species can have forms that cannot exist as egg (event/special forms). Same idea as <see cref="FormInfo.IsTotemForm(ushort,byte,EntityContext)"/>
2022-06-18 18:04:24 +00:00
/// </summary>
/// <returns>True if can be bred.</returns>
2022-08-27 19:53:30 +00:00
private static bool IsBreedableForm ( ushort species , byte form ) = > species switch
2022-06-18 18:04:24 +00:00
{
( int ) Pikachu or ( int ) Eevee = > false , // can't get these forms as egg
( int ) Pichu = > false , // can't get Spiky Ear Pichu eggs
( int ) Floette when form = = 5 = > false , // can't get Eternal Flower from egg
2023-01-27 03:03:06 +00:00
( int ) Greninja when form = = 1 = > false , // can't get Battle Bond Greninja from egg
2022-06-18 18:04:24 +00:00
( int ) Sinistea or ( int ) Polteageist = > false , // can't get Antique eggs
_ = > true ,
} ;
/// <summary>
/// Species that cannot hatch from an egg.
/// </summary>
2023-07-08 19:46:46 +00:00
private static bool IsAbleToHatchFromEgg ( ushort species ) = > species switch
2022-06-18 18:04:24 +00:00
{
// Gen1
2023-07-08 19:46:46 +00:00
( int ) Ditto = > false ,
( int ) Articuno or ( int ) Zapdos or ( int ) Moltres = > false ,
( int ) Mewtwo or ( int ) Mew = > false ,
2022-06-18 18:04:24 +00:00
// Gen2
2023-07-08 19:46:46 +00:00
( int ) Unown = > false ,
( int ) Raikou or ( int ) Entei or ( int ) Suicune = > false ,
( int ) Lugia or ( int ) HoOh or ( int ) Celebi = > false ,
2022-06-18 18:04:24 +00:00
// Gen3
2023-07-08 19:46:46 +00:00
( int ) Regirock or ( int ) Regice or ( int ) Registeel = > false ,
( int ) Latias or ( int ) Latios = > false ,
( int ) Kyogre or ( int ) Groudon or ( int ) Rayquaza = > false ,
( int ) Jirachi or ( int ) Deoxys = > false ,
2022-06-18 18:04:24 +00:00
// Gen4
2023-07-08 19:46:46 +00:00
( int ) Uxie or ( int ) Mesprit or ( int ) Azelf = > false ,
( int ) Dialga or ( int ) Palkia or ( int ) Heatran = > false ,
( int ) Regigigas or ( int ) Giratina or ( int ) Cresselia = > false ,
( int ) Manaphy or ( int ) Darkrai or ( int ) Shaymin or ( int ) Arceus = > false ,
2022-06-18 18:04:24 +00:00
// Gen5
2023-07-08 19:46:46 +00:00
( int ) Victini = > false ,
( int ) Cobalion or ( int ) Terrakion or ( int ) Virizion = > false ,
( int ) Tornadus or ( int ) Thundurus = > false ,
( int ) Reshiram or ( int ) Zekrom = > false ,
( int ) Landorus or ( int ) Kyurem = > false ,
( int ) Keldeo or ( int ) Meloetta or ( int ) Genesect = > false ,
2022-06-18 18:04:24 +00:00
// Gen6
2023-07-08 19:46:46 +00:00
( int ) Xerneas or ( int ) Yveltal or ( int ) Zygarde = > false ,
( int ) Diancie or ( int ) Hoopa or ( int ) Volcanion = > false ,
2022-06-18 18:04:24 +00:00
// Gen7
2023-07-08 19:46:46 +00:00
( int ) TypeNull or ( int ) Silvally = > false ,
( int ) TapuKoko or ( int ) TapuLele or ( int ) TapuBulu or ( int ) TapuFini = > false ,
( int ) Cosmog or ( int ) Cosmoem or ( int ) Solgaleo or ( int ) Lunala = > false ,
( int ) Nihilego or ( int ) Buzzwole or ( int ) Pheromosa or ( int ) Xurkitree or ( int ) Celesteela or ( int ) Kartana or ( int ) Guzzlord or ( int ) Necrozma = > false ,
( int ) Magearna or ( int ) Marshadow = > false ,
( int ) Poipole or ( int ) Naganadel or ( int ) Stakataka or ( int ) Blacephalon or ( int ) Zeraora = > false ,
2022-06-18 18:04:24 +00:00
2023-07-08 19:46:46 +00:00
( int ) Meltan or ( int ) Melmetal = > false ,
2022-06-18 18:04:24 +00:00
// Gen8
2023-07-08 19:46:46 +00:00
( int ) Dracozolt or ( int ) Arctozolt or ( int ) Dracovish or ( int ) Arctovish = > false ,
( int ) Zacian or ( int ) Zamazenta or ( int ) Eternatus = > false ,
( int ) Kubfu or ( int ) Urshifu or ( int ) Zarude = > false ,
( int ) Regieleki or ( int ) Regidrago = > false ,
( int ) Glastrier or ( int ) Spectrier or ( int ) Calyrex = > false ,
( int ) Enamorus = > false ,
2022-11-25 01:42:17 +00:00
// Gen9
2023-07-08 19:46:46 +00:00
( int ) GreatTusk or ( int ) ScreamTail or ( int ) BruteBonnet or ( int ) FlutterMane or ( int ) SlitherWing or ( int ) SandyShocks = > false ,
( int ) IronTreads or ( int ) IronBundle or ( int ) IronHands or ( int ) IronJugulis or ( int ) IronMoth or ( int ) IronThorns = > false ,
( int ) Gimmighoul or ( int ) Gholdengo = > false ,
( int ) WoChien or ( int ) ChienPao or ( int ) TingLu or ( int ) ChiYu = > false ,
( int ) RoaringMoon or ( int ) IronValiant = > false ,
( int ) Koraidon or ( int ) Miraidon = > false ,
( int ) WalkingWake or ( int ) IronLeaves = > false ,
_ = > true ,
2022-06-18 18:04:24 +00:00
} ;
2020-12-08 04:54:55 +00:00
}