diff --git a/PKHeX.Core/Saves/SAV3.cs b/PKHeX.Core/Saves/SAV3.cs
index b8e7289a0..4f8a5d2b9 100644
--- a/PKHeX.Core/Saves/SAV3.cs
+++ b/PKHeX.Core/Saves/SAV3.cs
@@ -594,5 +594,95 @@ public override void CopyChangesFrom(SaveFile sav)
SetData(Large, s3.Large, 0);
SetData(Storage, s3.Storage, 0);
}
+
+ #region External Connections
+ protected abstract int ExternalEventData { get; }
+ protected int ExternalEventFlags => ExternalEventData + 0x14;
+
+ public uint ColosseumRaw1
+ {
+ get => BitConverter.ToUInt32(Large, ExternalEventData + 7);
+ set => SetData(Large, BitConverter.GetBytes(value), ExternalEventData + 7);
+ }
+
+ public uint ColosseumRaw2
+ {
+ get => BitConverter.ToUInt32(Large, ExternalEventData + 11);
+ set => SetData(Large, BitConverter.GetBytes(value), ExternalEventData + 11);
+ }
+
+ ///
+ /// PokéCoupons stored by Pokémon Colosseum and XD from Mt. Battle runs. Earned PokéCoupons are also added to .
+ ///
+ /// Colosseum/XD caps this at 9,999,999, but will read up to 16,777,215.
+ public uint ColosseumCoupons
+ {
+ get => ColosseumRaw1 >> 8;
+ set => ColosseumRaw1 = (value << 8) | (ColosseumRaw1 & 0xFF);
+ }
+
+ /// Master Ball from JP Colosseum Bonus Disc; for reaching 30,000
+ public bool ColosseumPokeCouponTitleGold
+ {
+ get => (ColosseumRaw2 & (1 << 0)) != 0;
+ set => ColosseumRaw2 = (ColosseumRaw2 & (1 << 0)) | ((value ? 1u : 0) << 0);
+ }
+
+ /// Light Ball Pikachu from JP Colosseum Bonus Disc; for reaching 5000
+ public bool ColosseumPokeCouponTitleSilver
+ {
+ get => (ColosseumRaw2 & (1 << 1)) != 0;
+ set => ColosseumRaw2 = (ColosseumRaw2 & (1 << 1)) | ((value ? 1u : 0) << 1);
+ }
+
+ /// PP Max from JP Colosseum Bonus Disc; for reaching 2500
+ public bool ColosseumPokeCouponTitleBronze
+ {
+ get => (ColosseumRaw2 & (1 << 2)) != 0;
+ set => ColosseumRaw2 = (ColosseumRaw2 & (1 << 2)) | ((value ? 1u : 0) << 2);
+ }
+
+ /// Received Celebi Gift from JP Colosseum Bonus Disc
+ public bool ColosseumReceivedAgeto
+ {
+ get => (ColosseumRaw2 & (1 << 3)) != 0;
+ set => ColosseumRaw2 = (ColosseumRaw2 & (1 << 3)) | ((value ? 1u : 0) << 3);
+ }
+
+ ///
+ /// Used by the JP Colosseum bonus disc. Determines PokéCoupon rank to distribute rewards. Unread in International games.
+ ///
+ ///
+ /// Colosseum/XD caps this at 9,999,999.
+ ///
+ public uint ColosseumCouponsTotal
+ {
+ get => ColosseumRaw2 >> 8;
+ set => ColosseumRaw2 = (value << 8) | (ColosseumRaw2 & 0xFF);
+ }
+
+ /// Indicates if this save has connected to RSBOX and triggered the free False Swipe Swablu Egg giveaway.
+ public bool HasUsedRSBOX
+ {
+ get => GetFlag(ExternalEventFlags + 0, 0);
+ set => SetFlag(ExternalEventFlags + 0, 0, value);
+ }
+
+ ///
+ /// 1 for ExtremeSpeed Zigzagoon (at 100 deposited), 2 for Pay Day Skitty (at 500 deposited), 3 for Surf Pichu (at 1499 deposited)
+ ///
+ public int RSBoxDepositEggsUnlocked
+ {
+ get => (Large[ExternalEventFlags] >> 1) & 3;
+ set => Large[ExternalEventFlags] = (byte)((Large[ExternalEventFlags] & ~(3 << 1)) | ((value & 3) << 1));
+ }
+
+ /// Received Jirachi Gift from Colosseum Bonus Disc
+ public bool HasReceivedWishmkrJirachi
+ {
+ get => GetFlag(ExternalEventFlags + 2, 0);
+ set => SetFlag(ExternalEventFlags + 2, 0, value);
+ }
+ #endregion
}
}
diff --git a/PKHeX.Core/Saves/SAV3E.cs b/PKHeX.Core/Saves/SAV3E.cs
index ca819516f..482d6d3c4 100644
--- a/PKHeX.Core/Saves/SAV3E.cs
+++ b/PKHeX.Core/Saves/SAV3E.cs
@@ -179,13 +179,7 @@ public int SwarmIndex
public override string GetDaycareRNGSeed(int loc) => BitConverter.ToUInt32(Large, GetDaycareSlotOffset(0, 2)).ToString("X8"); // after the 2 slots, before the step counter
public override void SetDaycareRNGSeed(int loc, string seed) => BitConverter.GetBytes(Util.GetHexValue(seed)).CopyTo(Large, GetDaycareEXPOffset(2));
- private const int ExternalEventFlags = 0x31C7;
-
- public bool HasReceivedWishmkrJirachi
- {
- get => GetFlag(ExternalEventFlags + 2, 0);
- set => SetFlag(ExternalEventFlags + 2, 0, value);
- }
+ protected override int ExternalEventData => 0x31B3;
#region eBerry
private const int OFFSET_EBERRY = 0x31F8;
diff --git a/PKHeX.Core/Saves/SAV3FRLG.cs b/PKHeX.Core/Saves/SAV3FRLG.cs
index 88aac3bec..d8eb558a7 100644
--- a/PKHeX.Core/Saves/SAV3FRLG.cs
+++ b/PKHeX.Core/Saves/SAV3FRLG.cs
@@ -137,6 +137,8 @@ protected override InventoryPouch3[] GetItems()
public override string GetDaycareRNGSeed(int loc) => BitConverter.ToUInt16(Large, GetDaycareEXPOffset(2)).ToString("X4"); // after the 2nd slot EXP, before the step counter
public override void SetDaycareRNGSeed(int loc, string seed) => BitConverter.GetBytes((ushort)Util.GetHexValue(seed)).CopyTo(Large, GetDaycareEXPOffset(2));
+ protected override int ExternalEventData => 0x30A7;
+
#region eBerry
private const int OFFSET_EBERRY = 0x30EC;
private const int SIZE_EBERRY = 0x134;
diff --git a/PKHeX.Core/Saves/SAV3RS.cs b/PKHeX.Core/Saves/SAV3RS.cs
index 7bd3a7b50..5305eeb41 100644
--- a/PKHeX.Core/Saves/SAV3RS.cs
+++ b/PKHeX.Core/Saves/SAV3RS.cs
@@ -142,13 +142,7 @@ public int SwarmIndex
public override string GetDaycareRNGSeed(int loc) => BitConverter.ToUInt16(Large, GetDaycareEXPOffset(2)).ToString("X4");
public override void SetDaycareRNGSeed(int loc, string seed) => BitConverter.GetBytes((ushort)Util.GetHexValue(seed)).CopyTo(Large, GetDaycareEXPOffset(2));
- private const int ExternalEventFlags = 0x312F;
-
- public bool HasReceivedWishmkrJirachi
- {
- get => GetFlag(ExternalEventFlags + 2, 0);
- set => SetFlag(ExternalEventFlags + 2, 0, value);
- }
+ protected override int ExternalEventData => 0x311B;
#region eBerry
private const int OFFSET_EBERRY = 0x3160;
diff --git a/PKHeX.Core/Saves/Substructures/Gen3/IGen3Hoenn.cs b/PKHeX.Core/Saves/Substructures/Gen3/IGen3Hoenn.cs
index d37924c81..103242742 100644
--- a/PKHeX.Core/Saves/Substructures/Gen3/IGen3Hoenn.cs
+++ b/PKHeX.Core/Saves/Substructures/Gen3/IGen3Hoenn.cs
@@ -12,7 +12,6 @@ public interface IGen3Hoenn
PokeBlock3Case PokeBlocks { get; set; }
DecorationInventory3 Decorations { get; set; }
Swarm3 Swarm { get; set; }
- bool HasReceivedWishmkrJirachi { get; set; }
IReadOnlyList DefaultSwarms { get; }
int SwarmIndex { get; set; }