using static PKHeX.Core.GameVersion;
namespace PKHeX.Core;
///
/// Provides information for what values an Egg can have, while it still is an egg.
///
public static class EggStateLegality
{
///
/// Checks if the Egg Entity's hatch counter value is within the confines of game legality.
///
/// Egg Entity
/// Encounter the egg was generated from
/// True if valid, false if invalid.
public static bool GetIsEggHatchCyclesValid(PKM pk, IEncounterTemplate enc)
{
var hatchCounter = pk.OT_Friendship;
var max = GetMaximumEggHatchCycles(pk, enc);
if (hatchCounter > max)
return false;
var min = GetMinimumEggHatchCycles(pk);
if (hatchCounter < min)
return false;
return true;
}
///
/// Gets the minimum hatch counter value allowed for an Egg Entity.
///
/// Egg Entity
/// Usually 0...
public static int GetMinimumEggHatchCycles(PKM pk) => pk switch
{
PK2 or PB8 => 1, // no grace period between 1 step remaining and hatch
_ => 0, // having several Eggs in your party and then hatching one will give the rest 0... they can then be boxed!
};
///
/// Will create a new to find the encounter.
public static int GetMaximumEggHatchCycles(PKM pk)
{
var la = new LegalityAnalysis(pk);
var enc = la.EncounterMatch;
return GetMaximumEggHatchCycles(pk, enc);
}
///
/// Gets the original Hatch Cycle value for an Egg Entity.
///
/// Egg Entity
/// Encounter the egg was generated from
/// Maximum value the Hatch Counter can be.
public static int GetMaximumEggHatchCycles(PKM pk, IEncounterTemplate enc)
{
if (enc is EncounterStatic { EggCycles: not 0 } s)
return s.EggCycles;
return pk.PersonalInfo.HatchCycles;
}
///
/// Level which eggs are given to the player.
///
/// Generation the egg is given in
public static byte GetEggLevel(int generation) => generation >= 4 ? (byte)1 : (byte)5;
///
/// Met Level which eggs are given to the player. May change if transferred to future games.
///
/// Game the egg is obtained in
/// Generation the egg is given in
public static int GetEggLevelMet(GameVersion version, int generation) => generation switch
{
2 => version is C ? 1 : 0, // GS do not store met data
3 or 4 => 0,
_ => 1,
};
///
/// Checks if the and associated details can be set for the provided egg .
///
/// Egg Entity
/// True if valid, false if invalid.
public static bool IsValidHTEgg(PKM pk) => pk switch
{
PB8 { Met_Location: Locations.LinkTrade6NPC } pb8 when pb8.HT_Friendship == PersonalTable.BDSP[pb8.Species].BaseFriendship => true,
_ => false,
};
///
/// Indicates if the flag should be set for an Egg entity.
///
/// Encounter the egg was generated with
/// Egg Entity
/// True if the flag should be set, otherwise false.
public static bool IsNicknameFlagSet(IEncounterTemplate enc, PKM pk) => enc switch
{
EncounterStatic7 => false,
WB8 or EncounterStatic8b when pk.IsUntraded => false,
{ Generation: 4 } => false,
_ => true,
};
///
public static bool IsNicknameFlagSet(PKM pk) => IsNicknameFlagSet(new LegalityAnalysis(pk).EncounterMatch, pk);
///
/// Gets a valid for an egg hatched in the origin game, accounting for future format transfers altering the data.
///
public static int GetEggHatchLocation(GameVersion game, int format) => game switch
{
R or S or E or FR or LG => format switch
{
3 => game is FR or LG ? Locations.HatchLocationFRLG : Locations.HatchLocationRSE,
4 => Locations.Transfer3, // Pal Park
_ => Locations.Transfer4,
},
D or P or Pt => format > 4 ? Locations.Transfer4 : Locations.HatchLocationDPPt,
HG or SS => format > 4 ? Locations.Transfer4 : Locations.HatchLocationHGSS,
B or W or B2 or W2 => Locations.HatchLocation5,
X or Y => Locations.HatchLocation6XY,
AS or OR => Locations.HatchLocation6AO,
SN or MN or US or UM => Locations.HatchLocation7,
GSC or C when format <= 2 => Locations.HatchLocationC,
RD or BU or GN or YW => Locations.Transfer1,
GD or SI or C => Locations.Transfer2,
SW or SH => Locations.HatchLocation8,
BD or SP => Locations.HatchLocation8b,
_ => -1,
};
}