Add readonly interface for 3DS georegion

This commit is contained in:
Kurt 2025-04-13 11:52:51 -05:00
parent be874dcc50
commit 1914c482c6
11 changed files with 79 additions and 34 deletions

View File

@ -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;
}
/// <summary>

View File

@ -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;

View File

@ -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)))

View File

@ -3,19 +3,49 @@ namespace PKHeX.Core;
/// <summary>
/// Exposes details about the 3DS Console geolocation settings the trainer has set.
/// </summary>
public interface IRegionOrigin
public interface IRegionOrigin : IRegionOriginReadOnly
{
/// <summary> Console hardware region. </summary>
/// <see cref="Region3DSIndex"/>
byte ConsoleRegion { get; set; }
new byte ConsoleRegion { get; set; }
/// <summary> Console's configured Country via System Settings. </summary>
byte Country { get; set; }
new byte Country { get; set; }
/// <summary> Console's configured Region within <see cref="Country"/> via System Settings. </summary>
byte Region { get; set; }
new byte Region { get; set; }
}
public static partial class Extensions
public interface IRegionOriginReadOnly
{
/// <summary> Console hardware region. </summary>
/// <see cref="Region3DSIndex"/>
byte ConsoleRegion { get; }
/// <summary> Console's configured Country via System Settings. </summary>
byte Country { get; }
/// <summary> Console's configured Region within <see cref="Country"/> via System Settings. </summary>
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;

View File

@ -44,7 +44,7 @@ public static class TrainerIDExtensions
/// <summary>
/// Detects the correct <see cref="TrainerIDFormat"/> to use for the input <see cref="tr"/>.
/// </summary>
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,

View File

@ -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;

View File

@ -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;
/// <summary> Most recently loaded <see cref="ITrainerInfo.OT"/>. </summary>
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;
}

View File

@ -5,14 +5,14 @@ namespace PKHeX.Core;
/// <summary>
/// Minimal Trainer Information necessary for generating a <see cref="PKM"/>.
/// </summary>
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);
}

View File

@ -3,7 +3,7 @@ namespace PKHeX.Core;
/// <summary>
/// Simple record containing trainer data
/// </summary>
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;

View File

@ -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;

View File

@ -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;