Add GS Ball manual enable button

Adds a "misc" editor for Gen2 saves (only crystal for now), with a single button to enable the event (button enabled if the event is not yet enabled, lol)

746a06f1de/engine/menus/save.asm (L164-L175)

Closes #4335
This commit is contained in:
Kurt 2024-08-07 18:55:19 -05:00
parent c9f3894076
commit 97aa9805a9
4 changed files with 152 additions and 1 deletions

View file

@ -825,6 +825,25 @@ public sealed class SAV2 : SaveFile, ILangDeviantSave, IEventFlagArray, IEventWo
Data[0x9000] = (byte)(0xFF - value);
}
}
private const byte GS_BALL_AVAILABLE = 0x0B;
/// <summary>
/// Triggered on Virtual Console by adding Hall of Fame entry, enabling the event.
/// </summary>
public void EnableGSBallMobileEvent()
{
if (Version is not GameVersion.C)
return;
// Write to the Crystal region of savedata
var primary = Japanese ? 0xA000 : 0x3E3C;
var backup = Japanese ? 0xA083 : 0x3E44;
Data[primary] = Data[backup] = GS_BALL_AVAILABLE;
}
public bool IsEnabledGSBallMobileEvent => Data[Japanese ? 0xA000 : 0x3E3C] == GS_BALL_AVAILABLE;
}
public enum GBMobileCableColor : byte

View file

@ -774,6 +774,7 @@ public partial class SAVEditor : UserControl, ISlotViewer<PictureBox>, ISaveFile
{
using var form = SAV switch
{
SAV2 sav2 => new SAV_Misc2(sav2),
SAV3 sav3 => new SAV_Misc3(sav3),
SAV4 sav4 => new SAV_Misc4(sav4),
SAV5 sav5 => new SAV_Misc5(sav5),
@ -1217,7 +1218,7 @@ public partial class SAVEditor : UserControl, ISlotViewer<PictureBox>, ISaveFile
B_OtherSlots.Visible = sav is SAV1StadiumJ or SAV1Stadium or SAV2Stadium;
B_OpenTrainerInfo.Visible = B_OpenItemPouch.Visible = (sav.HasParty && SAV is not SAV4BR) || SAV is SAV7b; // Box RS & Battle Revolution
B_OpenMiscEditor.Visible = sav is SAV3 or SAV4 or SAV5 or SAV8BS;
B_OpenMiscEditor.Visible = sav is SAV2 { Version: GameVersion.C} or SAV3 or SAV4 or SAV5 or SAV8BS;
B_Roamer.Visible = sav is SAV3 or SAV6XY;
B_OpenHoneyTreeEditor.Visible = sav is SAV4Sinnoh;

View file

@ -0,0 +1,93 @@
namespace PKHeX.WinForms
{
partial class SAV_Misc2
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
B_Save = new System.Windows.Forms.Button();
B_Cancel = new System.Windows.Forms.Button();
B_VirtualConsoleGSBall = new System.Windows.Forms.Button();
SuspendLayout();
//
// B_Save
//
B_Save.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
B_Save.Location = new System.Drawing.Point(248, 220);
B_Save.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
B_Save.Name = "B_Save";
B_Save.Size = new System.Drawing.Size(88, 27);
B_Save.TabIndex = 73;
B_Save.Text = "Save";
B_Save.UseVisualStyleBackColor = true;
B_Save.Click += B_Save_Click;
//
// B_Cancel
//
B_Cancel.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
B_Cancel.Location = new System.Drawing.Point(154, 220);
B_Cancel.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
B_Cancel.Name = "B_Cancel";
B_Cancel.Size = new System.Drawing.Size(88, 27);
B_Cancel.TabIndex = 72;
B_Cancel.Text = "Cancel";
B_Cancel.UseVisualStyleBackColor = true;
B_Cancel.Click += B_Cancel_Click;
//
// B_VirtualConsoleGSBall
//
B_VirtualConsoleGSBall.Location = new System.Drawing.Point(12, 12);
B_VirtualConsoleGSBall.Name = "B_VirtualConsoleGSBall";
B_VirtualConsoleGSBall.Size = new System.Drawing.Size(160, 64);
B_VirtualConsoleGSBall.TabIndex = 74;
B_VirtualConsoleGSBall.Text = "Enable GS Ball Event (Virtual Console)";
B_VirtualConsoleGSBall.UseVisualStyleBackColor = true;
B_VirtualConsoleGSBall.Click += B_VirtualConsoleGSBall_Click;
//
// SAV_Misc2
//
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
ClientSize = new System.Drawing.Size(344, 261);
Controls.Add(B_VirtualConsoleGSBall);
Controls.Add(B_Save);
Controls.Add(B_Cancel);
FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
Icon = Properties.Resources.Icon;
Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
MaximizeBox = false;
MinimumSize = new System.Drawing.Size(231, 167);
Name = "SAV_Misc2";
StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
Text = "Misc Editor";
ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button B_Save;
private System.Windows.Forms.Button B_Cancel;
private System.Windows.Forms.Button B_VirtualConsoleGSBall;
}
}

View file

@ -0,0 +1,38 @@
using System;
using System.Windows.Forms;
using PKHeX.Core;
namespace PKHeX.WinForms;
public partial class SAV_Misc2 : Form
{
private readonly SaveFile Origin;
private readonly SAV2 SAV;
public SAV_Misc2(SAV2 sav)
{
InitializeComponent();
WinFormsUtil.TranslateInterface(this, Main.CurrentLanguage);
SAV = (SAV2)(Origin = sav).Clone();
B_VirtualConsoleGSBall.Visible = SAV.Version is GameVersion.C;
B_VirtualConsoleGSBall.Enabled = !SAV.IsEnabledGSBallMobileEvent;
}
private void B_Save_Click(object sender, EventArgs e)
{
Origin.CopyChangesFrom(SAV);
Close();
}
private void B_Cancel_Click(object sender, EventArgs e) => Close();
private void B_VirtualConsoleGSBall_Click(object sender, EventArgs e)
{
// Don't bother checking if the save is from Virtual Console.
// Can be moved between VC and GB era, and can be a quick way to enable the event on either.
SAV.EnableGSBallMobileEvent();
B_VirtualConsoleGSBall.Enabled = false;
System.Media.SystemSounds.Asterisk.Play();
}
}