Update dex abstractions, add gg dex

This commit is contained in:
Kurt 2018-11-13 19:14:23 -08:00
parent 5f9afe83d6
commit 49c4043e19
4 changed files with 194 additions and 23 deletions

View file

@ -16,36 +16,45 @@ namespace PKHeX.Core
protected abstract int DexLangIDCount { get; } protected abstract int DexLangIDCount { get; }
protected abstract int GetDexLangFlag(int lang); protected abstract int GetDexLangFlag(int lang);
protected Func<int, int, int, int> DexFormIndexFetcher { get; set; } public Func<int, int, int, int> DexFormIndexFetcher { get; protected set; }
protected abstract bool GetSaneFormsToIterate(int species, out int formStart, out int formEnd, int formIn); protected abstract bool GetSaneFormsToIterate(int species, out int formStart, out int formEnd, int formIn);
protected abstract void SetSpindaDexData(PKM pkm, bool alreadySeen); protected virtual void SetSpindaDexData(PKM pkm, bool alreadySeen) { }
protected abstract void SetAllDexFlagsLanguage(int bit, int lang, bool value = true); protected abstract void SetAllDexFlagsLanguage(int bit, int lang, bool value = true);
protected abstract void SetAllDexSeenFlags(int baseBit, int altform, int gender, bool isShiny, bool value = true); protected abstract void SetAllDexSeenFlags(int baseBit, int altform, int gender, bool isShiny, bool value = true);
public bool GetFlag(int ofs, int bitIndex) => SAV.GetFlag(PokeDex + ofs, bitIndex); protected bool GetFlag(int ofs, int bitIndex) => SAV.GetFlag(PokeDex + ofs + (bitIndex >> 3), bitIndex);
public void SetFlag(int ofs, int bitIndex, bool value = true) => SAV.SetFlag(PokeDex + ofs, bitIndex, value); protected void SetFlag(int ofs, int bitIndex, bool value = true) => SAV.SetFlag(PokeDex + ofs + (bitIndex >> 3), bitIndex, value);
public bool GetCaught(int species) => GetFlag(OFS_CAUGHT, species - 1); public virtual bool GetCaught(int species) => GetFlag(OFS_CAUGHT, species - 1);
public void SetCaught(int species, bool value = true) => SetFlag(OFS_CAUGHT, species - 1, value); public virtual void SetCaught(int species, bool value = true) => SetFlag(OFS_CAUGHT, species - 1, value);
public int SeenCount => Enumerable.Range(1, SAV.MaxSpeciesID).Count(GetSeen); public int SeenCount => Enumerable.Range(1, SAV.MaxSpeciesID).Count(GetSeen);
public int CaughtCount => Enumerable.Range(1, SAV.MaxSpeciesID).Count(GetCaught); public int CaughtCount => Enumerable.Range(1, SAV.MaxSpeciesID).Count(GetCaught);
public decimal PercentSeen => (decimal)SeenCount / SAV.MaxSpeciesID; public decimal PercentSeen => (decimal)SeenCount / SAV.MaxSpeciesID;
public decimal PercentCaught => (decimal)CaughtCount / SAV.MaxSpeciesID; public decimal PercentCaught => (decimal)CaughtCount / SAV.MaxSpeciesID;
public bool GetSeen(int species) public virtual bool GetSeen(int species)
{ {
// check all 4 seen flags (gender/shiny) // check all 4 seen flags (gender/shiny)
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
if (GetFlag(OFS_SEEN + (i * BitSeenSize), species - 1)) if (GetSeen(species, i))
return true; return true;
} }
return false; return false;
} }
public void SetSeen(int species, bool value = true) public bool GetSeen(int species, int i) => GetFlag(OFS_SEEN + (i * BitSeenSize), species - 1);
public void SetSeen(int species, int i, bool value) => SetFlag(OFS_SEEN + (i * BitSeenSize), species - 1, value);
public bool GetDisplayed(int bit, int i) => GetFlag(OFS_SEEN + ((i + 4) * BitSeenSize), bit);
public void SetDisplayed(int bit, int i, bool value) => SetFlag(OFS_SEEN + ((i + 4) * BitSeenSize), bit, value);
public bool GetLanguageFlag(int bit, int lang) => GetFlag(PokeDexLanguageFlags, (bit * DexLangIDCount) + lang);
public void SetLanguageFlag(int bit, int lang, bool value) => SetFlag(PokeDexLanguageFlags, (bit * DexLangIDCount) + lang, value);
public virtual void SetSeen(int species, bool value = true)
{ {
if (!value) if (!value)
{ {
@ -79,12 +88,23 @@ namespace PKHeX.Core
if (pkm.IsEgg) // do not add if (pkm.IsEgg) // do not add
return; return;
int species = pkm.Species;
if (species == 327) // Spinda
SetSpindaDexData(pkm, GetSeen(species));
int bit = pkm.Species - 1; int bit = pkm.Species - 1;
SetCaught(pkm.Species); // Set the Owned Flag int form = pkm.AltForm;
if (pkm.Species == 327) // Spinda int gender = pkm.Gender & 1;
SetSpindaDexData(pkm, GetSeen(pkm.Species)); bool shiny = pkm.IsShiny;
SetAllDexSeenFlags(bit, pkm.AltForm, pkm.Gender & 1, pkm.IsShiny); // genderless -> male int lang = pkm.Language;
SetAllDexFlagsLanguage(bit, pkm.Language); SetDex(species, bit, form, gender, shiny, lang);
}
protected virtual void SetDex(int species, int bit, int form, int gender, bool shiny, int lang)
{
SetCaught(species); // Set the Owned Flag
SetAllDexSeenFlags(bit, form, gender, shiny); // genderless -> male
SetAllDexFlagsLanguage(bit, lang);
} }
protected void SetDexFlags(int baseBit, int formBit, int gender, int shiny, bool value = true) protected void SetDexFlags(int baseBit, int formBit, int gender, int shiny, bool value = true)
@ -103,18 +123,18 @@ namespace PKHeX.Core
private bool GetIsSpeciesFormAnyDisplayed(int baseBit, int formBit) private bool GetIsSpeciesFormAnyDisplayed(int baseBit, int formBit)
{ {
// Check Displayed Status for base form // Check Displayed Status for base form
for (int i = 4; i < 8; i++) for (int i = 0; i < 4; i++)
{ {
if (GetFlag(OFS_SEEN + (i * BitSeenSize), baseBit)) if (GetDisplayed(baseBit, i))
return true; return true;
} }
if (baseBit == formBit) if (baseBit == formBit)
return false; return false;
// If form is not base form, check form too // If form is not base form, check form too
for (int i = 4; i < 8; i++) for (int i = 0; i < 4; i++)
{ {
if (GetFlag(OFS_SEEN + (i * BitSeenSize), formBit)) if (GetDisplayed(formBit, i))
return true; return true;
} }
return false; return false;

View file

@ -1,3 +1,5 @@
using System;
namespace PKHeX.Core namespace PKHeX.Core
{ {
public class Zukan6 : Zukan public class Zukan6 : Zukan
@ -8,6 +10,15 @@ namespace PKHeX.Core
protected override int DexLangFlagByteCount => 7; protected override int DexLangFlagByteCount => 7;
protected override int DexLangIDCount => 7; protected override int DexLangIDCount => 7;
public Zukan6(SaveFile sav, int dex, int langflag)
{
SAV = sav;
PokeDex = dex;
PokeDexLanguageFlags = langflag;
var wrap = SAV.ORAS ? SaveUtil.GetDexFormIndexORAS : (Func<int,int,int>)SaveUtil.GetDexFormIndexXY;
DexFormIndexFetcher = (spec, form, _) => wrap(spec, form);
}
protected override int GetDexLangFlag(int lang) protected override int GetDexLangFlag(int lang)
{ {
lang--; lang--;
@ -103,7 +114,7 @@ namespace PKHeX.Core
private void SetFormFlags(int species, int form, int shiny, bool value = true) private void SetFormFlags(int species, int form, int shiny, bool value = true)
{ {
int fc = SAV.Personal[species].FormeCount; int fc = SAV.Personal[species].FormeCount;
int f = SAV.ORAS ? SaveUtil.GetDexFormIndexORAS(species, fc) : SaveUtil.GetDexFormIndexXY(species, fc); int f = DexFormIndexFetcher(species, fc, SAV.MaxSpeciesID - 1);
if (f < 0) if (f < 0)
return; return;

View file

@ -19,9 +19,11 @@ namespace PKHeX.Core
protected override int DexLangFlagByteCount => 920; // 0x398 = 817*9, top off the savedata block. protected override int DexLangFlagByteCount => 920; // 0x398 = 817*9, top off the savedata block.
protected override int DexLangIDCount => 9; // CHT, skipping langID 6 (unused) protected override int DexLangIDCount => 9; // CHT, skipping langID 6 (unused)
private readonly IList<int> FormBaseSpecies; private IList<int> FormBaseSpecies;
protected Zukan7() { } protected Zukan7()
{
}
public Zukan7(SaveFile sav, int dex, int langflag) public Zukan7(SaveFile sav, int dex, int langflag)
{ {
@ -29,10 +31,12 @@ namespace PKHeX.Core
PokeDex = dex; PokeDex = dex;
PokeDexLanguageFlags = langflag; PokeDexLanguageFlags = langflag;
DexFormIndexFetcher = SAV.USUM ? (Func<int, int, int, int>) SaveUtil.GetDexFormIndexSM : SaveUtil.GetDexFormIndexSM; DexFormIndexFetcher = SAV.USUM ? (Func<int, int, int, int>) SaveUtil.GetDexFormIndexSM : SaveUtil.GetDexFormIndexSM;
FormBaseSpecies = GetFormIndexBaseSpeciesList(); LoadDexList();
Debug.Assert(BitConverter.ToUInt32(SAV.Data, PokeDex) == MAGIC); Debug.Assert(BitConverter.ToUInt32(SAV.Data, PokeDex) == MAGIC);
} }
protected void LoadDexList() => FormBaseSpecies = GetFormIndexBaseSpeciesList();
protected override void SetAllDexSeenFlags(int baseBit, int altform, int gender, bool isShiny, bool value = true) protected override void SetAllDexSeenFlags(int baseBit, int altform, int gender, bool isShiny, bool value = true)
{ {
int species = baseBit + 1; int species = baseBit + 1;
@ -191,7 +195,7 @@ namespace PKHeX.Core
return index + SAV.MaxSpeciesID - 1; return index + SAV.MaxSpeciesID - 1;
} }
public IEnumerable<string> GetEntryNames(IReadOnlyList<string> Species) public IList<string> GetEntryNames(IReadOnlyList<string> Species)
{ {
var names = new List<string>(); var names = new List<string>();
for (int i = 1; i <= SAV.MaxSpeciesID; i++) for (int i = 1; i <= SAV.MaxSpeciesID; i++)

View file

@ -0,0 +1,136 @@
namespace PKHeX.Core
{
/// <summary>
/// Beluga specific Dex manipulator, slightly modified from Gen7.
/// </summary>
public class Zukan7b : Zukan7
{
private const int SIZE_MAGIC = 4; // 0x2F120F17 magic
private const int SIZE_FLAGS = 4;
private const int SIZE_MISC = 0x80; // Misc Data (1024 bits)
private const int SIZE_CAUGHT = 0x68; // 832 bits
protected override int OFS_CAUGHT => SIZE_MAGIC + SIZE_FLAGS + SIZE_MISC;
protected override int OFS_SEEN => OFS_CAUGHT + SIZE_CAUGHT;
protected override int BitSeenSize => 0x8C; // 1120 bits
protected override int DexLangFlagByteCount => 920; // 0x398 = 817*9, top off the savedata block.
protected override int DexLangIDCount => 9; // CHT, skipping langID 6 (unused)
public Zukan7b(SaveFile sav, int dex, int langflag)
{
SAV = sav;
PokeDex = dex;
PokeDexLanguageFlags = langflag;
DexFormIndexFetcher = SaveUtil.GetDexFormIndexGG;
LoadDexList();
}
public override void SetDex(PKM pkm)
{
if (!TryGetIndex(pkm.AltForm, pkm.Species, out _))
return;
SetSizeData(pkm);
base.SetDex(pkm);
}
protected override void SetDex(int species, int bit, int form, int gender, bool shiny, int lang)
{
if (IsBuddy(species, form))
form = 0;
base.SetDex(species, bit, form, gender, shiny, lang);
}
private static bool IsBuddy(int species, int form) => (species == 25 && form == 8) || (species == 133 && form == 1);
private void SetSizeData(PKM pkm)
{
int species = pkm.Species;
int form = pkm.AltForm;
if (!TryGetIndex(form, species, out int index))
return;
const int group = 0; // what differentiates the 4 groups?
int offset = 0x3978 + (index * 6) + (group * 0x45C); //0x1170/4
// todo?
}
private static bool TryGetIndex(int form, int species, out int index)
{
index = -1;
if (form == 0 && species <= 151)
{
index = species - 1;
return true;
}
for (int i = 0; i < SizeDexInfoTable.Length; i += 3)
{
if (SizeDexInfoTable[i] != species)
continue;
if (SizeDexInfoTable[i + 1] != form)
continue;
index = SizeDexInfoTable[i + 2];
return true;
}
return false;
}
public static readonly ushort[] SizeDexInfoTable =
{
// spec, form, index
808, 0, 151,
809, 0, 152,
003, 1, 153,
006, 1, 154,
006, 2, 155,
009, 1, 156,
015, 1, 157,
018, 1, 158,
019, 1, 159,
020, 1, 160,
026, 1, 161,
027, 1, 162,
028, 1, 163,
037, 1, 164,
038, 1, 165,
050, 1, 166,
051, 1, 167,
052, 1, 168,
053, 1, 169,
065, 1, 170,
074, 1, 171,
075, 1, 172,
076, 1, 173,
080, 1, 174,
088, 1, 175,
089, 1, 176,
094, 1, 177,
103, 1, 178,
105, 1, 179,
115, 1, 180,
127, 1, 181,
130, 1, 182,
142, 1, 183,
150, 1, 184,
150, 2, 185,
};
protected override bool GetSaneFormsToIterate(int species, out int formStart, out int formEnd, int formIn)
{
switch (species)
{
case 020: // Raticate
case 105: // Marowak
formStart = 0;
formEnd = 1;
return true;
default:
int count = SaveUtil.GetDexFormCountGG(species);
formStart = formEnd = 0;
return count < formIn;
}
}
}
}