pkNX/pkNX.Structures/Personal/Table/PersonalTable8SWSH.cs
duckdoom4 56cb75340a Minor refactor
Rename all the interfaces to give them a more sensible name
Rename the Set<InterfaceName> extension methods to Import<InterfaceName>, since evenI got confused about it's purpose for a while. It's supposed to be used by the data importer to fill in missing properties from older generation data. This means it should actually not set every property that is part of the interface and 'set' is therefor a confusing name.
Update PokeDataUI to fix layout of new property names
2023-07-05 19:35:57 +02:00

149 lines
4.6 KiB
C#

using System;
using System.Diagnostics;
namespace pkNX.Structures;
/// <summary>
/// Personal Table storing <see cref="PersonalTable8SWSH"/> used in <see cref="GameVersion.SWSH"/>.
/// </summary>
public sealed class PersonalTable8SWSH : IPersonalTable, IPersonalTable<PersonalInfo8SWSH>
{
public PersonalInfo8SWSH[] Table { get; }
private const int SIZE = PersonalInfo8SWSH.SIZE;
public int MaxSpeciesID => Legal.MaxSpeciesID_8;
public PersonalTable8SWSH(ReadOnlySpan<byte> data)
{
Table = data.GetArray(x => new PersonalInfo8SWSH(x.ToArray()), SIZE);
}
public void Save()
{
throw new NotImplementedException();
}
public PersonalInfo8SWSH this[int index] => Table[(uint)index < Table.Length ? index : 0];
public PersonalInfo8SWSH this[ushort species, byte form] => Table[GetFormIndex(species, form)];
public PersonalInfo8SWSH GetFormEntry(ushort species, byte form) => Table[GetFormIndex(species, form)];
public int GetFormIndex(ushort species, byte form)
{
if ((uint)species <= MaxSpeciesID)
return Table[species].FormIndex(species, form);
return 0;
}
public bool IsSpeciesInGame(ushort species)
{
if ((uint)species > MaxSpeciesID)
return false;
var form0 = Table[species];
if (form0.IsPresentInGame)
return true;
var fc = form0.FormCount;
for (byte i = 1; i < fc; i++)
{
var entry = GetFormEntry(species, i);
if (entry.IsPresentInGame)
return true;
}
return false;
}
public bool IsPresentInGame(ushort species, byte form)
{
if ((uint)species > MaxSpeciesID)
return false;
var form0 = Table[species];
if (form == 0)
return form0.IsPresentInGame;
if (!form0.HasForm(form))
return false;
var entry = GetFormEntry(species, form);
return entry.IsPresentInGame;
}
IPersonalInfo[] IPersonalTable.Table => Table;
IPersonalInfo IPersonalTable.this[int index] => this[index];
IPersonalInfo IPersonalTable.this[ushort species, byte form] => this[species, form];
IPersonalInfo IPersonalTable.GetFormEntry(ushort species, byte form) => GetFormEntry(species, form);
public void FixMissingData()
{
// Fix all base forms
int sFormCount = 0;
for (ushort i = 1; i <= Legal.MaxSpeciesID_7_USUM; i++)
{
var s = Table[i];
s.DexIndexNational = i;
var u = ResourcesUtil.USUM.Table[i];
if (s.FormCount == 0)
{
s.ImportPersonalInfo(u);
s.FormCount = Math.Max((byte)1, FormInfo.GetOutOfBattleFormCount(i, u.FormCount, 7));
}
if (s.FormCount == 1)
continue;
var formsAt = MaxSpeciesID + 1 + sFormCount;
if (s.FormStatsIndex != 0)
Debug.Assert(s.FormStatsIndex == formsAt);
s.FormStatsIndex = formsAt;
sFormCount += s.FormCount - 1;
for (byte f = 1; f < s.FormCount; f++)
{
var formS = Table[s.FormStatsIndex + (f - 1)];
if (formS.FormCount == 0)
{
// Check if USUM table has form data for this entry
if (f < u.FormCount)
{
if (u.FormCount <= s.FormCount || (FormInfo.HasTotemForm(i) && !FormInfo.IsTotemForm(i, f)))
{
var formU = ResourcesUtil.USUM.GetFormEntry(i, f);
formS.ImportPersonalInfo(formU);
}
}
else
{
// No form data was found, just write the base form data
formS.ImportPersonalInfo(s);
}
formS.FormCount = s.FormCount;
formS.FormStatsIndex = s.FormStatsIndex;
}
formS.DexIndexNational = i;
formS.Form = f;
}
}
// Fix form number
for (ushort i = Legal.MaxSpeciesID_7_USUM; i <= MaxSpeciesID; i++)
{
var s = Table[i];
s.DexIndexNational = i;
for (byte f = 1; f < s.FormCount; f++)
{
var formS = Table[s.FormStatsIndex + (f - 1)];
formS.DexIndexNational = i;
formS.Form = f;
}
}
Debug.WriteLine("Auto fix for SWSH data succeeded");
}
}