namespace PKHeX.Core; /// /// Minimal Trainer Information necessary for generating a . /// public interface ITrainerInfo : ITrainerID32 { string OT { get; } int Gender { get; } int Game { get; } int Language { get; } int Generation { get; } EntityContext Context { get; } } /// /// Extension methods for . /// public static class TrainerInfoExtensions { /// /// Copies the data to the object. /// /// Trainer Information /// Pokémon to copy to public static void ApplyTo(this ITrainerInfo info, PKM pk) { pk.OT_Name = info.OT; pk.TID16 = info.TID16; pk.SID16 = pk.Format < 3 || pk.VC ? (ushort)0 : info.SID16; pk.OT_Gender = info.Gender; pk.Language = info.Language; pk.Version = info.Game; if (pk is not IRegionOrigin tr) return; if (info is not IRegionOrigin o) return; o.CopyRegionOrigin(tr); } /// /// Copies the data to the object's Handling Trainer data. /// /// Trainer Information /// Pokémon to copy to /// If true, will overwrite the Handling Trainer Data even if it has not been traded. public static void ApplyHandlingTrainerInfo(this ITrainerInfo sav, PKM pk, bool force = false) { if (pk.Format == sav.Generation && !force) return; pk.HT_Name = sav.OT; pk.HT_Gender = sav.Gender; pk.HT_Friendship = pk.OT_Friendship; pk.CurrentHandler = 1; if (pk is IHandlerLanguage h) h.HT_Language = (byte)sav.Language; if (pk is PK6 pk6 && sav is IRegionOrigin o) { pk6.Geo1_Country = o.Country; pk6.Geo1_Region = o.Region; pk6.SetTradeMemoryHT6(true); } else if (pk is PK8 pk8 && PersonalTable.SWSH.IsPresentInGame(pk.Species, pk.Form)) { pk8.SetTradeMemoryHT8(); } } /// /// Checks if the data matches the object's Original Trainer data. /// /// Trainer Information /// Pokémon to compare to /// True if the data matches. public static bool IsFromTrainer(this ITrainerInfo tr, PKM pk) { if (pk.IsEgg) return tr.IsFromTrainerEgg(pk); if (tr.Game == (int)GameVersion.Any) return true; if (!IsFromTrainerNoVersion(tr, pk)) return false; return IsMatchVersion(tr, pk); } /// /// Checks if the data matches the object's Original Trainer data, ignoring the version. /// /// Trainer Information /// Pokémon to compare to /// True if the data matches. public static bool IsFromTrainerNoVersion(ITrainerInfo tr, PKM pk) { if (tr.ID32 != pk.ID32) return false; if (tr.OT != pk.OT_Name) return false; if (pk.Format == 3) return true; // Generation 3 does not check ot gender nor pokemon version if (tr.Gender != pk.OT_Gender) { if (pk.Format == 2) return pk is ICaughtData2 { CaughtData: 0 }; return false; } return true; } /// /// Only call this if it is still an egg. /// public static bool IsFromTrainerEgg(this ITrainerInfo tr, PKM pk) { System.Diagnostics.Debug.Assert(pk.IsEgg); if (tr.Context != pk.Context) return false; if (tr.ID32 != pk.ID32) return false; if (tr.Gender != pk.OT_Gender) return false; if (tr.Game != pk.Version) { // PK9 does not store version for Picnic eggs. if (pk is PK9 { Version: 0 }) { } else { return false; } } if (tr.OT != pk.OT_Name) return false; return true; } private static bool IsMatchVersion(ITrainerInfo tr, PKM pk) { if (tr.Game == pk.Version) return true; if (pk.GO_LGPE) return tr.Game is (int)GameVersion.GP or (int)GameVersion.GE; return false; } }