diff --git a/PKHeX.Core/Editing/CommonEdits.cs b/PKHeX.Core/Editing/CommonEdits.cs
index 41b3d930a..27ded6590 100644
--- a/PKHeX.Core/Editing/CommonEdits.cs
+++ b/PKHeX.Core/Editing/CommonEdits.cs
@@ -344,7 +344,7 @@ public static void ForceHatchPKM(this PKM pk, ITrainerInfo? tr = null, bool reHa
return;
pk.IsEgg = false;
pk.ClearNickname();
- pk.CurrentFriendship = pk.PersonalInfo.BaseFriendship;
+ pk.OriginalTrainerFriendship = Math.Min(pk.OriginalTrainerFriendship, EggStateLegality.GetEggHatchFriendship(pk.Context));
if (pk.IsTradedEgg)
pk.EggLocation = pk.MetLocation;
if (pk.Version == 0)
diff --git a/PKHeX.Core/Editing/Saves/Editors/FakeSaveFile.cs b/PKHeX.Core/Editing/Saves/Editors/FakeSaveFile.cs
index 0144cfc66..c8e667bb5 100644
--- a/PKHeX.Core/Editing/Saves/Editors/FakeSaveFile.cs
+++ b/PKHeX.Core/Editing/Saves/Editors/FakeSaveFile.cs
@@ -30,7 +30,7 @@ public sealed class FakeSaveFile : SaveFile
public override int BoxCount => 1;
public override int GetPartyOffset(int slot) => -1;
protected override void SetChecksums() { }
-
+ public override GameVersion Version { get => GameVersion.R; set { } }
public override Type PKMType => typeof(PK3);
protected override PK3 GetPKM(byte[] data) => BlankPKM;
protected override byte[] DecryptPKM(byte[] data) => data;
diff --git a/PKHeX.Core/Legality/Encounters/Templates/Shared/EncounterEgg.cs b/PKHeX.Core/Legality/Encounters/Templates/Shared/EncounterEgg.cs
index 1df89673c..fa4ecd5b3 100644
--- a/PKHeX.Core/Legality/Encounters/Templates/Shared/EncounterEgg.cs
+++ b/PKHeX.Core/Legality/Encounters/Templates/Shared/EncounterEgg.cs
@@ -42,7 +42,7 @@ public PKM ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
var ball = FixedBall;
pk.Ball = ball is Ball.None ? (byte)Ball.Poke : (byte)ball;
- pk.OriginalTrainerFriendship = pk.PersonalInfo.BaseFriendship;
+ pk.OriginalTrainerFriendship = EggStateLegality.GetEggHatchFriendship(Context);
SetEncounterMoves(pk, version);
pk.HealPP();
@@ -51,17 +51,22 @@ public PKM ConvertToPKM(ITrainerInfo tr, EncounterCriteria criteria)
if (gen <= 2)
{
- if (version != GameVersion.C)
+ var pk2 = (PK2)pk;
+ if (version == GameVersion.C)
{
- pk.OriginalTrainerGender = 0;
+ // Set met data for Crystal hatch.
+ pk2.MetLocation = Locations.HatchLocationC;
+ pk2.MetLevel = 1;
+ pk2.MetTimeOfDay = rnd.Next(1, 4); // Morning | Day | Night
}
- else
+ else // G/S
{
- pk.MetLocation = Locations.HatchLocationC;
- pk.MetLevel = 1;
- ((PK2)pk).MetTimeOfDay = rnd.Next(1, 4); // Morning | Day | Night
+ // G/S can't set any data for Trainer Gender.
+ pk2.OriginalTrainerGender = 0;
}
- return pk;
+
+ // No other revisions needed.
+ return pk2;
}
SetMetData(pk);
diff --git a/PKHeX.Core/Legality/Verifiers/Egg/EggStateLegality.cs b/PKHeX.Core/Legality/Verifiers/Egg/EggStateLegality.cs
index d142357d5..2bc287c27 100644
--- a/PKHeX.Core/Legality/Verifiers/Egg/EggStateLegality.cs
+++ b/PKHeX.Core/Legality/Verifiers/Egg/EggStateLegality.cs
@@ -153,4 +153,29 @@ public static int GetMaximumEggHatchCycles(PKM pk, IEncounterTemplate enc)
SL or VL => Locations.HatchLocation9,
_ => 0,
};
+
+ ///
+ /// Gets the initial friendship value for an egg when it is hatched.
+ ///
+ public static byte GetEggHatchFriendship(EntityContext context) => context switch
+ {
+ // From Gen2->Gen7, the value was 120.
+ EntityContext.Gen2 => 120,
+ EntityContext.Gen3 => 120,
+ EntityContext.Gen4 => 120,
+ EntityContext.Gen5 => 120,
+ EntityContext.Gen6 => 120,
+ EntityContext.Gen7 => 120,
+ // No eggs in LGP/E.
+
+ // Starting in SW/SH, Friendship was rescaled away from 255 (to 160-ish), so the value is lower than prior.
+ _ => 100,
+ };
+
+ ///
+ /// Reasonable value for the friendship of an egg when it is hatched.
+ ///
+ /// Only use if you're trying to generalize a value for hatched eggs without checking context.
+
+ public const byte EggHatchFriendshipGeneral = 100;
}
diff --git a/PKHeX.Core/PKM/Interfaces/IHandlerUpdate.cs b/PKHeX.Core/PKM/Interfaces/IHandlerUpdate.cs
new file mode 100644
index 000000000..2beac48a6
--- /dev/null
+++ b/PKHeX.Core/PKM/Interfaces/IHandlerUpdate.cs
@@ -0,0 +1,19 @@
+namespace PKHeX.Core;
+
+///
+/// Interface exposing a method to adapt the entity to the Handling Trainer.
+///
+public interface IHandlerUpdate
+{
+ ///
+ /// Indicates if the entity belongs to the .
+ ///
+ /// Trainer to check if it originally possessed the entity.
+ bool BelongsTo(ITrainerInfo tr);
+
+ ///
+ /// Updates the entity to match the .
+ ///
+ /// Trainer that is now in possession of the entity.
+ void UpdateHandler(ITrainerInfo tr);
+}
diff --git a/PKHeX.Core/PKM/PA8.cs b/PKHeX.Core/PKM/PA8.cs
index 890c4c22f..a0766cbd9 100644
--- a/PKHeX.Core/PKM/PA8.cs
+++ b/PKHeX.Core/PKM/PA8.cs
@@ -8,7 +8,8 @@ namespace PKHeX.Core;
/// Generation 8 format.
public sealed class PA8 : PKM, ISanityChecksum,
IGanbaru, IAlpha, INoble, ITechRecord, ISociability, IMoveShop8Mastery, IContestStats, IHyperTrain, IScaledSizeValue, IScaledSize3, IGigantamax, IFavorite, IDynamaxLevel, IHandlerLanguage, IFormArgument, IHomeTrack, IBattleVersion, ITrainerMemories, IPokerusStatus,
- IRibbonIndex, IRibbonSetAffixed, IRibbonSetRibbons, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetCommon6, IRibbonSetMemory6, IRibbonSetCommon7, IRibbonSetCommon8, IRibbonSetMarks, IRibbonSetMark8, IRibbonSetCommon9, IRibbonSetMark9
+ IRibbonIndex, IRibbonSetAffixed, IRibbonSetRibbons, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetCommon6, IRibbonSetMemory6, IRibbonSetCommon7, IRibbonSetCommon8, IRibbonSetMarks, IRibbonSetMark8, IRibbonSetCommon9, IRibbonSetMark9,
+ IHandlerUpdate
{
public override ReadOnlySpan ExtraBytes =>
[
@@ -570,7 +571,19 @@ public int GetRibbonByte(int index)
return 0x40 + (index >> 3);
}
- public void Trade(ITrainerInfo tr)
+ public bool BelongsTo(ITrainerInfo tr)
+ {
+ if (tr.Version != Version)
+ return false;
+ if (tr.ID32 != ID32)
+ return false;
+ if (tr.Gender != OriginalTrainerGender)
+ return false;
+ return tr.OT == OriginalTrainerName;
+ }
+
+
+ public void UpdateHandler(ITrainerInfo tr)
{
// Process to the HT if the OT of the Pokémon does not match the SAV's OT info.
if (!TradeOT(tr))
@@ -581,38 +594,27 @@ public void FixMemories()
{
if (LA)
{
- OriginalTrainerMemoryVariable = OriginalTrainerMemory = OriginalTrainerMemoryIntensity = OriginalTrainerMemoryFeeling = 0;
- HandlingTrainerMemoryVariable = HandlingTrainerMemory = HandlingTrainerMemoryIntensity = HandlingTrainerMemoryFeeling = 0; // future inter-format conversion?
- }
-
- if (IsEgg) // No memories if is egg.
- {
- HandlingTrainerMemoryVariable = HandlingTrainerMemory = HandlingTrainerMemoryIntensity = HandlingTrainerMemoryFeeling = 0;
- OriginalTrainerMemoryVariable = OriginalTrainerMemory = OriginalTrainerMemoryIntensity = OriginalTrainerMemoryFeeling = 0;
-
- // Clear Handler
- if (!IsTradedEgg)
- {
- HandlingTrainerFriendship = HandlingTrainerGender = HandlingTrainerLanguage = 0;
- HandlingTrainerTrash.Clear();
- }
- return;
+ this.ClearMemoriesOT();
+ this.ClearMemoriesHT();
}
if (IsUntraded)
- HandlingTrainerMemoryVariable = HandlingTrainerGender = HandlingTrainerFriendship = HandlingTrainerMemory = HandlingTrainerMemoryIntensity = HandlingTrainerMemoryFeeling = HandlingTrainerLanguage = 0;
-
- var gen = Generation;
- if (gen < 6)
- OriginalTrainerMemoryVariable = OriginalTrainerMemory = OriginalTrainerMemoryIntensity = OriginalTrainerMemoryFeeling = 0;
- // if (gen != 8) // must be transferred via HOME, and must have memories
- // this.SetTradeMemoryHT8(); // not faking HOME tracker.
+ {
+ HandlingTrainerGender = HandlingTrainerFriendship = HandlingTrainerLanguage = 0;
+ HandlingTrainerTrash.Clear();
+ }
+ else
+ {
+ var gen = Generation;
+ if (gen < 6)
+ this.ClearMemoriesOT();
+ }
}
private bool TradeOT(ITrainerInfo tr)
{
// Check to see if the OT matches the SAV's OT info.
- if (!(tr.ID32 == ID32 && tr.Gender == OriginalTrainerGender && tr.OT == OriginalTrainerName))
+ if (!BelongsTo(tr))
return false;
CurrentHandler = 0;
diff --git a/PKHeX.Core/PKM/PB7.cs b/PKHeX.Core/PKM/PB7.cs
index 341367fbe..a8d1eee74 100644
--- a/PKHeX.Core/PKM/PB7.cs
+++ b/PKHeX.Core/PKM/PB7.cs
@@ -5,7 +5,8 @@
namespace PKHeX.Core;
/// Generation 7 format used for .
-public sealed class PB7 : G6PKM, IHyperTrain, IAwakened, IScaledSizeValue, ICombatPower, IFavorite, IFormArgument, IAppliedMarkings7
+public sealed class PB7 : G6PKM, IHyperTrain, IAwakened, IScaledSizeValue, ICombatPower, IFavorite,
+ IFormArgument, IAppliedMarkings7, IHandlerUpdate
{
public override ReadOnlySpan ExtraBytes =>
[
@@ -336,7 +337,7 @@ public void SetMarking(int index, MarkingColor value)
protected override bool TradeOT(ITrainerInfo tr)
{
// Check to see if the OT matches the SAV's OT info.
- if (!(tr.ID32 == ID32 && tr.Gender == OriginalTrainerGender && tr.OT == OriginalTrainerName))
+ if (!BelongsTo(tr))
return false;
CurrentHandler = 0;
@@ -357,7 +358,10 @@ protected override void TradeHT(ITrainerInfo tr)
public void FixMemories()
{
if (IsUntraded)
- HT_TextVar = HandlingTrainerFriendship = HT_Memory = HT_Intensity = HT_Feeling = 0;
+ {
+ HandlingTrainerTrash.Clear();
+ HandlingTrainerGender = HandlingTrainerFriendship = 0;
+ }
}
// Maximums
diff --git a/PKHeX.Core/PKM/PB8.cs b/PKHeX.Core/PKM/PB8.cs
index c286b5afa..ece5561cc 100644
--- a/PKHeX.Core/PKM/PB8.cs
+++ b/PKHeX.Core/PKM/PB8.cs
@@ -45,13 +45,28 @@ public bool IsDprIllegal
set => Data[0x52] = (byte)((Data[0x52] & 0xFE) | (value ? 1 : 0));
}
- public void Trade(ITrainerInfo tr, int Day = 1, int Month = 1, int Year = 2015)
+ public bool BelongsTo(ITrainerInfo tr)
+ {
+ if (tr.Version != Version)
+ return false;
+ if (tr.ID32 != ID32)
+ return false;
+ if (tr.Gender != OriginalTrainerGender)
+ return false;
+ return tr.OT == OriginalTrainerName;
+ }
+
+ public void UpdateHandler(ITrainerInfo tr)
{
if (IsEgg)
{
// Apply link trade data, only if it left the OT (ignore if dumped & imported, or cloned, etc.)
- if ((tr.TID16 != TID16) || (tr.SID16 != SID16) || (tr.Gender != OriginalTrainerGender) || (tr.OT != OriginalTrainerName))
- SetLinkTradeEgg(Day, Month, Year, Locations.LinkTrade6NPC);
+ const ushort location = Locations.LinkTrade6NPC;
+ if (MetLocation != location && !BelongsTo(tr))
+ {
+ var date = EncounterDate.GetDate3DS();
+ SetLinkTradeEgg(date.Day, date.Month, date.Year, location);
+ }
// Unfortunately, BD/SP doesn't return if it's an egg, and can update the HT details & handler.
// Continue to the rest of the method.
@@ -67,15 +82,13 @@ public void FixMemories()
{
if (BDSP)
{
- OriginalTrainerMemoryVariable = OriginalTrainerMemory = OriginalTrainerMemoryIntensity = OriginalTrainerMemoryFeeling = 0;
- HandlingTrainerMemoryVariable = HandlingTrainerMemory = HandlingTrainerMemoryIntensity = HandlingTrainerMemoryFeeling = 0; // future inter-format conversion?
+ this.ClearMemoriesOT();
+ this.ClearMemoriesHT();
}
if (IsEgg) // No memories if is egg.
{
- HandlingTrainerMemoryVariable = HandlingTrainerMemory = HandlingTrainerMemoryIntensity = HandlingTrainerMemoryFeeling = 0;
- OriginalTrainerMemoryVariable = OriginalTrainerMemory = OriginalTrainerMemoryIntensity = OriginalTrainerMemoryFeeling = 0;
-
+ // Memories already cleared above.
// Clear Handler
if (!IsTradedEgg)
{
@@ -86,19 +99,23 @@ public void FixMemories()
}
if (IsUntraded)
- HandlingTrainerMemoryVariable = HandlingTrainerGender = HandlingTrainerFriendship = HandlingTrainerMemory = HandlingTrainerMemoryIntensity = HandlingTrainerMemoryFeeling = HandlingTrainerLanguage = 0;
-
- var gen = Generation;
- if (gen < 6)
- OriginalTrainerMemoryVariable = OriginalTrainerMemory = OriginalTrainerMemoryIntensity = OriginalTrainerMemoryFeeling = 0;
- // if (gen != 8) // must be transferred via HOME, and must have memories
- // this.SetTradeMemoryHT8(); // not faking HOME tracker.
+ {
+ // Memories already cleared above.
+ HandlingTrainerFriendship = HandlingTrainerGender = HandlingTrainerLanguage = 0;
+ HandlingTrainerTrash.Clear();
+ }
+ else
+ {
+ var gen = Generation;
+ if (gen < 6)
+ this.ClearMemoriesOT();
+ }
}
private bool TradeOT(ITrainerInfo tr)
{
// Check to see if the OT matches the SAV's OT info.
- if (!(tr.ID32 == ID32 && tr.Gender == OriginalTrainerGender && tr.OT == OriginalTrainerName))
+ if (!BelongsTo(tr))
return false;
CurrentHandler = 0;
diff --git a/PKHeX.Core/PKM/PK5.cs b/PKHeX.Core/PKM/PK5.cs
index da5abb937..96689cefa 100644
--- a/PKHeX.Core/PKM/PK5.cs
+++ b/PKHeX.Core/PKM/PK5.cs
@@ -7,7 +7,7 @@ namespace PKHeX.Core;
/// Generation 5 format.
public sealed class PK5 : PKM, ISanityChecksum,
IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetUnique3, IRibbonSetUnique4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetRibbons,
- IContestStats, IGroundTile, IAppliedMarkings4
+ IContestStats, IGroundTile, IAppliedMarkings4, IHandlerUpdate
{
public override ReadOnlySpan ExtraBytes =>
[
@@ -297,14 +297,29 @@ protected override byte[] Encrypt()
}
// Synthetic Trading Logic
- public bool Trade(string SAV_Trainer, uint savID32, int SAV_GENDER, int Day = 1, int Month = 1, int Year = 2013)
+ public bool BelongsTo(ITrainerInfo tr)
{
- if (IsEgg && !(SAV_Trainer == OriginalTrainerName && savID32 == ID32 && SAV_GENDER == OriginalTrainerGender))
+ if (tr.Version != Version)
+ return false;
+ if (tr.ID32 != ID32)
+ return false;
+ if (tr.Gender != OriginalTrainerGender)
+ return false;
+ return tr.OT == OriginalTrainerName;
+ }
+
+ public void UpdateHandler(ITrainerInfo tr)
+ {
+ if (IsEgg)
{
- SetLinkTradeEgg(Day, Month, Year, Locations.LinkTrade5);
- return true;
+ // Don't bother updating eggs that were already traded.
+ const ushort location = Locations.LinkTrade5;
+ if (MetLocation != location && !BelongsTo(tr))
+ {
+ var date = EncounterDate.GetDateNDS();
+ SetLinkTradeEgg(date.Day, date.Month, date.Year, location);
+ }
}
- return false;
}
public int MarkingCount => 6;
diff --git a/PKHeX.Core/PKM/PK6.cs b/PKHeX.Core/PKM/PK6.cs
index 0b3089ed5..68c406e98 100644
--- a/PKHeX.Core/PKM/PK6.cs
+++ b/PKHeX.Core/PKM/PK6.cs
@@ -413,7 +413,7 @@ public void FixMemories()
protected override bool TradeOT(ITrainerInfo tr)
{
// Check to see if the OT matches the SAV's OT info.
- if (!(tr.ID32 == ID32 && tr.Gender == OriginalTrainerGender && tr.OT == OriginalTrainerName))
+ if (!BelongsTo(tr))
return false;
CurrentHandler = 0;
diff --git a/PKHeX.Core/PKM/PK7.cs b/PKHeX.Core/PKM/PK7.cs
index 7f88022ea..d792afd97 100644
--- a/PKHeX.Core/PKM/PK7.cs
+++ b/PKHeX.Core/PKM/PK7.cs
@@ -477,7 +477,7 @@ public void FixMemories()
protected override bool TradeOT(ITrainerInfo tr)
{
// Check to see if the OT matches the SAV's OT info.
- if (!(tr.ID32 == ID32 && tr.Gender == OriginalTrainerGender && tr.OT == OriginalTrainerName))
+ if (!BelongsTo(tr))
return false;
CurrentHandler = 0;
diff --git a/PKHeX.Core/PKM/PK8.cs b/PKHeX.Core/PKM/PK8.cs
index edaa11581..e58e4b189 100644
--- a/PKHeX.Core/PKM/PK8.cs
+++ b/PKHeX.Core/PKM/PK8.cs
@@ -4,7 +4,7 @@
namespace PKHeX.Core;
/// Generation 8 format.
-public sealed class PK8 : G8PKM
+public sealed class PK8 : G8PKM, IHandlerUpdate
{
public override ReadOnlySpan ExtraBytes =>
[
@@ -35,14 +35,30 @@ public PK8() => AffixedRibbon = -1; // 00 would make it show Kalos Champion :)
public PK8(byte[] data) : base(data) { }
public override PK8 Clone() => new((byte[])Data.Clone());
- public void Trade(ITrainerInfo tr, int Day = 1, int Month = 1, int Year = 2015)
+ // Synthetic Trading Logic
+ public bool BelongsTo(ITrainerInfo tr)
+ {
+ if (tr.Version != Version)
+ return false;
+ if (tr.ID32 != ID32)
+ return false;
+ if (tr.Gender != OriginalTrainerGender)
+ return false;
+ return tr.OT == OriginalTrainerName;
+ }
+
+ public void UpdateHandler(ITrainerInfo tr)
{
if (IsEgg)
{
// Eggs do not have any modifications done if they are traded
// Apply link trade data, only if it left the OT (ignore if dumped & imported, or cloned, etc.)
- if ((tr.TID16 != TID16) || (tr.SID16 != SID16) || (tr.Gender != OriginalTrainerGender) || (tr.OT != OriginalTrainerName))
- SetLinkTradeEgg(Day, Month, Year, Locations.LinkTrade6);
+ const ushort location = Locations.LinkTrade6;
+ if (MetLocation != location && !BelongsTo(tr))
+ {
+ var date = EncounterDate.GetDateSwitch();
+ SetLinkTradeEgg(date.Day, date.Month, date.Year, location);
+ }
return;
}
@@ -57,28 +73,31 @@ public void FixMemories()
{
if (IsEgg) // No memories if is egg.
{
- HandlingTrainerMemoryVariable = HandlingTrainerFriendship = HandlingTrainerMemory = HandlingTrainerMemoryIntensity = HandlingTrainerMemoryFeeling = HandlingTrainerLanguage = 0;
- /* OriginalTrainerFriendship */ OriginalTrainerMemoryVariable = OriginalTrainerMemory = OriginalTrainerMemoryIntensity = OriginalTrainerMemoryFeeling = 0;
-
- // Clear Handler
+ this.ClearMemoriesOT();
+ this.ClearMemoriesHT();
+ HandlingTrainerGender = HandlingTrainerFriendship = HandlingTrainerLanguage = 0;
HandlingTrainerTrash.Clear();
return;
}
if (IsUntraded)
- HandlingTrainerMemoryVariable = HandlingTrainerFriendship = HandlingTrainerMemory = HandlingTrainerMemoryIntensity = HandlingTrainerMemoryFeeling = HandlingTrainerLanguage = 0;
-
- var gen = Generation;
- if (gen < 6)
- OriginalTrainerMemoryVariable = OriginalTrainerMemory = OriginalTrainerMemoryIntensity = OriginalTrainerMemoryFeeling = 0;
- if (gen != 8) // must be transferred via HOME, and must have memories
- this.SetTradeMemoryHT8(); // not faking HOME tracker.
+ {
+ this.ClearMemoriesHT();
+ HandlingTrainerGender = HandlingTrainerFriendship = HandlingTrainerLanguage = 0;
+ HandlingTrainerTrash.Clear();
+ }
+ else
+ {
+ var gen = Generation;
+ if (gen < 6)
+ this.ClearMemoriesOT();
+ }
}
private bool TradeOT(ITrainerInfo tr)
{
// Check to see if the OT matches the SAV's OT info.
- if (!(tr.ID32 == ID32 && tr.Gender == OriginalTrainerGender && tr.OT == OriginalTrainerName))
+ if (!BelongsTo(tr))
return false;
CurrentHandler = 0;
diff --git a/PKHeX.Core/PKM/PK9.cs b/PKHeX.Core/PKM/PK9.cs
index c7699449e..6f5107b75 100644
--- a/PKHeX.Core/PKM/PK9.cs
+++ b/PKHeX.Core/PKM/PK9.cs
@@ -5,7 +5,7 @@
namespace PKHeX.Core;
/// Generation 9 format.
-public sealed class PK9 : PKM, ISanityChecksum, ITeraType, ITechRecord, IObedienceLevel,
+public sealed class PK9 : PKM, ISanityChecksum, ITeraType, ITechRecord, IObedienceLevel, IHandlerUpdate,
IContestStats, IHyperTrain, IScaledSize, IScaledSize3, IFavorite, IHandlerLanguage, IFormArgument, IHomeTrack, IBattleVersion, ITrainerMemories, IAppliedMarkings7,
IRibbonIndex, IRibbonSetAffixed, IRibbonSetRibbons, IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetCommon6, IRibbonSetMemory6, IRibbonSetCommon7, IRibbonSetCommon8, IRibbonSetCommon9, IRibbonSetMarks, IRibbonSetMark8, IRibbonSetMark9
{
@@ -549,34 +549,30 @@ public int GetRibbonByte(int index)
return 0x40 + (index >> 3);
}
- public void Trade(ITrainerInfo tr, int Day = 1, int Month = 1, int Year = 2015)
+ // Synthetic Trading Logic
+ public bool BelongsTo(ITrainerInfo tr)
+ {
+ if (tr.Version != Version)
+ return false;
+ return BelongsToSkipVersion(tr);
+ }
+
+ public bool BelongsToSkipVersion(ITrainerInfo tr)
+ {
+ if (tr.ID32 != ID32)
+ return false;
+ if (tr.Gender != OriginalTrainerGender)
+ return false;
+ if (tr.Language != Language)
+ return false;
+ return tr.OT == OriginalTrainerName;
+ }
+
+ public void UpdateHandler(ITrainerInfo tr)
{
if (IsEgg)
{
- if (EggLocation == 60005 && tr.Gender == OriginalTrainerGender && tr.Language == Language && tr.OT == OriginalTrainerName)
- return; // Jacq gift, don't change.
-
- // Apply link trade data, only if it left the OT (ignore if dumped & imported, or cloned, etc.)
- // If not matching the trainer details, mark as a traded egg.
- if (!IsTradedEgg && tr.Gender == OriginalTrainerGender && tr.Language == Language && tr.OT == OriginalTrainerName)
- {
- OriginalTrainerTrash.Clear();
- NicknameTrash.Clear();
- HandlingTrainerTrash.Clear();
- CurrentHandler = 0;
- Language = tr.Language;
- Nickname = SpeciesName.GetEggName(tr.Language, 9);
- OriginalTrainerName = tr.OT;
- HandlingTrainerLanguage = 0;
- }
- else
- {
- HandlingTrainerName = tr.OT;
- HandlingTrainerGender = tr.Gender;
- HandlingTrainerLanguage = (byte)tr.Language;
- SetLinkTradeEgg(Day, Month, Year, Locations.LinkTrade6);
- CurrentHandler = 1;
- }
+ UpdateHandlerEgg(tr);
return;
}
@@ -585,33 +581,79 @@ public void Trade(ITrainerInfo tr, int Day = 1, int Month = 1, int Year = 2015)
TradeHT(tr);
}
+ private void UpdateHandlerEgg(ITrainerInfo tr)
+ {
+ bool belongs = BelongsToSkipVersion(tr);
+ if (EggLocation == 60005 && belongs)
+ return; // Jacq gift, don't change.
+
+ // Apply link trade data, only if it left the OT (ignore if dumped & imported, or cloned, etc.)
+ // If not matching the trainer details, mark as a traded egg.
+ // If it's the OT's, be nice and reset the data.
+ if (belongs)
+ SetHandlerEggOT(tr);
+ else
+ SetHandlerEggTraded(tr);
+ }
+
+ private void SetHandlerEggOT(ITrainerInfo tr)
+ {
+ // Reset back to the OT.
+ OriginalTrainerTrash.Clear();
+ NicknameTrash.Clear();
+ HandlingTrainerTrash.Clear();
+ HandlingTrainerGender = 0;
+ HandlingTrainerLanguage = 0;
+
+ Nickname = SpeciesName.GetEggName(tr.Language, 9);
+ OriginalTrainerName = tr.OT;
+ CurrentHandler = 0;
+ }
+
+ private void SetHandlerEggTraded(ITrainerInfo tr)
+ {
+ HandlingTrainerName = tr.OT;
+ HandlingTrainerGender = tr.Gender;
+ HandlingTrainerLanguage = (byte)tr.Language;
+
+ var date = EncounterDate.GetDateSwitch();
+ SetLinkTradeEgg(date.Day, date.Month, date.Year, Locations.LinkTrade6);
+ CurrentHandler = 1;
+ }
+
public void FixMemories()
{
if (IsEgg) // No memories if is egg.
{
// HT_Language is set for eggs
- HandlingTrainerMemoryVariable = HandlingTrainerFriendship = HandlingTrainerMemory = HandlingTrainerMemoryIntensity = HandlingTrainerMemoryFeeling = 0;
- /* OriginalTrainerFriendship */
- OriginalTrainerMemoryVariable = OriginalTrainerMemory = OriginalTrainerMemoryIntensity = OriginalTrainerMemoryFeeling = 0;
+ this.ClearMemoriesOT();
+ this.ClearMemoriesHT();
+ HandlingTrainerGender = 0;
+ HandlingTrainerFriendship = 0;
+ HandlingTrainerTrash.Clear();
return;
}
if (IsUntraded)
{
- // HT_Language is set for gifts
- // Skip clearing that.
- HandlingTrainerMemoryVariable = HandlingTrainerFriendship = HandlingTrainerMemory = HandlingTrainerMemoryIntensity = HandlingTrainerMemoryFeeling = 0;
+ // HT_Language is set for gifts -- skip clearing that.
+ this.ClearMemoriesHT();
+ HandlingTrainerGender = 0;
+ HandlingTrainerFriendship = 0;
+ HandlingTrainerTrash.Clear();
+ }
+ else
+ {
+ var gen = Generation;
+ if (gen < 6)
+ this.ClearMemoriesOT();
}
-
- var gen = Generation;
- if (gen < 6)
- OriginalTrainerMemoryVariable = OriginalTrainerMemory = OriginalTrainerMemoryIntensity = OriginalTrainerMemoryFeeling = 0;
}
private bool TradeOT(ITrainerInfo tr)
{
// Check to see if the OT matches the SAV's OT info.
- if (!(tr.ID32 == ID32 && tr.Gender == OriginalTrainerGender && tr.OT == OriginalTrainerName))
+ if (!BelongsTo(tr))
return false;
CurrentHandler = 0;
diff --git a/PKHeX.Core/PKM/PKM.cs b/PKHeX.Core/PKM/PKM.cs
index e8f8601f4..89bc45fc2 100644
--- a/PKHeX.Core/PKM/PKM.cs
+++ b/PKHeX.Core/PKM/PKM.cs
@@ -797,13 +797,13 @@ public bool ForcePartyData()
///
/// Day the was traded.
/// Month the was traded.
- /// Day the was traded.
+ /// Day the was traded.
/// Link Trade location value.
- protected void SetLinkTradeEgg(int day, int month, int y, ushort location)
+ protected void SetLinkTradeEgg(int day, int month, int year, ushort location)
{
MetDay = (byte)day;
MetMonth = (byte)month;
- MetYear = (byte)(y - 2000);
+ MetYear = (byte)(year - 2000);
MetLocation = location;
}
diff --git a/PKHeX.Core/PKM/Shared/G4PKM.cs b/PKHeX.Core/PKM/Shared/G4PKM.cs
index 1b2e2da76..114add24b 100644
--- a/PKHeX.Core/PKM/Shared/G4PKM.cs
+++ b/PKHeX.Core/PKM/Shared/G4PKM.cs
@@ -5,7 +5,7 @@
namespace PKHeX.Core;
/// Generation 4 format.
-public abstract class G4PKM : PKM,
+public abstract class G4PKM : PKM, IHandlerUpdate,
IRibbonSetEvent3, IRibbonSetEvent4, IRibbonSetUnique3, IRibbonSetUnique4, IRibbonSetCommon3, IRibbonSetCommon4, IRibbonSetRibbons, IContestStats, IGroundTile, IAppliedMarkings4
{
protected G4PKM(byte[] data) : base(data) { }
@@ -279,15 +279,29 @@ public sealed override byte Ball
}
// Synthetic Trading Logic
- public bool Trade(string SAV_Trainer, uint savID32, int SAV_GENDER, int Day = 1, int Month = 1, int Year = 2009)
+ public bool BelongsTo(ITrainerInfo tr)
{
- // Eggs do not have any modifications done if they are traded
- if (IsEgg && !(SAV_Trainer == OriginalTrainerName && savID32 == ID32 && SAV_GENDER == OriginalTrainerGender))
+ if (tr.Version != Version)
+ return false;
+ if (tr.ID32 != ID32)
+ return false;
+ if (tr.Gender != OriginalTrainerGender)
+ return false;
+ return tr.OT == OriginalTrainerName;
+ }
+
+ public void UpdateHandler(ITrainerInfo tr)
+ {
+ if (IsEgg)
{
- SetLinkTradeEgg(Day, Month, Year, Locations.LinkTrade4);
- return true;
+ // Don't bother updating eggs that were already traded.
+ const ushort location = Locations.LinkTrade4;
+ if (MetLocation != location && !BelongsTo(tr))
+ {
+ var date = EncounterDate.GetDateNDS();
+ SetLinkTradeEgg(date.Day, date.Month, date.Year, location);
+ }
}
- return false;
}
// Enforce D/P content only (no Pt or HG/SS)
diff --git a/PKHeX.Core/PKM/Shared/G6PKM.cs b/PKHeX.Core/PKM/Shared/G6PKM.cs
index fe8f7bce8..3fc26cedc 100644
--- a/PKHeX.Core/PKM/Shared/G6PKM.cs
+++ b/PKHeX.Core/PKM/Shared/G6PKM.cs
@@ -4,7 +4,7 @@
namespace PKHeX.Core;
/// Generation 6 format.
-public abstract class G6PKM : PKM, ISanityChecksum
+public abstract class G6PKM : PKM, ISanityChecksum, IHandlerUpdate
{
public override int SIZE_PARTY => PokeCrypto.SIZE_6PARTY;
public override int SIZE_STORED => PokeCrypto.SIZE_6STORED;
@@ -79,20 +79,41 @@ public void FixRelearn()
}
// Synthetic Trading Logic
- public void Trade(ITrainerInfo tr, int Day = 1, int Month = 1, int Year = 2015)
+ public bool BelongsTo(ITrainerInfo tr)
+ {
+ if (tr.Version != Version)
+ return false;
+ if (tr.ID32 != ID32)
+ return false;
+ if (tr.Gender != OriginalTrainerGender)
+ return false;
+ return tr.OT == OriginalTrainerName;
+ }
+
+ public void UpdateHandler(ITrainerInfo tr)
{
if (IsEgg)
{
// Eggs do not have any modifications done if they are traded
// Apply link trade data, only if it left the OT (ignore if dumped & imported, or cloned, etc.)
- if ((tr.TID16 != TID16) || (tr.SID16 != SID16) || (tr.Gender != OriginalTrainerGender) || (tr.OT != OriginalTrainerName))
- SetLinkTradeEgg(Day, Month, Year, Locations.LinkTrade6);
+ const ushort location = Locations.LinkTrade6;
+ if (MetLocation != location && !BelongsTo(tr))
+ {
+ var date = EncounterDate.GetDate3DS();
+ SetLinkTradeEgg(date.Day, date.Month, date.Year, location);
+ }
return;
}
// Process to the HT if the OT of the Pokémon does not match the SAV's OT info.
+ var handler = CurrentHandler;
if (!TradeOT(tr))
TradeHT(tr);
+ if (handler == CurrentHandler)
+ return; // Logic updated Friendship
+ // Copy over the Friendship Value only under certain circumstances
+ if (HasMove((int)Move.Return) || HasMove((int)Move.Frustration))
+ CurrentFriendship = OppositeFriendship;
}
protected abstract bool TradeOT(ITrainerInfo tr);
diff --git a/PKHeX.Core/PKM/Util/EntitySorting.cs b/PKHeX.Core/PKM/Util/EntitySorting.cs
index a7df26b06..1fb361e13 100644
--- a/PKHeX.Core/PKM/Util/EntitySorting.cs
+++ b/PKHeX.Core/PKM/Util/EntitySorting.cs
@@ -251,7 +251,16 @@ private static int GetFriendshipDelta(PKM pk)
var currentFriendship = pk.CurrentFriendship;
if (currentFriendship == 255)
return 255;
- var baseFriendship = pk.PersonalInfo.BaseFriendship;
+
+ var baseFriendship = GetInitialFriendship(pk);
return currentFriendship - baseFriendship;
}
+
+ private static byte GetInitialFriendship(PKM pk)
+ {
+ // Don't get too intricate with this, we generally want to know if it's been raised.
+ if (pk.WasEgg)
+ return EggStateLegality.EggHatchFriendshipGeneral;
+ return pk.PersonalInfo.BaseFriendship;
+ }
}
diff --git a/PKHeX.Core/Saves/Abstractions/ITrainerInfo.cs b/PKHeX.Core/Saves/Abstractions/ITrainerInfo.cs
index 3f5e11203..b957606f0 100644
--- a/PKHeX.Core/Saves/Abstractions/ITrainerInfo.cs
+++ b/PKHeX.Core/Saves/Abstractions/ITrainerInfo.cs
@@ -41,36 +41,6 @@ public static void ApplyTo(this ITrainerInfo info, PKM pk)
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.HandlingTrainerName = sav.OT;
- pk.HandlingTrainerGender = sav.Gender;
- pk.HandlingTrainerFriendship = pk.OriginalTrainerFriendship;
- pk.CurrentHandler = 1;
- if (pk is IHandlerLanguage h)
- h.HandlingTrainerLanguage = (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.
///
@@ -82,9 +52,6 @@ public static bool IsFromTrainer(this ITrainerInfo tr, PKM pk)
if (pk.IsEgg)
return tr.IsFromTrainerEgg(pk);
- if (tr.Version == GameVersion.Any)
- return true;
-
if (!IsFromTrainerNoVersion(tr, pk))
return false;
diff --git a/PKHeX.Core/Saves/SAV4.cs b/PKHeX.Core/Saves/SAV4.cs
index ae44fcd48..b5ac05ceb 100644
--- a/PKHeX.Core/Saves/SAV4.cs
+++ b/PKHeX.Core/Saves/SAV4.cs
@@ -347,9 +347,8 @@ protected sealed override void SetPKM(PKM pk, bool isParty = false)
{
var pk4 = (PK4)pk;
// Apply to this Save File
- var now = EncounterDate.GetDateNDS();
- if (pk4.Trade(OT, ID32, Gender, now.Day, now.Month, now.Year))
- pk.RefreshChecksum();
+ pk4.UpdateHandler(this);
+ pk.RefreshChecksum();
}
// Daycare
diff --git a/PKHeX.Core/Saves/SAV4BR.cs b/PKHeX.Core/Saves/SAV4BR.cs
index bd99cfab5..74fd6369f 100644
--- a/PKHeX.Core/Saves/SAV4BR.cs
+++ b/PKHeX.Core/Saves/SAV4BR.cs
@@ -244,9 +244,8 @@ protected override void SetPKM(PKM pk, bool isParty = false)
{
var pk4 = (BK4)pk;
// Apply to this Save File
- var now = EncounterDate.GetDateNDS();
- if (pk4.Trade(OT, ID32, Gender, now.Day, now.Month, now.Year))
- pk.RefreshChecksum();
+ pk4.UpdateHandler(this);
+ pk.RefreshChecksum();
}
protected override void SetPartyValues(PKM pk, bool isParty)
diff --git a/PKHeX.Core/Saves/SAV4DP.cs b/PKHeX.Core/Saves/SAV4DP.cs
index 0f74bf516..4a6164157 100644
--- a/PKHeX.Core/Saves/SAV4DP.cs
+++ b/PKHeX.Core/Saves/SAV4DP.cs
@@ -24,6 +24,7 @@ public SAV4DP(byte[] data) : base(data, GeneralSize, StorageSize, GeneralSize)
public override Zukan4 Dex { get; }
protected override SAV4 CloneInternal4() => State.Exportable ? new SAV4DP((byte[])Data.Clone()) : new SAV4DP();
+ public override GameVersion Version { get => GameVersion.DP; set { } }
public override PersonalTable4 Personal => PersonalTable.DP;
public override ReadOnlySpan HeldItems => Legal.HeldItems_DP;
public override int MaxItemID => Legal.MaxItemID_4_DP;
diff --git a/PKHeX.Core/Saves/SAV4HGSS.cs b/PKHeX.Core/Saves/SAV4HGSS.cs
index 76dbec195..23d8450c1 100644
--- a/PKHeX.Core/Saves/SAV4HGSS.cs
+++ b/PKHeX.Core/Saves/SAV4HGSS.cs
@@ -25,6 +25,7 @@ public SAV4HGSS(byte[] data) : base(data, GeneralSize, StorageSize, GeneralSize
public override Zukan4 Dex { get; }
protected override SAV4 CloneInternal4() => State.Exportable ? new SAV4HGSS((byte[])Data.Clone()) : new SAV4HGSS();
+ public override GameVersion Version { get => GameVersion.HGSS; set { } }
public override PersonalTable4 Personal => PersonalTable.HGSS;
public override ReadOnlySpan HeldItems => Legal.HeldItems_HGSS;
public override int MaxItemID => Legal.MaxItemID_4_HGSS;
diff --git a/PKHeX.Core/Saves/SAV4Pt.cs b/PKHeX.Core/Saves/SAV4Pt.cs
index 94deb3883..02ea01367 100644
--- a/PKHeX.Core/Saves/SAV4Pt.cs
+++ b/PKHeX.Core/Saves/SAV4Pt.cs
@@ -23,6 +23,7 @@ public SAV4Pt(byte[] data) : base(data, GeneralSize, StorageSize, GeneralSize)
public override Zukan4 Dex { get; }
protected override SAV4 CloneInternal4() => State.Exportable ? new SAV4Pt((byte[])Data.Clone()) : new SAV4Pt();
+ public override GameVersion Version { get => GameVersion.Pt; set { } }
public override PersonalTable4 Personal => PersonalTable.Pt;
public override ReadOnlySpan HeldItems => Legal.HeldItems_Pt;
public override int MaxItemID => Legal.MaxItemID_4_Pt;
diff --git a/PKHeX.Core/Saves/SAV5.cs b/PKHeX.Core/Saves/SAV5.cs
index 8b00573e6..db11c3d48 100644
--- a/PKHeX.Core/Saves/SAV5.cs
+++ b/PKHeX.Core/Saves/SAV5.cs
@@ -109,9 +109,8 @@ protected override void SetPKM(PKM pk, bool isParty = false)
{
var pk5 = (PK5)pk;
// Apply to this Save File
- var now = EncounterDate.GetDateNDS();
- if (pk5.Trade(OT, ID32, Gender, now.Day, now.Month, now.Year))
- pk.RefreshChecksum();
+ pk5.UpdateHandler(this);
+ pk5.RefreshChecksum();
}
// Player Data
diff --git a/PKHeX.Core/Saves/SAV6.cs b/PKHeX.Core/Saves/SAV6.cs
index 06b9a1270..b5fee4815 100644
--- a/PKHeX.Core/Saves/SAV6.cs
+++ b/PKHeX.Core/Saves/SAV6.cs
@@ -111,15 +111,7 @@ protected override void SetPKM(PKM pk, bool isParty = false)
{
PK6 pk6 = (PK6)pk;
// Apply to this Save File
- int CT = pk6.CurrentHandler;
- var now = EncounterDate.GetDate3DS();
- pk6.Trade(this, now.Day, now.Month, now.Year);
- if (CT != pk6.CurrentHandler) // Logic updated Friendship
- {
- // Copy over the Friendship Value only under certain circumstances
- if (pk6.HasMove((int)Move.Return) || pk6.HasMove((int)Move.Frustration))
- pk6.CurrentFriendship = pk6.OppositeFriendship;
- }
+ pk6.UpdateHandler(this);
pk6.FormArgumentElapsed = pk6.FormArgumentMaximum = 0;
pk6.FormArgumentRemain = (byte)GetFormArgument(pk, isParty);
diff --git a/PKHeX.Core/Saves/SAV7.cs b/PKHeX.Core/Saves/SAV7.cs
index c8f4a0d94..2a46c5dbc 100644
--- a/PKHeX.Core/Saves/SAV7.cs
+++ b/PKHeX.Core/Saves/SAV7.cs
@@ -169,15 +169,7 @@ protected override void SetPKM(PKM pk, bool isParty = false)
{
PK7 pk7 = (PK7)pk;
// Apply to this Save File
- int CT = pk7.CurrentHandler;
- var now = EncounterDate.GetDate3DS();
- pk7.Trade(this, now.Day, now.Month, now.Year);
- if (CT != pk7.CurrentHandler) // Logic updated Friendship
- {
- // Copy over the Friendship Value only under certain circumstances
- if (pk7.HasMove((int)Move.Return) || pk7.HasMove((int)Move.Frustration))
- pk7.CurrentFriendship = pk7.OppositeFriendship;
- }
+ pk7.UpdateHandler(this);
pk7.FormArgumentElapsed = pk7.FormArgumentMaximum = 0;
pk7.FormArgumentRemain = (byte)GetFormArgument(pk);
diff --git a/PKHeX.Core/Saves/SAV7b.cs b/PKHeX.Core/Saves/SAV7b.cs
index 00a92f405..2382430c5 100644
--- a/PKHeX.Core/Saves/SAV7b.cs
+++ b/PKHeX.Core/Saves/SAV7b.cs
@@ -96,8 +96,7 @@ protected override void SetPKM(PKM pk, bool isParty = false)
{
var pb7 = (PB7)pk;
// Apply to this Save File
- var now = EncounterDate.GetDateSwitch();
- pb7.Trade(this, now.Day, now.Month, now.Year);
+ pb7.UpdateHandler(this);
pb7.RefreshChecksum();
}
diff --git a/PKHeX.Core/Saves/SAV8BS.cs b/PKHeX.Core/Saves/SAV8BS.cs
index 346b9002c..1b833aff1 100644
--- a/PKHeX.Core/Saves/SAV8BS.cs
+++ b/PKHeX.Core/Saves/SAV8BS.cs
@@ -304,8 +304,7 @@ protected override void SetPKM(PKM pk, bool isParty = false)
{
var pb8 = (PB8)pk;
// Apply to this Save File
- var now = EncounterDate.GetDateSwitch();
- pb8.Trade(this, now.Day, now.Month, now.Year);
+ pb8.UpdateHandler(this);
pb8.RefreshChecksum();
if (SetUpdateRecords != PKMImportSetting.Skip)
diff --git a/PKHeX.Core/Saves/SAV8LA.cs b/PKHeX.Core/Saves/SAV8LA.cs
index 473cf9b2e..8115ccaf4 100644
--- a/PKHeX.Core/Saves/SAV8LA.cs
+++ b/PKHeX.Core/Saves/SAV8LA.cs
@@ -148,7 +148,7 @@ protected override void SetPKM(PKM pk, bool isParty = false)
{
var pa8 = (PA8)pk;
// Apply to this Save File
- pa8.Trade(this);
+ pa8.UpdateHandler(this);
pa8.RefreshChecksum();
}
diff --git a/PKHeX.Core/Saves/SAV8SWSH.cs b/PKHeX.Core/Saves/SAV8SWSH.cs
index 53ec75eda..4752ce9a1 100644
--- a/PKHeX.Core/Saves/SAV8SWSH.cs
+++ b/PKHeX.Core/Saves/SAV8SWSH.cs
@@ -191,8 +191,7 @@ protected override void SetPKM(PKM pk, bool isParty = false)
{
PK8 pk8 = (PK8)pk;
// Apply to this Save File
- var now = EncounterDate.GetDateSwitch();
- pk8.Trade(this, now.Day, now.Month, now.Year);
+ pk8.UpdateHandler(this);
if (FormArgumentUtil.IsFormArgumentTypeDatePair(pk8.Species, pk8.Form))
{
diff --git a/PKHeX.Core/Saves/SAV9SV.cs b/PKHeX.Core/Saves/SAV9SV.cs
index 890ae86d8..2b0380e8a 100644
--- a/PKHeX.Core/Saves/SAV9SV.cs
+++ b/PKHeX.Core/Saves/SAV9SV.cs
@@ -197,8 +197,7 @@ protected override void SetPKM(PKM pk, bool isParty = false)
{
PK9 pk9 = (PK9)pk;
// Apply to this Save File
- var now = EncounterDate.GetDateSwitch();
- pk9.Trade(this, now.Day, now.Month, now.Year);
+ pk9.UpdateHandler(this);
if (FormArgumentUtil.IsFormArgumentTypeDatePair(pk9.Species, pk9.Form))
{
diff --git a/PKHeX.Core/Saves/SaveFile.cs b/PKHeX.Core/Saves/SaveFile.cs
index 54bd49b81..d76451dac 100644
--- a/PKHeX.Core/Saves/SaveFile.cs
+++ b/PKHeX.Core/Saves/SaveFile.cs
@@ -61,7 +61,7 @@ protected virtual byte[] GetFinalData()
#region Metadata & Limits
public virtual string MiscSaveInfo() => string.Empty;
public virtual bool IsVersionValid() => true;
- public virtual GameVersion Version { get => default; set { } }
+ public abstract GameVersion Version { get; set; }
public abstract bool ChecksumsValid { get; }
public abstract string ChecksumInfo { get; }
public abstract byte Generation { get; }
diff --git a/PKHeX.Core/Saves/Storage/Bank3.cs b/PKHeX.Core/Saves/Storage/Bank3.cs
index e97de240b..da8bf35f2 100644
--- a/PKHeX.Core/Saves/Storage/Bank3.cs
+++ b/PKHeX.Core/Saves/Storage/Bank3.cs
@@ -9,6 +9,7 @@ public sealed class Bank3 : BulkStorage
{
public Bank3(byte[] data) : base(data, typeof(PK3), 0) => Version = GameVersion.RS;
+ public override GameVersion Version { get => GameVersion.RS; set { } }
public override PersonalTable3 Personal => PersonalTable.RS;
public override ReadOnlySpan HeldItems => Legal.HeldItems_RS;
protected override Bank3 CloneInternal() => new((byte[])Data.Clone());
diff --git a/PKHeX.Core/Saves/Storage/Bank4.cs b/PKHeX.Core/Saves/Storage/Bank4.cs
index 195f961e3..8b1e10ae9 100644
--- a/PKHeX.Core/Saves/Storage/Bank4.cs
+++ b/PKHeX.Core/Saves/Storage/Bank4.cs
@@ -9,6 +9,7 @@ public sealed class Bank4 : BulkStorage
{
public Bank4(byte[] data) : base(data, typeof(PK4), 0) => Version = GameVersion.HGSS;
+ public override GameVersion Version { get => GameVersion.HGSS; set { } }
public override PersonalTable4 Personal => PersonalTable.HGSS;
public override ReadOnlySpan HeldItems => Legal.HeldItems_HGSS;
protected override Bank4 CloneInternal() => new((byte[])Data.Clone());
diff --git a/PKHeX.Core/Saves/Storage/Bank7.cs b/PKHeX.Core/Saves/Storage/Bank7.cs
index 808573d32..8eac84a85 100644
--- a/PKHeX.Core/Saves/Storage/Bank7.cs
+++ b/PKHeX.Core/Saves/Storage/Bank7.cs
@@ -11,6 +11,7 @@ public sealed class Bank7 : BulkStorage
{
public Bank7(byte[] data, Type t, [ConstantExpected] int start, int slotsPerBox = 30) : base(data, t, start, slotsPerBox) => Version = GameVersion.USUM;
+ public override GameVersion Version { get => GameVersion.USUM; set { } }
public override PersonalTable7 Personal => PersonalTable.USUM;
public override ReadOnlySpan HeldItems => Legal.HeldItems_SM;
protected override Bank7 CloneInternal() => new((byte[])Data.Clone(), PKMType, BoxStart, SlotsPerBox);
diff --git a/PKHeX.Core/Saves/Storage/SAV4Ranch.cs b/PKHeX.Core/Saves/Storage/SAV4Ranch.cs
index 561b8f394..2d66c7165 100644
--- a/PKHeX.Core/Saves/Storage/SAV4Ranch.cs
+++ b/PKHeX.Core/Saves/Storage/SAV4Ranch.cs
@@ -13,7 +13,6 @@ public sealed class SAV4Ranch : BulkStorage, ISaveFileRevision
protected override int SIZE_STORED => PokeCrypto.SIZE_4RSTORED;
protected override int SIZE_PARTY => PokeCrypto.SIZE_4RSTORED;
public int MaxToyID => (int) ((SaveRevision == 0) ? RanchToyType.Poke_Ball : RanchToyType.Water);
-
public int SaveRevision => Version == GameVersion.DP ? 0 : 1;
public string SaveRevisionString => Version == GameVersion.DP ? "-DP" : "-Pt";
@@ -46,9 +45,12 @@ public sealed class SAV4Ranch : BulkStorage, ISaveFileRevision
protected override bool IsSlotSwapProtected(int box, int slot) => IsSlotOverwriteProtected(box, slot);
public override bool IsPKMPresent(ReadOnlySpan data) => EntityDetection.IsPresentSAV4Ranch(data);
+
+ private readonly GameVersion _version;
+ public override GameVersion Version { get => _version; set { } }
public SAV4Ranch(byte[] data) : base(data, typeof(RK4), 0)
{
- Version = Data.Length == SaveUtil.SIZE_G4RANCH_PLAT ? GameVersion.Pt : GameVersion.DP;
+ _version = Data.Length == SaveUtil.SIZE_G4RANCH_PLAT ? GameVersion.Pt : GameVersion.DP;
OT = GetString(Data.AsSpan(0x770, 0x12));