PKHeX/PKHeX.Core/Legality/Encounters/Data/EncounterEvent.cs
Kurt 0b32cbf132 Update PKHeX.Core abstractions with latest logic
Co-Authored-By: Matt <17801814+sora10pls@users.noreply.github.com>
Co-Authored-By: SciresM <8676005+SciresM@users.noreply.github.com>
Co-Authored-By: Lusamine <30205550+Lusamine@users.noreply.github.com>
2022-02-04 17:35:15 -08:00

141 lines
6.3 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using static PKHeX.Core.EncountersWC3;
namespace PKHeX.Core
{
public static class EncounterEvent
{
/// <summary>Event Database for Generation 3</summary>
public static IReadOnlyList<WC3> MGDB_G3 { get; private set; } = Array.Empty<WC3>();
/// <summary>Event Database for Generation 4</summary>
public static IReadOnlyList<PCD> MGDB_G4 { get; private set; } = Array.Empty<PCD>();
/// <summary>Event Database for Generation 5</summary>
public static IReadOnlyList<PGF> MGDB_G5 { get; private set; } = Array.Empty<PGF>();
/// <summary>Event Database for Generation 6</summary>
public static IReadOnlyList<WC6> MGDB_G6 { get; private set; } = Array.Empty<WC6>();
/// <summary>Event Database for Generation 7</summary>
public static IReadOnlyList<WC7> MGDB_G7 { get; private set; } = Array.Empty<WC7>();
/// <summary>Event Database for Generation 7 <see cref="GameVersion.GG"/></summary>
public static IReadOnlyList<WB7> MGDB_G7GG { get; private set; } = Array.Empty<WB7>();
/// <summary>Event Database for Generation 8</summary>
public static IReadOnlyList<WC8> MGDB_G8 { get; private set; } = Array.Empty<WC8>();
/// <summary>Event Database for Generation 8 <see cref="GameVersion.BDSP"/></summary>
public static IReadOnlyList<WA8> MGDB_G8A { get; private set; } = Array.Empty<WA8>();
/// <summary>Event Database for Generation 8 <see cref="GameVersion.BDSP"/></summary>
public static IReadOnlyList<WB8> MGDB_G8B { get; private set; } = Array.Empty<WB8>();
/// <summary>Indicates if the databases are initialized.</summary>
public static bool Initialized => MGDB_G3.Count != 0;
private static PCD[] GetPCDDB(ReadOnlySpan<byte> bin) => Get(bin, PCD.Size, d => new PCD(d));
private static PGF[] GetPGFDB(ReadOnlySpan<byte> bin) => Get(bin, PGF.Size, d => new PGF(d));
private static WC6[] GetWC6DB(ReadOnlySpan<byte> wc6bin, ReadOnlySpan<byte> wc6full) => WC6Full.GetArray(wc6full, wc6bin);
private static WC7[] GetWC7DB(ReadOnlySpan<byte> wc7bin, ReadOnlySpan<byte> wc7full) => WC7Full.GetArray(wc7full, wc7bin);
private static WB7[] GetWB7DB(ReadOnlySpan<byte> bin) => Get(bin, WB7.SizeFull, d => new WB7(d));
private static WC8[] GetWC8DB(ReadOnlySpan<byte> bin) => Get(bin, WC8.Size, d => new WC8(d));
private static WB8[] GetWB8DB(ReadOnlySpan<byte> bin) => Get(bin, WB8.Size, d => new WB8(d));
private static WA8[] GetWA8DB(ReadOnlySpan<byte> bin) => Get(bin, WA8.Size, d => new WA8(d));
private static T[] Get<T>(ReadOnlySpan<byte> bin, int size, Func<byte[], T> ctor)
{
var result = new T[bin.Length / size];
System.Diagnostics.Debug.Assert(result.Length * size == bin.Length);
for (int i = 0; i < result.Length; i++)
{
var offset = i * size;
var slice = bin.Slice(offset, size).ToArray();
result[i] = ctor(slice);
}
return result;
}
public static void RefreshMGDB(params string[] paths)
{
ICollection<PCD> g4 = GetPCDDB(Util.GetBinaryResource("wc4.pkl"));
ICollection<PGF> g5 = GetPGFDB(Util.GetBinaryResource("pgf.pkl"));
ICollection<WC6> g6 = GetWC6DB(Util.GetBinaryResource("wc6.pkl"), Util.GetBinaryResource("wc6full.pkl"));
ICollection<WC7> g7 = GetWC7DB(Util.GetBinaryResource("wc7.pkl"), Util.GetBinaryResource("wc7full.pkl"));
ICollection<WB7> b7 = GetWB7DB(Util.GetBinaryResource("wb7full.pkl"));
ICollection<WC8> g8 = GetWC8DB(Util.GetBinaryResource("wc8.pkl"));
ICollection<WB8> b8 = GetWB8DB(Util.GetBinaryResource("wb8.pkl"));
ICollection<WA8> a8 = GetWA8DB(Util.GetBinaryResource("wa8.pkl"));
foreach (var gift in paths.Where(Directory.Exists).SelectMany(MysteryUtil.GetGiftsFromFolder))
{
static void AddOrExpand<T>(ref ICollection<T> arr, T obj)
{
if (arr is HashSet<T> h)
h.Add(obj);
else
arr = new HashSet<T>(arr) {obj};
}
switch (gift)
{
case PCD pcd: AddOrExpand(ref g4, pcd); continue;
case PGF pgf: AddOrExpand(ref g5, pgf); continue;
case WC6 wc6: AddOrExpand(ref g6, wc6); continue;
case WC7 wc7: AddOrExpand(ref g7, wc7); continue;
case WB7 wb7: AddOrExpand(ref b7, wb7); continue;
case WC8 wc8: AddOrExpand(ref g8, wc8); continue;
case WB8 wb8: AddOrExpand(ref b8, wb8); continue;
case WA8 wa8: AddOrExpand(ref a8, wa8); continue;
}
}
static T[] SetArray<T>(ICollection<T> arr)
{
if (arr is T[] x)
return x;
// rather than use Linq to build an array, just do it the quick way directly.
var result = new T[arr.Count];
((HashSet<T>)arr).CopyTo(result, 0);
return result;
}
MGDB_G3 = Encounter_WC3; // hardcoded
MGDB_G4 = SetArray(g4);
MGDB_G5 = SetArray(g5);
MGDB_G6 = SetArray(g6);
MGDB_G7 = SetArray(g7);
MGDB_G7GG = SetArray(b7);
MGDB_G8 = SetArray(g8);
MGDB_G8A = SetArray(a8);
MGDB_G8B = SetArray(b8);
}
public static IEnumerable<MysteryGift> GetAllEvents(bool sorted = true)
{
var regular = new IReadOnlyList<MysteryGift>[]
{
MGDB_G4,
MGDB_G5,
MGDB_G6,
MGDB_G7,
MGDB_G7GG,
MGDB_G8,
MGDB_G8A,
MGDB_G8B,
}.SelectMany(z => z);
regular = regular.Where(mg => !mg.IsItem && mg.IsPokémon && mg.Species > 0);
var result = MGDB_G3.Concat(regular);
if (sorted)
result = result.OrderBy(mg => mg.Species);
return result;
}
}
}