PKHeX/PKHeX/Legality/Structures/EncounterArea.cs

151 lines
5 KiB
C#
Raw Normal View History

using System;
using System.Linq;
namespace PKHeX.Core
{
public class EncounterArea
{
public int Location;
public EncounterSlot[] Slots;
public EncounterArea() { }
private EncounterArea(byte[] data)
{
Location = BitConverter.ToUInt16(data, 0);
Slots = new EncounterSlot[(data.Length - 2) / 4];
for (int i = 0; i < Slots.Length; i++)
{
ushort SpecForm = BitConverter.ToUInt16(data, 2 + i * 4);
Slots[i] = new EncounterSlot
{
Species = SpecForm & 0x7FF,
Form = SpecForm >> 11,
LevelMin = data[4 + i * 4],
LevelMax = data[5 + i * 4],
};
}
}
private static EncounterSlot1[] getSlots1_GW(byte[] data, ref int ofs, SlotType t)
{
int rate = data[ofs++];
return rate == 0 ? new EncounterSlot1[0] : readSlots(data, ref ofs, 10, t, rate);
}
private static EncounterSlot1[] getSlots1_F(byte[] data, ref int ofs)
{
int count = data[ofs++];
return readSlots(data, ref ofs, count, SlotType.Super_Rod, -1);
}
/// <summary>
/// RBY Format Slot Getter from data.
/// </summary>
/// <param name="data">Byte array containing complete slot data table.</param>
/// <param name="ofs">Offset to start reading from.</param>
/// <param name="count">Amount of slots to read.</param>
/// <param name="t">Type of encounter slot.</param>
/// <param name="rate">Slot type encounter rate.</param>
/// <returns>Array of encounter slots.</returns>
private static EncounterSlot1[] readSlots(byte[] data, ref int ofs, int count, SlotType t, int rate)
{
EncounterSlot1[] slots = new EncounterSlot1[count];
for (int i = 0; i < count; i++)
{
int lvl = data[ofs++];
int spec = data[ofs++];
slots[i] = new EncounterSlot1
{
LevelMax = lvl,
LevelMin = lvl,
Species = spec,
Type = t,
Rate = rate,
};
}
return slots;
}
public static EncounterArea[] getArray1_GW(byte[] data)
{
// RBY Format
var ptr = new int[255];
int count = 0;
for (int i = 0; i < ptr.Length; i++)
{
ptr[i] = BitConverter.ToInt16(data, i*2);
if (ptr[i] != -1)
continue;
count = i;
break;
}
EncounterArea[] areas = new EncounterArea[count];
for (int i = 0; i < areas.Length; i++)
{
var grass = getSlots1_GW(data, ref ptr[i], SlotType.Grass);
var water = getSlots1_GW(data, ref ptr[i], SlotType.Surf);
areas[i] = new EncounterArea
{
Location = i,
Slots = grass.Concat(water).ToArray()
};
}
return areas.Where(area => area.Slots.Any()).ToArray();
}
public static EncounterArea[] getArray1_FY(byte[] data)
{
const int size = 9;
int count = data.Length/size;
EncounterArea[] areas = new EncounterArea[count];
for (int i = 0; i < count; i++)
{
int ofs = i*size + 1;
areas[i] = new EncounterArea
{
Location = data[i*size + 0],
Slots = readSlots(data, ref ofs, 4, SlotType.Super_Rod, -1)
};
}
return areas;
}
public static EncounterArea[] getArray1_F(byte[] data)
{
var ptr = new int[255];
var map = new int[255];
int count = 0;
for (int i = 0; i < ptr.Length; i++)
{
map[i] = data[i*3 + 0];
if (map[i] == 0xFF)
{
count = i;
break;
}
ptr[i] = BitConverter.ToInt16(data, i * 3 + 1);
}
EncounterArea[] areas = new EncounterArea[count];
for (int i = 0; i < areas.Length; i++)
{
areas[i] = new EncounterArea
{
Location = map[i],
Slots = getSlots1_F(data, ref ptr[i])
};
}
return areas;
}
public static EncounterArea[] getArray(byte[][] entries)
{
if (entries == null)
return null;
EncounterArea[] data = new EncounterArea[entries.Length];
for (int i = 0; i < data.Length; i++)
data[i] = new EncounterArea(entries[i]);
return data;
}
}
}