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. // 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. // 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; return;
// Check the correlation of Stats & Sheen! // 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)) if (ItemStorage3FRLG_VC.IsUnreleasedHeld(pk.HeldItem))
data.AddLine(GetInvalid(ItemUnreleased)); 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(); CLB_Caught = new System.Windows.Forms.CheckedListBox();
Label_Seen = new System.Windows.Forms.Label(); Label_Seen = new System.Windows.Forms.Label();
CLB_Seen = new System.Windows.Forms.CheckedListBox(); CLB_Seen = new System.Windows.Forms.CheckedListBox();
tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
tableLayoutPanel1.SuspendLayout();
SuspendLayout(); SuspendLayout();
// //
// B_Save // B_Save
// //
B_Save.Location = new System.Drawing.Point(170, 347); B_Save.Anchor = System.Windows.Forms.AnchorStyles.Left;
B_Save.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); 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.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.TabIndex = 19;
B_Save.Text = "Save"; B_Save.Text = "Save";
B_Save.UseVisualStyleBackColor = true; B_Save.UseVisualStyleBackColor = true;
@ -53,10 +56,11 @@ private void InitializeComponent()
// //
// B_Cancel // B_Cancel
// //
B_Cancel.Location = new System.Drawing.Point(62, 347); B_Cancel.Anchor = System.Windows.Forms.AnchorStyles.Right;
B_Cancel.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); 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.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.TabIndex = 18;
B_Cancel.Text = "Cancel"; B_Cancel.Text = "Cancel";
B_Cancel.UseVisualStyleBackColor = true; B_Cancel.UseVisualStyleBackColor = true;
@ -64,10 +68,11 @@ private void InitializeComponent()
// //
// B_CaughtNone // B_CaughtNone
// //
B_CaughtNone.Location = new System.Drawing.Point(176, 308); B_CaughtNone.Dock = System.Windows.Forms.DockStyle.Fill;
B_CaughtNone.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); 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.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.TabIndex = 17;
B_CaughtNone.Text = "Caught None"; B_CaughtNone.Text = "Caught None";
B_CaughtNone.UseVisualStyleBackColor = true; B_CaughtNone.UseVisualStyleBackColor = true;
@ -75,10 +80,11 @@ private void InitializeComponent()
// //
// B_CaughtAll // B_CaughtAll
// //
B_CaughtAll.Location = new System.Drawing.Point(176, 275); B_CaughtAll.Dock = System.Windows.Forms.DockStyle.Fill;
B_CaughtAll.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); 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.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.TabIndex = 16;
B_CaughtAll.Text = "Caught All"; B_CaughtAll.Text = "Caught All";
B_CaughtAll.UseVisualStyleBackColor = true; B_CaughtAll.UseVisualStyleBackColor = true;
@ -86,10 +92,11 @@ private void InitializeComponent()
// //
// B_SeenNone // B_SeenNone
// //
B_SeenNone.Location = new System.Drawing.Point(16, 308); B_SeenNone.Dock = System.Windows.Forms.DockStyle.Fill;
B_SeenNone.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); 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.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.TabIndex = 15;
B_SeenNone.Text = "Seen None"; B_SeenNone.Text = "Seen None";
B_SeenNone.UseVisualStyleBackColor = true; B_SeenNone.UseVisualStyleBackColor = true;
@ -97,10 +104,11 @@ private void InitializeComponent()
// //
// B_SeenAll // B_SeenAll
// //
B_SeenAll.Location = new System.Drawing.Point(16, 275); B_SeenAll.Dock = System.Windows.Forms.DockStyle.Fill;
B_SeenAll.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); 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.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.TabIndex = 14;
B_SeenAll.Text = "Seen All"; B_SeenAll.Text = "Seen All";
B_SeenAll.UseVisualStyleBackColor = true; B_SeenAll.UseVisualStyleBackColor = true;
@ -109,69 +117,89 @@ private void InitializeComponent()
// Label_Caught // Label_Caught
// //
Label_Caught.AutoSize = true; Label_Caught.AutoSize = true;
Label_Caught.Location = new System.Drawing.Point(176, 15); Label_Caught.Location = new System.Drawing.Point(196, 4);
Label_Caught.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); Label_Caught.Margin = new System.Windows.Forms.Padding(4);
Label_Caught.Name = "Label_Caught"; 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.TabIndex = 13;
Label_Caught.Text = "Caught:"; Label_Caught.Text = "Caught:";
// //
// CLB_Caught // CLB_Caught
// //
CLB_Caught.CheckOnClick = true; CLB_Caught.CheckOnClick = true;
CLB_Caught.Dock = System.Windows.Forms.DockStyle.Fill;
CLB_Caught.FormattingEnabled = true; CLB_Caught.FormattingEnabled = true;
CLB_Caught.Location = new System.Drawing.Point(176, 38); CLB_Caught.Location = new System.Drawing.Point(196, 29);
CLB_Caught.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); CLB_Caught.Margin = new System.Windows.Forms.Padding(4);
CLB_Caught.Name = "CLB_Caught"; 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; CLB_Caught.TabIndex = 12;
// //
// Label_Seen // Label_Seen
// //
Label_Seen.AutoSize = true; Label_Seen.AutoSize = true;
Label_Seen.Location = new System.Drawing.Point(16, 15); Label_Seen.Location = new System.Drawing.Point(4, 4);
Label_Seen.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); Label_Seen.Margin = new System.Windows.Forms.Padding(4);
Label_Seen.Name = "Label_Seen"; 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.TabIndex = 11;
Label_Seen.Text = "Seen:"; Label_Seen.Text = "Seen:";
// //
// CLB_Seen // CLB_Seen
// //
CLB_Seen.CheckOnClick = true; CLB_Seen.CheckOnClick = true;
CLB_Seen.Dock = System.Windows.Forms.DockStyle.Fill;
CLB_Seen.FormattingEnabled = true; CLB_Seen.FormattingEnabled = true;
CLB_Seen.Location = new System.Drawing.Point(16, 38); CLB_Seen.Location = new System.Drawing.Point(4, 29);
CLB_Seen.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); CLB_Seen.Margin = new System.Windows.Forms.Padding(4);
CLB_Seen.Name = "CLB_Seen"; 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; 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 // SAV_SimplePokedex
// //
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit; AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
ClientSize = new System.Drawing.Size(331, 388); ClientSize = new System.Drawing.Size(384, 401);
Controls.Add(B_Save); Controls.Add(tableLayoutPanel1);
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);
FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
Icon = Properties.Resources.Icon; Icon = Properties.Resources.Icon;
Margin = new System.Windows.Forms.Padding(4, 3, 4, 3); Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
MaximizeBox = false; MaximizeBox = false;
MaximumSize = new System.Drawing.Size(347, 427);
MinimizeBox = false; MinimizeBox = false;
MinimumSize = new System.Drawing.Size(347, 427);
Name = "SAV_SimplePokedex"; Name = "SAV_SimplePokedex";
StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
Text = "Pokedex Editor"; Text = "Pokedex Editor";
tableLayoutPanel1.ResumeLayout(false);
tableLayoutPanel1.PerformLayout();
ResumeLayout(false); ResumeLayout(false);
PerformLayout();
} }
#endregion #endregion
@ -186,5 +214,6 @@ private void InitializeComponent()
private System.Windows.Forms.CheckedListBox CLB_Caught; private System.Windows.Forms.CheckedListBox CLB_Caught;
private System.Windows.Forms.Label Label_Seen; private System.Windows.Forms.Label Label_Seen;
private System.Windows.Forms.CheckedListBox CLB_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++) 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_Seen.Items.Add(text);
CLB_Caught.Items.Add(text); CLB_Caught.Items.Add(text);
} }