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 or PK9 => 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, PK9 { CurrentHandler: 1, Met_Location: Locations.LinkTrade6, HT_Language: not 0 } => 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, SL or VL => Locations.HatchLocation9, _ => -1, }; }