mirror of
https://github.com/kwsch/PKHeX.git
synced 2026-04-25 16:35:02 -05:00
Refer to pull request notes and the eventual changelog for a high-level summary. Co-authored-by: Matt <17801814+sora10pls@users.noreply.github.com> Co-authored-by: Lusamine <30205550+Lusamine@users.noreply.github.com> Co-authored-by: SciresM <8676005+SciresM@users.noreply.github.com>
208 lines
9.1 KiB
C#
208 lines
9.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Runtime.CompilerServices;
|
|
|
|
namespace PKHeX.Core;
|
|
|
|
/// <summary>
|
|
/// Helper class that stores references to all the event data templates.
|
|
/// </summary>
|
|
public static class EncounterEvent
|
|
{
|
|
#region Pickle Data
|
|
/// <summary>Event Database for Generation 4</summary>
|
|
public static readonly PCD[] MGDB_G4 = GetPCDDB(Util.GetBinaryResource("wc4.pkl"));
|
|
|
|
/// <summary>Event Database for Generation 5</summary>
|
|
public static readonly PGF[] MGDB_G5 = GetPGFDB(Util.GetBinaryResource("pgf.pkl"));
|
|
|
|
/// <summary>Event Database for Generation 6</summary>
|
|
public static readonly WC6[] MGDB_G6 = GetWC6DB(Util.GetBinaryResource("wc6.pkl"), Util.GetBinaryResource("wc6full.pkl"));
|
|
|
|
/// <summary>Event Database for Generation 7</summary>
|
|
public static readonly WC7[] MGDB_G7 = GetWC7DB(Util.GetBinaryResource("wc7.pkl"), Util.GetBinaryResource("wc7full.pkl"));
|
|
|
|
/// <summary>Event Database for Generation 7 <see cref="EntityContext.Gen7b"/></summary>
|
|
public static readonly WB7[] MGDB_G7GG = GetWB7DB(Util.GetBinaryResource("wb7full.pkl"));
|
|
|
|
/// <summary>Event Database for Generation 8 <see cref="EntityContext.Gen8"/></summary>
|
|
public static readonly WC8[] MGDB_G8 = GetWC8DB(Util.GetBinaryResource("wc8.pkl"));
|
|
|
|
/// <summary>Event Database for Generation 8 <see cref="EntityContext.Gen8a"/></summary>
|
|
public static readonly WA8[] MGDB_G8A = GetWA8DB(Util.GetBinaryResource("wa8.pkl"));
|
|
|
|
/// <summary>Event Database for Generation 8 <see cref="EntityContext.Gen8b"/></summary>
|
|
public static readonly WB8[] MGDB_G8B = GetWB8DB(Util.GetBinaryResource("wb8.pkl"));
|
|
|
|
/// <summary>Event Database for Generation 9 <see cref="EntityContext.Gen9"/></summary>
|
|
public static readonly WC9[] MGDB_G9 = GetWC9DB(Util.GetBinaryResource("wc9.pkl"));
|
|
|
|
/// <summary>Event Database for Generation 9 <see cref="EntityContext.Gen9a"/></summary>
|
|
public static readonly WA9[] MGDB_G9A = GetWA9DB(Util.GetBinaryResource("wa9.pkl"));
|
|
#endregion
|
|
|
|
#region Locally Loaded Data
|
|
/// <summary>Event Database for Generation 4</summary>
|
|
public static PCD[] EGDB_G4 { get; private set; } = [];
|
|
|
|
/// <summary>Event Database for Generation 5</summary>
|
|
public static PGF[] EGDB_G5 { get; private set; } = [];
|
|
|
|
/// <summary>Event Database for Generation 6</summary>
|
|
public static WC6[] EGDB_G6 { get; private set; } = [];
|
|
|
|
/// <summary>Event Database for Generation 7</summary>
|
|
public static WC7[] EGDB_G7 { get; private set; } = [];
|
|
|
|
/// <summary>Event Database for Generation 7 <see cref="EntityContext.Gen7b"/></summary>
|
|
public static WB7[] EGDB_G7GG { get; private set; } = [];
|
|
|
|
/// <summary>Event Database for Generation 8 <see cref="EntityContext.Gen8"/></summary>
|
|
public static WC8[] EGDB_G8 { get; private set; } = [];
|
|
|
|
/// <summary>Event Database for Generation 8 <see cref="EntityContext.Gen8a"/></summary>
|
|
public static WA8[] EGDB_G8A { get; private set; } = [];
|
|
|
|
/// <summary>Event Database for Generation 8 <see cref="EntityContext.Gen8b"/></summary>
|
|
public static WB8[] EGDB_G8B { get; private set; } = [];
|
|
|
|
/// <summary>Event Database for Generation 9 <see cref="EntityContext.Gen9"/></summary>
|
|
public static WC9[] EGDB_G9 { get; private set; } = [];
|
|
|
|
/// <summary>Event Database for Generation 9 <see cref="EntityContext.Gen9a"/></summary>
|
|
public static WA9[] EGDB_G9A { get; private set; } = [];
|
|
#endregion
|
|
|
|
private static PCD[] GetPCDDB(Memory<byte> bin) => Get(bin, PCD.Size, static d => new PCD(d));
|
|
private static PGF[] GetPGFDB(Memory<byte> bin) => Get(bin, PGF.Size, static d => new PGF(d));
|
|
|
|
private static WC6[] GetWC6DB(Memory<byte> wc6bin, Memory<byte> wc6full) => WC6Full.GetArray(wc6full, wc6bin);
|
|
private static WC7[] GetWC7DB(Memory<byte> wc7bin, Memory<byte> wc7full) => WC7Full.GetArray(wc7full, wc7bin);
|
|
|
|
private static WB7[] GetWB7DB(Memory<byte> bin) => Get(bin, WB7.Size, static d => new WB7(d));
|
|
private static WC8[] GetWC8DB(Memory<byte> bin) => Get(bin, WC8.Size, static d => new WC8(d));
|
|
private static WB8[] GetWB8DB(Memory<byte> bin) => Get(bin, WB8.Size, static d => new WB8(d));
|
|
private static WA8[] GetWA8DB(Memory<byte> bin) => Get(bin, WA8.Size, static d => new WA8(d));
|
|
private static WC9[] GetWC9DB(Memory<byte> bin) => Get(bin, WC9.Size, static d => new WC9(d));
|
|
private static WA9[] GetWA9DB(Memory<byte> bin) => Get(bin, WA9.Size, static d => new WA9(d));
|
|
|
|
private static T[] Get<T>(Memory<byte> bin, int size, Func<Memory<byte>, T> ctor)
|
|
{
|
|
// bin is a multiple of size
|
|
// bin.Length % size == 0
|
|
var result = new T[bin.Length / size];
|
|
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);
|
|
result[i] = ctor(slice);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reloads the locally stored event templates.
|
|
/// </summary>
|
|
/// <param name="paths">External folder(s) to source individual mystery gift template files from.</param>
|
|
public static void RefreshMGDB(params ReadOnlySpan<string> paths)
|
|
{
|
|
// If no paths are provided, clear the arrays. See the bottom of this method.
|
|
HashSet<PCD>? g4 = null; List<PCD>? lg4 = null;
|
|
HashSet<PGF>? g5 = null; List<PGF>? lg5 = null;
|
|
HashSet<WC6>? g6 = null; List<WC6>? lg6 = null;
|
|
HashSet<WC7>? g7 = null; List<WC7>? lg7 = null;
|
|
HashSet<WB7>? b7 = null; List<WB7>? lb7 = null;
|
|
HashSet<WC8>? g8 = null; List<WC8>? lg8 = null;
|
|
HashSet<WB8>? b8 = null; List<WB8>? lb8 = null;
|
|
HashSet<WA8>? a8 = null; List<WA8>? la8 = null;
|
|
HashSet<WC9>? g9 = null; List<WC9>? lg9 = null;
|
|
HashSet<WA9>? a9 = null; List<WA9>? la9 = null;
|
|
|
|
// Load external files
|
|
// For each file, load the gift object into the appropriate list.
|
|
foreach (var path in paths)
|
|
{
|
|
if (!Directory.Exists(path))
|
|
continue;
|
|
var gifts = MysteryUtil.GetGiftsFromFolder(path);
|
|
foreach (var gift in gifts)
|
|
{
|
|
var added = gift switch
|
|
{
|
|
PCD pcd => AddOrExpand(ref g4, ref lg4, pcd),
|
|
PGF pgf => AddOrExpand(ref g5, ref lg5, pgf),
|
|
WC6 wc6 => AddOrExpand(ref g6, ref lg6, wc6),
|
|
WC7 wc7 => AddOrExpand(ref g7, ref lg7, wc7),
|
|
WB7 wb7 => AddOrExpand(ref b7, ref lb7, wb7),
|
|
WC8 wc8 => AddOrExpand(ref g8, ref lg8, wc8),
|
|
WB8 wb8 => AddOrExpand(ref b8, ref lb8, wb8),
|
|
WA8 wa8 => AddOrExpand(ref a8, ref la8, wa8),
|
|
WC9 wc9 => AddOrExpand(ref g9, ref lg9, wc9),
|
|
WA9 wa9 => AddOrExpand(ref a9, ref la9, wa9),
|
|
_ => false,
|
|
};
|
|
if (!added)
|
|
Trace.WriteLine($"Failed to add gift in {Path.GetDirectoryName(path)}: {gift.FileName}");
|
|
|
|
static bool AddOrExpand<T>([NotNullWhen(true)] ref HashSet<T>? arr, ref List<T>? extra, T obj)
|
|
{
|
|
if (arr is null)
|
|
{
|
|
// Most users won't be adding more than 1-2 gifts
|
|
// Save memory by initializing the HashSet and List minimally.
|
|
arr = new HashSet<T>(1);
|
|
extra = new List<T>(1);
|
|
}
|
|
if (arr.Add(obj))
|
|
extra!.Add(obj);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
EGDB_G4 = SetArray(lg4);
|
|
EGDB_G5 = SetArray(lg5);
|
|
EGDB_G6 = SetArray(lg6);
|
|
EGDB_G7 = SetArray(lg7);
|
|
EGDB_G7GG = SetArray(lb7);
|
|
EGDB_G8 = SetArray(lg8);
|
|
EGDB_G8A = SetArray(la8);
|
|
EGDB_G8B = SetArray(lb8);
|
|
EGDB_G9 = SetArray(lg9);
|
|
EGDB_G9A = SetArray(la9);
|
|
return;
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
static T[] SetArray<T>(List<T>? update) => update is null ? [] : update.ToArray();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets all event gifts.
|
|
/// </summary>
|
|
/// <param name="sorted">If true, the result will be sorted by ascending species ID. Otherwise, will be ordered by generation ascending.</param>
|
|
public static IEnumerable<MysteryGift> GetAllEvents(bool sorted = true)
|
|
{
|
|
var regular = new IReadOnlyList<MysteryGift>[]
|
|
{
|
|
MGDB_G4, EGDB_G4,
|
|
MGDB_G5, EGDB_G5,
|
|
MGDB_G6, EGDB_G6,
|
|
MGDB_G7, EGDB_G7,
|
|
MGDB_G7GG, EGDB_G7GG,
|
|
MGDB_G8, EGDB_G8,
|
|
MGDB_G8A, EGDB_G8A,
|
|
MGDB_G8B, EGDB_G8B,
|
|
MGDB_G9, EGDB_G9,
|
|
}.SelectMany(z => z);
|
|
var result = regular.Where(mg => mg is { IsItem: false, IsEntity: true, Species: not 0 });
|
|
if (sorted)
|
|
result = result.OrderBy(mg => mg.Species);
|
|
return result;
|
|
}
|
|
}
|