mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-08-28 08:05:32 -05:00
Add entree forest abstractions
make cryptarray public
This commit is contained in:
@@ -492,7 +492,7 @@ private static void CryptPKM45(byte[] data, uint pv, uint chk, int blockSize)
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static void CryptArray(byte[] data, uint seed, int start, int end)
|
||||
public static void CryptArray(byte[] data, uint seed, int start, int end)
|
||||
{
|
||||
for (int i = start; i < end; i += 2)
|
||||
Crypt(data, ref seed, i);
|
||||
|
||||
119
PKHeX.Core/Saves/Substructures/EntreeForest/EntreeForest.cs
Normal file
119
PKHeX.Core/Saves/Substructures/EntreeForest/EntreeForest.cs
Normal file
@@ -0,0 +1,119 @@
|
||||
using System;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
public class EntreeForest
|
||||
{
|
||||
/// <summary>
|
||||
/// Areas 1 thru 8 have 20 slots.
|
||||
/// </summary>
|
||||
private const byte Count18 = 20;
|
||||
|
||||
/// <summary>
|
||||
/// 9th Area has only 10 slots.
|
||||
/// </summary>
|
||||
private const byte Count9 = 10;
|
||||
|
||||
private const int TotalSlots = Count18 + (3 * 8 * Count18) + (3 * Count9);
|
||||
|
||||
/// <summary>
|
||||
/// Areas 3 thru 8 can be unlocked (set a value 0 to 6).
|
||||
/// </summary>
|
||||
private const byte MaxUnlock38Areas = 6;
|
||||
|
||||
|
||||
private readonly byte[] Data;
|
||||
|
||||
public EntreeForest(byte[] data)
|
||||
{
|
||||
Data = data;
|
||||
PKX.CryptArray(data, EncryptionSeed, 0, data.Length);
|
||||
}
|
||||
public byte[] Write()
|
||||
{
|
||||
byte[] data = (byte[])Data.Clone();
|
||||
PKX.CryptArray(data, EncryptionSeed, 0, data.Length);
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all Entree Slot data.
|
||||
/// </summary>
|
||||
public EntreeSlot[] Slots
|
||||
{
|
||||
get
|
||||
{
|
||||
var slots = new EntreeSlot[TotalSlots];
|
||||
for (int i = 0; i < slots.Length; i++)
|
||||
slots[i] = new EntreeSlot(Data, i * 4) { Area = GetSlotArea(i) };
|
||||
return slots;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the 9th Area is available to enter.
|
||||
/// </summary>
|
||||
public bool Unlock9thArea
|
||||
{
|
||||
get => Data[0x848] == 1;
|
||||
set => Data[0x848] = (byte)(value ? 1 : 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines how many extra areas are available to enter. Areas 1 & 2 are already available by default.
|
||||
/// </summary>
|
||||
public int Unlock38Areas
|
||||
{
|
||||
get => Data[0x849];
|
||||
set => Data[0x849] = (byte)Math.Max(MaxUnlock38Areas, value);
|
||||
}
|
||||
|
||||
public uint EncryptionSeed
|
||||
{
|
||||
get => BitConverter.ToUInt32(Data, 0x84C);
|
||||
private set => BitConverter.GetBytes(value).CopyTo(Data, 0x84C);
|
||||
}
|
||||
public void UnlockAllAreas()
|
||||
{
|
||||
Unlock38Areas = MaxUnlock38Areas;
|
||||
Unlock9thArea = true;
|
||||
}
|
||||
|
||||
public void DeleteAll()
|
||||
{
|
||||
foreach (var e in Slots)
|
||||
e.Delete();
|
||||
}
|
||||
|
||||
private static EntreeForestArea GetSlotArea(int index)
|
||||
{
|
||||
if (index < Count18)
|
||||
return EntreeForestArea.Deepest;
|
||||
index -= Count18;
|
||||
|
||||
const int slots9 = 3 * Count9;
|
||||
if (index < slots9)
|
||||
return EntreeForestArea.Ninth | GetSlotPosition(index / Count9);
|
||||
index -= slots9;
|
||||
|
||||
const int slots18 = 3 * Count18;
|
||||
int area = index / slots18;
|
||||
if (area >= 8)
|
||||
throw new ArgumentOutOfRangeException(nameof(index));
|
||||
index %= slots18;
|
||||
|
||||
return (EntreeForestArea)((int)EntreeForestArea.First << area) | GetSlotPosition(index / Count18);
|
||||
}
|
||||
|
||||
private static EntreeForestArea GetSlotPosition(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return EntreeForestArea.Center;
|
||||
case 1: return EntreeForestArea.Left;
|
||||
case 2: return EntreeForestArea.Right;
|
||||
default: throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
[Flags]
|
||||
public enum EntreeForestArea
|
||||
{
|
||||
Deepest = 1 << 0,
|
||||
First = 1 << 1,
|
||||
Second = 1 << 2,
|
||||
Third = 1 << 3,
|
||||
Fourth = 1 << 4,
|
||||
Fifth = 1 << 5,
|
||||
Sixth = 1 << 6,
|
||||
Seventh = 1 << 7,
|
||||
Eighth = 1 << 8,
|
||||
Ninth = 1 << 9,
|
||||
|
||||
Left = 1 << 10,
|
||||
Right = 1 << 11,
|
||||
Center = 1 << 12,
|
||||
}
|
||||
}
|
||||
57
PKHeX.Core/Saves/Substructures/EntreeForest/EntreeSlot.cs
Normal file
57
PKHeX.Core/Saves/Substructures/EntreeForest/EntreeSlot.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
|
||||
namespace PKHeX.Core
|
||||
{
|
||||
public class EntreeSlot
|
||||
{
|
||||
public int Species // bits 0-10
|
||||
{
|
||||
get => (int)(RawValue & 0x7FF) >> 0;
|
||||
set => RawValue = (RawValue & 0xFFFF_F800) | ((uint)value << 0);
|
||||
}
|
||||
public int Move // bits 11-20
|
||||
{
|
||||
get => (int)(RawValue & 0x1F_F800) >> 10;
|
||||
set => RawValue = (RawValue & 0xFFF0_02FF) | ((uint)value << 10);
|
||||
}
|
||||
public int Gender // bits 21-22
|
||||
{
|
||||
get => (int)(RawValue & 60_0000) >> 21;
|
||||
set => RawValue = (RawValue & 0xFF9F_FFFF) | ((uint)value << 21);
|
||||
}
|
||||
public int Form // bits 23-27
|
||||
{
|
||||
get => (int)(RawValue & 0x0F80_0000) >> 23;
|
||||
set => RawValue = (RawValue & 0xF07F_FFFF) | ((uint)value << 23);
|
||||
}
|
||||
public bool Invisible // bit 28
|
||||
{
|
||||
get => ((RawValue >> 28) & 1) == 1;
|
||||
set => RawValue = (RawValue & 0xEFFFFFFF) | (value ? 0 : 1u << 28);
|
||||
}
|
||||
public int Animation // bits 29-31
|
||||
{
|
||||
get => (int)(RawValue >> 29);
|
||||
set => RawValue = (RawValue << 3) >> 3 | (uint)(value << 29);
|
||||
}
|
||||
|
||||
private readonly byte[] Data;
|
||||
private readonly int Offset;
|
||||
|
||||
public uint RawValue
|
||||
{
|
||||
get => BitConverter.ToUInt32(Data, Offset);
|
||||
set => BitConverter.GetBytes(value).CopyTo(Data, Offset);
|
||||
}
|
||||
|
||||
public void Delete() => RawValue = 0;
|
||||
|
||||
public EntreeForestArea Area { get; internal set; }
|
||||
|
||||
public EntreeSlot(byte[] data, int ofs)
|
||||
{
|
||||
Data = data;
|
||||
Offset = ofs;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user