Add Battle Test metadata properties

Set the magic, set the flags to whatever, and refresh the checksum -> NPC recognizes you have DLC battle test ready and lets you challenge it immediately when starting a conversation with him.
Of course, it crashes immediately because we don't know what the 0x000 - 0x5C1 region data should be, but hey, this is progress for unlocking unreleased content.
This commit is contained in:
Kurt 2024-10-06 14:50:17 -05:00
parent ec24b8b8d5
commit 53b9c27ec9
3 changed files with 49 additions and 3 deletions

View file

@ -1,4 +1,5 @@
using System;
using static System.Buffers.Binary.BinaryPrimitives;
namespace PKHeX.Core;
@ -9,4 +10,37 @@ public class BattleTest5(Memory<byte> Raw)
private Span<byte> Data => Raw.Span;
public bool IsUninitialized => !Data.ContainsAnyExcept<byte>(0xFF, 0);
public const ushort Sentinel = 0x0D68;
// Should be equal to Sentinel otherwise the data is not valid.
public ushort Magic { get => ReadUInt16LittleEndian(Data[0x5C2..]); set => WriteUInt16LittleEndian(Data[0x5C2..], value); }
public ushort Flags { get => ReadUInt16LittleEndian(Data[0x5C4..]); set => WriteUInt16LittleEndian(Data[0x5C4..], value); }
public ushort Checksum { get => ReadUInt16LittleEndian(Data[0x5C6..]); set => WriteUInt16LittleEndian(Data[0x5C6..], value); }
public bool IsDoubles
{
get => (Flags & 0x8000) != 0;
set
{
if (value)
Flags |= 0x8000;
else
Flags &= 0x7FFF;
}
}
public ushort CalculateChecksum() => Checksums.CRC16_CCITT(Data[..0x5C6]);
public void RefreshChecksums() => Checksum = CalculateChecksum();
// Script command 0x1F2 in B2/W2
public ushort GetScriptResultIsValid()
{
var chk = CalculateChecksum();
if (chk != Checksum)
return 0;
if (Magic != Sentinel)
return 0;
return IsDoubles ? (ushort)2 : (ushort)1;
}
}

View file

@ -10,6 +10,7 @@ public sealed class MusicalShow5(Memory<byte> Raw)
public const string Extension = "pms";
public Span<byte> Data => Raw.Span;
public bool IsUninitialized => !Data.ContainsAnyExcept<byte>(0xFF, 0);
public int Length
{

View file

@ -141,7 +141,7 @@ public partial class SAV_DLC5 : Form
LB_PWT.SelectedIndex = 0;
}
private string? LastImportedFile = null;
private string? LastImportedFile;
private bool ImportFile(string extension, string name, int expectSize, out byte[] data, string? initialName = null, int otherSize = -1)
{
@ -349,9 +349,11 @@ public partial class SAV_DLC5 : Form
const int pporg = 0x17D78;
if (!ImportFile(MusicalShow5.Extension, MusicalShowFileName, size, out var data, otherSize: pporg))
return;
var musical = new MusicalShow5(data);
SAV.SetMusical(data);
if (LastImportedFile is { } name)
SAV.Musical.MusicalName = Path.GetFileNameWithoutExtension(name).Trim();
SAV.Musical.MusicalName = musical.IsUninitialized ? "" : Path.GetFileNameWithoutExtension(name).Trim();
}
private void B_MusicalExport_Click(object sender, EventArgs e)
@ -367,7 +369,8 @@ public partial class SAV_DLC5 : Form
bool decrypted = BattleVideo5.GetIsDecrypted(data);
var bvid = new BattleVideo5(data) { IsDecrypted = decrypted };
bvid.Encrypt();
bvid.RefreshChecksums();
if (!bvid.IsUninitialized)
bvid.RefreshChecksums();
var index = LB_BattleVideo.SelectedIndex;
SAV.SetBattleVideo(index, data);
@ -454,6 +457,14 @@ public partial class SAV_DLC5 : Form
{
if (!ImportFile(BattleTest5.Extension, BattleTestFileName, BattleTest5.SIZE, out var data))
return;
// Ensure checksums are valid for user-fuzzed data.
var test = new BattleTest5(data);
if (!test.IsUninitialized)
{
test.Magic = BattleTest5.Sentinel;
test.RefreshChecksums();
}
SAV.SetBattleTest(data);
}
}