Misc refactoring

more usum prep
don't allocate empty array on every savefile creation (use linq All
comparison)
add percent seen/caught savefile properties for data analysis purposes
This commit is contained in:
Kurt 2017-10-31 09:24:54 -07:00
parent e9cebf933c
commit 60e719a65a
16 changed files with 82 additions and 62 deletions

View file

@ -185,7 +185,7 @@ namespace PKHeX.Core
itemlist[842] += " (SM)"; // Fishing Rod itemlist[842] += " (SM)"; // Fishing Rod
// Append Z-Crystal flagging // Append Z-Crystal flagging
foreach (var i in Legal.Pouch_ZCrystal_SM) foreach (var i in Legal.Pouch_ZCrystal_USUM)
itemlist[i] += " [Z]"; itemlist[i] += " [Z]";
} }
private void SanitizeMetLocations() private void SanitizeMetLocations()

View file

@ -2178,33 +2178,31 @@ namespace PKHeX.Core
info = PersonalTable.B2W2[species]; info = PersonalTable.B2W2[species];
moves.AddRange(TypeTutor6.Where((t, i) => info.TypeTutors[i])); moves.AddRange(TypeTutor6.Where((t, i) => info.TypeTutors[i]));
if (pkm.InhabitedGeneration(5) && specialTutors) if (pkm.InhabitedGeneration(5) && specialTutors)
{ moves.AddRange(GetTutors(PersonalTable.B2W2, Tutors_B2W2));
PersonalInfo pi = PersonalTable.B2W2.GetFormeEntry(species, form);
for (int i = 0; i < Tutors_B2W2.Length; i++)
for (int b = 0; b < Tutors_B2W2[i].Length; b++)
if (pi.SpecialTutors[i][b])
moves.Add(Tutors_B2W2[i][b]);
}
break; break;
case 6: case 6:
info = PersonalTable.AO[species]; info = PersonalTable.AO[species];
moves.AddRange(TypeTutor6.Where((t, i) => info.TypeTutors[i])); moves.AddRange(TypeTutor6.Where((t, i) => info.TypeTutors[i]));
if (pkm.InhabitedGeneration(6) && specialTutors && (pkm.AO || !pkm.IsUntraded)) if (pkm.InhabitedGeneration(6) && specialTutors && (pkm.AO || !pkm.IsUntraded))
{ moves.AddRange(GetTutors(PersonalTable.AO, Tutors_AO));
PersonalInfo pi = PersonalTable.AO.GetFormeEntry(species, form);
for (int i = 0; i < Tutors_AO.Length; i++)
for (int b = 0; b < Tutors_AO[i].Length; b++)
if (pi.SpecialTutors[i][b])
moves.Add(Tutors_AO[i][b]);
}
break; break;
case 7: case 7:
info = PersonalTable.USUM.GetFormeEntry(species, form); info = PersonalTable.USUM.GetFormeEntry(species, form);
moves.AddRange(TypeTutor6.Where((t, i) => info.TypeTutors[i])); moves.AddRange(TypeTutor6.Where((t, i) => info.TypeTutors[i]));
// No special tutors in G7 if (pkm.InhabitedGeneration(7) && specialTutors && (pkm.USUM || !pkm.IsUntraded))
moves.AddRange(GetTutors(PersonalTable.USUM, Tutors_USUM));
break; break;
} }
return moves.Distinct(); return moves.Distinct();
IEnumerable<int> GetTutors(PersonalTable t, IReadOnlyList<int[]> tutors)
{
var pi = t.GetFormeEntry(species, form);
for (int i = 0; i < tutors.Count; i++)
for (int b = 0; b < tutors[i].Length; b++)
if (pi.SpecialTutors[i][b])
yield return tutors[i][b];
}
} }
internal static bool IsTradedKadabraG1(PKM pkm) internal static bool IsTradedKadabraG1(PKM pkm)
{ {

View file

@ -1,4 +1,6 @@
namespace PKHeX.Core using System.Collections.Generic;
namespace PKHeX.Core
{ {
/// <summary> /// <summary>
/// Static Encounter Data /// Static Encounter Data
@ -78,15 +80,13 @@
}; };
} }
public EncounterStatic[] DreamRadarClone() public IEnumerable<EncounterStatic> DreamRadarClone()
{ {
EncounterStatic[] Encounters = new EncounterStatic[8];
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
Encounters[i] = DreamRadarClone(5 * i + 5); //Level from 5->40 depends on the number of badage yield return DreamRadarClone(5 * i + 5); //Level from 5->40 depends on the number of badges
return Encounters;
} }
public EncounterStatic DreamRadarClone(int level) private EncounterStatic DreamRadarClone(int level)
{ {
return new EncounterStatic return new EncounterStatic
{ {

View file

@ -50,6 +50,13 @@ namespace PKHeX.Core
#endregion #endregion
internal static readonly int[][] Tutors_USUM =
{
new int[0], // todo
new int[0], // todo
new int[0], // todo
new int[0], // todo
};
internal static readonly ushort[] Pouch_Regular_SM = // 00 internal static readonly ushort[] Pouch_Regular_SM = // 00
{ {
068, 069, 070, 071, 072, 073, 074, 075, 076, 077, 078, 079, 080, 081, 082, 083, 084, 085, 086, 087, 068, 069, 070, 071, 072, 073, 074, 075, 076, 077, 078, 079, 080, 081, 082, 083, 084, 085, 086, 087,
@ -83,6 +90,9 @@ namespace PKHeX.Core
705, 706, 765, 773, 797, 705, 706, 765, 773, 797,
841, 842, 843, 845, 847, 850, 857, 858, 860, 841, 842, 843, 845, 847, 850, 857, 858, 860,
}; };
internal static readonly ushort[] Pouch_Key_USUM = {
// todo
};
internal static readonly ushort[] Pouch_TMHM_SM = { // 02 internal static readonly ushort[] Pouch_TMHM_SM = { // 02
328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345,
346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363,
@ -106,8 +116,14 @@ namespace PKHeX.Core
internal static readonly ushort[] Pouch_ZCrystalHeld_SM = { // Piece internal static readonly ushort[] Pouch_ZCrystalHeld_SM = { // Piece
776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 798, 799, 800, 801, 802, 803, 804, 805, 806, 836 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 798, 799, 800, 801, 802, 803, 804, 805, 806, 836
}; };
public static readonly Dictionary<int, int> ZCrystalDictionary = Pouch_ZCrystal_SM internal static readonly ushort[] Pouch_ZCrystal_USUM = Pouch_ZCrystal_SM.Concat(new ushort[] { // Bead
.Zip(Pouch_ZCrystalHeld_SM, (k, v) => new { Key = (int)k, Value = (int)v }) // todo
}).ToArray();
internal static readonly ushort[] Pouch_ZCrystalHeld_USUM = Pouch_ZCrystalHeld_SM.Concat(new ushort[] { // Piece
// todo
}).ToArray();
public static readonly Dictionary<int, int> ZCrystalDictionary = Pouch_ZCrystal_USUM
.Zip(Pouch_ZCrystalHeld_USUM, (k, v) => new { Key = (int)k, Value = (int)v })
.ToDictionary(x => x.Key, x => x.Value); .ToDictionary(x => x.Key, x => x.Value);
internal static readonly ushort[] HeldItems_SM = new ushort[1].Concat(Pouch_Items_SM).Concat(Pouch_Berries_SM).Concat(Pouch_Medicine_SM).Concat(Pouch_ZCrystalHeld_SM).ToArray(); internal static readonly ushort[] HeldItems_SM = new ushort[1].Concat(Pouch_Items_SM).Concat(Pouch_Berries_SM).Concat(Pouch_Medicine_SM).Concat(Pouch_ZCrystalHeld_SM).ToArray();
internal static readonly ushort[] HeldItems_USUM = HeldItems_SM; // todo internal static readonly ushort[] HeldItems_USUM = HeldItems_SM; // todo

View file

@ -8,7 +8,7 @@ namespace PKHeX.Core
{ {
public static readonly byte[] ExtraBytes = public static readonly byte[] ExtraBytes =
{ {
0x2A, // Old Marking Value 0x2A, // Old Marking Value (PelagoEventStatus)
// 0x36, 0x37, // Unused Ribbons // 0x36, 0x37, // Unused Ribbons
0x58, 0x59, 0x73, 0x90, 0x91, 0x9E, 0x9F, 0xA0, 0xA1, 0xA7, 0xAA, 0xAB, 0xAC, 0xAD, 0xC8, 0xC9, 0xD7, 0xE4, 0xE5, 0xE6, 0xE7 0x58, 0x59, 0x73, 0x90, 0x91, 0x9E, 0x9F, 0xA0, 0xA1, 0xA7, 0xAA, 0xAB, 0xAC, 0xAD, 0xC8, 0xC9, 0xD7, 0xE4, 0xE5, 0xE6, 0xE7
}; };

View file

@ -21,7 +21,7 @@ namespace PKHeX.Core
{ {
Data = data == null ? new byte[SaveUtil.SIZE_G1RAW] : (byte[])data.Clone(); Data = data == null ? new byte[SaveUtil.SIZE_G1RAW] : (byte[])data.Clone();
BAK = (byte[])Data.Clone(); BAK = (byte[])Data.Clone();
Exportable = !Data.SequenceEqual(new byte[Data.Length]); Exportable = !Data.All(z => z == 0);
if (data == null) if (data == null)
Version = GameVersion.RBY; Version = GameVersion.RBY;

View file

@ -23,7 +23,7 @@ namespace PKHeX.Core
{ {
Data = data == null ? new byte[SaveUtil.SIZE_G2RAW_U] : (byte[])data.Clone(); Data = data == null ? new byte[SaveUtil.SIZE_G2RAW_U] : (byte[])data.Clone();
BAK = (byte[])Data.Clone(); BAK = (byte[])Data.Clone();
Exportable = !Data.SequenceEqual(new byte[Data.Length]); Exportable = !Data.All(z => z == 0);
if (data == null) if (data == null)
Version = GameVersion.C; Version = GameVersion.C;

View file

@ -44,7 +44,7 @@ namespace PKHeX.Core
{ {
Data = data == null ? new byte[SaveUtil.SIZE_G3RAW] : (byte[])data.Clone(); Data = data == null ? new byte[SaveUtil.SIZE_G3RAW] : (byte[])data.Clone();
BAK = (byte[])Data.Clone(); BAK = (byte[])Data.Clone();
Exportable = !Data.SequenceEqual(new byte[Data.Length]); Exportable = !Data.All(z => z == 0);
if (data == null) if (data == null)
Version = GameVersion.FRLG; Version = GameVersion.FRLG;

View file

@ -48,7 +48,7 @@ namespace PKHeX.Core
{ {
Data = data == null ? new byte[SaveUtil.SIZE_G3COLO] : (byte[])data.Clone(); Data = data == null ? new byte[SaveUtil.SIZE_G3COLO] : (byte[])data.Clone();
BAK = (byte[])Data.Clone(); BAK = (byte[])Data.Clone();
Exportable = !Data.SequenceEqual(new byte[Data.Length]); Exportable = !Data.All(z => z == 0);
if (SaveUtil.GetIsG3COLOSAV(Data) != GameVersion.COLO) if (SaveUtil.GetIsG3COLOSAV(Data) != GameVersion.COLO)
return; return;

View file

@ -26,8 +26,8 @@ namespace PKHeX.Core
{ {
Data = data == null ? new byte[SaveUtil.SIZE_G3BOX] : (byte[])data.Clone(); Data = data == null ? new byte[SaveUtil.SIZE_G3BOX] : (byte[])data.Clone();
BAK = (byte[])Data.Clone(); BAK = (byte[])Data.Clone();
Exportable = !Data.SequenceEqual(new byte[Data.Length]); Exportable = !Data.All(z => z == 0);
if (SaveUtil.GetIsG3BOXSAV(Data) != GameVersion.RSBOX) if (SaveUtil.GetIsG3BOXSAV(Data) != GameVersion.RSBOX)
return; return;

View file

@ -40,7 +40,7 @@ namespace PKHeX.Core
{ {
Data = data == null ? new byte[SaveUtil.SIZE_G3XD] : (byte[])data.Clone(); Data = data == null ? new byte[SaveUtil.SIZE_G3XD] : (byte[])data.Clone();
BAK = (byte[])Data.Clone(); BAK = (byte[])Data.Clone();
Exportable = !Data.SequenceEqual(new byte[Data.Length]); Exportable = !Data.All(z => z == 0);
if (SaveUtil.GetIsG3XDSAV(Data) != GameVersion.XD) if (SaveUtil.GetIsG3XDSAV(Data) != GameVersion.XD)
return; return;

View file

@ -16,7 +16,7 @@ namespace PKHeX.Core
{ {
Data = data == null ? new byte[SaveUtil.SIZE_G4RAW] : (byte[])data.Clone(); Data = data == null ? new byte[SaveUtil.SIZE_G4RAW] : (byte[])data.Clone();
BAK = (byte[])Data.Clone(); BAK = (byte[])Data.Clone();
Exportable = !Data.SequenceEqual(new byte[Data.Length]); Exportable = !Data.All(z => z == 0);
// Get Version // Get Version
if (data == null) if (data == null)

View file

@ -19,7 +19,7 @@ namespace PKHeX.Core
{ {
Data = data == null ? new byte[SaveUtil.SIZE_G5RAW] : (byte[])data.Clone(); Data = data == null ? new byte[SaveUtil.SIZE_G5RAW] : (byte[])data.Clone();
BAK = (byte[])Data.Clone(); BAK = (byte[])Data.Clone();
Exportable = !Data.SequenceEqual(new byte[Data.Length]); Exportable = !Data.All(z => z == 0);
// Get Version // Get Version
if (data == null) if (data == null)

View file

@ -19,7 +19,7 @@ namespace PKHeX.Core
{ {
Data = data == null ? new byte[SaveUtil.SIZE_G6ORAS] : (byte[])data.Clone(); Data = data == null ? new byte[SaveUtil.SIZE_G6ORAS] : (byte[])data.Clone();
BAK = (byte[])Data.Clone(); BAK = (byte[])Data.Clone();
Exportable = !Data.SequenceEqual(new byte[Data.Length]); Exportable = !Data.All(z => z == 0);
// Load Info // Load Info
GetBlockInfo(); GetBlockInfo();

View file

@ -24,18 +24,18 @@ namespace PKHeX.Core
{ {
Data = data == null ? new byte[SaveUtil.SIZE_G7SM] : (byte[])data.Clone(); Data = data == null ? new byte[SaveUtil.SIZE_G7SM] : (byte[])data.Clone();
BAK = (byte[])Data.Clone(); BAK = (byte[])Data.Clone();
Exportable = !Data.SequenceEqual(new byte[Data.Length]); Exportable = !Data.All(z => z == 0);
// Load Info // Load Info
GetBlockInfo(); GetBlockInfo();
GetSAVOffsets(); GetSAVOffsets();
HeldItems = Legal.HeldItems_SM; HeldItems = USUM ? Legal.HeldItems_USUM : Legal.HeldItems_SM;
Personal = USUM ? PersonalTable.USUM : PersonalTable.SM; Personal = USUM ? PersonalTable.USUM : PersonalTable.SM;
if (!Exportable) if (!Exportable)
ClearBoxes(); ClearBoxes();
var demo = new byte[0x4C4].SequenceEqual(Data.Skip(PCLayout).Take(0x4C4)); // up to Battle Box values var demo = !USUM && Data.Skip(PCLayout).Take(0x4C4).All(z => z == 0); // up to Battle Box values
if (demo || !Exportable) if (demo || !Exportable)
{ {
PokeDex = -1; // Disabled PokeDex = -1; // Disabled
@ -44,28 +44,10 @@ namespace PKHeX.Core
} }
else // Valid slot locking info present else // Valid slot locking info present
{ {
int lockedCount = 0, teamCount = 0; LoadLockedSlots();
for (int i = 0; i < TeamCount; i++)
{
bool locked = Data[PCBackgrounds - TeamCount - i] == 1;
for (int j = 0; j < 6; j++)
{
short val = BitConverter.ToInt16(Data, BattleBoxFlags + (i*6 + j) * 2);
if (val < 0)
continue;
var slotVal = (BoxSlotCount*(val >> 8) + (val & 0xFF)) & 0xFFFF;
if (locked)
LockedSlots[lockedCount++] = slotVal;
else TeamSlots[teamCount++] = slotVal;
}
}
Array.Resize(ref LockedSlots, lockedCount);
Array.Resize(ref TeamSlots, teamCount);
} }
} }
// Configuration // Configuration
public override SaveFile Clone() { return new SAV7(Data); } public override SaveFile Clone() { return new SAV7(Data); }
@ -822,8 +804,8 @@ namespace PKHeX.Core
new InventoryPouch(InventoryType.Items, Legal.Pouch_Items_SM, 999, OFS_PouchHeldItem), new InventoryPouch(InventoryType.Items, Legal.Pouch_Items_SM, 999, OFS_PouchHeldItem),
new InventoryPouch(InventoryType.TMHMs, Legal.Pouch_TMHM_SM, 1, OFS_PouchTMHM), new InventoryPouch(InventoryType.TMHMs, Legal.Pouch_TMHM_SM, 1, OFS_PouchTMHM),
new InventoryPouch(InventoryType.Berries, Legal.Pouch_Berries_SM, 999, OFS_PouchBerry), new InventoryPouch(InventoryType.Berries, Legal.Pouch_Berries_SM, 999, OFS_PouchBerry),
new InventoryPouch(InventoryType.KeyItems, Legal.Pouch_Key_SM, 1, OFS_PouchKeyItem), new InventoryPouch(InventoryType.KeyItems, USUM ? Legal.Pouch_Key_USUM : Legal.Pouch_Key_SM, 1, OFS_PouchKeyItem),
new InventoryPouch(InventoryType.ZCrystals, Legal.Pouch_ZCrystal_SM, 1, OFS_PouchZCrystals), new InventoryPouch(InventoryType.ZCrystals, USUM ? Legal.Pouch_ZCrystal_USUM : Legal.Pouch_ZCrystal_SM, 1, OFS_PouchZCrystals),
}; };
foreach (var p in pouch) foreach (var p in pouch)
p.GetPouch7(ref Data); p.GetPouch7(ref Data);
@ -1178,6 +1160,28 @@ namespace PKHeX.Core
int slotIndex = slot + BoxSlotCount * box; int slotIndex = slot + BoxSlotCount * box;
return TeamSlots.Any(s => s == slotIndex); return TeamSlots.Any(s => s == slotIndex);
} }
private void LoadLockedSlots()
{
int lockedCount = 0, teamCount = 0;
for (int i = 0; i < TeamCount; i++)
{
bool locked = Data[PCBackgrounds - TeamCount - i] == 1;
for (int j = 0; j < 6; j++)
{
short val = BitConverter.ToInt16(Data, BattleBoxFlags + (i * 6 + j) * 2);
if (val < 0)
continue;
var slotVal = (BoxSlotCount * (val >> 8) + (val & 0xFF)) & 0xFFFF;
if (locked)
LockedSlots[lockedCount++] = slotVal;
else TeamSlots[teamCount++] = slotVal;
}
}
Array.Resize(ref LockedSlots, lockedCount);
Array.Resize(ref TeamSlots, teamCount);
}
public override int DaycareSeedSize => 32; // 128 bits public override int DaycareSeedSize => 32; // 128 bits
public override int GetDaycareSlotOffset(int loc, int slot) public override int GetDaycareSlotOffset(int loc, int slot)

View file

@ -659,8 +659,10 @@ namespace PKHeX.Core
public virtual void SetSeen(int species, bool seen) { } public virtual void SetSeen(int species, bool seen) { }
public virtual bool GetCaught(int species) => false; public virtual bool GetCaught(int species) => false;
public virtual void SetCaught(int species, bool caught) { } public virtual void SetCaught(int species, bool caught) { }
public int SeenCount => HasPokeDex ? new bool[MaxSpeciesID].Where((b, i) => GetSeen(i+1)).Count() : 0; public int SeenCount => HasPokeDex ? Enumerable.Range(1, MaxSpeciesID).Count(GetSeen) : 0;
public int CaughtCount => HasPokeDex ? new bool[MaxSpeciesID].Where((b, i) => GetCaught(i+1)).Count() : 0; public int CaughtCount => HasPokeDex ? Enumerable.Range(1, MaxSpeciesID).Count(GetCaught) : 0;
public decimal PercentSeen => (decimal) SeenCount / MaxSpeciesID;
public decimal PercentCaught => (decimal)CaughtCount / MaxSpeciesID;
public byte[] GetData(int Offset, int Length) public byte[] GetData(int Offset, int Length)
{ {