PKHeX/PKHeX.Core/Saves/Substructures/Mail/Mail3.cs
Kurt 94f3937f2f Refactor: extract gen3 save block structures
Changed: Inventory editor no longer needs to clone the save file on GUI open
Changed: some method signatures have moved from SAV3* to the specific block
Allows the block structures to be used without a SAV3 object
Allows the Inventory editor to open from a blank save file.
2026-03-14 13:40:17 -05:00

75 lines
2.8 KiB
C#

using System;
using static System.Buffers.Binary.BinaryPrimitives;
namespace PKHeX.Core;
public sealed class Mail3 : MailDetail
{
public const int SIZE = 0x24;
private bool JP;
public Mail3() : base(new byte[SIZE], -1) => ResetData();
public Mail3(Memory<byte> data, int ofs) : base(data, ofs) => JP = Data[0x12 + 5] == 0xFF; // author name length < 6
private void ResetData()
{
for (int y = 0; y < 3; y++)
{
for (int x = 0; x < 3; x++)
SetMessage(y, x, 0xFFFF);
}
AuthorName = string.Empty;
AuthorTID = 0;
AuthorTID = 0;
AppearPKM = 1;
MailType = 0;
}
public override ushort GetMessage(int index1, int index2) => ReadUInt16LittleEndian(Data[(((index1 * 3) + index2) * 2)..]);
public override void SetMessage(int index1, int index2, ushort value) => WriteUInt16LittleEndian(Data[(((index1 * 3) + index2) * 2)..], value);
public override void CopyTo(SaveFile sav) => sav.SetData(((SAV3)sav).Large[DataOffset..], Data);
public void CopyTo(Span<byte> dest) => Data.CopyTo(dest);
public override string AuthorName
{
get => StringConverter3.GetString(Data.Slice(0x12, 7), JP);
set
{
var span = Data.Slice(0x12, 8);
if (value.Length == 0)
{
span.Fill(0xFF);
return;
}
int len = JP ? 5 : 7;
StringConverter3.SetString(span[..(len + 1)], value, len, JP, StringConverterOption.ClearFF);
if (!JP)
span[..(len - 1)].Replace<byte>(0xFF, 0x00); // Pad with spaces to at least 6 characters
else
span[^2] = 0x00; // Last two bytes of OT names should be zeroes
span[^1] = 0xFF; // Ensure terminator
}
}
public override byte AuthorLanguage
{
get => JP ? (byte)LanguageID.Japanese : (byte)LanguageID.English;
set => JP = value == (byte)LanguageID.Japanese;
}
public override ushort AuthorTID { get => ReadUInt16LittleEndian(Data[0x1A..]); set => WriteUInt16LittleEndian(Data[0x1A..], value); }
public override ushort AuthorSID { get => ReadUInt16LittleEndian(Data[0x1C..]); set => WriteUInt16LittleEndian(Data[0x1C..], value); }
public override ushort AppearPKM { get => ReadUInt16LittleEndian(Data[0x1E..]); set => WriteUInt16LittleEndian(Data[0x1E..], (ushort)(value == 0 ? 1 : value)); }
public override int MailType { get => ReadUInt16LittleEndian(Data[0x20..]); set => WriteUInt16LittleEndian(Data[0x20..], (ushort)value); }
public override bool? IsEmpty => MailType switch
{
0 => true,
>= 0x79 and <= 0x84 => false,
_ => null,
};
public override void SetBlank() => new Mail3().Data.CopyTo(Data);
}