From a75e09780cb2e1ec4244f9fb62fb8a17f2c73da6 Mon Sep 17 00:00:00 2001 From: Pasquale Nardiello Date: Tue, 17 Dec 2024 03:23:50 +0100 Subject: [PATCH] Added Initial edito for Secret Bases in RSE (#4386) * Started making Secret base 3 editor * Completed Initial RSE secret bases manipulation. --- PKHeX.Core/Saves/SAV3E.cs | 3 + PKHeX.Core/Saves/SAV3RS.cs | 3 + .../Saves/Substructures/Gen3/IGen3Hoenn.cs | 1 + .../Saves/Substructures/Gen3/SecretBase3.cs | 46 +- .../Substructures/Gen3/SecretBaseManager3.cs | 61 +++ .../Controls/SAV Editor/SAVEditor.cs | 13 +- .../Gen3/SAV_SecretBase3.Designer.cs | 502 ++++++++++++++++++ .../Save Editors/Gen3/SAV_SecretBase3.cs | 225 ++++++++ 8 files changed, 834 insertions(+), 20 deletions(-) create mode 100644 PKHeX.Core/Saves/Substructures/Gen3/SecretBaseManager3.cs create mode 100644 PKHeX.WinForms/Subforms/Save Editors/Gen3/SAV_SecretBase3.Designer.cs create mode 100644 PKHeX.WinForms/Subforms/Save Editors/Gen3/SAV_SecretBase3.cs diff --git a/PKHeX.Core/Saves/SAV3E.cs b/PKHeX.Core/Saves/SAV3E.cs index ffdea2144..6aa974862 100644 --- a/PKHeX.Core/Saves/SAV3E.cs +++ b/PKHeX.Core/Saves/SAV3E.cs @@ -283,6 +283,9 @@ public override Gen3MysteryData MysteryData public byte WaldaPatternID { get => Large[Walda + 0x15]; set => Large[Walda + 0x15] = value; } public bool WaldaUnlocked { get => Large[Walda + 0x16] != 0; set => Large[Walda + 0x16] = (byte)(value ? 1 : 0); } + private Memory SecretBaseData => Large.AsMemory(0x1A9C, SecretBaseManager3.BaseCount * SecretBase3.SIZE); + public SecretBaseManager3 SecretBases => new(SecretBaseData); + private const int Painting = 0x2F90; private const int CountPaintings = 5; private Span GetPaintingSpan(int index) diff --git a/PKHeX.Core/Saves/SAV3RS.cs b/PKHeX.Core/Saves/SAV3RS.cs index 2ceb979d4..6abf98428 100644 --- a/PKHeX.Core/Saves/SAV3RS.cs +++ b/PKHeX.Core/Saves/SAV3RS.cs @@ -165,6 +165,9 @@ public int SwarmIndex protected override int SeenOffset3 => 0x3A8C; + private Memory SecretBaseData => Large.AsMemory(0x1A08, SecretBaseManager3.BaseCount * SecretBase3.SIZE); + public SecretBaseManager3 SecretBases => new(SecretBaseData); + private const int Painting = 0x2EFC; private const int CountPaintings = 5; private Span GetPaintingSpan(int index) diff --git a/PKHeX.Core/Saves/Substructures/Gen3/IGen3Hoenn.cs b/PKHeX.Core/Saves/Substructures/Gen3/IGen3Hoenn.cs index 8799f8e5c..09666240b 100644 --- a/PKHeX.Core/Saves/Substructures/Gen3/IGen3Hoenn.cs +++ b/PKHeX.Core/Saves/Substructures/Gen3/IGen3Hoenn.cs @@ -17,6 +17,7 @@ public interface IGen3Hoenn int SwarmIndex { get; set; } RecordMixing3Gift RecordMixingGift { get; set; } + SecretBaseManager3 SecretBases { get; } Paintings3 GetPainting(int index); void SetPainting(int index, Paintings3 value); diff --git a/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3.cs b/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3.cs index 6b6762a6c..1c2ea6b2a 100644 --- a/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3.cs +++ b/PKHeX.Core/Saves/Substructures/Gen3/SecretBase3.cs @@ -7,11 +7,24 @@ public sealed class SecretBase3(Memory raw) { public const int SIZE = 160; - private Span Data => raw.Span; + public static string GetTrainerClass(int value) => value switch + { + 0 => "Rich Boy/Lady", + 1 => "Youngster/Lass", + 2 => "Bug Catcher/Schoolkid", + 3 => "Camper/Picnicker", + 4 => "Ace Trainer", + 5 => "Rich Boy/Lady", + 6 => "Youngster/Lass", + 7 => "Bug Catcher/Schoolkid", + 8 => "Camper/Picnicker", + 9 => "Ace Trainer", + _ => "???", + }; - private bool Japanese => Language == (int) LanguageID.Japanese; + public Span Data => raw.Span; - public int SecretBaseLocation { get => Data[0]; set => Data[0] = (byte) value; } + public int SecretBaseLocation { get => Data[0]; set => Data[0] = (byte)value; } public byte OriginalTrainerGender { @@ -31,19 +44,18 @@ public int RegistryStatus set => Data[1] = (byte)((Data[1] & 0x3F) | ((value & 3) << 6)); } + public Span OriginalTrainerTrash => Data.Slice(2, 7); + + public bool IsTrainerPresent => OriginalTrainerTrash[0] != StringConverter3.TerminatorByte; + public string OriginalTrainerName { - get => StringConverter3.GetString(Data.Slice(2, 7), Language); - set => StringConverter3.SetString(Data.Slice(2, 7), value, 7, Language, StringConverterOption.ClearFF); + get => StringConverter3.GetString(OriginalTrainerTrash, Language); + set => StringConverter3.SetString(OriginalTrainerTrash, value, 7, Language, StringConverterOption.ClearFF); } - public uint OT_ID - { - get => ReadUInt32LittleEndian(Data[9..]); - set => WriteUInt32LittleEndian(Data[9..], value); - } - - public int OT_Class => Data[9] % 5; + public int OriginalTrainerClass => Data[9] % 5; + public string OriginalTrainerClassName => GetTrainerClass(OriginalTrainerClass); public int Language { get => Data[0x0D]; set => Data[0x0D] = (byte)value; } public ushort SecretBasesReceived @@ -53,7 +65,7 @@ public ushort SecretBasesReceived } public byte TimesEntered { get => Data[0x10]; set => Data[0x10] = value; } - public int Unused11 { get => Data[0x11]; set => Data[0x11] = (byte)value; } // alignment padding + public int Unused11 { get => Data[0x11]; set => Data[0x11] = (byte)value; } // alignment padding public Span GetDecorations() => Data.Slice(0x12, 0x10); public void SetDecorations(Span value) => value.CopyTo(GetDecorations()); @@ -70,13 +82,13 @@ public SecretBase3Team Team public ushort TID16 { - get => (ushort)OT_ID; - set => OT_ID = (ushort)(SID16 | value); + get => ReadUInt16LittleEndian(Data[0x9..]); + set => WriteUInt16LittleEndian(Data[0x9..], value); } public ushort SID16 { - get => (ushort)(OT_ID >> 16); - set => OT_ID = (ushort)((value << 16) | TID16); + get => ReadUInt16LittleEndian(Data[0xB..]); + set => WriteUInt16LittleEndian(Data[0xB..], value); } } diff --git a/PKHeX.Core/Saves/Substructures/Gen3/SecretBaseManager3.cs b/PKHeX.Core/Saves/Substructures/Gen3/SecretBaseManager3.cs new file mode 100644 index 000000000..c51ebc842 --- /dev/null +++ b/PKHeX.Core/Saves/Substructures/Gen3/SecretBaseManager3.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace PKHeX.Core; + +public sealed class SecretBaseManager3 +{ + public const int BaseCount = 20; + private readonly bool[] Occupied = new bool[BaseCount]; + + private readonly Memory Data; + + public List Bases { get; set; } + public int Count => Bases.Count; + + public SecretBaseManager3(Memory data) + { + Data = data; + Bases = new List(BaseCount); + for (int i = 0; i < 20 ; i ++) + { + var slice = GetBase(i); + var tmp = new SecretBase3(slice); + if (tmp.IsTrainerPresent) + { + Occupied[i] = true; + Bases.Add(tmp); + } + else + { + Occupied[i] = false; + } + } + } + + private Memory GetBase(int index) + { + ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, BaseCount, nameof(index)); + return Data.Slice(index * SecretBase3.SIZE, SecretBase3.SIZE); + } + + public void Save() => WriteTo(Data.Span); + + private void WriteTo(Span data) + { + // Initialize: Wipe trainer name of each slot + for (int i = 0; i < BaseCount; i++) + data.Slice((i * SecretBase3.SIZE) + 2, 7).Fill(StringConverter3.TerminatorByte); + + var tmp = Bases.ToList(); + for (int i = 0; i < BaseCount; i++) + { + if (!Occupied[i]) + continue; + var tmpbase = tmp[0]; + tmpbase.Data.CopyTo(data[(i * SecretBase3.SIZE)..]); + tmp.RemoveAt(0); + } + } +} diff --git a/PKHeX.WinForms/Controls/SAV Editor/SAVEditor.cs b/PKHeX.WinForms/Controls/SAV Editor/SAVEditor.cs index dfbfb54a0..0840b4484 100644 --- a/PKHeX.WinForms/Controls/SAV Editor/SAVEditor.cs +++ b/PKHeX.WinForms/Controls/SAV Editor/SAVEditor.cs @@ -209,7 +209,7 @@ private SlotInfoMisc GetSlotData(int index) { if (GetCurrentDaycare() is not { } s) throw new Exception(); - return new SlotInfoMisc(s.GetDaycareSlot(index), index) {Type = StorageSlotType.Daycare}; + return new SlotInfoMisc(s.GetDaycareSlot(index), index) { Type = StorageSlotType.Daycare }; } public void SetPKMBoxes() @@ -605,7 +605,6 @@ private static void OpenDialog(Form f) private void B_OpenBerryField_Click(object sender, EventArgs e) => OpenDialog(new SAV_BerryFieldXY((SAV6XY)SAV)); private void B_OpenPokeblocks_Click(object sender, EventArgs e) => OpenDialog(new SAV_PokeBlockORAS((SAV6AO)SAV)); private void B_OpenSuperTraining_Click(object sender, EventArgs e) => OpenDialog(new SAV_SuperTrain((SAV6)SAV)); - private void B_OpenSecretBase_Click(object sender, EventArgs e) => OpenDialog(new SAV_SecretBase((SAV6AO)SAV)); private void B_CellsStickers_Click(object sender, EventArgs e) => OpenDialog(new SAV_ZygardeCell((SAV7)SAV)); private void B_LinkInfo_Click(object sender, EventArgs e) => OpenDialog(new SAV_Link6(SAV)); private void B_OpenApricorn_Click(object sender, EventArgs e) => OpenDialog(new SAV_Apricorn((SAV4HGSS)SAV)); @@ -617,6 +616,14 @@ private static void OpenDialog(Form f) private void B_OpenUnityTowerEditor_Click(object sender, EventArgs e) => OpenDialog(new SAV_UnityTower((SAV5)SAV)); private void B_OpenChatterEditor_Click(object sender, EventArgs e) => OpenDialog(new SAV_Chatter(SAV)); + private void B_OpenSecretBase_Click(object sender, EventArgs e) + { + if (SAV is SAV3 s3) + OpenDialog(new SAV_SecretBase3(s3)); + else if (SAV is SAV6AO ao) + OpenDialog(new SAV_SecretBase(ao)); + } + private void B_Roamer_Click(object sender, EventArgs e) { if (SAV is SAV3 s3) @@ -1210,7 +1217,7 @@ private void ToggleViewSubEditors(SaveFile sav) GB_Daycare.Visible = sav is IDaycareStorage or IDaycareMulti; B_ConvertKorean.Visible = sav is SAV4; B_OpenPokeblocks.Visible = sav is SAV6AO; - B_OpenSecretBase.Visible = sav is SAV6AO; + B_OpenSecretBase.Visible = sav is SAV6AO or IGen3Hoenn; B_OpenPokepuffs.Visible = sav is ISaveBlock6Main; B_JPEG.Visible = B_OpenLinkInfo.Visible = B_OpenSuperTraining.Visible = B_OUTPasserby.Visible = sav is ISaveBlock6Main; B_OpenBoxLayout.Visible = sav is IBoxDetailName; diff --git a/PKHeX.WinForms/Subforms/Save Editors/Gen3/SAV_SecretBase3.Designer.cs b/PKHeX.WinForms/Subforms/Save Editors/Gen3/SAV_SecretBase3.Designer.cs new file mode 100644 index 000000000..9dc96053c --- /dev/null +++ b/PKHeX.WinForms/Subforms/Save Editors/Gen3/SAV_SecretBase3.Designer.cs @@ -0,0 +1,502 @@ +namespace PKHeX.WinForms +{ + partial class SAV_SecretBase3 + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + LB_Bases = new System.Windows.Forms.ListBox(); + L_Trainers = new System.Windows.Forms.Label(); + T_TrainerGender = new Controls.GenderToggle(); + TB_Name = new System.Windows.Forms.TextBox(); + CHK_Battled = new System.Windows.Forms.CheckBox(); + CHK_Registered = new System.Windows.Forms.CheckBox(); + TB_Entered = new System.Windows.Forms.TextBox(); + L_Entered = new System.Windows.Forms.Label(); + TB_Class = new System.Windows.Forms.TextBox(); + L_Class = new System.Windows.Forms.Label(); + TB_TID = new System.Windows.Forms.TextBox(); + TB_SID = new System.Windows.Forms.TextBox(); + L_TID = new System.Windows.Forms.Label(); + L_SID = new System.Windows.Forms.Label(); + NUD_TeamMember = new System.Windows.Forms.NumericUpDown(); + CB_Species = new System.Windows.Forms.ComboBox(); + L_Member = new System.Windows.Forms.Label(); + CB_Form = new System.Windows.Forms.ComboBox(); + L_Item = new System.Windows.Forms.Label(); + CB_Item = new System.Windows.Forms.ComboBox(); + L_PID = new System.Windows.Forms.Label(); + TB_PID = new System.Windows.Forms.TextBox(); + NUD_Level = new System.Windows.Forms.NumericUpDown(); + NUD_EVs = new System.Windows.Forms.NumericUpDown(); + L_Level = new System.Windows.Forms.Label(); + L_EVs = new System.Windows.Forms.Label(); + CB_Move1 = new System.Windows.Forms.ComboBox(); + CB_Move2 = new System.Windows.Forms.ComboBox(); + CB_Move3 = new System.Windows.Forms.ComboBox(); + CB_Move4 = new System.Windows.Forms.ComboBox(); + L_Move1 = new System.Windows.Forms.Label(); + L_Move2 = new System.Windows.Forms.Label(); + L_Move3 = new System.Windows.Forms.Label(); + L_Move4 = new System.Windows.Forms.Label(); + B_UpdateTrainer = new System.Windows.Forms.Button(); + B_UpdatePKM = new System.Windows.Forms.Button(); + B_Save = new System.Windows.Forms.Button(); + B_Cancel = new System.Windows.Forms.Button(); + ((System.ComponentModel.ISupportInitialize)NUD_TeamMember).BeginInit(); + ((System.ComponentModel.ISupportInitialize)NUD_Level).BeginInit(); + ((System.ComponentModel.ISupportInitialize)NUD_EVs).BeginInit(); + SuspendLayout(); + // + // LB_Bases + // + LB_Bases.FormattingEnabled = true; + LB_Bases.ItemHeight = 15; + LB_Bases.Location = new System.Drawing.Point(12, 26); + LB_Bases.Name = "LB_Bases"; + LB_Bases.Size = new System.Drawing.Size(125, 379); + LB_Bases.TabIndex = 0; + // + // L_Trainers + // + L_Trainers.AutoSize = true; + L_Trainers.Location = new System.Drawing.Point(12, 9); + L_Trainers.Name = "L_Trainers"; + L_Trainers.Size = new System.Drawing.Size(50, 15); + L_Trainers.TabIndex = 1; + L_Trainers.Text = "Trainers:"; + // + // T_TrainerGender + // + T_TrainerGender.AllowClick = true; + T_TrainerGender.Gender = 2; + T_TrainerGender.Location = new System.Drawing.Point(282, 31); + T_TrainerGender.Name = "T_TrainerGender"; + T_TrainerGender.Size = new System.Drawing.Size(18, 18); + T_TrainerGender.TabIndex = 2; + // + // TB_Name + // + TB_Name.Location = new System.Drawing.Point(154, 26); + TB_Name.Name = "TB_Name"; + TB_Name.Size = new System.Drawing.Size(122, 23); + TB_Name.TabIndex = 3; + // + // CHK_Battled + // + CHK_Battled.AutoSize = true; + CHK_Battled.Location = new System.Drawing.Point(168, 65); + CHK_Battled.Name = "CHK_Battled"; + CHK_Battled.Size = new System.Drawing.Size(97, 19); + CHK_Battled.TabIndex = 4; + CHK_Battled.Text = "Battled Today"; + CHK_Battled.UseVisualStyleBackColor = true; + // + // CHK_Registered + // + CHK_Registered.AutoSize = true; + CHK_Registered.Location = new System.Drawing.Point(168, 90); + CHK_Registered.Name = "CHK_Registered"; + CHK_Registered.Size = new System.Drawing.Size(81, 19); + CHK_Registered.TabIndex = 5; + CHK_Registered.Text = "Registered"; + CHK_Registered.UseVisualStyleBackColor = true; + // + // TB_Entered + // + TB_Entered.Location = new System.Drawing.Point(154, 218); + TB_Entered.Name = "TB_Entered"; + TB_Entered.Size = new System.Drawing.Size(74, 23); + TB_Entered.TabIndex = 7; + // + // L_Entered + // + L_Entered.AutoSize = true; + L_Entered.Location = new System.Drawing.Point(154, 200); + L_Entered.Name = "L_Entered"; + L_Entered.Size = new System.Drawing.Size(122, 15); + L_Entered.TabIndex = 8; + L_Entered.Text = "Number of entrances:"; + // + // TB_Class + // + TB_Class.Location = new System.Drawing.Point(154, 283); + TB_Class.Name = "TB_Class"; + TB_Class.ReadOnly = true; + TB_Class.Size = new System.Drawing.Size(146, 23); + TB_Class.TabIndex = 9; + // + // L_Class + // + L_Class.AutoSize = true; + L_Class.Location = new System.Drawing.Point(154, 265); + L_Class.Name = "L_Class"; + L_Class.Size = new System.Drawing.Size(73, 15); + L_Class.TabIndex = 10; + L_Class.Text = "Trainer class:"; + // + // TB_TID + // + TB_TID.Location = new System.Drawing.Point(191, 127); + TB_TID.Name = "TB_TID"; + TB_TID.Size = new System.Drawing.Size(74, 23); + TB_TID.TabIndex = 11; + // + // TB_SID + // + TB_SID.Location = new System.Drawing.Point(191, 156); + TB_SID.Name = "TB_SID"; + TB_SID.Size = new System.Drawing.Size(74, 23); + TB_SID.TabIndex = 12; + // + // L_TID + // + L_TID.AutoSize = true; + L_TID.Location = new System.Drawing.Point(158, 130); + L_TID.Name = "L_TID"; + L_TID.Size = new System.Drawing.Size(27, 15); + L_TID.TabIndex = 13; + L_TID.Text = "TID:"; + // + // L_SID + // + L_SID.AutoSize = true; + L_SID.Location = new System.Drawing.Point(158, 159); + L_SID.Name = "L_SID"; + L_SID.Size = new System.Drawing.Size(27, 15); + L_SID.TabIndex = 14; + L_SID.Text = "SID:"; + // + // NUD_TeamMember + // + NUD_TeamMember.Location = new System.Drawing.Point(476, 32); + NUD_TeamMember.Maximum = new decimal(new int[] { 6, 0, 0, 0 }); + NUD_TeamMember.Minimum = new decimal(new int[] { 1, 0, 0, 0 }); + NUD_TeamMember.Name = "NUD_TeamMember"; + NUD_TeamMember.Size = new System.Drawing.Size(33, 23); + NUD_TeamMember.TabIndex = 15; + NUD_TeamMember.Value = new decimal(new int[] { 1, 0, 0, 0 }); + // + // CB_Species + // + CB_Species.FormattingEnabled = true; + CB_Species.Location = new System.Drawing.Point(384, 74); + CB_Species.Name = "CB_Species"; + CB_Species.Size = new System.Drawing.Size(139, 23); + CB_Species.TabIndex = 16; + // + // L_Member + // + L_Member.AutoSize = true; + L_Member.Location = new System.Drawing.Point(384, 34); + L_Member.Name = "L_Member"; + L_Member.Size = new System.Drawing.Size(86, 15); + L_Member.TabIndex = 17; + L_Member.Text = "Team Member:"; + // + // CB_Form + // + CB_Form.Enabled = false; + CB_Form.FormattingEnabled = true; + CB_Form.Location = new System.Drawing.Point(529, 74); + CB_Form.Name = "CB_Form"; + CB_Form.Size = new System.Drawing.Size(38, 23); + CB_Form.TabIndex = 18; + CB_Form.Visible = false; + // + // L_Item + // + L_Item.AutoSize = true; + L_Item.Location = new System.Drawing.Point(384, 173); + L_Item.Name = "L_Item"; + L_Item.Size = new System.Drawing.Size(34, 15); + L_Item.TabIndex = 19; + L_Item.Text = "Item:"; + // + // CB_Item + // + CB_Item.FormattingEnabled = true; + CB_Item.Location = new System.Drawing.Point(384, 191); + CB_Item.Name = "CB_Item"; + CB_Item.Size = new System.Drawing.Size(139, 23); + CB_Item.TabIndex = 20; + // + // L_PID + // + L_PID.AutoSize = true; + L_PID.Location = new System.Drawing.Point(384, 114); + L_PID.Name = "L_PID"; + L_PID.Size = new System.Drawing.Size(28, 15); + L_PID.TabIndex = 21; + L_PID.Text = "PID:"; + // + // TB_PID + // + TB_PID.Location = new System.Drawing.Point(384, 132); + TB_PID.Name = "TB_PID"; + TB_PID.Size = new System.Drawing.Size(100, 23); + TB_PID.TabIndex = 22; + // + // NUD_Level + // + NUD_Level.Location = new System.Drawing.Point(412, 235); + NUD_Level.Name = "NUD_Level"; + NUD_Level.Size = new System.Drawing.Size(46, 23); + NUD_Level.TabIndex = 23; + // + // NUD_EVs + // + NUD_EVs.Location = new System.Drawing.Point(510, 235); + NUD_EVs.Maximum = new decimal(new int[] { 85, 0, 0, 0 }); + NUD_EVs.Name = "NUD_EVs"; + NUD_EVs.Size = new System.Drawing.Size(46, 23); + NUD_EVs.TabIndex = 24; + // + // L_Level + // + L_Level.AutoSize = true; + L_Level.Location = new System.Drawing.Point(384, 237); + L_Level.Name = "L_Level"; + L_Level.Size = new System.Drawing.Size(22, 15); + L_Level.TabIndex = 25; + L_Level.Text = "LV:"; + // + // L_EVs + // + L_EVs.AutoSize = true; + L_EVs.Location = new System.Drawing.Point(476, 237); + L_EVs.Name = "L_EVs"; + L_EVs.Size = new System.Drawing.Size(28, 15); + L_EVs.TabIndex = 26; + L_EVs.Text = "EVs:"; + // + // CB_Move1 + // + CB_Move1.FormattingEnabled = true; + CB_Move1.Location = new System.Drawing.Point(439, 283); + CB_Move1.Name = "CB_Move1"; + CB_Move1.Size = new System.Drawing.Size(139, 23); + CB_Move1.TabIndex = 27; + // + // CB_Move2 + // + CB_Move2.FormattingEnabled = true; + CB_Move2.Location = new System.Drawing.Point(439, 312); + CB_Move2.Name = "CB_Move2"; + CB_Move2.Size = new System.Drawing.Size(139, 23); + CB_Move2.TabIndex = 28; + // + // CB_Move3 + // + CB_Move3.FormattingEnabled = true; + CB_Move3.Location = new System.Drawing.Point(439, 341); + CB_Move3.Name = "CB_Move3"; + CB_Move3.Size = new System.Drawing.Size(139, 23); + CB_Move3.TabIndex = 29; + // + // CB_Move4 + // + CB_Move4.FormattingEnabled = true; + CB_Move4.Location = new System.Drawing.Point(439, 370); + CB_Move4.Name = "CB_Move4"; + CB_Move4.Size = new System.Drawing.Size(139, 23); + CB_Move4.TabIndex = 31; + // + // L_Move1 + // + L_Move1.AutoSize = true; + L_Move1.Location = new System.Drawing.Point(384, 286); + L_Move1.Name = "L_Move1"; + L_Move1.Size = new System.Drawing.Size(49, 15); + L_Move1.TabIndex = 32; + L_Move1.Text = "Move 1:"; + // + // L_Move2 + // + L_Move2.AutoSize = true; + L_Move2.Location = new System.Drawing.Point(384, 315); + L_Move2.Name = "L_Move2"; + L_Move2.Size = new System.Drawing.Size(49, 15); + L_Move2.TabIndex = 33; + L_Move2.Text = "Move 2:"; + // + // L_Move3 + // + L_Move3.AutoSize = true; + L_Move3.Location = new System.Drawing.Point(384, 344); + L_Move3.Name = "L_Move3"; + L_Move3.Size = new System.Drawing.Size(49, 15); + L_Move3.TabIndex = 34; + L_Move3.Text = "Move 3:"; + // + // L_Move4 + // + L_Move4.AutoSize = true; + L_Move4.Location = new System.Drawing.Point(384, 373); + L_Move4.Name = "L_Move4"; + L_Move4.Size = new System.Drawing.Size(49, 15); + L_Move4.TabIndex = 35; + L_Move4.Text = "Move 4:"; + // + // B_UpdateTrainer + // + B_UpdateTrainer.Location = new System.Drawing.Point(154, 332); + B_UpdateTrainer.Name = "B_UpdateTrainer"; + B_UpdateTrainer.Size = new System.Drawing.Size(118, 27); + B_UpdateTrainer.TabIndex = 36; + B_UpdateTrainer.Text = "Update Trainer"; + B_UpdateTrainer.UseVisualStyleBackColor = true; + B_UpdateTrainer.Click += B_UpdateTrainer_Click; + // + // B_UpdatePKM + // + B_UpdatePKM.Location = new System.Drawing.Point(154, 366); + B_UpdatePKM.Name = "B_UpdatePKM"; + B_UpdatePKM.Size = new System.Drawing.Size(118, 27); + B_UpdatePKM.TabIndex = 37; + B_UpdatePKM.Text = "Update PKM"; + B_UpdatePKM.UseVisualStyleBackColor = true; + B_UpdatePKM.Click += B_UpdatePKM_Click; + // + // B_Save + // + B_Save.Location = new System.Drawing.Point(479, 413); + B_Save.Name = "B_Save"; + B_Save.Size = new System.Drawing.Size(88, 27); + B_Save.TabIndex = 38; + B_Save.Text = "Save"; + B_Save.UseVisualStyleBackColor = true; + B_Save.Click += B_Save_Click; + // + // B_Cancel + // + B_Cancel.Location = new System.Drawing.Point(384, 413); + B_Cancel.Name = "B_Cancel"; + B_Cancel.Size = new System.Drawing.Size(88, 27); + B_Cancel.TabIndex = 39; + B_Cancel.Text = "Cancel"; + B_Cancel.UseVisualStyleBackColor = true; + B_Cancel.Click += B_Cancel_Click; + // + // SAV_SecretBase3 + // + AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + ClientSize = new System.Drawing.Size(591, 461); + Controls.Add(B_Cancel); + Controls.Add(B_Save); + Controls.Add(B_UpdatePKM); + Controls.Add(B_UpdateTrainer); + Controls.Add(L_Move4); + Controls.Add(L_Move3); + Controls.Add(L_Move2); + Controls.Add(L_Move1); + Controls.Add(CB_Move4); + Controls.Add(CB_Move3); + Controls.Add(CB_Move2); + Controls.Add(CB_Move1); + Controls.Add(L_EVs); + Controls.Add(L_Level); + Controls.Add(NUD_EVs); + Controls.Add(NUD_Level); + Controls.Add(TB_PID); + Controls.Add(L_PID); + Controls.Add(CB_Item); + Controls.Add(L_Item); + Controls.Add(CB_Form); + Controls.Add(L_Member); + Controls.Add(CB_Species); + Controls.Add(NUD_TeamMember); + Controls.Add(L_SID); + Controls.Add(L_TID); + Controls.Add(TB_SID); + Controls.Add(TB_TID); + Controls.Add(L_Class); + Controls.Add(TB_Class); + Controls.Add(L_Entered); + Controls.Add(TB_Entered); + Controls.Add(CHK_Registered); + Controls.Add(CHK_Battled); + Controls.Add(TB_Name); + Controls.Add(T_TrainerGender); + Controls.Add(L_Trainers); + Controls.Add(LB_Bases); + FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + Icon = Properties.Resources.Icon; + MaximizeBox = false; + MinimizeBox = false; + Name = "SAV_SecretBase3"; + StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; + Text = "Secret Base Editor"; + ((System.ComponentModel.ISupportInitialize)NUD_TeamMember).EndInit(); + ((System.ComponentModel.ISupportInitialize)NUD_Level).EndInit(); + ((System.ComponentModel.ISupportInitialize)NUD_EVs).EndInit(); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private System.Windows.Forms.ListBox LB_Bases; + private System.Windows.Forms.Label L_Trainers; + private Controls.GenderToggle T_TrainerGender; + private System.Windows.Forms.TextBox TB_Name; + private System.Windows.Forms.CheckBox CHK_Battled; + private System.Windows.Forms.CheckBox CHK_Registered; + private System.Windows.Forms.TextBox TB_Entered; + private System.Windows.Forms.Label L_Entered; + private System.Windows.Forms.TextBox TB_Class; + private System.Windows.Forms.Label L_Class; + private System.Windows.Forms.TextBox TB_TID; + private System.Windows.Forms.TextBox TB_SID; + private System.Windows.Forms.Label L_TID; + private System.Windows.Forms.Label L_SID; + private System.Windows.Forms.NumericUpDown NUD_TeamMember; + private System.Windows.Forms.ComboBox CB_Species; + private System.Windows.Forms.Label L_Member; + private System.Windows.Forms.ComboBox CB_Form; + private System.Windows.Forms.Label L_Item; + private System.Windows.Forms.ComboBox CB_Item; + private System.Windows.Forms.Label L_PID; + private System.Windows.Forms.TextBox TB_PID; + private System.Windows.Forms.NumericUpDown NUD_Level; + private System.Windows.Forms.NumericUpDown NUD_EVs; + private System.Windows.Forms.Label L_Level; + private System.Windows.Forms.Label L_EVs; + private System.Windows.Forms.ComboBox CB_Move1; + private System.Windows.Forms.ComboBox CB_Move2; + private System.Windows.Forms.ComboBox CB_Move3; + private System.Windows.Forms.ComboBox CB_Move4; + private System.Windows.Forms.Label L_Move1; + private System.Windows.Forms.Label L_Move2; + private System.Windows.Forms.Label L_Move3; + private System.Windows.Forms.Label L_Move4; + private System.Windows.Forms.Button B_UpdateTrainer; + private System.Windows.Forms.Button B_UpdatePKM; + private System.Windows.Forms.Button B_Save; + private System.Windows.Forms.Button B_Cancel; + } +} diff --git a/PKHeX.WinForms/Subforms/Save Editors/Gen3/SAV_SecretBase3.cs b/PKHeX.WinForms/Subforms/Save Editors/Gen3/SAV_SecretBase3.cs new file mode 100644 index 000000000..00e8a2876 --- /dev/null +++ b/PKHeX.WinForms/Subforms/Save Editors/Gen3/SAV_SecretBase3.cs @@ -0,0 +1,225 @@ +using PKHeX.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Windows.Forms; + +namespace PKHeX.WinForms; + +public partial class SAV_SecretBase3 : Form +{ + private readonly SaveFile Origin; + private readonly SAV3 SAV; + private readonly SecretBaseManager3 Manager; + + public SAV_SecretBase3(SAV3 sav) + { + InitializeComponent(); + //WinFormsUtil.TranslateInterface(this, Main.CurrentLanguage); + SAV = (SAV3)(Origin = sav).Clone(); + + TB_Name.MaxLength = 7; + TB_SID.MaxLength = 5; + TB_TID.MaxLength = 5; + TB_Entered.MaxLength = 3; + TB_PID.CharacterCasing = CharacterCasing.Upper; + TB_PID.MaxLength = 8; + + CB_Species.InitializeBinding(); + CB_Item.InitializeBinding(); + CB_Move1.InitializeBinding(); + CB_Move2.InitializeBinding(); + CB_Move3.InitializeBinding(); + CB_Move4.InitializeBinding(); + CB_Form.InitializeBinding(); + var filtered = GameInfo.FilteredSources; + var moves = filtered.Moves; + CB_Move1.DataSource = new BindingSource(moves, string.Empty); + CB_Move2.DataSource = new BindingSource(moves, string.Empty); + CB_Move3.DataSource = new BindingSource(moves, string.Empty); + CB_Move4.DataSource = new BindingSource(moves, string.Empty); + CB_Item.DataSource = new BindingSource(filtered.Items, string.Empty); + CB_Species.DataSource = new BindingSource(filtered.Species, string.Empty); + CB_Form.DataSource = new List { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '!', '?' }; + + TB_Entered.KeyPress += (_, e) => e.Handled = !(char.IsDigit(e.KeyChar) || char.IsControl(e.KeyChar)); + TB_TID.KeyPress += (_, e) => e.Handled = !(char.IsDigit(e.KeyChar) || char.IsControl(e.KeyChar)); + TB_SID.KeyPress += (_, e) => e.Handled = !(char.IsDigit(e.KeyChar) || char.IsControl(e.KeyChar)); + TB_TID.TextChanged += (_, _) => + { + if (TB_TID.Text.Length == 0) + TB_TID.Text = "0"; + if (uint.Parse(TB_TID.Text) > ushort.MaxValue) + TB_TID.Text = ushort.MaxValue.ToString(); + }; + TB_SID.TextChanged += (_, _) => + { + if (TB_SID.Text.Length == 0) + TB_SID.Text = "0"; + if (uint.Parse(TB_SID.Text) > ushort.MaxValue) + TB_SID.Text = ushort.MaxValue.ToString(); + }; + TB_Entered.TextChanged += (_, _) => + { + if (TB_Entered.Text.Length == 0) + TB_Entered.Text = "0"; + if (uint.Parse(TB_Entered.Text) > byte.MaxValue) + TB_Entered.Text = byte.MaxValue.ToString(); + }; + TB_PID.TextChanged += (_, _) => + { + if (TB_PID.Text.Length == 0) + TB_PID.Text = "0"; + if (!TB_PID.Text.All(c => "0123456789abcdefABCDEF\n".Contains(c))) + TB_PID.Text = uint.MaxValue.ToString("X8"); + }; + + Manager = ((IGen3Hoenn)SAV).SecretBases; + LB_Bases.InitializeBinding(); + LB_Bases.DataSource = Manager.Bases; + LB_Bases.DisplayMember = "OriginalTrainerName"; + + CB_Species.SelectedIndexChanged += (_, _) => + { + if (CB_Species.SelectedIndex <= 0) + { + NUD_Level.Minimum = 0; + TB_PID.Text = "0"; + TB_PID.Enabled = false; + CB_Item.SelectedIndex = 0; + CB_Item.Enabled = false; + CB_Move1.SelectedIndex = 0; + CB_Move1.Enabled = false; + CB_Move2.SelectedIndex = 0; + CB_Move2.Enabled = false; + CB_Move3.SelectedIndex = 0; + CB_Move3.Enabled = false; + CB_Move4.SelectedIndex = 0; + CB_Move4.Enabled = false; + NUD_Level.Value = 0; + NUD_Level.Enabled = false; + NUD_EVs.Value = 0; + NUD_EVs.Enabled = false; + } + else + { + NUD_Level.Minimum = 2; + TB_PID.Enabled = true; + CB_Item.Enabled = true; + CB_Move1.Enabled = true; + CB_Move2.Enabled = true; + CB_Move3.Enabled = true; + CB_Move4.Enabled = true; + NUD_Level.Enabled = true; + NUD_EVs.Enabled = true; + } + }; + NUD_TeamMember.ValueChanged += (_, _) => + { + var secret = (SecretBase3)LB_Bases.SelectedItem!; + ShowPKM(secret.Team.Team[(int)NUD_TeamMember.Value - 1]); + }; + LB_Bases.SelectedIndexChanged += (_, _) => + { + ShowTrainer(); + //NUD_TeamMember.Maximum = ((SecretBase3)LB_Bases.SelectedItem).Team.Team.Length; + }; + + if (Manager.Count > 0) + { + LB_Bases.SelectedIndex = 0; + ShowTrainer(); + } + else + { + B_Save.Enabled = false; + } + } + + private void ShowTrainer() + { + var secret = (SecretBase3)LB_Bases.SelectedItem!; + ShowTrainer(secret); + } + + private void ShowTrainer(SecretBase3 trainer) + { + TB_Name.Text = trainer.OriginalTrainerName; + T_TrainerGender.Gender = trainer.OriginalTrainerGender; + T_TrainerGender.Show(); + TB_TID.Text = trainer.TID16.ToString(); + TB_SID.Text = trainer.SID16.ToString(); + TB_Entered.Text = trainer.TimesEntered.ToString(); + TB_Class.Text = trainer.OriginalTrainerClassName; + CHK_Battled.Checked = trainer.BattledToday; + CHK_Registered.Checked = trainer.RegistryStatus == 1; + NUD_TeamMember.Value = 1; + ShowPKM(trainer.Team.Team[(int)NUD_TeamMember.Value - 1]); + } + + private void ShowPKM(SecretBase3PKM pk) + { + CB_Species.SelectedValue = (int)pk.Species; + if (pk.Species == (int)Species.Unown) + { + CB_Form.SelectedIndex = pk.Form - 1; + CB_Form.Visible = true; + } + else + { + CB_Form.Visible = false; + } + TB_PID.Text = pk.PID.ToString("X8"); + CB_Item.SelectedValue = (int)pk.HeldItem; + CB_Move1.SelectedValue = (int)pk.Move1; + CB_Move2.SelectedValue = (int)pk.Move2; + CB_Move3.SelectedValue = (int)pk.Move3; + CB_Move4.SelectedValue = (int)pk.Move4; + NUD_Level.Value = pk.Level; + NUD_EVs.Value = pk.EVAll; + } + + private void B_UpdateTrainer_Click(object sender, EventArgs e) + { + var secret = (SecretBase3)LB_Bases.SelectedItem!; + secret.OriginalTrainerName = TB_Name.Text; + secret.OriginalTrainerGender = T_TrainerGender.Gender; + secret.TID16 = ushort.Parse(TB_TID.Text); + secret.SID16 = ushort.Parse(TB_SID.Text); + secret.TimesEntered = byte.Parse(TB_Entered.Text); + secret.BattledToday = CHK_Battled.Checked; + secret.RegistryStatus = CHK_Registered.Checked ? 1 : 0; + LB_Bases.DisplayMember = null!; + LB_Bases.DisplayMember = "OriginalTrainerName"; + System.Media.SystemSounds.Asterisk.Play(); + } + + private void B_UpdatePKM_Click(object sender, EventArgs e) + { + var secret = (SecretBase3)LB_Bases.SelectedItem!; + var pkmteam = secret.Team; + var pkm = pkmteam.Team[(int)NUD_TeamMember.Value - 1]; + pkm.Species = (ushort)WinFormsUtil.GetIndex(CB_Species); + pkm.PID = Util.GetHexValue(TB_PID.Text); + pkm.HeldItem = (ushort)WinFormsUtil.GetIndex(CB_Item); + pkm.Move1 = (ushort)WinFormsUtil.GetIndex(CB_Move1); + pkm.Move2 = (ushort)WinFormsUtil.GetIndex(CB_Move2); + pkm.Move3 = (ushort)WinFormsUtil.GetIndex(CB_Move3); + pkm.Move4 = (ushort)WinFormsUtil.GetIndex(CB_Move4); + pkm.Level = Convert.ToByte(NUD_Level.Value); + pkm.EVAll = Convert.ToByte(NUD_EVs.Value); + secret.Team = pkmteam; // save changes + System.Media.SystemSounds.Asterisk.Play(); + } + + private void B_Cancel_Click(object sender, EventArgs e) => Close(); + + private void B_Save_Click(object sender, EventArgs e) + { + var bases = LB_Bases.Items.Cast().ToList(); + Manager.Bases = bases; + Manager.Save(); + Origin.CopyChangesFrom(SAV); + Close(); + } +}