SAV6AO: Fix dexnav get/set

Was looking in the wrong segment of save data. Now points to the correct span (pokedex).

Extract a few more save blocks and interactions.
Basically try to get rid of any remaining `SAV.Data` references. Still a few left, but aren't broken.

Closes #4259
This commit is contained in:
Kurt 2024-05-01 22:58:47 -05:00
parent 0f4024952e
commit ad0c9b147d
15 changed files with 195 additions and 94 deletions

View file

@ -19,4 +19,5 @@ public interface ISaveBlock6Main : ISaveBlock6Core
MaisonBlock Maison { get; }
SubEventLog6 SUBE { get; }
Encount6 Encount { get; }
HallOfFame6 HallOfFame { get; }
}

View file

@ -1,4 +1,4 @@
namespace PKHeX.Core;
namespace PKHeX.Core;
/// <summary>
/// Interface for Accessing named blocks within a Generation 6 save file.
@ -9,4 +9,5 @@ public interface ISaveBlock6XY : ISaveBlock6Main
Misc6XY Misc { get; }
Zukan6XY Zukan { get; }
Fashion6XY Fashion { get; }
BerryField6XY BerryField { get; }
}

View file

@ -91,6 +91,7 @@ public sealed class SaveBlockAccessor6AO(SAV6AO sav) : ISaveBlockAccessor<BlockI
public OPower6 OPower { get; } = new(sav, Block(sav, 25));
public GTS6 GTS { get; } = new(sav, Block(sav, 28));
public Encount6 Encount { get; } = new(sav, Block(sav, 31));
public HallOfFame6 HallOfFame { get; } = new(sav, Block(sav, 36));
public MaisonBlock Maison { get; } = new(sav, Block(sav, 37));
public Daycare6AO Daycare { get; } = new(sav, Block(sav, 38));
public BerryField6AO BerryField { get; } = new(sav, Block(sav, 40));
@ -99,6 +100,7 @@ public sealed class SaveBlockAccessor6AO(SAV6AO sav) : ISaveBlockAccessor<BlockI
public RecordBlock6AO Records { get; } = new(sav, Block(sav, 44));
public SuperTrainBlock SuperTrain { get; } = new(sav, Block(sav, 46));
public LinkBlock6 Link { get; } = new(sav, Block(sav, 48));
public Contest6 Contest { get; } = new(sav, Block(sav, 53));
public SecretBase6Block SecretBase { get; } = new(sav, Block(sav, 54));
public SangoInfoBlock Sango { get; } = new(sav, Block(sav, 55));

View file

@ -89,8 +89,10 @@ public sealed class SaveBlockAccessor6XY(SAV6XY sav) : ISaveBlockAccessor<BlockI
public OPower6 OPower { get; } = new(sav, Block(sav, 25));
public GTS6 GTS { get; } = new(sav, Block(sav, 28));
public Encount6 Encount { get; } = new(sav, Block(sav, 31));
public HallOfFame6 HallOfFame { get; } = new(sav, Block(sav, 36));
public MaisonBlock Maison { get; } = new(sav, Block(sav, 37));
public Daycare6XY Daycare { get; } = new(sav, Block(sav, 38));
public BerryField6XY BerryField { get; } = new(sav, Block(sav, 40));
public MysteryBlock6 MysteryGift { get; } = new(sav, Block(sav, 41));
public SubEventLog6XY SUBE { get; } = new(sav, Block(sav, 42));
public RecordBlock6XY Records { get; } = new(sav, Block(sav, 44));

View file

@ -42,7 +42,6 @@ public sealed class SAV6AO : SAV6, ISaveBlock6AO, IMultiplayerSprite, IBoxDetail
}
/// <summary> Offset of the Contest data block. </summary>
public const int Contest = 0x23600;
#region Blocks
public override IReadOnlyList<BlockInfo> AllBlocks => Blocks.BlockInfo;
@ -71,6 +70,8 @@ public sealed class SAV6AO : SAV6, ISaveBlock6AO, IMultiplayerSprite, IBoxDetail
public Zukan6AO Zukan => Blocks.Zukan;
public SecretBase6Block SecretBase => Blocks.SecretBase;
public BerryField6AO BerryField => Blocks.BerryField;
public Contest6 Contest => Blocks.Contest;
public HallOfFame6 HallOfFame => Blocks.HallOfFame;
MyItem ISaveBlock6Core.Items => Items;
SubEventLog6 ISaveBlock6Main.SUBE => SUBE;

View file

@ -43,8 +43,6 @@ public sealed class SAV6XY : SAV6, ISaveBlock6XY, IMultiplayerSprite, IBoxDetail
JPEG = 0x57200;
}
public const int BerryField = 0x1B800;
#region Blocks
public override IReadOnlyList<BlockInfo> AllBlocks => Blocks.BlockInfo;
public override MyItem Items => Blocks.Items;
@ -71,6 +69,8 @@ public sealed class SAV6XY : SAV6, ISaveBlock6XY, IMultiplayerSprite, IBoxDetail
public SubEventLog6 SUBE => Blocks.SUBE;
public ConfigSave6 Config => Blocks.Config;
public Encount6 Encount => Blocks.Encount;
public BerryField6XY BerryField => Blocks.BerryField;
public HallOfFame6 HallOfFame => Blocks.HallOfFame;
IMysteryGiftStorage IMysteryGiftStorageProvider.MysteryGiftStorage => MysteryGift;
#endregion

View file

@ -0,0 +1,19 @@
using System;
namespace PKHeX.Core;
public sealed class BerryField6XY(SAV6XY sav, Memory<byte> raw) : SaveBlock<SAV6XY>(sav, raw)
{
// Is this the same as the BerryField6AO class?
public const int Size = 16; // bytes per entry
public const int Count = 32; // 32+25 = 57 allocated?
private const int PlotStart = 0xC;
public Span<byte> GetPlot(int index)
{
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, (uint)Count);
return Data.Slice(PlotStart + (index * Size), Size);
}
}

View file

@ -0,0 +1,26 @@
using System;
using static System.Buffers.Binary.BinaryPrimitives;
namespace PKHeX.Core;
public sealed class Contest6(SAV6AO sav, Memory<byte> raw) : SaveBlock<SAV6AO>(sav, raw)
{
public const int CountBlock = 12;
public const uint MaxBlock = 999;
public uint GetBlockCount(int index)
{
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, (uint)CountBlock);
return ReadUInt32LittleEndian(Data[(index * 4)..]);
}
public void SetBlockCount(int index, uint value)
{
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, (uint)CountBlock);
if (value > MaxBlock)
value = MaxBlock;
WriteUInt32LittleEndian(Data[(index * 4)..], value);
}
// 0x48.. ???
}

View file

@ -57,3 +57,26 @@ public readonly ref struct HallFame6Entity
set => StringConverter6.SetString(OriginalTrainerTrash, value, 12, Option);
}
}
public readonly ref struct HallFame6Index
{
public const int SIZE = 0x4;
private readonly Span<byte> Data;
// ReSharper disable once ConvertToPrimaryConstructor
public HallFame6Index(Span<byte> data) => Data = data;
public uint Value { get => ReadUInt32LittleEndian(Data); set => WriteUInt32LittleEndian(Data, value); }
// Structure:
// u32:14 - Clear Index (how many times Fame has been completed/cleared)
// u32:08 - Year (since 2000)
// u32:04 - Month
// u32:05 - Day
// u32:01 - Index has Data bool flag (0 = no data, 1 = has data)
public uint ClearIndex { get => Value & 0x3FFFu; set => Value = (Value & ~0x3FFFu) | (value & 0x3FFFu); }
public uint Year { get => (Value >> 14) & 0xFFu; set => Value = (Value & ~(0xFFu << 14)) | ((value & 0xFFu) << 14); }
public uint Month { get => (Value >> 22) & 0xFu; set => Value = (Value & ~(0xFu << 22)) | ((value & 0xFu) << 22); }
public uint Day { get => (Value >> 26) & 0x1Fu; set => Value = (Value & ~(0x1Fu << 26)) | ((value & 0x1Fu) << 26); }
public bool HasData { get => (Value >> 31) == 1; set => Value = (Value & ~(0x1u << 31)) | ((value ? 1u : 0u) << 31); }
}

View file

@ -0,0 +1,58 @@
using System;
namespace PKHeX.Core;
public sealed class HallOfFame6(SAV6 sav, Memory<byte> raw) : SaveBlock<SAV6>(sav, raw)
{
public const int Entries = 16; // First clear, and 15 most-recent entries.
public const int PokeSize = HallFame6Entity.SIZE; // 0x48
public const int PokeCount = 6;
public const int EntrySize = (PokeCount * PokeSize) + HallFame6Index.SIZE; // 0x1B4
public const int MaxComplete = 9999;
public Span<byte> GetEntry(int index)
{
ArgumentOutOfRangeException.ThrowIfGreaterThanOrEqual((uint)index, (uint)Entries);
return Data.Slice(index * EntrySize, EntrySize);
}
public uint GetInsertIndex(out uint clear)
{
// Check for empty slots (where player hasn't yet registered enough Fame clears)
clear = 0;
for (uint i = 0; i < Entries; i++)
{
var entry = GetEntry((int)i);
var vnd = new HallFame6Index(entry[^4..]);
if (!vnd.HasData)
return clear = i;
clear = vnd.ClearIndex;
}
// No empty slots, return the last slot.
ClearEntry(1);
clear = new HallFame6Index(GetEntry(14)).ClearIndex + 1;
return 15;
}
public void ClearEntry(int index)
{
int offset = index * EntrySize;
if (index != 15)
{
// Shift down
var dest = Data[offset..];
var above = Data.Slice(offset + EntrySize, EntrySize * (Entries - 1 - index));
above.CopyTo(dest);
}
// Ensure Last Entry is Cleared
Data.Slice(EntrySize * (Entries - 1), EntrySize).Clear();
}
public Span<byte> GetEntity(int team, int member)
{
return GetEntry(team).Slice(member * PokeSize, PokeSize);
}
}

View file

@ -198,13 +198,13 @@ public sealed class Zukan6AO : Zukan6
public ushort GetEncounterCount(int index)
{
var ofs = 0x686 + (index * 2);
return ReadUInt16LittleEndian(SAV.Data.AsSpan(ofs));
return ReadUInt16LittleEndian(Data[ofs..]);
}
public void SetEncounterCount(int index, ushort value)
{
var ofs = 0x686 + (index * 2);
WriteUInt16LittleEndian(SAV.Data.AsSpan(ofs), value);
WriteUInt16LittleEndian(Data[ofs..], value);
}
}

View file

@ -9,7 +9,6 @@ namespace PKHeX.Core;
public sealed class Zukan7b(SAV7b sav, Memory<byte> dex, int langflag) : Zukan7(sav, dex, langflag)
{
private const int UNSET = 0x007F00FE;
private const int BaseOffset = 0x2A00;
private const int EntryStart = 0xF78; // 0x3978 - 0x2A00
private const int EntryCount = 186;
private const int EntrySize = 6;
@ -46,7 +45,7 @@ public sealed class Zukan7b(SAV7b sav, Memory<byte> dex, int langflag) : Zukan7(
public bool GetSizeData(DexSizeType group, int index, out byte height, out byte weight, out bool isFlagged)
{
var ofs = GetDexSizeOffset(group, index);
var entry = SAV.Data.AsSpan(ofs);
var entry = Data.Slice(ofs, EntrySize);
height = entry[0];
isFlagged = entry[1] == 1;
weight = entry[2];
@ -66,7 +65,7 @@ public sealed class Zukan7b(SAV7b sav, Memory<byte> dex, int langflag) : Zukan7(
if (pk.HeightAbsolute < pi.Height) // possible minimum height
{
int ofs = GetDexSizeOffset(DexSizeType.MinHeight, index);
var entry = SAV.Data.AsSpan(ofs, EntrySize);
var entry = Data.Slice(ofs, EntrySize);
var minHeight = entry[0];
if (pk.HeightScalar < minHeight || IsUnset(entry))
SetSizeData(pk, DexSizeType.MinHeight);
@ -74,7 +73,7 @@ public sealed class Zukan7b(SAV7b sav, Memory<byte> dex, int langflag) : Zukan7(
else if (pk.HeightAbsolute > pi.Height) // possible maximum height
{
int ofs = GetDexSizeOffset(DexSizeType.MaxHeight, index);
var entry = SAV.Data.AsSpan(ofs, EntrySize);
var entry = Data.Slice(ofs, EntrySize);
var maxHeight = entry[0];
if (pk.HeightScalar > maxHeight || IsUnset(entry))
SetSizeData(pk, DexSizeType.MaxHeight);
@ -83,7 +82,7 @@ public sealed class Zukan7b(SAV7b sav, Memory<byte> dex, int langflag) : Zukan7(
if (pk.WeightAbsolute < pi.Weight) // possible minimum weight
{
int ofs = GetDexSizeOffset(DexSizeType.MinWeight, index);
var entry = SAV.Data.AsSpan(ofs, EntrySize);
var entry = Data.Slice(ofs, EntrySize);
var minHeight = entry[0];
var minWeight = entry[2];
var calcWeight = PB7.GetWeightAbsolute(pi, minHeight, minWeight);
@ -93,7 +92,7 @@ public sealed class Zukan7b(SAV7b sav, Memory<byte> dex, int langflag) : Zukan7(
else if (pk.WeightAbsolute > pi.Weight) // possible maximum weight
{
int ofs = GetDexSizeOffset(DexSizeType.MaxWeight, index);
var entry = SAV.Data.AsSpan(ofs, EntrySize);
var entry = Data.Slice(ofs, EntrySize);
var maxHeight = entry[0];
var maxWeight = entry[2];
var calcWeight = PB7.GetWeightAbsolute(pi, maxHeight, maxWeight);
@ -105,7 +104,7 @@ public sealed class Zukan7b(SAV7b sav, Memory<byte> dex, int langflag) : Zukan7(
private static bool IsUnset(Span<byte> entry) => ReadUInt32LittleEndian(entry) == UNSET;
// blockofs + 0xF78 + ([186*6]*n) + x*6
private static int GetDexSizeOffset(DexSizeType group, int index) => BaseOffset + EntryStart + (EntrySize * (index + ((int)group * EntryCount)));
private static int GetDexSizeOffset(DexSizeType group, int index) => EntryStart + (EntrySize * (index + ((int)group * EntryCount)));
private void SetSizeData(PB7 pk, DexSizeType group, bool flag = false)
{
@ -131,7 +130,7 @@ public sealed class Zukan7b(SAV7b sav, Memory<byte> dex, int langflag) : Zukan7(
public void SetSizeData(DexSizeType group, int index, byte height, byte weight, bool flag = false)
{
var ofs = GetDexSizeOffset(group, index);
var span = SAV.Data.AsSpan(ofs);
var span = Data.Slice(ofs, EntrySize);
span[0] = height;
span[1] = flag ? (byte)1 : (byte)0;
span[2] = weight;

View file

@ -22,15 +22,15 @@ public partial class SAV_BerryFieldXY : Form
// Change Berry Field
// Gather Data
int ofs = SAV6XY.BerryField + 0xC + (listBox1.SelectedIndex * 0x18);
int berry = ReadUInt16LittleEndian(SAV.Data.AsSpan(ofs + (2 * 0)));
int u1 = ReadUInt16LittleEndian(SAV.Data.AsSpan(ofs + (2 * 1)));
int u2 = ReadUInt16LittleEndian(SAV.Data.AsSpan(ofs + (2 * 2)));
int u3 = ReadUInt16LittleEndian(SAV.Data.AsSpan(ofs + (2 * 3)));
int u4 = ReadUInt16LittleEndian(SAV.Data.AsSpan(ofs + (2 * 4)));
int u5 = ReadUInt16LittleEndian(SAV.Data.AsSpan(ofs + (2 * 5)));
int u6 = ReadUInt16LittleEndian(SAV.Data.AsSpan(ofs + (2 * 6)));
int u7 = ReadUInt16LittleEndian(SAV.Data.AsSpan(ofs + (2 * 7)));
var span = SAV.BerryField.GetPlot(listBox1.SelectedIndex);
int berry = ReadUInt16LittleEndian(span);
int u1 = ReadUInt16LittleEndian(span[(2 * 1)..]);
int u2 = ReadUInt16LittleEndian(span[(2 * 2)..]);
int u3 = ReadUInt16LittleEndian(span[(2 * 3)..]);
int u4 = ReadUInt16LittleEndian(span[(2 * 4)..]);
int u5 = ReadUInt16LittleEndian(span[(2 * 5)..]);
int u6 = ReadUInt16LittleEndian(span[(2 * 6)..]);
int u7 = ReadUInt16LittleEndian(span[(2 * 7)..]);
// Display Data
TB_Berry.Text = berry.ToString();
@ -43,8 +43,5 @@ public partial class SAV_BerryFieldXY : Form
TB_u7.Text = u7.ToString();
}
private void B_Cancel_Click(object sender, EventArgs e)
{
Close();
}
private void B_Cancel_Click(object sender, EventArgs e) => Close();
}

View file

@ -4,7 +4,6 @@ using System.Drawing;
using System.Windows.Forms;
using PKHeX.Core;
using PKHeX.Drawing.PokeSprite;
using static System.Buffers.Binary.BinaryPrimitives;
namespace PKHeX.WinForms;
@ -12,24 +11,19 @@ public partial class SAV_HallOfFame : Form
{
private readonly SAV6 Origin;
private readonly SAV6 SAV;
private readonly HallOfFame6 Fame;
private bool editing;
private readonly IReadOnlyList<string> gendersymbols = Main.GenderSymbols;
private readonly Memory<byte> Raw;
private Span<byte> Data => Raw.Span;
private const int Count = 16;
private const int StructureSize = 0x1B4;
private const int StructureTotal = Count * StructureSize;
public SAV_HallOfFame(SAV6 sav)
{
InitializeComponent();
WinFormsUtil.TranslateInterface(this, Main.CurrentLanguage);
SAV = (SAV6)(Origin = sav).Clone();
Fame = ((ISaveBlock6Main)SAV).HallOfFame;
Raw = SAV.Data.AsSpan(SAV.HoF, StructureTotal).ToArray(); // Copy HoF section of save into Data
Setup();
LB_DataEntry.SelectedIndex = 0;
NUP_PartyIndex_ValueChanged(this, EventArgs.Empty);
@ -69,7 +63,7 @@ public partial class SAV_HallOfFame : Form
private void B_Close_Click(object sender, EventArgs e)
{
Origin.SetData(Data, SAV.HoF);
Origin.CopyChangesFrom(SAV);
Close();
}
@ -79,17 +73,12 @@ public partial class SAV_HallOfFame : Form
RTB.Font = new Font("Courier New", 8);
RTB.LanguageOption = RichTextBoxLanguageOptions.DualFont;
int index = LB_DataEntry.SelectedIndex;
int offset = index * StructureSize;
uint vnd = ReadUInt32LittleEndian(Data[(offset + 0x1B0)..]);
uint vn = vnd & 0xFF;
TB_VN.Text = vn.ToString("000");
var s = new List<string> { $"Entry #{vn}" };
uint date = (vnd >> 14) & 0x1FFFF;
uint month = (date >> 8) & 0xF;
uint year = (date & 0xFF) + 2000;
uint day = date >> 12;
if (day == 0)
var span = Fame.GetEntry(index);
var vnd = new HallFame6Index(span[^4..]);
TB_VN.Text = vnd.ClearIndex.ToString("000");
var s = new List<string> { $"Entry #{vnd.ClearIndex}" };
if (!vnd.HasData)
{
s.Add("No records in this slot.");
groupBox1.Enabled = false;
@ -100,7 +89,7 @@ public partial class SAV_HallOfFame : Form
else
{
groupBox1.Enabled = true;
var moncount = AddEntries(offset, s, year, month, day);
var moncount = AddEntries(span, s, vnd);
if (sender != this)
{
@ -118,24 +107,25 @@ public partial class SAV_HallOfFame : Form
RTB.Font = new Font("Courier New", 8);
}
private int AddEntries(int offset, List<string> s, uint year, uint month, uint day)
private int AddEntries(Span<byte> data, List<string> s, HallFame6Index vnd)
{
var year = vnd.Year + 2000;
var month = vnd.Month;
var day = vnd.Day;
s.Add($"Date: {year}/{month:00}/{day:00}");
s.Add(string.Empty);
CAL_MetDate.Value = new DateTime((int)year, (int)month, (int)day);
int moncount = 0;
for (int i = 0; i < 6; i++)
{
var entry = new HallFame6Entity(Data.Slice(offset, HallFame6Entity.SIZE));
var slice = data[(i * HallFame6Entity.SIZE)..];
var entry = new HallFame6Entity(slice);
if (entry.Species == 0)
continue;
moncount++;
AddEntryDescription(s, entry);
offset += HallFame6Entity.SIZE;
}
return moncount;
}
@ -164,12 +154,9 @@ public partial class SAV_HallOfFame : Form
{
editing = false;
int index = LB_DataEntry.SelectedIndex;
int offset = (index * StructureSize) + ((Convert.ToInt32(NUP_PartyIndex.Value) - 1) * HallFame6Entity.SIZE);
if (offset < 0)
return;
var entry = new HallFame6Entity(Data.Slice(offset, HallFame6Entity.SIZE));
var member = (Convert.ToInt32(NUP_PartyIndex.Value) - 1);
var slice = Fame.GetEntity(index, member);
var entry = new HallFame6Entity(slice);
CB_Species.SelectedValue = (int)entry.Species;
CB_HeldItem.SelectedValue = (int)entry.HeldItem;
CB_Move1.SelectedValue = (int)entry.Move1;
@ -206,10 +193,10 @@ public partial class SAV_HallOfFame : Form
Validate_TextBoxes();
int index = LB_DataEntry.SelectedIndex;
int partymember = Convert.ToInt32(NUP_PartyIndex.Value) - 1;
int offset = (index * StructureSize) + (partymember * HallFame6Entity.SIZE);
var span = Data.Slice(offset, HallFame6Entity.SIZE);
var entry = new HallFame6Entity(span)
int member = Convert.ToInt32(NUP_PartyIndex.Value) - 1;
var slice = Fame.GetEntity(index, member);
var entry = new HallFame6Entity(slice)
{
Species = Convert.ToUInt16(CB_Species.SelectedValue),
HeldItem = Convert.ToUInt16(CB_HeldItem.SelectedValue),
@ -230,19 +217,15 @@ public partial class SAV_HallOfFame : Form
OriginalTrainerGender = (uint)EntityGender.GetFromString(Label_OTGender.Text) & 1,
};
offset = index * StructureSize;
uint vnd = 0;
uint date = 0;
vnd |= Convert.ToUInt32(TB_VN.Text) & 0xFF;
date |= (uint)((CAL_MetDate.Value.Year - 2000) & 0xFF);
date |= (uint)((CAL_MetDate.Value.Month & 0xF) << 8);
date |= (uint)((CAL_MetDate.Value.Day & 0x1F) << 12);
vnd |= (date & 0x1FFFF) << 14;
//Fix for top bit
uint rawvnd = ReadUInt32LittleEndian(Data[(offset + 0x1B0)..]);
vnd |= rawvnd & 0x80000000;
WriteUInt32LittleEndian(Data[(offset + 0x1B0)..], vnd);
var span = Fame.GetEntry(index);
_ = new HallFame6Index(span[^4..])
{
ClearIndex = Convert.ToUInt16(TB_VN.Text),
Year = (uint)CAL_MetDate.Value.Year - 2000,
Month = (uint)CAL_MetDate.Value.Month,
Day = (uint)CAL_MetDate.Value.Day,
HasData = true,
};
var shiny = entry.IsShiny ? Shiny.Always : Shiny.Never;
bpkx.Image = SpriteUtil.GetSprite(entry.Species, entry.Form, (byte)entry.Gender, 0, entry.HeldItem, false, shiny, EntityContext.Gen6);
@ -372,17 +355,7 @@ public partial class SAV_HallOfFame : Form
if (prompt != DialogResult.Yes)
return;
int offset = index * StructureSize;
if (index != 15)
{
// Shift down
var dest = Data[offset..];
var above = Data.Slice(offset + StructureSize, StructureSize * (Count - 1 - index));
above.CopyTo(dest);
}
// Ensure Last Entry is Cleared
Data.Slice(StructureSize * (Count - 1), StructureSize).Clear();
Fame.ClearEntry(index);
DisplayEntry(LB_DataEntry, EventArgs.Empty);
}
@ -395,8 +368,8 @@ public partial class SAV_HallOfFame : Form
var team = LB_DataEntry.SelectedIndex;
var member = (int)NUP_PartyIndex.Value - 1;
int offset = (team * (4 + (6 * HallFame6Entity.SIZE))) + (member * HallFame6Entity.SIZE);
var nicktrash = Data.Slice(0x18 + offset, 26);
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);

View file

@ -1,7 +1,6 @@
using System;
using System.Windows.Forms;
using PKHeX.Core;
using static System.Buffers.Binary.BinaryPrimitives;
namespace PKHeX.WinForms;
@ -18,11 +17,11 @@ public partial class SAV_PokeBlockORAS : Form
nup_spec = [NUP_Red, NUP_Blue, NUP_Pink, NUP_Green, NUP_Yellow, NUP_Rainbow, NUP_RedPlus, NUP_BluePlus, NUP_PinkPlus, NUP_GreenPlus, NUP_YellowPlus, NUP_RainbowPlus];
Label[] lbl_spec = [L_Red, L_Blue, L_Pink, L_Green, L_Yellow, L_Rainbow, L_RedPlus, L_BluePlus, L_PinkPlus, L_GreenPlus, L_YellowPlus, L_RainbowPlus];
var span = SAV.Data.AsSpan(SAV6AO.Contest);
var contest = SAV.Contest;
for (int i = 0; i < lbl_spec.Length; i++)
{
lbl_spec[i].Text = $"{GameInfo.Strings.pokeblocks[94 + i]}:";
nup_spec[i].Value = ReadUInt32LittleEndian(span[(i * 4)..]);
nup_spec[i].Value = contest.GetBlockCount(i);
}
}
@ -35,9 +34,9 @@ public partial class SAV_PokeBlockORAS : Form
private void B_Save_Click(object sender, EventArgs e)
{
var span = SAV.Data.AsSpan(SAV6AO.Contest);
var contest = SAV.Contest;
for (int i = 0; i < nup_spec.Length; i++)
WriteUInt32LittleEndian(span[(i * 4)..], (uint)nup_spec[i].Value);
contest.SetBlockCount(i, (uint)nup_spec[i].Value);
Origin.CopyChangesFrom(SAV);
Close();
}