From d19acdb6ecffced567b530a0d659e4b9c6d17a75 Mon Sep 17 00:00:00 2001 From: abcboy101 <16735361+abcboy101@users.noreply.github.com> Date: Tue, 22 Oct 2024 09:06:39 -0400 Subject: [PATCH] Support G6/7 player gender editing (#4370) --- PKHeX.Core/Saves/Access/ISaveBlock6Core.cs | 1 + .../Saves/Access/SaveBlockAccessor6AO.cs | 1 + .../Saves/Access/SaveBlockAccessor6AODemo.cs | 1 + .../Saves/Access/SaveBlockAccessor6XY.cs | 1 + PKHeX.Core/Saves/SAV6.cs | 1 + PKHeX.Core/Saves/SAV6AO.cs | 1 + PKHeX.Core/Saves/SAV6AODemo.cs | 1 + PKHeX.Core/Saves/SAV6XY.cs | 1 + .../Substructures/Gen6/FieldMoveModelSave6.cs | 51 +++++++++++++++++++ .../Save Editors/Gen6/SAV_Trainer.Designer.cs | 1 - .../Subforms/Save Editors/Gen6/SAV_Trainer.cs | 1 + .../Gen7/SAV_Trainer7.Designer.cs | 2 +- .../Save Editors/Gen7/SAV_Trainer7.cs | 7 +++ .../Gen7/SAV_Trainer7GG.Designer.cs | 1 - 14 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 PKHeX.Core/Saves/Substructures/Gen6/FieldMoveModelSave6.cs diff --git a/PKHeX.Core/Saves/Access/ISaveBlock6Core.cs b/PKHeX.Core/Saves/Access/ISaveBlock6Core.cs index ba30ab59d..e177cc726 100644 --- a/PKHeX.Core/Saves/Access/ISaveBlock6Core.cs +++ b/PKHeX.Core/Saves/Access/ISaveBlock6Core.cs @@ -11,6 +11,7 @@ public interface ISaveBlock6Core GameTime6 GameTime { get; } Situation6 Situation { get; } PlayTime6 Played { get; } + FieldMoveModelSave6 Overworld { get; } MyStatus6 Status { get; } RecordBlock6 Records { get; } } diff --git a/PKHeX.Core/Saves/Access/SaveBlockAccessor6AO.cs b/PKHeX.Core/Saves/Access/SaveBlockAccessor6AO.cs index 95518a71a..b85a500b0 100644 --- a/PKHeX.Core/Saves/Access/SaveBlockAccessor6AO.cs +++ b/PKHeX.Core/Saves/Access/SaveBlockAccessor6AO.cs @@ -80,6 +80,7 @@ public sealed class SaveBlockAccessor6AO(SAV6AO sav) : ISaveBlockAccessor destBuffer, ReadOnlySpan v public abstract GameTime6 GameTime { get; } public abstract Situation6 Situation { get; } public abstract PlayTime6 Played { get; } + public abstract FieldMoveModelSave6 Overworld { get; } public abstract MyStatus6 Status { get; } public abstract RecordBlock6 Records { get; } public abstract EventWork6 EventWork { get; } diff --git a/PKHeX.Core/Saves/SAV6AO.cs b/PKHeX.Core/Saves/SAV6AO.cs index a3278d79a..047e9c598 100644 --- a/PKHeX.Core/Saves/SAV6AO.cs +++ b/PKHeX.Core/Saves/SAV6AO.cs @@ -48,6 +48,7 @@ private void Initialize() public override GameTime6 GameTime => Blocks.GameTime; public override Situation6 Situation => Blocks.Situation; public override PlayTime6 Played => Blocks.Played; + public override FieldMoveModelSave6 Overworld => Blocks.Overworld; public override MyStatus6 Status => Blocks.Status; public override RecordBlock6AO Records => Blocks.Records; public override EventWork6 EventWork => Blocks.EventWork; diff --git a/PKHeX.Core/Saves/SAV6AODemo.cs b/PKHeX.Core/Saves/SAV6AODemo.cs index 0c91b6f4c..e9fcbc7e3 100644 --- a/PKHeX.Core/Saves/SAV6AODemo.cs +++ b/PKHeX.Core/Saves/SAV6AODemo.cs @@ -45,6 +45,7 @@ private void Initialize() public override GameTime6 GameTime => Blocks.GameTime; public override Situation6 Situation => Blocks.Situation; public override PlayTime6 Played => Blocks.Played; + public override FieldMoveModelSave6 Overworld => Blocks.Overworld; public override MyStatus6 Status => Blocks.Status; public override RecordBlock6 Records => Blocks.Records; public override EventWork6 EventWork => Blocks.EventWork; diff --git a/PKHeX.Core/Saves/SAV6XY.cs b/PKHeX.Core/Saves/SAV6XY.cs index 1513547a0..8ff4973a1 100644 --- a/PKHeX.Core/Saves/SAV6XY.cs +++ b/PKHeX.Core/Saves/SAV6XY.cs @@ -50,6 +50,7 @@ private void Initialize() public override GameTime6 GameTime => Blocks.GameTime; public override Situation6 Situation => Blocks.Situation; public override PlayTime6 Played => Blocks.Played; + public override FieldMoveModelSave6 Overworld => Blocks.Overworld; public override MyStatus6 Status => Blocks.Status; public override RecordBlock6 Records => Blocks.Records; public override EventWork6 EventWork => Blocks.EventWork; diff --git a/PKHeX.Core/Saves/Substructures/Gen6/FieldMoveModelSave6.cs b/PKHeX.Core/Saves/Substructures/Gen6/FieldMoveModelSave6.cs new file mode 100644 index 000000000..321f4a6b3 --- /dev/null +++ b/PKHeX.Core/Saves/Substructures/Gen6/FieldMoveModelSave6.cs @@ -0,0 +1,51 @@ +using System; +using static System.Buffers.Binary.BinaryPrimitives; + +namespace PKHeX.Core; + +public sealed class FieldMoveModelSave6(SAV6 sav, Memory raw) : SaveBlock(sav, raw) +{ + private const int SIZE = 0x108; + private const int PLAYER_MAGIC = 0x43; + private const int OFS_MODEL = 0x8; + + private int GetPlayerModelOffset() + { + for (int i = 0; i < Data.Length; i += SIZE) + { + if (Data[i] == PLAYER_MAGIC) + return i; + } + return -1; + } + + /// + /// Model used for the player when the save is loaded. + /// + /// + /// 1: Serena, 2: Calem, 3: Shauna, 4: Tierno, 5: Trevor, ..., 171: May, 172: Brendan + /// + public int PlayerModel + { + get + { + var ofs = GetPlayerModelOffset(); + if (ofs == -1) + return -1; + return ReadUInt16LittleEndian(Data[(ofs + OFS_MODEL)..]); + } + + set + { + var ofs = GetPlayerModelOffset(); + if (ofs == -1) + return; + WriteUInt16LittleEndian(Data[(ofs + OFS_MODEL)..], (ushort)value); + } + } + + /// + /// Resets the player's model to the expected value based on version and gender. + /// + public void ResetPlayerModel() => PlayerModel = (SAV.Gender == 0 ? 2 : 1) + (SAV is SAV6AO or SAV6AODemo ? 170 : 0); +} diff --git a/PKHeX.WinForms/Subforms/Save Editors/Gen6/SAV_Trainer.Designer.cs b/PKHeX.WinForms/Subforms/Save Editors/Gen6/SAV_Trainer.Designer.cs index 3679b5acf..5064d29d5 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/Gen6/SAV_Trainer.Designer.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/Gen6/SAV_Trainer.Designer.cs @@ -725,7 +725,6 @@ private void InitializeComponent() // CB_Gender // CB_Gender.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - CB_Gender.Enabled = false; CB_Gender.FormattingEnabled = true; CB_Gender.Items.AddRange(new object[] { "♂", "♀" }); CB_Gender.Location = new System.Drawing.Point(115, 59); diff --git a/PKHeX.WinForms/Subforms/Save Editors/Gen6/SAV_Trainer.cs b/PKHeX.WinForms/Subforms/Save Editors/Gen6/SAV_Trainer.cs index 2c83f375e..6a3afe742 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/Gen6/SAV_Trainer.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/Gen6/SAV_Trainer.cs @@ -192,6 +192,7 @@ private void Save() { SAV.Version = (GameVersion)(CB_Game.SelectedIndex + 0x18); SAV.Gender = (byte)CB_Gender.SelectedIndex; + SAV.Overworld.ResetPlayerModel(); SAV.TID16 = (ushort)Util.ToUInt32(MT_TID.Text); SAV.SID16 = (ushort)Util.ToUInt32(MT_SID.Text); diff --git a/PKHeX.WinForms/Subforms/Save Editors/Gen7/SAV_Trainer7.Designer.cs b/PKHeX.WinForms/Subforms/Save Editors/Gen7/SAV_Trainer7.Designer.cs index f57073c64..3bfb1d040 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/Gen7/SAV_Trainer7.Designer.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/Gen7/SAV_Trainer7.Designer.cs @@ -573,7 +573,6 @@ private void InitializeComponent() // CB_Gender // CB_Gender.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - CB_Gender.Enabled = false; CB_Gender.FormattingEnabled = true; CB_Gender.Items.AddRange(new object[] { "♂", "♀" }); CB_Gender.Location = new System.Drawing.Point(115, 59); @@ -581,6 +580,7 @@ private void InitializeComponent() CB_Gender.Name = "CB_Gender"; CB_Gender.Size = new System.Drawing.Size(46, 23); CB_Gender.TabIndex = 22; + CB_Gender.SelectedIndexChanged += UpdateSkinColor; // // TB_MBMS // diff --git a/PKHeX.WinForms/Subforms/Save Editors/Gen7/SAV_Trainer7.cs b/PKHeX.WinForms/Subforms/Save Editors/Gen7/SAV_Trainer7.cs index cca1e1d0a..afa19b190 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/Gen7/SAV_Trainer7.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/Gen7/SAV_Trainer7.cs @@ -601,6 +601,13 @@ private void UpdateBallThrowTypeUnlocked(object sender, EventArgs e) } } + private void UpdateSkinColor(object sender, EventArgs e) + { + if (Loading) + return; + CB_SkinColor.SelectedIndex = (CB_SkinColor.SelectedIndex & ~0x1) | (CB_Gender.SelectedIndex & 1); + } + private void B_AllFlyDest_Click(object sender, EventArgs e) { for (int i = 0; i < CLB_FlyDest.Items.Count; i++) diff --git a/PKHeX.WinForms/Subforms/Save Editors/Gen7/SAV_Trainer7GG.Designer.cs b/PKHeX.WinForms/Subforms/Save Editors/Gen7/SAV_Trainer7GG.Designer.cs index 91cd12df6..f5a25a4c8 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/Gen7/SAV_Trainer7GG.Designer.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/Gen7/SAV_Trainer7GG.Designer.cs @@ -355,7 +355,6 @@ private void InitializeComponent() // CB_Gender // CB_Gender.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; - CB_Gender.Enabled = false; CB_Gender.FormattingEnabled = true; CB_Gender.Items.AddRange(new object[] { "♂", "♀" }); CB_Gender.Location = new System.Drawing.Point(226, 90);