2018-11-28 06:05:36 +00:00
|
|
|
using System;
|
|
|
|
|
2018-11-14 03:14:23 +00:00
|
|
|
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;
|
2018-11-28 06:05:36 +00:00
|
|
|
SetSizeData((PB7)pkm);
|
2018-11-14 03:14:23 +00:00
|
|
|
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);
|
|
|
|
|
2018-11-28 06:05:36 +00:00
|
|
|
private void SetSizeData(PB7 pkm)
|
2018-11-14 03:14:23 +00:00
|
|
|
{
|
|
|
|
int species = pkm.Species;
|
|
|
|
int form = pkm.AltForm;
|
|
|
|
if (!TryGetIndex(form, species, out int index))
|
|
|
|
return;
|
|
|
|
|
2018-11-28 06:05:36 +00:00
|
|
|
if (Math.Round(pkm.HeightAbsolute) < pkm.PersonalInfo.Height) // possible minimum height
|
|
|
|
{
|
|
|
|
int ofs = GetDexSizeOffset(0, index);
|
|
|
|
var minHeight = BitConverter.ToUInt16(SAV.Data, ofs) >> 1;
|
|
|
|
var calcHeight = PB7.GetHeightAbsolute(pkm.PersonalInfo, minHeight);
|
|
|
|
if (Math.Round(pkm.HeightAbsolute) < Math.Round(calcHeight) || BitConverter.ToUInt32(SAV.Data, ofs) == 0x007F00FE) // unset
|
|
|
|
UpdateSizeIndex(pkm, 0);
|
|
|
|
}
|
|
|
|
else if (Math.Round(pkm.HeightAbsolute) > pkm.PersonalInfo.Height) // possible maximum height
|
|
|
|
{
|
|
|
|
int ofs = GetDexSizeOffset(1, index);
|
|
|
|
var maxHeight = BitConverter.ToUInt16(SAV.Data, ofs) >> 1;
|
|
|
|
var calcHeight = PB7.GetHeightAbsolute(pkm.PersonalInfo, maxHeight);
|
|
|
|
if (Math.Round(pkm.HeightAbsolute) > Math.Round(calcHeight) || BitConverter.ToUInt32(SAV.Data, ofs) == 0x007F00FE) // unset
|
|
|
|
UpdateSizeIndex(pkm, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Math.Round(pkm.WeightAbsolute) < pkm.PersonalInfo.Weight) // possible minimum weight
|
|
|
|
{
|
|
|
|
int ofs = GetDexSizeOffset(2, index);
|
|
|
|
var minWeight = BitConverter.ToUInt16(SAV.Data, ofs + 2);
|
|
|
|
var minHeight = BitConverter.ToUInt16(SAV.Data, ofs) >> 1;
|
|
|
|
var calcWeight = PB7.GetWeightAbsolute(pkm.PersonalInfo, minHeight, minWeight);
|
|
|
|
if (Math.Round(pkm.WeightAbsolute) < Math.Round(calcWeight) || BitConverter.ToUInt32(SAV.Data, ofs) == 0x007F00FE) // unset
|
|
|
|
UpdateSizeIndex(pkm, 2);
|
|
|
|
}
|
|
|
|
else if (Math.Round(pkm.WeightAbsolute) > pkm.PersonalInfo.Weight) // possible maximum weight
|
|
|
|
{
|
|
|
|
int ofs = GetDexSizeOffset(3, index);
|
|
|
|
var maxWeight = BitConverter.ToUInt16(SAV.Data, ofs + 2);
|
|
|
|
var maxHeight = BitConverter.ToUInt16(SAV.Data, ofs) >> 1;
|
|
|
|
var calcWeight = PB7.GetWeightAbsolute(pkm.PersonalInfo, maxHeight, maxWeight);
|
|
|
|
if (Math.Round(pkm.WeightAbsolute) > Math.Round(calcWeight) || BitConverter.ToUInt32(SAV.Data, ofs) == 0x007F00FE) // unset
|
|
|
|
UpdateSizeIndex(pkm, 3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private int GetDexSizeOffset(int group, int index) => 0x3978 + (index * 6) + (group * 0x45C); // blockofs + 0xF78 + ([186*6]*n) + x*6
|
|
|
|
|
|
|
|
private void UpdateSizeIndex(PB7 pkm, int group)
|
|
|
|
{
|
|
|
|
var tree = EvolutionTree.GetEvolutionTree(pkm, 7);
|
|
|
|
int species = pkm.Species;
|
|
|
|
int form = pkm.AltForm;
|
|
|
|
|
|
|
|
// update for all species in potential lineage
|
|
|
|
var allspec = tree.GetEvolutionsAndPreEvolutions(species, form);
|
|
|
|
foreach (var s in allspec)
|
|
|
|
{
|
|
|
|
if (!TryGetIndex(form, s, out var index))
|
|
|
|
continue; // shouldn't hit this
|
|
|
|
|
|
|
|
var ofs = GetDexSizeOffset(group, index);
|
|
|
|
BitConverter.GetBytes((ushort)(pkm.HeightScalar << 1)).CopyTo(SAV.Data, ofs);
|
|
|
|
BitConverter.GetBytes((ushort)(pkm.WeightScalar)).CopyTo(SAV.Data, ofs + 2);
|
|
|
|
}
|
2018-11-14 03:14:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|