From 7e4877e7de6fb0016474ebca084b191d137ee77c Mon Sep 17 00:00:00 2001 From: Kurt Date: Sat, 4 Dec 2021 23:52:33 -0800 Subject: [PATCH] Add 3 more useless blocks Spinda registers correctly now, lol --- PKHeX.Core/Saves/SAV8BS.cs | 9 ++-- .../Gen8/BS/ContestPhotoLanguage8b.cs | 29 ++++++++++++ .../Substructures/Gen8/BS/UnionSaveData8b.cs | 18 ++++++++ .../Saves/Substructures/Gen8/BS/Zukan8b.cs | 3 ++ .../Substructures/Gen8/BS/ZukanSpinda8b.cs | 46 +++++++++++++++++++ 5 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 PKHeX.Core/Saves/Substructures/Gen8/BS/ContestPhotoLanguage8b.cs create mode 100644 PKHeX.Core/Saves/Substructures/Gen8/BS/UnionSaveData8b.cs create mode 100644 PKHeX.Core/Saves/Substructures/Gen8/BS/ZukanSpinda8b.cs diff --git a/PKHeX.Core/Saves/SAV8BS.cs b/PKHeX.Core/Saves/SAV8BS.cs index e1dfafd6c..a6e573f61 100644 --- a/PKHeX.Core/Saves/SAV8BS.cs +++ b/PKHeX.Core/Saves/SAV8BS.cs @@ -59,9 +59,9 @@ public SAV8BS(byte[] data, bool exportable = true) : base(data, exportable) UgSaveData = new UgSaveData8b(this, 0x9A89C); // size: 0x27A0 // 0x9D03C - GMS_DATA // size: 0x31304, (GMS_POINT_DATA[650], ushort, ushort, byte)?; substructure GMS_POINT_HISTORY_DATA[5] // 0xCE340 - PLAYER_NETWORK_DATA; bcatFlagArray byte[1300] - // 0xCEA10(?) - UnionSaveData - // 0xCEA1C(?) - CON_PHOTO_LANG_DATA -- contest photo language data; photo_data[5], photo_fx[5] - // ZUKAN_PERSONAL_RND_DATA -- Spinda PID storage; uint[4] see, uint[4] get, uint[17] reserve + UnionSave = new UnionSaveData8b(this, 0xCEA10); // size: 0xC + ContestPhotoLanguage = new ContestPhotoLanguage8b(this, 0xCEA1C); // size: 0x18 + ZukanExtra = new ZukanSpinda8b(this, 0xCEA34); // size: 0x64 (100) // CON_PHOTO_EXT_DATA[5] // GMS_POINT_HISTORY_EXT_DATA[3250] UgCount = new UgCountRecord8b(this, 0xE8178); // size: 0x20 @@ -221,6 +221,9 @@ public override bool ChecksumsValid public Poketch8b Poketch { get; } public Daycare8b Daycare { get; } public UgSaveData8b UgSaveData { get; } + public UnionSaveData8b UnionSave { get; } + public ContestPhotoLanguage8b ContestPhotoLanguage { get; } + public ZukanSpinda8b ZukanExtra { get; } public UgCountRecord8b UgCount { get; } // First Savedata Expansion! diff --git a/PKHeX.Core/Saves/Substructures/Gen8/BS/ContestPhotoLanguage8b.cs b/PKHeX.Core/Saves/Substructures/Gen8/BS/ContestPhotoLanguage8b.cs new file mode 100644 index 000000000..57a714a86 --- /dev/null +++ b/PKHeX.Core/Saves/Substructures/Gen8/BS/ContestPhotoLanguage8b.cs @@ -0,0 +1,29 @@ +using System; + +namespace PKHeX.Core; + +/// +/// Contest photo language data +/// +/// CON_PHOTO_LANG_DATA size: 0x18 +public sealed class ContestPhotoLanguage8b : SaveBlock +{ + // structure: + // 5 (Style, Beautiful, Cute, Clever, Strong) bytes of language IDs + // (3+4 bytes alignment) + // 2 s64 reserved + private const int COUNT_CONTEST = 5; + + public ContestPhotoLanguage8b(SAV8BS sav, int offset) : base(sav) => Offset = offset; + + public byte GetLanguage(int contest) => Data[Offset + GetContestOffset(contest)]; + + private static int GetContestOffset(int contest) + { + if ((uint)contest >= COUNT_CONTEST) + throw new ArgumentOutOfRangeException(nameof(contest)); + return contest; + } + + public void SetLanguage(int contest, int language) => Data[Offset + GetContestOffset(contest)] = (byte)language; +} diff --git a/PKHeX.Core/Saves/Substructures/Gen8/BS/UnionSaveData8b.cs b/PKHeX.Core/Saves/Substructures/Gen8/BS/UnionSaveData8b.cs new file mode 100644 index 000000000..ecd8bccb8 --- /dev/null +++ b/PKHeX.Core/Saves/Substructures/Gen8/BS/UnionSaveData8b.cs @@ -0,0 +1,18 @@ +using System; +using System.ComponentModel; + +namespace PKHeX.Core; + +/// +/// Details about the Player's union room unlock/penalty. +/// +/// UnionSaveData size: 0xC +[TypeConverter(typeof(ExpandableObjectConverter))] +public sealed class UnionSaveData8b : SaveBlock +{ + public UnionSaveData8b(SAV8BS sav, int offset) : base(sav) => Offset = offset; + + public bool IsInitTalk { get => BitConverter.ToUInt32(Data, Offset) == 1; set => BitConverter.GetBytes(value ? 1u : 0u).CopyTo(Data, Offset); } + public int PenaltyCount { get => BitConverter.ToInt32(Data, Offset + 0x4); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x4); } + public float PenaltyTime { get => BitConverter.ToSingle(Data, Offset + 0x8); set => BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x8); } +} diff --git a/PKHeX.Core/Saves/Substructures/Gen8/BS/Zukan8b.cs b/PKHeX.Core/Saves/Substructures/Gen8/BS/Zukan8b.cs index e666b8c70..d69340e4a 100644 --- a/PKHeX.Core/Saves/Substructures/Gen8/BS/Zukan8b.cs +++ b/PKHeX.Core/Saves/Substructures/Gen8/BS/Zukan8b.cs @@ -339,11 +339,14 @@ public override void SetDex(PKM pkm) if (pkm.IsEgg) // do not add return; + var originalState = GetState(species); bool shiny = pkm.IsShiny; SetState(species, ZukanState8b.Caught); SetGenderFlag(species, pkm.Gender, shiny); SetLanguageFlag(species, pkm.Language, true); SetHasFormFlag(species, pkm.Form, shiny, true); + if (species is (int)Species.Spinda) + ((SAV8BS)SAV).ZukanExtra.SetDex(originalState, pkm.EncryptionConstant, pkm.Gender, shiny); } private void SetGenderFlag(int species, int gender, bool shiny) diff --git a/PKHeX.Core/Saves/Substructures/Gen8/BS/ZukanSpinda8b.cs b/PKHeX.Core/Saves/Substructures/Gen8/BS/ZukanSpinda8b.cs new file mode 100644 index 000000000..f86e67fed --- /dev/null +++ b/PKHeX.Core/Saves/Substructures/Gen8/BS/ZukanSpinda8b.cs @@ -0,0 +1,46 @@ +using System; + +namespace PKHeX.Core; + +/// +/// Tracks data for the game. +/// +/// ZUKAN_PERSONAL_RND_DATA size: 0x64 (100) +public sealed class ZukanSpinda8b : SaveBlock +{ + public ZukanSpinda8b(SAV8BS sav, int offset) : base(sav) => Offset = offset; + + public uint GetSeen(int gender, bool shiny) + { + var ofs = GetOffset(gender, shiny); + return BitConverter.ToUInt32(Data, Offset + ofs); + } + + public uint GetCaught(int gender, bool shiny) + { + var ofs = GetOffset(gender, shiny); + return BitConverter.ToUInt32(Data, Offset + 0x10 + ofs); + } + + public void SetSeen(int gender, bool shiny, uint value) + { + var ofs = GetOffset(gender, shiny); + BitConverter.GetBytes(value).CopyTo(Data, Offset + ofs); + } + + public void SetCaught(int gender, bool shiny, uint value) + { + var ofs = GetOffset(gender, shiny); + BitConverter.GetBytes(value).CopyTo(Data, Offset + 0x10 + ofs); + } + + private static int GetOffset(int gender, bool shiny) => 4 * ((gender & 1) + (shiny ? 2 : 0)); + + public void SetDex(ZukanState8b state, uint ec, int gender, bool shiny) + { + if (state < ZukanState8b.Seen) // not seen yet + SetSeen(gender, shiny, ec); + if (state < ZukanState8b.Caught) // not caught yet + SetCaught(gender, shiny, ec); + } +}