FR/LG VC: trash byte checks, reflow dex editor

a little more ergonomic in dex editor (size increased)

in-game trades now correctly allow initial contest stats, and their special handling for OT Trash bytes.
This commit is contained in:
Kurt 2026-02-28 13:32:12 -06:00
parent 0d96d75b7a
commit 2939bfae48
4 changed files with 124 additions and 46 deletions

View File

@ -18,7 +18,7 @@ public override void Verify(LegalityAnalysis data)
// If no stats have been increased from the initial amount, then we're done here.
// some encounters have contest stats built in. they're already checked by the initial encounter match.
if (!s.HasContestStats())
if (!s.HasContestStats() || data.EncounterOriginal is IContestStatsReadOnly ro && ro.IsContestEqual(s))
return;
// Check the correlation of Stats & Sheen!

View File

@ -27,5 +27,54 @@ internal void Verify(LegalityAnalysis data, G3PKM pk)
if (ItemStorage3FRLG_VC.IsUnreleasedHeld(pk.HeldItem))
data.AddLine(GetInvalid(ItemUnreleased));
if (pk is PK3 pk3)
VerifyTrash(data, pk3);
}
private void VerifyTrash(LegalityAnalysis data, PK3 pk)
{
var enc = data.EncounterOriginal;
if (enc is EncounterTrade3)
VerifyTrashTrade(data, pk);
else if (pk.Japanese && !(pk.IsEgg && pk.OriginalTrainerTrash[^1] == 0x00))
VerifyTrashJPN(data, pk);
else
VerifyTrashINT(data, pk);
}
private void VerifyTrashTrade(LegalityAnalysis data, PK3 pk)
{
// For in-game trades, zeroes after the first terminator.
var trash = pk.OriginalTrainerTrash;
int len = TrashBytes8.GetStringLength(trash);
if (len == trash.Length)
return; // OK
if (trash[(len+1)..].ContainsAnyExcept<byte>(0))
data.AddLine(GetInvalid(TrashBytesMissingTerminator));
}
private void VerifyTrashJPN(LegalityAnalysis data, PK3 pk)
{
var trash = pk.OriginalTrainerTrash;
// OT name from save file is copied byte-for-byte. Byte 7 & 8 are always zero.
// PK3 do not store the 8th byte. Check the 7th explicitly.
if (trash[^1] != 0x00)
data.AddLine(GetInvalid(TrashBytesMissingTerminator));
int len = TrashBytes8.GetStringLength(trash);
if (trash[len..^2].ContainsAnyExcept<byte>(0xFF))
data.AddLine(GetInvalid(TrashBytesMissingTerminator));
}
private void VerifyTrashINT(LegalityAnalysis data, PK3 pk)
{
var trash = pk.OriginalTrainerTrash;
// OT name from save file is copied byte-for-byte. All 8 bytes are initialized to FF on new game.
int len = TrashBytes8.GetStringLength(trash);
if (trash[len..].ContainsAnyExcept<byte>(0xFF))
data.AddLine(GetInvalid(TrashBytesMissingTerminator));
}
}

View File

@ -38,14 +38,17 @@ private void InitializeComponent()
CLB_Caught = new System.Windows.Forms.CheckedListBox();
Label_Seen = new System.Windows.Forms.Label();
CLB_Seen = new System.Windows.Forms.CheckedListBox();
tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
tableLayoutPanel1.SuspendLayout();
SuspendLayout();
//
// B_Save
//
B_Save.Location = new System.Drawing.Point(170, 347);
B_Save.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
B_Save.Anchor = System.Windows.Forms.AnchorStyles.Left;
B_Save.Location = new System.Drawing.Point(196, 365);
B_Save.Margin = new System.Windows.Forms.Padding(4);
B_Save.Name = "B_Save";
B_Save.Size = new System.Drawing.Size(99, 27);
B_Save.Size = new System.Drawing.Size(120, 32);
B_Save.TabIndex = 19;
B_Save.Text = "Save";
B_Save.UseVisualStyleBackColor = true;
@ -53,10 +56,11 @@ private void InitializeComponent()
//
// B_Cancel
//
B_Cancel.Location = new System.Drawing.Point(62, 347);
B_Cancel.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
B_Cancel.Anchor = System.Windows.Forms.AnchorStyles.Right;
B_Cancel.Location = new System.Drawing.Point(68, 365);
B_Cancel.Margin = new System.Windows.Forms.Padding(4);
B_Cancel.Name = "B_Cancel";
B_Cancel.Size = new System.Drawing.Size(99, 27);
B_Cancel.Size = new System.Drawing.Size(120, 32);
B_Cancel.TabIndex = 18;
B_Cancel.Text = "Cancel";
B_Cancel.UseVisualStyleBackColor = true;
@ -64,10 +68,11 @@ private void InitializeComponent()
//
// B_CaughtNone
//
B_CaughtNone.Location = new System.Drawing.Point(176, 308);
B_CaughtNone.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
B_CaughtNone.Dock = System.Windows.Forms.DockStyle.Fill;
B_CaughtNone.Location = new System.Drawing.Point(196, 325);
B_CaughtNone.Margin = new System.Windows.Forms.Padding(4);
B_CaughtNone.Name = "B_CaughtNone";
B_CaughtNone.Size = new System.Drawing.Size(140, 27);
B_CaughtNone.Size = new System.Drawing.Size(184, 32);
B_CaughtNone.TabIndex = 17;
B_CaughtNone.Text = "Caught None";
B_CaughtNone.UseVisualStyleBackColor = true;
@ -75,10 +80,11 @@ private void InitializeComponent()
//
// B_CaughtAll
//
B_CaughtAll.Location = new System.Drawing.Point(176, 275);
B_CaughtAll.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
B_CaughtAll.Dock = System.Windows.Forms.DockStyle.Fill;
B_CaughtAll.Location = new System.Drawing.Point(196, 285);
B_CaughtAll.Margin = new System.Windows.Forms.Padding(4);
B_CaughtAll.Name = "B_CaughtAll";
B_CaughtAll.Size = new System.Drawing.Size(140, 27);
B_CaughtAll.Size = new System.Drawing.Size(184, 32);
B_CaughtAll.TabIndex = 16;
B_CaughtAll.Text = "Caught All";
B_CaughtAll.UseVisualStyleBackColor = true;
@ -86,10 +92,11 @@ private void InitializeComponent()
//
// B_SeenNone
//
B_SeenNone.Location = new System.Drawing.Point(16, 308);
B_SeenNone.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
B_SeenNone.Dock = System.Windows.Forms.DockStyle.Fill;
B_SeenNone.Location = new System.Drawing.Point(4, 325);
B_SeenNone.Margin = new System.Windows.Forms.Padding(4);
B_SeenNone.Name = "B_SeenNone";
B_SeenNone.Size = new System.Drawing.Size(140, 27);
B_SeenNone.Size = new System.Drawing.Size(184, 32);
B_SeenNone.TabIndex = 15;
B_SeenNone.Text = "Seen None";
B_SeenNone.UseVisualStyleBackColor = true;
@ -97,10 +104,11 @@ private void InitializeComponent()
//
// B_SeenAll
//
B_SeenAll.Location = new System.Drawing.Point(16, 275);
B_SeenAll.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
B_SeenAll.Dock = System.Windows.Forms.DockStyle.Fill;
B_SeenAll.Location = new System.Drawing.Point(4, 285);
B_SeenAll.Margin = new System.Windows.Forms.Padding(4);
B_SeenAll.Name = "B_SeenAll";
B_SeenAll.Size = new System.Drawing.Size(140, 27);
B_SeenAll.Size = new System.Drawing.Size(184, 32);
B_SeenAll.TabIndex = 14;
B_SeenAll.Text = "Seen All";
B_SeenAll.UseVisualStyleBackColor = true;
@ -109,69 +117,89 @@ private void InitializeComponent()
// Label_Caught
//
Label_Caught.AutoSize = true;
Label_Caught.Location = new System.Drawing.Point(176, 15);
Label_Caught.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
Label_Caught.Location = new System.Drawing.Point(196, 4);
Label_Caught.Margin = new System.Windows.Forms.Padding(4);
Label_Caught.Name = "Label_Caught";
Label_Caught.Size = new System.Drawing.Size(49, 15);
Label_Caught.Size = new System.Drawing.Size(52, 17);
Label_Caught.TabIndex = 13;
Label_Caught.Text = "Caught:";
//
// CLB_Caught
//
CLB_Caught.CheckOnClick = true;
CLB_Caught.Dock = System.Windows.Forms.DockStyle.Fill;
CLB_Caught.FormattingEnabled = true;
CLB_Caught.Location = new System.Drawing.Point(176, 38);
CLB_Caught.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
CLB_Caught.Location = new System.Drawing.Point(196, 29);
CLB_Caught.Margin = new System.Windows.Forms.Padding(4);
CLB_Caught.Name = "CLB_Caught";
CLB_Caught.Size = new System.Drawing.Size(139, 220);
CLB_Caught.Size = new System.Drawing.Size(184, 248);
CLB_Caught.TabIndex = 12;
//
// Label_Seen
//
Label_Seen.AutoSize = true;
Label_Seen.Location = new System.Drawing.Point(16, 15);
Label_Seen.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
Label_Seen.Location = new System.Drawing.Point(4, 4);
Label_Seen.Margin = new System.Windows.Forms.Padding(4);
Label_Seen.Name = "Label_Seen";
Label_Seen.Size = new System.Drawing.Size(35, 15);
Label_Seen.Size = new System.Drawing.Size(39, 17);
Label_Seen.TabIndex = 11;
Label_Seen.Text = "Seen:";
//
// CLB_Seen
//
CLB_Seen.CheckOnClick = true;
CLB_Seen.Dock = System.Windows.Forms.DockStyle.Fill;
CLB_Seen.FormattingEnabled = true;
CLB_Seen.Location = new System.Drawing.Point(16, 38);
CLB_Seen.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
CLB_Seen.Location = new System.Drawing.Point(4, 29);
CLB_Seen.Margin = new System.Windows.Forms.Padding(4);
CLB_Seen.Name = "CLB_Seen";
CLB_Seen.Size = new System.Drawing.Size(139, 220);
CLB_Seen.Size = new System.Drawing.Size(184, 248);
CLB_Seen.TabIndex = 10;
//
// tableLayoutPanel1
//
tableLayoutPanel1.ColumnCount = 2;
tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
tableLayoutPanel1.Controls.Add(Label_Seen, 0, 0);
tableLayoutPanel1.Controls.Add(Label_Caught, 1, 0);
tableLayoutPanel1.Controls.Add(B_Save, 1, 4);
tableLayoutPanel1.Controls.Add(CLB_Seen, 0, 1);
tableLayoutPanel1.Controls.Add(B_Cancel, 0, 4);
tableLayoutPanel1.Controls.Add(CLB_Caught, 1, 1);
tableLayoutPanel1.Controls.Add(B_SeenNone, 0, 3);
tableLayoutPanel1.Controls.Add(B_CaughtNone, 1, 3);
tableLayoutPanel1.Controls.Add(B_SeenAll, 0, 2);
tableLayoutPanel1.Controls.Add(B_CaughtAll, 1, 2);
tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(4);
tableLayoutPanel1.Name = "tableLayoutPanel1";
tableLayoutPanel1.RowCount = 5;
tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
tableLayoutPanel1.Size = new System.Drawing.Size(384, 401);
tableLayoutPanel1.TabIndex = 20;
//
// SAV_SimplePokedex
//
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
ClientSize = new System.Drawing.Size(331, 388);
Controls.Add(B_Save);
Controls.Add(B_Cancel);
Controls.Add(B_CaughtNone);
Controls.Add(B_CaughtAll);
Controls.Add(B_SeenNone);
Controls.Add(B_SeenAll);
Controls.Add(Label_Caught);
Controls.Add(CLB_Caught);
Controls.Add(Label_Seen);
Controls.Add(CLB_Seen);
ClientSize = new System.Drawing.Size(384, 401);
Controls.Add(tableLayoutPanel1);
FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
Icon = Properties.Resources.Icon;
Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
MaximizeBox = false;
MaximumSize = new System.Drawing.Size(347, 427);
MinimizeBox = false;
MinimumSize = new System.Drawing.Size(347, 427);
Name = "SAV_SimplePokedex";
StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
Text = "Pokedex Editor";
tableLayoutPanel1.ResumeLayout(false);
tableLayoutPanel1.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
#endregion
@ -186,5 +214,6 @@ private void InitializeComponent()
private System.Windows.Forms.CheckedListBox CLB_Caught;
private System.Windows.Forms.Label Label_Seen;
private System.Windows.Forms.CheckedListBox CLB_Seen;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
}
}

View File

@ -25,7 +25,7 @@ private void AddAllSpecies(ReadOnlySpan<string> speciesNames)
{
for (var i = 0; i < speciesNames.Length; i++)
{
var text = $"{i+1:000} {speciesNames[i]}";
var text = $"{i+1:000} - {speciesNames[i]}";
CLB_Seen.Items.Add(text);
CLB_Caught.Items.Add(text);
}