PKHeX/Legality/Data.cs

280 lines
8.4 KiB
C#
Raw Normal View History

using System;
using System.IO;
using System.Linq;
namespace PKHeX
{
public class Learnset
{
public readonly int Count;
public readonly int[] Moves, Levels;
public Learnset(byte[] data)
{
if (data.Length < 4 || data.Length % 4 != 0)
{ Count = 0; Levels = new int[0]; Moves = new int[0]; return; }
Count = data.Length / 4 - 1;
Moves = new int[Count];
Levels = new int[Count];
using (BinaryReader br = new BinaryReader(new MemoryStream(data)))
for (int i = 0; i < Count; i++)
{
Moves[i] = br.ReadInt16();
Levels[i] = br.ReadInt16();
}
}
public static Learnset[] getArray(byte[][] entries)
{
Learnset[] data = new Learnset[entries.Length];
for (int i = 0; i < data.Length; i++)
data[i] = new Learnset(entries[i]);
return data;
}
public int[] getMoves(int level)
{
2016-03-12 17:13:52 +00:00
for (int i = 0; i < Levels.Length; i++)
if (Levels[i] > level)
return Moves.Take(i).ToArray();
return Moves;
}
}
public class EggMoves
{
public readonly int Count;
public readonly int[] Moves;
public EggMoves(byte[] data)
{
if (data.Length < 2 || data.Length % 2 != 0)
{ Count = 0; Moves = new int[0]; return; }
using (BinaryReader br = new BinaryReader(new MemoryStream(data)))
{
Moves = new int[Count = br.ReadUInt16()];
for (int i = 0; i < Count; i++)
Moves[i] = br.ReadUInt16();
}
}
public static EggMoves[] getArray(byte[][] entries)
{
EggMoves[] data = new EggMoves[entries.Length];
for (int i = 0; i < data.Length; i++)
data[i] = new EggMoves(entries[i]);
return data;
}
}
public class Evolutions
{
public readonly DexLevel[] Evos = new DexLevel[0];
public Evolutions(byte[] data)
{
int Count = data.Length / 4;
if (data.Length < 4 || data.Length % 4 != 0) return;
Evos = new DexLevel[Count];
for (int i = 0; i < data.Length; i += 4)
{
Evos[i/4] = new DexLevel
{
Species = BitConverter.ToUInt16(data, i),
Level = BitConverter.ToUInt16(data, i + 2)
};
}
}
public static Evolutions[] getArray(byte[][] entries)
{
Evolutions[] data = new Evolutions[entries.Length];
for (int i = 0; i < data.Length; i++)
data[i] = new Evolutions(entries[i]);
return data;
}
}
public class DexLevel
{
public int Species;
public int Level;
}
2016-02-25 00:36:26 +00:00
2016-02-26 00:19:59 +00:00
public class EncounterArea
2016-02-25 00:36:26 +00:00
{
public int Location;
2016-02-26 00:19:59 +00:00
public EncounterSlot[] Slots;
public EncounterArea() { }
2016-02-26 00:19:59 +00:00
public EncounterArea(byte[] data)
2016-02-25 00:36:26 +00:00
{
Location = BitConverter.ToUInt16(data, 0);
2016-02-26 00:19:59 +00:00
Slots = new EncounterSlot[(data.Length-2)/4];
2016-02-25 00:36:26 +00:00
for (int i = 0; i < Slots.Length; i++)
{
2016-02-26 00:19:59 +00:00
ushort SpecForm = BitConverter.ToUInt16(data, 2 + i*4);
2016-02-25 00:36:26 +00:00
Slots[i] = new EncounterSlot
{
2016-02-26 00:19:59 +00:00
Species = SpecForm & 0x7FF,
Form = SpecForm >> 11,
LevelMin = data[4 + i*4],
LevelMax = data[5 + i*4],
2016-02-25 00:36:26 +00:00
};
}
}
2016-02-26 00:19:59 +00:00
public static EncounterArea[] getArray(byte[][] entries)
2016-02-25 00:36:26 +00:00
{
2016-02-26 00:19:59 +00:00
EncounterArea[] data = new EncounterArea[entries.Length];
2016-02-25 00:36:26 +00:00
for (int i = 0; i < data.Length; i++)
2016-02-26 00:19:59 +00:00
data[i] = new EncounterArea(entries[i]);
2016-02-25 00:36:26 +00:00
return data;
}
}
public class EncounterSlot
{
public int Species;
public int Form;
public int LevelMin;
public int LevelMax;
public SlotType Type = SlotType.Any;
public bool AllowDexNav;
public bool Pressure;
public bool DexNav;
public bool WhiteFlute;
public bool BlackFlute;
public bool Normal => !(WhiteFlute || BlackFlute || DexNav);
public EncounterSlot() { }
public EncounterSlot(EncounterSlot template)
{
Species = template.Species;
AllowDexNav = template.AllowDexNav;
LevelMax = template.LevelMax;
LevelMin = template.LevelMin;
Type = template.Type;
Pressure = template.Pressure;
}
}
public enum SlotType
{
Any,
Grass,
Rough_Terrain,
Yellow_Flowers,
Purple_Flowers,
Red_Flowers,
Surf,
Old_Rod,
Good_Rod,
Super_Rod,
Rock_Smash,
Horde,
FriendSafari,
Special,
2016-02-25 00:36:26 +00:00
}
public class EncounterStatic
{
public int Species;
public int Level;
public int Location = 0;
public int Ability = 0;
public int Form = 0;
public bool? Shiny = null; // false = never, true = always, null = possible
public int[] Relearn = new int[4];
public int Gender = -1;
public int EggLocation = 0;
public Nature Nature = Nature.Random;
public bool Gift = false;
public int Ball = 4; // Gift Only
public GameVersion Version = GameVersion.Any;
public int[] IVs = {-1, -1, -1, -1, -1, -1};
2016-05-04 02:36:47 +00:00
public bool IV3;
public int[] Contest = {0, 0, 0, 0, 0, 0};
}
public class EncounterTrade
{
public int Species;
public int Level;
public int Location = 30001;
public int Ability = 0;
public Nature Nature = Nature.Random;
public int TID;
public int SID = 0;
public int[] IVs = { -1, -1, -1, -1, -1, -1 };
public int[] Moves;
public int Form = 0;
public bool Shiny = false;
public int Gender = -1;
}
public class EncounterLink
{
public int Species;
public int Level;
public int Location = 30011;
public int Ability = 4;
public int Ball = 4; // Pokéball
public Nature Nature = Nature.Random;
public int[] IVs = { -1, -1, -1, -1, -1, -1 };
public int FlawlessIVs = 0;
public bool Classic = true;
public bool Fateful = false;
public int[] RelearnMoves = new int[4];
public bool XY = true;
public bool ORAS = true;
public bool? Shiny = false;
public bool OT = true; // Receiver is OT?
}
public enum Nature
{
Random = -1,
Hardy, Lonely, Brave, Adamant, Naughty, Bold,
Docile, Relaxed, Impish, Lax, Timid, Hasty,
Serious, Jolly, Naive, Modest, Mild, Quiet,
Bashful, Rash, Calm, Gentle, Sassy, Careful,
Quirky,
}
2016-04-19 01:21:50 +00:00
internal static class Data
{
internal static byte[][] unpackMini(byte[] fileData, string identifier)
{
using (var s = new MemoryStream(fileData))
using (var br = new BinaryReader(s))
{
if (identifier != new string(br.ReadChars(2)))
return null;
ushort count = br.ReadUInt16();
byte[][] returnData = new byte[count][];
uint[] offsets = new uint[count + 1];
for (int i = 0; i < count; i++)
offsets[i] = br.ReadUInt32();
uint length = br.ReadUInt32();
offsets[offsets.Length - 1] = length;
for (int i = 0; i < count; i++)
{
br.BaseStream.Seek(offsets[i], SeekOrigin.Begin);
using (MemoryStream dataout = new MemoryStream())
{
byte[] data = new byte[0];
s.CopyTo(dataout, (int)offsets[i]);
int len = (int)offsets[i + 1] - (int)offsets[i];
if (len != 0)
{
data = dataout.ToArray();
Array.Resize(ref data, len);
}
returnData[i] = data;
}
}
return returnData;
}
}
}
}