diff --git a/PKHeX.Core/Editing/Database/TrainerDatabase.cs b/PKHeX.Core/Editing/Database/TrainerDatabase.cs index 1acc53004..fb12db6bc 100644 --- a/PKHeX.Core/Editing/Database/TrainerDatabase.cs +++ b/PKHeX.Core/Editing/Database/TrainerDatabase.cs @@ -152,19 +152,34 @@ public void Register(ITrainerInfo trainer) private static SimpleTrainerInfo GetTrainerReference(PKM pk) { - var result = new SimpleTrainerInfo(pk.Version) + var (cr, c, r) = GetRegion3DS(pk); + return GetTrainerReference(pk, cr, c, r); + } + + private static SimpleTrainerInfo GetTrainerReference(PKM pk, byte cr, byte c, byte r) => new(pk.Version) + { + TID16 = pk.TID16, + SID16 = pk.SID16, + OT = pk.OriginalTrainerName, + Gender = pk.OriginalTrainerGender, + Language = pk.Language, + Generation = pk.Generation, + ConsoleRegion = cr, + Country = c, + Region = r, + }; + + private static (byte ConsoleRegion, byte Country, byte Region) GetRegion3DS(PKM pk) + { + if (pk is IRegionOriginReadOnly x) + return (x.ConsoleRegion, x.Country, x.Region); + if (pk.Version.IsGen6() || pk.Version.IsGen7()) { - TID16 = pk.TID16, SID16 = pk.SID16, OT = pk.OriginalTrainerName, Gender = pk.OriginalTrainerGender, - Language = pk.Language, - Generation = pk.Generation, - }; - - if (pk is IRegionOrigin r) - r.CopyRegionOrigin(result); - else - result.SetDefaultRegionOrigins(result.Language); - - return result; + if (pk.Language == (int)LanguageID.Japanese) + return (0, 1, 0); + return (1, 7, 49); + } + return default; } /// diff --git a/PKHeX.Core/Editing/PKM/EntityTemplates.cs b/PKHeX.Core/Editing/PKM/EntityTemplates.cs index 7ba11565c..f78b68c6c 100644 --- a/PKHeX.Core/Editing/PKM/EntityTemplates.cs +++ b/PKHeX.Core/Editing/PKM/EntityTemplates.cs @@ -28,7 +28,7 @@ public static void TemplateFields(PKM pk, ITrainerInfo tr) pk.OriginalTrainerName = tr.OT; pk.OriginalTrainerGender = tr.Gender; pk.ID32 = tr.ID32; - if (tr is IRegionOrigin o && pk is IRegionOrigin gt) + if (tr is IRegionOriginReadOnly o && pk is IRegionOrigin gt) { gt.ConsoleRegion = o.ConsoleRegion; gt.Country = o.Country; diff --git a/PKHeX.Core/Legality/Encounters/Verifiers/MysteryGiftVerifier.cs b/PKHeX.Core/Legality/Encounters/Verifiers/MysteryGiftVerifier.cs index 4b58821e8..96163547e 100644 --- a/PKHeX.Core/Legality/Encounters/Verifiers/MysteryGiftVerifier.cs +++ b/PKHeX.Core/Legality/Encounters/Verifiers/MysteryGiftVerifier.cs @@ -48,7 +48,7 @@ public static CheckResult VerifyGift(PKM pk, MysteryGift g) if (lang != 0 && !lang.HasFlag((MysteryGiftRestriction) (1 << pk.Language))) return new CheckResult(Severity.Invalid, CheckIdentifier.GameOrigin, string.Format(LOTLanguage, lang.GetSuggestedLanguage(), pk.Language)); - if (pk is IRegionOrigin tr) + if (pk is IRegionOriginReadOnly tr) { var region = value & MysteryGiftRestriction.RegionRestrict; if (region != 0 && !region.HasFlag((MysteryGiftRestriction)((int)MysteryGiftRestriction.RegionBase << tr.ConsoleRegion))) diff --git a/PKHeX.Core/PKM/Interfaces/IRegionOrigin.cs b/PKHeX.Core/PKM/Interfaces/IRegionOrigin.cs index e26c52f69..c4272d956 100644 --- a/PKHeX.Core/PKM/Interfaces/IRegionOrigin.cs +++ b/PKHeX.Core/PKM/Interfaces/IRegionOrigin.cs @@ -3,19 +3,49 @@ namespace PKHeX.Core; /// /// Exposes details about the 3DS Console geolocation settings the trainer has set. /// -public interface IRegionOrigin +public interface IRegionOrigin : IRegionOriginReadOnly { /// Console hardware region. /// - byte ConsoleRegion { get; set; } + new byte ConsoleRegion { get; set; } /// Console's configured Country via System Settings. - byte Country { get; set; } + new byte Country { get; set; } /// Console's configured Region within via System Settings. - byte Region { get; set; } + new byte Region { get; set; } } -public static partial class Extensions +public interface IRegionOriginReadOnly { + /// Console hardware region. + /// + byte ConsoleRegion { get; } + /// Console's configured Country via System Settings. + byte Country { get; } + /// Console's configured Region within via System Settings. + byte Region { get; } +} + +public readonly record struct GeoRegion3DS(byte ConsoleRegion, byte Country, byte Region); + +public static class RegionOriginExtensions +{ + public static GeoRegion3DS GetRegionOrigin(this IRegionOriginReadOnly o) => new(o.ConsoleRegion, o.Country, o.Region); + public static void SetRegionOrigin(this IRegionOrigin o, GeoRegion3DS r) + { + o.ConsoleRegion = r.ConsoleRegion; + o.Country = r.Country; + o.Region = r.Region; + } + + public static GeoRegion3DS GetRegionOrigin(this ITrainerInfo tr, int language) + { + if (tr is IRegionOriginReadOnly r) + return r.GetRegionOrigin(); + if (language == 1) // Japanese + return new GeoRegion3DS(0, 1, 0); // Japan + return new GeoRegion3DS(1, 49, 7); // North America, USA, California + } + public static void SetDefaultRegionOrigins(this IRegionOrigin o, int language) { if (language == 1) @@ -32,7 +62,7 @@ public static void SetDefaultRegionOrigins(this IRegionOrigin o, int language) } } - public static void CopyRegionOrigin(this IRegionOrigin source, IRegionOrigin dest) + public static void CopyRegionOrigin(this IRegionOriginReadOnly source, IRegionOrigin dest) { dest.ConsoleRegion = source.ConsoleRegion; dest.Country = source.Country; diff --git a/PKHeX.Core/PKM/Interfaces/ITrainerID.cs b/PKHeX.Core/PKM/Interfaces/ITrainerID.cs index 055a893eb..72693dd98 100644 --- a/PKHeX.Core/PKM/Interfaces/ITrainerID.cs +++ b/PKHeX.Core/PKM/Interfaces/ITrainerID.cs @@ -44,7 +44,7 @@ public static class TrainerIDExtensions /// /// Detects the correct to use for the input . /// - public static TrainerIDFormat GetTrainerIDFormat(this ITrainerID tr) => tr switch + public static TrainerIDFormat GetTrainerIDFormat(this ITrainerID32ReadOnly tr) => tr switch { PKM { Format: <= 2 } => SixteenBitSingle, PKM { Version: 0 } pk => pk.Format >= 7 ? SixDigit : SixteenBit, diff --git a/PKHeX.Core/PKM/PK6.cs b/PKHeX.Core/PKM/PK6.cs index 207685ee9..87694b92a 100644 --- a/PKHeX.Core/PKM/PK6.cs +++ b/PKHeX.Core/PKM/PK6.cs @@ -417,7 +417,7 @@ protected override bool TradeOT(ITrainerInfo tr) return false; CurrentHandler = 0; - if (tr is IRegionOrigin o) + if (tr is IRegionOriginReadOnly o) { if (!IsUntraded && (o.Country != Geo1_Country || o.Region != Geo1_Region)) this.TradeGeoLocation(o.Country, o.Region); @@ -438,7 +438,7 @@ protected override void TradeHT(ITrainerInfo tr) HandlingTrainerName = other; HandlingTrainerFriendship = PersonalInfo.BaseFriendship; HandlingTrainerAffection = 0; - if (tr is IRegionOrigin o) + if (tr is IRegionOriginReadOnly o) this.TradeGeoLocation(o.Country, o.Region); } CurrentHandler = 1; diff --git a/PKHeX.Core/PKM/Util/RecentTrainerCache.cs b/PKHeX.Core/PKM/Util/RecentTrainerCache.cs index 42a70a457..8e0eaed0f 100644 --- a/PKHeX.Core/PKM/Util/RecentTrainerCache.cs +++ b/PKHeX.Core/PKM/Util/RecentTrainerCache.cs @@ -7,9 +7,9 @@ namespace PKHeX.Core; public static class RecentTrainerCache { private static ITrainerInfo Trainer = new SimpleTrainerInfo(); - private static IRegionOrigin Trainer67 = new SimpleTrainerInfo(GameVersion.SN); + private static IRegionOriginReadOnly Trainer67 = new SimpleTrainerInfo(GameVersion.SN); - private static IRegionOrigin GetTrainer3DS(ITrainerInfo tr) => tr as IRegionOrigin ?? Trainer67; + private static IRegionOriginReadOnly GetTrainer3DS(ITrainerInfo tr) => tr as IRegionOrigin ?? Trainer67; /// Most recently loaded . public static string OriginalTrainerName => Trainer.OT; @@ -36,7 +36,7 @@ public static class RecentTrainerCache public static void SetRecentTrainer(ITrainerInfo trainer) { Trainer = trainer; - if (trainer is IRegionOrigin g67) + if (trainer is IRegionOriginReadOnly g67) Trainer67 = g67; } diff --git a/PKHeX.Core/Saves/Abstractions/ITrainerInfo.cs b/PKHeX.Core/Saves/Abstractions/ITrainerInfo.cs index 332ade0f2..b3f45abc5 100644 --- a/PKHeX.Core/Saves/Abstractions/ITrainerInfo.cs +++ b/PKHeX.Core/Saves/Abstractions/ITrainerInfo.cs @@ -5,14 +5,14 @@ namespace PKHeX.Core; /// /// Minimal Trainer Information necessary for generating a . /// -public interface ITrainerInfo : ITrainerID32 +public interface ITrainerInfo : ITrainerID32ReadOnly, IVersion, IGeneration { string OT { get; } byte Gender { get; } - GameVersion Version { get; } + new GameVersion Version { get; } int Language { get; } - byte Generation { get; } + new byte Generation { get; } EntityContext Context { get; } } @@ -38,7 +38,7 @@ public static void ApplyTo(this ITrainerInfo info, PKM pk) if (pk is not IRegionOrigin tr) return; - if (info is not IRegionOrigin o) + if (info is not IRegionOriginReadOnly o) return; o.CopyRegionOrigin(tr); } diff --git a/PKHeX.Core/Saves/Abstractions/SimpleTrainerInfo.cs b/PKHeX.Core/Saves/Abstractions/SimpleTrainerInfo.cs index 2b63a21f1..59fec5b6a 100644 --- a/PKHeX.Core/Saves/Abstractions/SimpleTrainerInfo.cs +++ b/PKHeX.Core/Saves/Abstractions/SimpleTrainerInfo.cs @@ -3,7 +3,7 @@ namespace PKHeX.Core; /// /// Simple record containing trainer data /// -public sealed record SimpleTrainerInfo : ITrainerInfo, IRegionOrigin +public sealed record SimpleTrainerInfo : ITrainerInfo, IRegionOriginReadOnly { public string OT { get; set; } = TrainerName.ProgramINT; public ushort TID16 { get; set; } = 12345; diff --git a/PKHeX.WinForms/Controls/PKM Editor/LoadSave.cs b/PKHeX.WinForms/Controls/PKM Editor/LoadSave.cs index 7848392aa..50cc0012d 100644 --- a/PKHeX.WinForms/Controls/PKM Editor/LoadSave.cs +++ b/PKHeX.WinForms/Controls/PKM Editor/LoadSave.cs @@ -330,7 +330,7 @@ private void LoadMisc6(PKM pk) LoadRelearnMoves(pk); LoadHandlingTrainer(pk); - if (pk is IRegionOrigin tr) + if (pk is IRegionOriginReadOnly tr) LoadGeolocation(tr); } @@ -349,7 +349,7 @@ private void SaveMisc6(PKM pk) SaveGeolocation(tr); } - private void LoadGeolocation(IRegionOrigin pk) + private void LoadGeolocation(IRegionOriginReadOnly pk) { CB_Country.SelectedValue = (int)pk.Country; CB_SubRegion.SelectedValue = (int)pk.Region; diff --git a/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs b/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs index b076cfa93..c7c470351 100644 --- a/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs +++ b/PKHeX.WinForms/Controls/PKM Editor/PKMEditor.cs @@ -404,7 +404,7 @@ internal void UpdateSprite() if (lang <= 0) lang = (int)LanguageID.English; CB_Language.SelectedValue = lang; - if (tr is IRegionOrigin o) + if (tr is IRegionOriginReadOnly o) { CB_3DSReg.SelectedValue = (int)o.ConsoleRegion; CB_Country.SelectedValue = (int)o.Country;