Update dex minmax read offsets

Closes #3943

Also exposes the boolean flag in between the height/weight tuple.
Pretty sure this struct has an unused second half, and is just {byte, bool, byte}[2].
This commit is contained in:
Kurt 2023-08-20 13:48:01 -07:00
parent 86459812c1
commit 8dd9e0803d
4 changed files with 122 additions and 63 deletions

View File

@ -8,6 +8,15 @@ namespace PKHeX.Core;
/// </summary>>
public sealed class Zukan7b : Zukan7
{
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;
public const byte DefaultEntryValueH = 0xFE;
public const byte DefaultEntryValueW = 0x7F;
public Zukan7b(SAV7b sav, int dex, int langflag) : base(sav, dex, langflag)
{
}
@ -29,26 +38,26 @@ protected override void SetDex(ushort species, int bit, byte form, int gender, b
private static bool IsBuddy(ushort species, byte form) => (species == (int)Species.Pikachu && form == 8) || (species == (int)Species.Eevee && form == 1);
public const byte DefaultEntryValue = 0x7F;
public bool GetSizeData(DexSizeType group, ushort species, byte form, out byte height, out byte weight)
public bool GetSizeData(DexSizeType group, ushort species, byte form, out byte height, out byte weight, out bool isFlagged)
{
height = weight = DefaultEntryValue;
height = DefaultEntryValueH; weight = DefaultEntryValueW;
isFlagged = false;
if (TryGetSizeEntryIndex(species, form, out var index))
return GetSizeData(group, index, out height, out weight);
return GetSizeData(group, index, out height, out weight, out isFlagged);
return false;
}
public bool GetSizeData(DexSizeType group, int index, out byte height, out byte weight)
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);
height = entry[1];
height = entry[0];
isFlagged = entry[1] == 1;
weight = entry[2];
return !IsEntryUnset(height, weight);
}
private static bool IsEntryUnset(byte height, byte weight) => height == DefaultEntryValue && weight == DefaultEntryValue;
private static bool IsEntryUnset(byte height, byte weight) => height == DefaultEntryValueH && weight == DefaultEntryValueW;
private void SetSizeData(PB7 pk)
{
@ -60,47 +69,49 @@ private void SetSizeData(PB7 pk)
if (Math.Round(pk.HeightAbsolute) < pk.PersonalInfo.Height) // possible minimum height
{
int ofs = GetDexSizeOffset(DexSizeType.MinHeight, index);
var entry = SAV.Data.AsSpan(ofs);
var minHeight = entry[1];
var calcHeight = PB7.GetHeightAbsolute(pk.PersonalInfo, minHeight);
if (Math.Round(pk.HeightAbsolute) < Math.Round(calcHeight) || ReadUInt32LittleEndian(entry) == 0x007F00FE) // unset
var entry = SAV.Data.AsSpan(ofs, EntrySize);
var minHeight = entry[0];
if (pk.HeightScalar < minHeight || IsUnset(entry))
SetSizeData(pk, DexSizeType.MinHeight);
}
else if (Math.Round(pk.HeightAbsolute) > pk.PersonalInfo.Height) // possible maximum height
{
int ofs = GetDexSizeOffset(DexSizeType.MaxHeight, index);
var entry = SAV.Data.AsSpan(ofs);
var maxHeight = entry[1];
var calcHeight = PB7.GetHeightAbsolute(pk.PersonalInfo, maxHeight);
if (Math.Round(pk.HeightAbsolute) > Math.Round(calcHeight) || ReadUInt32LittleEndian(entry) == 0x007F00FE) // unset
var entry = SAV.Data.AsSpan(ofs, EntrySize);
var maxHeight = entry[0];
if (pk.HeightScalar > maxHeight || IsUnset(entry))
SetSizeData(pk, DexSizeType.MaxHeight);
}
var pi = PersonalTable.GG[species, form];
if (Math.Round(pk.WeightAbsolute) < pk.PersonalInfo.Weight) // possible minimum weight
{
int ofs = GetDexSizeOffset(DexSizeType.MinWeight, index);
var entry = SAV.Data.AsSpan(ofs);
var minHeight = entry[1];
var entry = SAV.Data.AsSpan(ofs, EntrySize);
var minHeight = entry[0];
var minWeight = entry[2];
var calcWeight = PB7.GetWeightAbsolute(pk.PersonalInfo, minHeight, minWeight);
if (Math.Round(pk.WeightAbsolute) < Math.Round(calcWeight) || ReadUInt32LittleEndian(entry) == 0x007F00FE) // unset
var calcWeight = PB7.GetWeightAbsolute(pi, minHeight, minWeight);
if (pk.WeightAbsolute < calcWeight || IsUnset(entry))
SetSizeData(pk, DexSizeType.MinWeight);
}
else if (Math.Round(pk.WeightAbsolute) > pk.PersonalInfo.Weight) // possible maximum weight
{
int ofs = GetDexSizeOffset(DexSizeType.MaxWeight, index);
var entry = SAV.Data.AsSpan(ofs);
var maxHeight = entry[1];
var entry = SAV.Data.AsSpan(ofs, EntrySize);
var maxHeight = entry[0];
var maxWeight = entry[2];
var calcWeight = PB7.GetWeightAbsolute(pk.PersonalInfo, maxHeight, maxWeight);
if (Math.Round(pk.WeightAbsolute) > Math.Round(calcWeight) || ReadUInt32LittleEndian(entry) == 0x007F00FE) // unset
var calcWeight = PB7.GetWeightAbsolute(pi, maxHeight, maxWeight);
if (pk.WeightAbsolute > calcWeight || IsUnset(entry))
SetSizeData(pk, DexSizeType.MaxWeight);
}
}
private static int GetDexSizeOffset(DexSizeType group, int index) => 0x3978 + (index * 6) + ((int)group * 0x45C); // blockofs + 0xF78 + ([186*6]*n) + x*6
private static bool IsUnset(Span<byte> entry) => ReadUInt32LittleEndian(entry) == UNSET;
private void SetSizeData(PB7 pk, DexSizeType group)
// blockofs + 0xF78 + ([186*6]*n) + x*6
private static int GetDexSizeOffset(DexSizeType group, int index) => BaseOffset + EntryStart + (EntrySize * (index + ((int)group * EntryCount)));
private void SetSizeData(PB7 pk, DexSizeType group, bool flag = false)
{
var tree = EvolutionTree.Evolves7b;
ushort species = pk.Species;
@ -112,21 +123,21 @@ private void SetSizeData(PB7 pk, DexSizeType group)
// update for all species in potential lineage
var allspec = tree.GetEvolutionsAndPreEvolutions(species, form);
foreach (var (s, f) in allspec)
SetSizeData(group, s, f, height, weight);
SetSizeData(group, s, f, height, weight, flag);
}
public void SetSizeData(DexSizeType group, ushort species, byte form, byte height, byte weight)
public void SetSizeData(DexSizeType group, ushort species, byte form, byte height, byte weight, bool flag = false)
{
if (TryGetSizeEntryIndex(species, form, out var index))
SetSizeData(group, index, height, weight);
SetSizeData(group, index, height, weight, flag);
}
public void SetSizeData(DexSizeType group, int index, byte height, byte weight)
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);
span[0] = 0;
span[1] = height;
span[0] = height;
span[1] = flag ? (byte)1 : (byte)0;
span[2] = weight;
span[3] = 0;
}

View File

@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using PKHeX.Core;
@ -30,8 +29,7 @@ public SAV_Capture7GG(SaveFile sav)
CB_Species.Items.Clear();
// Fill List
var list = GetLegalSpecies().ToArray();
var species = GameInfo.FilteredSources.Species.Where(z => list.Contains(z.Value)).ToList();
var species = GameInfo.FilteredSources.Species.Where(z => IsLegalSpecies(z.Value)).ToList();
CB_Species.InitializeBinding();
CB_Species.DataSource = new BindingSource(species, null);
foreach (var (text, value) in species.OrderBy(z => z.Value))
@ -44,13 +42,7 @@ public SAV_Capture7GG(SaveFile sav)
Loading = false;
}
private static IEnumerable<int> GetLegalSpecies()
{
foreach (var z in Enumerable.Range(1, 151))
yield return z;
yield return 808;
yield return 809;
}
private static bool IsLegalSpecies(int species) => species is >= 1 and (<= 151 or 808 or 809);
private void ChangeCBSpecies(object sender, EventArgs e)
{

View File

@ -88,6 +88,10 @@ private void InitializeComponent()
NUD_RHeightMax = new System.Windows.Forms.NumericUpDown();
NUD_RHeightMin = new System.Windows.Forms.NumericUpDown();
B_Counts = new System.Windows.Forms.Button();
CHK_MinH = new System.Windows.Forms.CheckBox();
CHK_MaxH = new System.Windows.Forms.CheckBox();
CHK_MinW = new System.Windows.Forms.CheckBox();
CHK_MaxW = new System.Windows.Forms.CheckBox();
GB_Language.SuspendLayout();
GB_Encountered.SuspendLayout();
GB_Owned.SuspendLayout();
@ -523,6 +527,10 @@ private void InitializeComponent()
//
// GB_SizeRecords
//
GB_SizeRecords.Controls.Add(CHK_MaxW);
GB_SizeRecords.Controls.Add(CHK_MinW);
GB_SizeRecords.Controls.Add(CHK_MaxH);
GB_SizeRecords.Controls.Add(CHK_MinH);
GB_SizeRecords.Controls.Add(CHK_RMaxWeight);
GB_SizeRecords.Controls.Add(CHK_RMinWeight);
GB_SizeRecords.Controls.Add(CHK_RMaxHeight);
@ -660,7 +668,7 @@ private void InitializeComponent()
//
// NUD_RWeightMax
//
NUD_RWeightMax.Location = new System.Drawing.Point(149, 113);
NUD_RWeightMax.Location = new System.Drawing.Point(145, 113);
NUD_RWeightMax.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
NUD_RWeightMax.Maximum = new decimal(new int[] { 255, 0, 0, 0 });
NUD_RWeightMax.Name = "NUD_RWeightMax";
@ -670,7 +678,7 @@ private void InitializeComponent()
//
// NUD_RWeightMin
//
NUD_RWeightMin.Location = new System.Drawing.Point(149, 90);
NUD_RWeightMin.Location = new System.Drawing.Point(145, 90);
NUD_RWeightMin.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
NUD_RWeightMin.Maximum = new decimal(new int[] { 255, 0, 0, 0 });
NUD_RWeightMin.Name = "NUD_RWeightMin";
@ -680,7 +688,7 @@ private void InitializeComponent()
//
// NUD_RHeightMaxWeight
//
NUD_RHeightMaxWeight.Location = new System.Drawing.Point(149, 67);
NUD_RHeightMaxWeight.Location = new System.Drawing.Point(145, 67);
NUD_RHeightMaxWeight.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
NUD_RHeightMaxWeight.Maximum = new decimal(new int[] { 255, 0, 0, 0 });
NUD_RHeightMaxWeight.Name = "NUD_RHeightMaxWeight";
@ -690,7 +698,7 @@ private void InitializeComponent()
//
// NUD_RHeightMinWeight
//
NUD_RHeightMinWeight.Location = new System.Drawing.Point(149, 44);
NUD_RHeightMinWeight.Location = new System.Drawing.Point(145, 44);
NUD_RHeightMinWeight.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
NUD_RHeightMinWeight.Maximum = new decimal(new int[] { 255, 0, 0, 0 });
NUD_RHeightMinWeight.Name = "NUD_RHeightMinWeight";
@ -700,7 +708,7 @@ private void InitializeComponent()
//
// NUD_RWeightMaxHeight
//
NUD_RWeightMaxHeight.Location = new System.Drawing.Point(50, 113);
NUD_RWeightMaxHeight.Location = new System.Drawing.Point(46, 113);
NUD_RWeightMaxHeight.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
NUD_RWeightMaxHeight.Maximum = new decimal(new int[] { 255, 0, 0, 0 });
NUD_RWeightMaxHeight.Name = "NUD_RWeightMaxHeight";
@ -710,7 +718,7 @@ private void InitializeComponent()
//
// NUD_RWeightMinHeight
//
NUD_RWeightMinHeight.Location = new System.Drawing.Point(50, 90);
NUD_RWeightMinHeight.Location = new System.Drawing.Point(46, 90);
NUD_RWeightMinHeight.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
NUD_RWeightMinHeight.Maximum = new decimal(new int[] { 255, 0, 0, 0 });
NUD_RWeightMinHeight.Name = "NUD_RWeightMinHeight";
@ -720,7 +728,7 @@ private void InitializeComponent()
//
// NUD_RHeightMax
//
NUD_RHeightMax.Location = new System.Drawing.Point(50, 67);
NUD_RHeightMax.Location = new System.Drawing.Point(46, 67);
NUD_RHeightMax.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
NUD_RHeightMax.Maximum = new decimal(new int[] { 255, 0, 0, 0 });
NUD_RHeightMax.Name = "NUD_RHeightMax";
@ -730,7 +738,7 @@ private void InitializeComponent()
//
// NUD_RHeightMin
//
NUD_RHeightMin.Location = new System.Drawing.Point(50, 44);
NUD_RHeightMin.Location = new System.Drawing.Point(46, 44);
NUD_RHeightMin.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
NUD_RHeightMin.Maximum = new decimal(new int[] { 255, 0, 0, 0 });
NUD_RHeightMin.Name = "NUD_RHeightMin";
@ -749,6 +757,46 @@ private void InitializeComponent()
B_Counts.UseVisualStyleBackColor = true;
B_Counts.Click += B_Counts_Click;
//
// CHK_MinH
//
CHK_MinH.AutoSize = true;
CHK_MinH.Location = new System.Drawing.Point(98, 47);
CHK_MinH.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
CHK_MinH.Name = "CHK_MinH";
CHK_MinH.Size = new System.Drawing.Size(15, 14);
CHK_MinH.TabIndex = 70;
CHK_MinH.UseVisualStyleBackColor = true;
//
// CHK_MaxH
//
CHK_MaxH.AutoSize = true;
CHK_MaxH.Location = new System.Drawing.Point(98, 70);
CHK_MaxH.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
CHK_MaxH.Name = "CHK_MaxH";
CHK_MaxH.Size = new System.Drawing.Size(15, 14);
CHK_MaxH.TabIndex = 71;
CHK_MaxH.UseVisualStyleBackColor = true;
//
// CHK_MinW
//
CHK_MinW.AutoSize = true;
CHK_MinW.Location = new System.Drawing.Point(98, 93);
CHK_MinW.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
CHK_MinW.Name = "CHK_MinW";
CHK_MinW.Size = new System.Drawing.Size(15, 14);
CHK_MinW.TabIndex = 72;
CHK_MinW.UseVisualStyleBackColor = true;
//
// CHK_MaxW
//
CHK_MaxW.AutoSize = true;
CHK_MaxW.Location = new System.Drawing.Point(98, 116);
CHK_MaxW.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
CHK_MaxW.Name = "CHK_MaxW";
CHK_MaxW.Size = new System.Drawing.Size(15, 14);
CHK_MaxW.TabIndex = 73;
CHK_MaxW.UseVisualStyleBackColor = true;
//
// SAV_PokedexGG
//
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
@ -859,5 +907,9 @@ private void InitializeComponent()
private System.Windows.Forms.NumericUpDown NUD_RHeightMax;
private System.Windows.Forms.NumericUpDown NUD_RHeightMin;
private System.Windows.Forms.Button B_Counts;
private System.Windows.Forms.CheckBox CHK_MaxW;
private System.Windows.Forms.CheckBox CHK_MinW;
private System.Windows.Forms.CheckBox CHK_MaxH;
private System.Windows.Forms.CheckBox CHK_MinH;
}
}

View File

@ -278,16 +278,17 @@ private void LoadRecord(ushort species, byte form)
if (!hasRecord)
return;
void set(DexSizeType type, NumericUpDown nudH, NumericUpDown nudW, CheckBox ck)
void set(DexSizeType type, NumericUpDown nudH, NumericUpDown nudW, CheckBox used, CheckBox flag)
{
nudH.Enabled = nudW.Enabled = ck.Checked = Dex.GetSizeData(type, index, out byte h, out byte w);
nudH.Enabled = nudW.Enabled = used.Checked = Dex.GetSizeData(type, index, out byte h, out byte w, out bool isFlagged);
flag.Checked = isFlagged;
nudH.Value = h;
nudW.Value = w;
}
set(DexSizeType.MinHeight, NUD_RHeightMin, NUD_RHeightMinWeight, CHK_RMinHeight);
set(DexSizeType.MaxHeight, NUD_RHeightMax, NUD_RHeightMaxWeight, CHK_RMaxHeight);
set(DexSizeType.MinWeight, NUD_RWeightMinHeight, NUD_RWeightMin, CHK_RMinWeight);
set(DexSizeType.MaxWeight, NUD_RWeightMaxHeight, NUD_RWeightMax, CHK_RMaxWeight);
set(DexSizeType.MinHeight, NUD_RHeightMin, NUD_RHeightMinWeight, CHK_RMinHeight, CHK_MinH);
set(DexSizeType.MaxHeight, NUD_RHeightMax, NUD_RHeightMaxWeight, CHK_RMaxHeight, CHK_MaxH);
set(DexSizeType.MinWeight, NUD_RWeightMinHeight, NUD_RWeightMin, CHK_RMinWeight, CHK_MinW);
set(DexSizeType.MaxWeight, NUD_RWeightMaxHeight, NUD_RWeightMax, CHK_RMaxWeight, CHK_MaxW);
}
private void SetRecord(ushort species, byte form)
@ -296,12 +297,13 @@ private void SetRecord(ushort species, byte form)
if (!hasRecord)
return;
static byte get(NumericUpDown nud, CheckBox ck) => !ck.Checked ? Zukan7b.DefaultEntryValue : (byte)nud.Value;
static byte getW(NumericUpDown nud, CheckBox ck) => !ck.Checked ? Zukan7b.DefaultEntryValueW : (byte)nud.Value;
static byte getH(NumericUpDown nud, CheckBox ck) => !ck.Checked ? Zukan7b.DefaultEntryValueH : (byte)nud.Value;
Dex.SetSizeData(DexSizeType.MinHeight, index, get(NUD_RHeightMin, CHK_RMinHeight), get(NUD_RHeightMinWeight, CHK_RMinHeight));
Dex.SetSizeData(DexSizeType.MaxHeight, index, get(NUD_RHeightMax, CHK_RMaxHeight), get(NUD_RHeightMaxWeight, CHK_RMaxHeight));
Dex.SetSizeData(DexSizeType.MinWeight, index, get(NUD_RWeightMinHeight, CHK_RMinWeight), get(NUD_RWeightMin, CHK_RMinWeight));
Dex.SetSizeData(DexSizeType.MaxWeight, index, get(NUD_RWeightMaxHeight, CHK_RMaxWeight), get(NUD_RWeightMax, CHK_RMaxWeight));
Dex.SetSizeData(DexSizeType.MinHeight, index, getH(NUD_RHeightMin, CHK_RMinHeight), getW(NUD_RHeightMinWeight, CHK_RMinHeight), CHK_MinH.Checked);
Dex.SetSizeData(DexSizeType.MaxHeight, index, getH(NUD_RHeightMax, CHK_RMaxHeight), getW(NUD_RHeightMaxWeight, CHK_RMaxHeight), CHK_MaxH.Checked);
Dex.SetSizeData(DexSizeType.MinWeight, index, getH(NUD_RWeightMinHeight, CHK_RMinWeight), getW(NUD_RWeightMin, CHK_RMinWeight), CHK_MinW.Checked);
Dex.SetSizeData(DexSizeType.MaxWeight, index, getH(NUD_RWeightMaxHeight, CHK_RMaxWeight), getW(NUD_RWeightMax, CHK_RMaxWeight), CHK_MaxW.Checked);
}
private void CHK_RUsed_CheckedChanged(object sender, EventArgs e)
@ -312,8 +314,10 @@ private void CHK_RUsed_CheckedChanged(object sender, EventArgs e)
var w = RecordWeight[index];
h.Enabled = w.Enabled = ck.Checked;
if (!editing && !ck.Checked)
h.Value = w.Value = Zukan7b.DefaultEntryValue;
if (editing || ck.Checked)
return;
h.Value = Zukan7b.DefaultEntryValueH;
w.Value = Zukan7b.DefaultEntryValueW;
}
private void B_Cancel_Click(object sender, EventArgs e)