Add trash view/edit to all Trainer forms

Make PID text entry uppercase across the program
Standardize RivalTrash => RivalNameTrash, same for Rival => RivalName
This commit is contained in:
Kurt 2026-03-14 22:28:00 -05:00
parent 94f3937f2f
commit 3317a8bfda
48 changed files with 179 additions and 137 deletions

View File

@ -11,7 +11,7 @@ namespace PKHeX.Core;
/// Object representing a <see cref="PKM"/>'s data and derived properties.
/// </summary>
[DynamicallyAccessedMembers(PublicProperties | NonPublicProperties | PublicParameterlessConstructor)]
public abstract class PKM : ISpeciesForm, ITrainerID32, IGeneration, IShiny, ILangNick, IGameValueLimit, INature, IFatefulEncounter, IStringConverter, ITrashIntrospection
public abstract class PKM : ISpeciesForm, ITrainerID32, IGeneration, IShiny, ILangNick, IGameValueLimit, INature, IFatefulEncounter, IStringConverter, ITrashIntrospection, IContext
{
public abstract int SIZE_PARTY { get; }
public abstract int SIZE_STORED { get; }

View File

@ -35,3 +35,20 @@ public interface IStringConverter
/// <returns>Count of bytes written to <see cref="data"/>.</returns>
int SetString(Span<byte> data, ReadOnlySpan<char> text, int length, StringConverterOption option);
}
public delegate string StringGetter(ReadOnlySpan<byte> data);
public delegate int StringLoader(ReadOnlySpan<byte> data, Span<char> text);
public delegate int StringSetter(Span<byte> data, ReadOnlySpan<char> text, int length, StringConverterOption option);
public sealed class CustomStringConverter : IStringConverter, IGeneration, IContext
{
public required StringGetter Get { get; init; }
public required StringLoader Load { get; init; }
public required StringSetter Set { get; init; }
public required byte Generation { get; init; }
public required EntityContext Context { get; init; }
public string GetString(ReadOnlySpan<byte> data) => Get(data);
public int LoadString(ReadOnlySpan<byte> data, Span<char> text) => Load(data, text);
public int SetString(Span<byte> data, ReadOnlySpan<char> text, int length, StringConverterOption option) => Set(data, text, length, option);
}

View File

@ -5,7 +5,7 @@ namespace PKHeX.Core;
/// <summary>
/// Minimal Trainer Information necessary for generating a <see cref="PKM"/>.
/// </summary>
public interface ITrainerInfo : ITrainerID32ReadOnly, IVersion, IGeneration
public interface ITrainerInfo : ITrainerID32ReadOnly, IVersion, IGeneration, IContext
{
string OT { get; }
byte Gender { get; }
@ -13,7 +13,6 @@ public interface ITrainerInfo : ITrainerID32ReadOnly, IVersion, IGeneration
int Language { get; }
new byte Generation { get; }
EntityContext Context { get; }
}
/// <summary>

View File

@ -293,13 +293,13 @@ public override ushort TID16
public override ushort SID16 { get => 0; set { } }
public string Rival
public string RivalName
{
get => GetString(Data.Slice(Offsets.Rival, MaxStringLengthTrainer));
set => SetString(Data.Slice(Offsets.Rival, MaxStringLengthTrainer), value, MaxStringLengthTrainer, StringConverterOption.Clear50);
}
public Span<byte> RivalTrash { get => Data.Slice(Offsets.Rival, StringLength); set { if (value.Length == StringLength) value.CopyTo(Data[Offsets.Rival..]); } }
public Span<byte> RivalNameTrash { get => Data.Slice(Offsets.Rival, StringLength); set { if (value.Length == StringLength) value.CopyTo(Data[Offsets.Rival..]); } }
public byte RivalStarter { get => Data[Offsets.Starter - 2]; set => Data[Offsets.Starter - 2] = value; }
public byte Starter { get => Data[Offsets.Starter]; set => Data[Offsets.Starter] = value; }

View File

@ -325,13 +325,13 @@ public Span<byte> OriginalTrainerTrash
set { if (value.Length == StringLength) value.CopyTo(Data[(Offsets.Trainer1 + 2)..]); }
}
public string Rival
public string RivalName
{
get => GetString(Data.Slice(Offsets.Rival, (Korean ? 2 : 1) * MaxStringLengthTrainer));
set => SetString(Data.Slice(Offsets.Rival, (Korean ? 2 : 1) * MaxStringLengthTrainer), value, 8, StringConverterOption.Clear50);
}
public Span<byte> RivalTrash
public Span<byte> RivalNameTrash
{
get => Data.Slice(Offsets.Rival, StringLength);
set { if (value.Length == StringLength) value.CopyTo(Data[Offsets.Rival..]); }

View File

@ -340,13 +340,13 @@ public override int PlayedSeconds
public abstract int X { get; set; }
public abstract int Y { get; set; }
public string Rival
public string RivalName
{
get => GetString(RivalTrash);
set => SetString(RivalTrash, value, MaxStringLengthTrainer, StringConverterOption.ClearZero);
get => GetString(RivalNameTrash);
set => SetString(RivalNameTrash, value, MaxStringLengthTrainer, StringConverterOption.ClearZero);
}
public abstract Span<byte> RivalTrash { get; set; }
public abstract Span<byte> RivalNameTrash { get; set; }
public abstract int X2 { get; set; }
public abstract int Y2 { get; set; }

View File

@ -97,7 +97,7 @@ public override void SetBoxWallpaper(int box, int value)
public override int X { get => ReadUInt16LittleEndian(General[0x1240..]); set => WriteUInt16LittleEndian(General[0x1240..], (ushort)(X2 = value)); }
public override int Y { get => ReadUInt16LittleEndian(General[0x1244..]); set => WriteUInt16LittleEndian(General[0x1244..], (ushort)(Y2 = value)); }
public override Span<byte> RivalTrash
public override Span<byte> RivalNameTrash
{
get => General.Slice(0x25A8, MaxStringLengthTrainer * 2);
set { if (value.Length == MaxStringLengthTrainer * 2) value.CopyTo(General[0x25A8..]); }

View File

@ -190,7 +190,7 @@ protected override void SetPKM(PKM pk, bool isParty = false)
public override int X { get => ReadUInt16LittleEndian(General[0x123C..]); set => WriteUInt16LittleEndian(General[0x123C..], (ushort)(X2 = value)); }
public override int Y { get => ReadUInt16LittleEndian(General[0x1240..]); set => WriteUInt16LittleEndian(General[0x1240..], (ushort)(Y2 = value)); }
public override Span<byte> RivalTrash
public override Span<byte> RivalNameTrash
{
get => RivalSpan;
set { if (value.Length == MaxStringLengthTrainer * 2) value.CopyTo(RivalSpan); }

View File

@ -137,7 +137,7 @@ public void SetWallpaperUnlocked(Wallpaper4Pt wallpaperId, bool value)
public override int X { get => ReadUInt16LittleEndian(General[0x1288..]); set => WriteUInt16LittleEndian(General[0x1288..], (ushort)(X2 = value)); }
public override int Y { get => ReadUInt16LittleEndian(General[0x128C..]); set => WriteUInt16LittleEndian(General[0x128C..], (ushort)(Y2 = value)); }
public override Span<byte> RivalTrash
public override Span<byte> RivalNameTrash
{
get => RivalSpan;
set { if (value.Length == MaxStringLengthTrainer * 2) value.CopyTo(RivalSpan); }

View File

@ -51,13 +51,13 @@ public sealed class SAV5B2W2 : SAV5, ISaveBlock5B2W2
public MedalList5 Medals => Blocks.Medals;
public KeySystem5 Keys => Blocks.Keys;
public string Rival
public string RivalName
{
get => GetString(RivalTrash);
set => SetString(RivalTrash, value, MaxStringLengthTrainer, StringConverterOption.ClearZero);
get => GetString(RivalNameTrash);
set => SetString(RivalNameTrash, value, MaxStringLengthTrainer, StringConverterOption.ClearZero);
}
public Span<byte> RivalTrash
public Span<byte> RivalNameTrash
{
get => Data.Slice(0x23BA4, MaxStringLengthTrainer * 2);
set { if (value.Length == MaxStringLengthTrainer * 2) value.CopyTo(Data[0x23BA4..]); }

View File

@ -280,10 +280,12 @@ public override int SetString(Span<byte> destBuffer, ReadOnlySpan<char> value, i
public override int CurrentBox { get => BoxLayout.CurrentBox; set => BoxLayout.CurrentBox = (byte)value; }
public override int BoxesUnlocked { get => BoxLayout.BoxesUnlocked; set => BoxLayout.BoxesUnlocked = (byte)value; }
public string Rival
public Span<byte> RivalNameTrash => Data.Slice(0x55F4, 0x1A);
public string RivalName
{
get => GetString(Data.Slice(0x55F4, 0x1A));
set => SetString(Data.Slice(0x55F4, 0x1A), value, MaxStringLengthTrainer, StringConverterOption.ClearZero);
get => GetString(RivalNameTrash);
set => SetString(RivalNameTrash, value, MaxStringLengthTrainer, StringConverterOption.ClearZero);
}
public short ZoneID // map

View File

@ -51,7 +51,7 @@ public int RegistryStatus
public string OriginalTrainerName
{
get => StringConverter3.GetString(OriginalTrainerTrash, Language);
set => StringConverter3.SetString(OriginalTrainerTrash, value, 7, Language, StringConverterOption.ClearFF);
set => StringConverter3.SetString(OriginalTrainerTrash, value, 7, Language, StringConverterOption.None);
}
public int OriginalTrainerClass => Data[9] % 5;

View File

@ -101,7 +101,7 @@ public int Language
set => Data[0x2D] = (byte)value;
}
private Span<byte> OriginalTrainerTrash => Data.Slice(0x48, 0x1A);
public Span<byte> OriginalTrainerTrash => Data.Slice(0x48, 0x1A);
public string OT
{

View File

@ -11,11 +11,11 @@ public uint Money
set => WriteUInt32LittleEndian(Data[4..], value);
}
private Span<byte> RivalTrash => Data.Slice(0x200, 0x1A);
public Span<byte> RivalNameTrash => Data.Slice(0x200, 0x1A);
public string Rival
public string RivalName
{
get => SAV.GetString(RivalTrash);
set => SAV.SetString(RivalTrash, value, SAV.MaxStringLengthTrainer, StringConverterOption.ClearZero);
get => SAV.GetString(RivalNameTrash);
set => SAV.SetString(RivalNameTrash, value, SAV.MaxStringLengthTrainer, StringConverterOption.ClearZero);
}
}

View File

@ -60,7 +60,7 @@ public int Language
set => Data[0x35] = (byte)value;
}
private Span<byte> OriginalTrainerTrash => Data.Slice(0x38, 0x1A);
public Span<byte> OriginalTrainerTrash => Data.Slice(0x38, 0x1A);
public string OT
{

View File

@ -93,7 +93,7 @@ public int Language
set => Data[0x35] = (byte)value;
}
private Span<byte> OriginalTrainerTrash => Data.Slice(0x38, 0x1A);
public Span<byte> OriginalTrainerTrash => Data.Slice(0x38, 0x1A);
public string OT
{

View File

@ -14,7 +14,7 @@ public sealed class MyStatus8b(SAV8BS sav, Memory<byte> raw) : SaveBlock<SAV8BS>
public const byte MAX_BADGE = 8;
// public const byte MAX_RANK = 5; // unused?
private Span<byte> OriginalTrainerTrash => Data[..0x1A];
public Span<byte> OriginalTrainerTrash => Data[..0x1A];
public string OT
{

View File

@ -57,7 +57,7 @@ public int Language
}
}
private Span<byte> OriginalTrainerTrash => Data.Slice(0x20, 0x1A);
public Span<byte> OriginalTrainerTrash => Data.Slice(0x20, 0x1A);
public string OT
{

View File

@ -175,7 +175,7 @@ public int Language
}
}
private Span<byte> OriginalTrainerTrash => Data.Slice(0xB0, 0x1A);
public Span<byte> OriginalTrainerTrash => Data.Slice(0xB0, 0x1A);
public string OT
{

View File

@ -7,7 +7,7 @@ namespace PKHeX.Core;
public sealed class TrainerCard8(SAV8SWSH sav, SCBlock block) : SaveBlock<SAV8SWSH>(sav, block.Raw)
{
private Span<byte> OriginalTrainerTrash => Data[..0x1A];
public Span<byte> OriginalTrainerTrash => Data[..0x1A];
public string OT
{

View File

@ -56,7 +56,7 @@ public RuntimeLanguage RuntimeLanguageId
set => SAV.SetValue(SaveBlockAccessor9SV.KGameLanguage, (int)value);
}
private Span<byte> OriginalTrainerTrash => Data.Slice(0x10, 0x1A);
public Span<byte> OriginalTrainerTrash => Data.Slice(0x10, 0x1A);
public string OT
{

View File

@ -15,7 +15,7 @@ public sealed class MyStatus9a(SAV9ZA sav, SCBlock block) : SaveBlock<SAV9ZA>(sa
public int Language { get => Data[0x07]; set => Data[0x07] = (byte)value; }
private Span<byte> OriginalTrainerTrash => Data.Slice(0x10, 0x1A);
public Span<byte> OriginalTrainerTrash => Data.Slice(0x10, 0x1A);
public string OT
{

View File

@ -543,6 +543,7 @@ private void InitializeComponent()
//
TB_PID.Anchor = System.Windows.Forms.AnchorStyles.Left;
TB_PID.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
TB_PID.CharacterCasing = System.Windows.Forms.CharacterCasing.Upper;
TB_PID.Font = new System.Drawing.Font("Courier New", 8.25F);
TB_PID.Location = new System.Drawing.Point(0, 3);
TB_PID.Margin = new System.Windows.Forms.Padding(0, 2, 0, 0);
@ -3261,6 +3262,7 @@ private void InitializeComponent()
// TB_EC
//
TB_EC.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
TB_EC.CharacterCasing = System.Windows.Forms.CharacterCasing.Upper;
TB_EC.Font = new System.Drawing.Font("Courier New", 8.25F);
TB_EC.Location = new System.Drawing.Point(184, 2);
TB_EC.Margin = new System.Windows.Forms.Padding(0, 2, 0, 0);

View File

@ -1439,10 +1439,11 @@ private void UpdateNicknameClick(object sender, MouseEventArgs e)
if (ModifierKeys != Keys.Control)
return;
if (sender is not TextBox tb)
return;
// Open Trash/Special Character form
// Set the string back to the entity in the right spot, so the span fetch has the latest data.
Span<byte> trash;
TextBox tb = sender as TextBox ?? TB_Nickname;
if (tb == TB_Nickname)
{
Entity.Nickname = tb.Text;
@ -1463,10 +1464,7 @@ private void UpdateNicknameClick(object sender, MouseEventArgs e)
return;
}
using var d = new TrashEditor(tb, trash, Entity, Entity.Format, Entity.Context);
d.ShowDialog();
tb.Text = d.FinalString;
d.FinalBytes.CopyTo(trash);
TrashEditor.Show(tb, Entity, trash);
}
private void UpdateNotOT(object sender, EventArgs e)

View File

@ -17,16 +17,34 @@ public partial class TrashEditor : Form
private readonly byte[] Raw;
private bool editing;
public TrashEditor(TextBoxBase TB_NN, IStringConverter sav, byte generation, EntityContext context)
: this(TB_NN, [], sav, generation, context) { }
private static TrashEditor Get<T>(TextBoxBase tb, T provider, Span<byte> trash = default) where T : IStringConverter, IGeneration, IContext
=> new(tb, provider, provider.Generation, provider.Context, trash);
public TrashEditor(TextBoxBase TB_NN, Span<byte> raw, IStringConverter converter, byte generation, EntityContext context)
public static void Show<T>(TextBoxBase tb, T provider, Span<byte> trash = default, bool readOnly = false)
where T : IStringConverter, IGeneration, IContext
{
using var form = Get(tb, provider, trash);
if (readOnly)
form.B_Save.Enabled = false;
form.ShowDialog();
tb.Text = form.FinalString;
form.FinalBytes.CopyTo(trash);
}
// workaround to being unable to translate this via reflection with the DevUtil scraper with ref structs
#nullable disable
// ReSharper disable once NotNullOrRequiredMemberIsNotInitialized
private TrashEditor()
{
InitializeComponent();
WinFormsUtil.TranslateInterface(this, Main.CurrentLanguage);
Converter = converter;
}
#nullable enable
FinalString = TB_NN.Text;
private TrashEditor(TextBoxBase tb, IStringConverter converter, byte generation, EntityContext context, Span<byte> raw = default) : this()
{
Converter = converter;
FinalString = tb.Text;
editing = true;
if (raw.Length != 0)
@ -41,8 +59,8 @@ public TrashEditor(TextBoxBase TB_NN, Span<byte> raw, IStringConverter converter
var f = FontUtil.GetPKXFont();
AddCharEditing(f, context);
TB_Text.MaxLength = TB_NN.MaxLength;
TB_Text.Text = TB_NN.Text;
TB_Text.MaxLength = tb.MaxLength;
TB_Text.Text = tb.Text;
TB_Text.Font = f;
if (FLP_Characters.Controls.Count == 0)

View File

@ -210,14 +210,7 @@ private void ClickNickname(object sender, MouseEventArgs e)
if (tb.Text != pk.Nickname) // preserve trash
pk.Nickname = tb.Text;
var nicktrash = pk.NicknameTrash;
var d = new TrashEditor(tb, nicktrash, SAV, SAV.Generation, SAV.Context);
d.ShowDialog();
tb.Text = d.FinalString;
d.FinalBytes.CopyTo(nicktrash);
if (tb.Text != pk.Nickname) // preserve trash
tb.Text = pk.Nickname;
TrashEditor.Show(tb, SAV, pk.NicknameTrash);
}
private void B_Delete_Click(object sender, EventArgs e)

View File

@ -151,13 +151,7 @@ private void ClickNickname(object? sender, EventArgs e)
if (tb.Text != pk.Nickname) // preserve trash
pk.Nickname = tb.Text;
var nicktrash = pk.NicknameTrash;
var d = new TrashEditor(tb, nicktrash, SAV, SAV.Generation, SAV.Context);
d.ShowDialog();
tb.Text = d.FinalString;
d.FinalBytes.CopyTo(nicktrash);
if (tb.Text != pk.Nickname) // preserve trash
tb.Text = pk.Nickname;
TrashEditor.Show(tb, SAV, pk.NicknameTrash);
}
}

View File

@ -1721,6 +1721,7 @@ private void InitializeComponent()
//
// TB_PID
//
TB_PID.CharacterCasing = System.Windows.Forms.CharacterCasing.Upper;
TB_PID.Font = new System.Drawing.Font("Courier New", 8F);
TB_PID.Location = new System.Drawing.Point(90, 53);
TB_PID.Name = "TB_PID";

View File

@ -56,6 +56,7 @@ public SAV_Misc3(SAV3 sav)
if (SAV is SAV3FRLG frlg)
{
TB_RivalName.Text = frlg.RivalName;
TB_RivalName.Click += (_, _) => TrashEditor.Show(TB_RivalName, frlg, frlg.LargeBlock.RivalNameTrash);
// Trainer Card Species
ComboBox[] cba = [CB_TCM1, CB_TCM2, CB_TCM3, CB_TCM4, CB_TCM5, CB_TCM6];
@ -92,7 +93,8 @@ private void B_Save_Click(object sender, EventArgs e)
SaveBattleFrontier();
if (SAV is SAV3FRLG frlg)
{
frlg.RivalName = TB_RivalName.Text;
if (frlg.RivalName != TB_RivalName.Text) // preserve trash
frlg.RivalName = TB_RivalName.Text;
ComboBox[] cba = [CB_TCM1, CB_TCM2, CB_TCM3, CB_TCM4, CB_TCM5, CB_TCM6];
for (int i = 0; i < cba.Length; i++)
{

View File

@ -209,6 +209,7 @@ private void InitializeComponent()
// TB_PID
//
TB_PID.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
TB_PID.CharacterCasing = System.Windows.Forms.CharacterCasing.Upper;
TB_PID.Font = new System.Drawing.Font("Courier New", 8.25F);
TB_PID.Location = new System.Drawing.Point(182, 42);
TB_PID.Margin = new System.Windows.Forms.Padding(0, 1, 0, 0);

View File

@ -255,6 +255,7 @@ private void InitializeComponent()
//
// TB_PID
//
TB_PID.CharacterCasing = System.Windows.Forms.CharacterCasing.Upper;
TB_PID.Location = new System.Drawing.Point(384, 132);
TB_PID.Name = "TB_PID";
TB_PID.Size = new System.Drawing.Size(100, 23);

View File

@ -75,9 +75,26 @@ public SAV_SecretBase3(SAV3 sav)
if (!TB_PID.Text.All(c => "0123456789abcdefABCDEF\n".Contains(c)))
TB_PID.Text = uint.MaxValue.ToString("X8");
};
TB_Name.Click += (_, _) =>
{
if (ModifierKeys != Keys.Control)
return;
var secret = (SecretBase3)LB_Bases.SelectedItem!;
var language = secret.Language;
var converter = new CustomStringConverter
{
Context = EntityContext.Gen3,
Generation = 3,
Get = data => StringConverter3.GetString(data, language),
Load = (data, result) => StringConverter3.LoadString(data, result, language),
Set = (data, value, maxLength, option) => StringConverter3.SetString(data, value, maxLength, language, option),
};
TrashEditor.Show(TB_Name, converter, secret.OriginalTrainerTrash);
};
LB_Bases.InitializeBinding();
LB_Bases.DataSource = Manager.Bases;
LB_Bases.DisplayMember = "OriginalTrainerName";
LB_Bases.DisplayMember = nameof(SecretBase3.OriginalTrainerName);
CB_Species.SelectedIndexChanged += (_, _) =>
{
@ -190,7 +207,7 @@ private void B_UpdateTrainer_Click(object sender, EventArgs e)
secret.BattledToday = CHK_Battled.Checked;
secret.RegistryStatus = CHK_Registered.Checked ? 1 : 0;
LB_Bases.DisplayMember = null!;
LB_Bases.DisplayMember = "OriginalTrainerName";
LB_Bases.DisplayMember = nameof(SecretBase3.OriginalTrainerName);
System.Media.SystemSounds.Asterisk.Play();
}

View File

@ -197,6 +197,7 @@ private void InitializeComponent()
// TB_EC
//
TB_EC.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
TB_EC.CharacterCasing = System.Windows.Forms.CharacterCasing.Upper;
TB_EC.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
TB_EC.Location = new System.Drawing.Point(294, 185);
TB_EC.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);

View File

@ -371,12 +371,7 @@ private void ChangeNickname(object sender, MouseEventArgs e)
var data = Fame.GetEntity(team, member);
var nicktrash = data.Slice(0x18, 26);
var text = tb.Text;
SAV.SetString(nicktrash, text, 12, StringConverterOption.ClearZero);
var d = new TrashEditor(tb, nicktrash, SAV, SAV.Generation, SAV.Context);
d.ShowDialog();
tb.Text = d.FinalString;
d.FinalBytes.CopyTo(nicktrash);
TB_Nickname.Text = StringConverter6.GetString(nicktrash);
SAV.SetString(nicktrash, text, 12, StringConverterOption.None);
TrashEditor.Show(tb, SAV, nicktrash);
}
}

View File

@ -666,6 +666,7 @@ private void InitializeComponent()
// TB_EC
//
TB_EC.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
TB_EC.CharacterCasing = System.Windows.Forms.CharacterCasing.Upper;
TB_EC.Font = new System.Drawing.Font("Courier New", 8.25F);
TB_EC.Location = new System.Drawing.Point(82, 37);
TB_EC.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);

View File

@ -203,7 +203,8 @@ private void Save()
SAV.ConsoleRegion = (byte)WinFormsUtil.GetIndex(CB_3DSReg);
SAV.Language = WinFormsUtil.GetIndex(CB_Language);
SAV.OT = TB_OTName.Text;
if (SAV.OT != TB_OTName.Text) // only modify if changed (preserve trash bytes?)
SAV.OT = TB_OTName.Text;
var status = SAV.Status;
status.Saying1 = TB_Saying1.Text;
@ -275,14 +276,11 @@ private void Save()
private void ClickOT(object sender, MouseEventArgs e)
{
TextBox tb = sender as TextBox ?? TB_OTName;
// Special Character Form
if (ModifierKeys != Keys.Control)
return;
var d = new TrashEditor(tb, SAV, SAV.Generation, SAV.Context);
d.ShowDialog();
tb.Text = d.FinalString;
TrashEditor.Show(TB_OTName, SAV, SAV.Status.OriginalTrainerTrash);
}
private void ShowTSV(object sender, EventArgs e)

View File

@ -399,14 +399,12 @@ private void B_AllPhrases_Click(object sender, EventArgs e)
private void TB_OTName_MouseDown(object sender, MouseEventArgs e)
{
TextBox tb = sender as TextBox ?? TB_OTName;
// Special Character Form
if (ModifierKeys != Keys.Control)
return;
var d = new TrashEditor(tb, SAV, SAV.Generation, SAV.Context);
d.ShowDialog();
tb.Text = d.FinalString;
var tb = sender as TextBox ?? TB_OTName;
TrashEditor.Show(tb, SAV);
}
private readonly string[] gendersymbols = ["♂", "♀"];

View File

@ -1,4 +1,4 @@
namespace PKHeX.WinForms
namespace PKHeX.WinForms
{
partial class SAV_HallOfFame7
{
@ -359,6 +359,7 @@ private void InitializeComponent()
// TB_EC
//
TB_EC.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
TB_EC.CharacterCasing = System.Windows.Forms.CharacterCasing.Upper;
TB_EC.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
TB_EC.Location = new System.Drawing.Point(150, 195);
TB_EC.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);

View File

@ -334,7 +334,8 @@ private void SaveTrainerInfo()
if (CB_AlolaTime.Enabled)
SAV.GameTime.AlolaTime = (ulong)WinFormsUtil.GetIndex(CB_AlolaTime);
SAV.OT = TB_OTName.Text;
if (SAV.OT != TB_OTName.Text) // only modify if changed (preserve trash bytes?)
SAV.OT = TB_OTName.Text;
// Copy Position
if (GB_Map.Enabled && MapUpdated)
@ -479,14 +480,11 @@ private static uint GetBits(ListBox listbox)
private void ClickOT(object sender, MouseEventArgs e)
{
TextBox tb = sender as TextBox ?? TB_OTName;
// Special Character Form
if (ModifierKeys != Keys.Control)
return;
var d = new TrashEditor(tb, SAV, SAV.Generation, SAV.Context);
d.ShowDialog();
tb.Text = d.FinalString;
TrashEditor.Show(TB_OTName, SAV, SAV.MyStatus.OriginalTrainerTrash);
}
private void B_Cancel_Click(object sender, EventArgs e)

View File

@ -67,7 +67,7 @@ private void LoadTrainerInfo()
{
// Get Data
TB_OTName.Text = SAV.OT;
TB_RivalName.Text = SAV.Blocks.Misc.Rival;
TB_RivalName.Text = SAV.Blocks.Misc.RivalName;
CB_Language.SelectedValue = SAV.Language;
MT_Money.Text = SAV.Blocks.Misc.Money.ToString();
@ -114,8 +114,10 @@ private void SaveTrainerInfo()
SAV.Money = Util.ToUInt32(MT_Money.Text);
SAV.Language = WinFormsUtil.GetIndex(CB_Language);
SAV.OT = TB_OTName.Text;
SAV.Blocks.Misc.Rival = TB_RivalName.Text;
if (SAV.OT != TB_OTName.Text)
SAV.OT = TB_OTName.Text;
if (SAV.Blocks.Misc.RivalName != TB_RivalName.Text)
SAV.Blocks.Misc.RivalName = TB_RivalName.Text;
// Copy Position
if (GB_Map.Enabled && MapUpdated)
@ -149,12 +151,11 @@ private void ClickString(object sender, MouseEventArgs e)
if (ModifierKeys != Keys.Control)
return;
TextBox tb = sender as TextBox ?? TB_OTName;
if (sender is not TextBox tb)
return;
// Special Character Form
var d = new TrashEditor(tb, SAV, SAV.Generation, SAV.Context);
d.ShowDialog();
tb.Text = d.FinalString;
var trash = tb == TB_OTName ? SAV.Status.OriginalTrainerTrash : SAV.Misc.RivalNameTrash;
TrashEditor.Show(tb, SAV, trash);
}
private void B_Cancel_Click(object sender, EventArgs e)

View File

@ -157,8 +157,13 @@ private void SaveTrainerInfo()
SAV.Money = Util.ToUInt32(MT_Money.Text);
SAV.Language = WinFormsUtil.GetIndex(CB_Language);
SAV.OT = TB_OTName.Text;
SAV.Blocks.TrainerCard.OT = TB_TrainerCardName.Text;
// only modify if changed (preserve trash bytes?)
if (SAV.OT != TB_OTName.Text)
SAV.OT = TB_OTName.Text;
if (SAV.Blocks.TrainerCard.OT != TB_TrainerCardName.Text)
SAV.Blocks.TrainerCard.OT = TB_TrainerCardName.Text;
SAV.Blocks.MyStatus.Number = SAV.Blocks.TrainerCard.Number = TB_TrainerCardNumber.Text;
SAV.Blocks.TrainerCard.TrainerID = Util.ToInt32(MT_TrainerCardID.Text);
SAV.Blocks.TrainerCard.RotoRallyScore = Util.ToInt32(MT_RotoRally.Text);
@ -204,14 +209,13 @@ private void SaveTrainerInfo()
private void ClickOT(object sender, MouseEventArgs e)
{
TextBox tb = sender as TextBox ?? TB_OTName;
if (sender is not TextBox tb)
return;
// Special Character Form
if (ModifierKeys != Keys.Control)
return;
var d = new TrashEditor(tb, SAV, SAV.Generation, SAV.Context);
d.ShowDialog();
tb.Text = d.FinalString;
var trash = tb == TB_OTName ? SAV.MyStatus.OriginalTrainerTrash : SAV.Blocks.TrainerCard.OriginalTrainerTrash;
TrashEditor.Show(tb, SAV, trash);
}
private void B_Cancel_Click(object sender, EventArgs e)

View File

@ -88,7 +88,10 @@ private void SaveTrainerInfo()
SAV.Money = Util.ToUInt32(MT_Money.Text);
SAV.Language = WinFormsUtil.GetIndex(CB_Language);
SAV.OT = TB_OTName.Text;
// only modify if changed (preserve trash bytes?)
if (SAV.OT != TB_OTName.Text)
SAV.OT = TB_OTName.Text;
// Copy Position
if (GB_Map.Enabled && MapUpdated)
@ -121,20 +124,14 @@ private void SaveTrainerInfo()
private void ClickOT(object sender, MouseEventArgs e)
{
TextBox tb = sender as TextBox ?? TB_OTName;
var tb = TB_OTName;
// Special Character Form
if (ModifierKeys != Keys.Control)
return;
var d = new TrashEditor(tb, SAV, SAV.Generation, SAV.Context);
d.ShowDialog();
tb.Text = d.FinalString;
TrashEditor.Show(tb, SAV, SAV.MyStatus.OriginalTrainerTrash);
}
private void B_Cancel_Click(object sender, EventArgs e)
{
Close();
}
private void B_Cancel_Click(object sender, EventArgs e) => Close();
private void B_Save_Click(object sender, EventArgs e)
{

View File

@ -56,7 +56,7 @@ private void GetTextBoxes()
trainerID1.LoadIDValues(SAV, SAV.Generation);
MT_Money.Text = SAV.Money.ToString();
CB_Language.SelectedValue = SAV.Language;
TB_Rival.Text = SAV.Rival;
TB_Rival.Text = SAV.RivalName;
NUD_M.Value = SAV.ZoneID;
NUD_X.Value = SAV.MyStatus.X;
@ -108,8 +108,13 @@ private void SaveTrainerInfo()
SAV.Money = Util.ToUInt32(MT_Money.Text);
SAV.Language = WinFormsUtil.GetIndex(CB_Language);
SAV.OT = TB_OTName.Text;
SAV.Rival = TB_Rival.Text;
// only modify if changed (preserve trash bytes?)
if (SAV.OT != TB_OTName.Text)
SAV.OT = TB_OTName.Text;
if (SAV.RivalName != TB_Rival.Text)
SAV.RivalName = TB_Rival.Text;
SAV.BattleTower.BP = (uint)NUD_BP.Value;
// Copy Position
@ -152,14 +157,15 @@ private static DateTime ReviseTimestamp(DateTime original, DateTime date, DateTi
private void ClickOT(object sender, MouseEventArgs e)
{
TextBox tb = sender as TextBox ?? TB_OTName;
if (sender is not TextBox tb)
return;
// Special Character Form
if (ModifierKeys != Keys.Control)
return;
var d = new TrashEditor(tb, SAV, SAV.Generation, SAV.Context);
d.ShowDialog();
tb.Text = d.FinalString;
var trash = tb == TB_OTName ? SAV.MyStatus.OriginalTrainerTrash : SAV.RivalNameTrash;
TrashEditor.Show(tb, SAV, trash);
}
private void B_Cancel_Click(object sender, EventArgs e)

View File

@ -88,6 +88,7 @@ private void InitializeComponent()
// TB_SeedTomorrow
//
TB_SeedTomorrow.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
TB_SeedTomorrow.CharacterCasing = System.Windows.Forms.CharacterCasing.Upper;
TB_SeedTomorrow.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
TB_SeedTomorrow.Location = new System.Drawing.Point(120, 336);
TB_SeedTomorrow.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
@ -100,6 +101,7 @@ private void InitializeComponent()
// TB_SeedToday
//
TB_SeedToday.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
TB_SeedToday.CharacterCasing = System.Windows.Forms.CharacterCasing.Upper;
TB_SeedToday.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
TB_SeedToday.Location = new System.Drawing.Point(120, 304);
TB_SeedToday.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);

View File

@ -159,7 +159,10 @@ private void SaveTrainerInfo()
SAV.Money = Util.ToUInt32(MT_Money.Text);
SAV.LeaguePoints = Util.ToUInt32(MT_LP.Text);
SAV.Language = WinFormsUtil.GetIndex(CB_Language);
SAV.OT = TB_OTName.Text;
// only modify if changed (preserve trash bytes?)
if (SAV.OT != TB_OTName.Text)
SAV.OT = TB_OTName.Text;
// Save PlayTime
SAV.PlayedHours = ushort.Parse(MT_Hours.Text);
@ -175,14 +178,10 @@ private void SaveTrainerInfo()
private void ClickOT(object sender, MouseEventArgs e)
{
TextBox tb = sender as TextBox ?? TB_OTName;
// Special Character Form
if (ModifierKeys != Keys.Control)
return;
var d = new TrashEditor(tb, SAV, SAV.Generation, SAV.Context);
d.ShowDialog();
tb.Text = d.FinalString;
TrashEditor.Show(TB_OTName, SAV, SAV.MyStatus.OriginalTrainerTrash);
}
private void B_Cancel_Click(object sender, EventArgs e)

View File

@ -173,7 +173,10 @@ private void SaveTrainerInfo()
SAV.Money = Util.ToUInt32(MT_Money.Text);
SAV.Language = WinFormsUtil.GetIndex(CB_Language);
SAV.OT = TB_OTName.Text;
// only modify if changed (preserve trash bytes?)
if (SAV.OT != TB_OTName.Text)
SAV.OT = TB_OTName.Text;
// Save PlayTime
SAV.PlayedHours = ushort.Parse(MT_Hours.Text);
@ -189,14 +192,10 @@ private void SaveTrainerInfo()
private void ClickOT(object sender, MouseEventArgs e)
{
TextBox tb = sender as TextBox ?? TB_OTName;
// Special Character Form
if (ModifierKeys != Keys.Control)
return;
var d = new TrashEditor(tb, SAV, SAV.Generation, SAV.Context);
d.ShowDialog();
tb.Text = d.FinalString;
TrashEditor.Show(TB_OTName, SAV, SAV.MyStatus.OriginalTrainerTrash);
}
private void B_Cancel_Click(object sender, EventArgs e)

View File

@ -109,7 +109,7 @@ private void CreateBagViews()
}
}
private DataGridView GetDGV(InventoryPouch pouch)
private DoubleBufferedDataGridView GetDGV(InventoryPouch pouch)
{
// Add DataGrid
var dgv = GetBaseDataGrid(pouch);

View File

@ -205,15 +205,12 @@ public SAV_SimpleTrainer(SaveFile sav)
private readonly bool Loading;
private bool MapUpdated;
private void ClickOT(Span<byte> text, TextBox tb)
private void ClickOT(Span<byte> trash, TextBox tb)
{
// Special Character Form
if (ModifierKeys != Keys.Control)
return;
var d = new TrashEditor(tb, text, SAV, SAV.Generation, SAV.Context);
d.ShowDialog();
tb.Text = d.FinalString;
TrashEditor.Show(tb, SAV, trash);
}
private void ChangeFFFF(object sender, EventArgs e)