diff --git a/PKHeX.Core/Legality/Encounters/Data/EncounterEvent.cs b/PKHeX.Core/Legality/Encounters/Data/EncounterEvent.cs index a92068aec..964c5989c 100644 --- a/PKHeX.Core/Legality/Encounters/Data/EncounterEvent.cs +++ b/PKHeX.Core/Legality/Encounters/Data/EncounterEvent.cs @@ -33,52 +33,73 @@ namespace PKHeX.Core /// Indicates if the databases are initialized. public static bool Initialized => MGDB_G3.Count != 0; - private static HashSet GetPCDDB(byte[] bin) => new(ArrayUtil.EnumerateSplit(bin, PCD.Size).Select(d => new PCD(d))); + private static PCD[] GetPCDDB(byte[] bin) => Get(bin, PCD.Size, d => new PCD(d)); + private static PGF[] GetPGFDB(byte[] bin) => Get(bin, PGF.Size, d => new PGF(d)); - private static HashSet GetPGFDB(byte[] bin) => new(ArrayUtil.EnumerateSplit(bin, PGF.Size).Select(d => new PGF(d))); + private static WC6[] GetWC6DB(byte[] wc6bin, byte[] wc6full) => WC6Full.GetArray(wc6full, wc6bin); + private static WC7[] GetWC7DB(byte[] wc7bin, byte[] wc7full) => WC7Full.GetArray(wc7full, wc7bin); - private static HashSet GetWC6DB(byte[] wc6bin, byte[] wc6full) => new( - ArrayUtil.EnumerateSplit(wc6full, WC6Full.Size).Select(d => new WC6Full(d).Gift) - .Concat(ArrayUtil.EnumerateSplit(wc6bin, WC6.Size).Select(d => new WC6(d)))); + private static WB7[] GetWB7DB(byte[] bin) => Get(bin, WB7.SizeFull, d => new WB7(d)); + private static WC8[] GetWC8DB(byte[] bin) => Get(bin, WC8.Size, d => new WC8(d)); - private static HashSet GetWC7DB(byte[] wc7bin, byte[] wc7full) => new( - ArrayUtil.EnumerateSplit(wc7full, WC7Full.Size).Select(d => new WC7Full(d).Gift) - .Concat(ArrayUtil.EnumerateSplit(wc7bin, WC7.Size).Select(d => new WC7(d)))); - - private static HashSet GetWB7DB(byte[] wc7full) => new(ArrayUtil.EnumerateSplit(wc7full, WB7.SizeFull).Select(d => new WB7(d))); - - private static HashSet GetWC8DB(byte[] wc8bin) => - new(ArrayUtil.EnumerateSplit(wc8bin, WC8.Size).Select(d => new WC8(d))); + private static T[] Get(byte[] bin, int size, Func 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); + result[i] = ctor(slice); + } + return result; + } public static void RefreshMGDB(params string[] paths) { - var g4 = GetPCDDB(Util.GetBinaryResource("wc4.pkl")); - var g5 = GetPGFDB(Util.GetBinaryResource("pgf.pkl")); - var g6 = GetWC6DB(Util.GetBinaryResource("wc6.pkl"), Util.GetBinaryResource("wc6full.pkl")); - var g7 = GetWC7DB(Util.GetBinaryResource("wc7.pkl"), Util.GetBinaryResource("wc7full.pkl")); - var b7 = GetWB7DB(Util.GetBinaryResource("wb7full.pkl")); - var g8 = GetWC8DB(Util.GetBinaryResource("wc8.pkl")); + ICollection g4 = GetPCDDB(Util.GetBinaryResource("wc4.pkl")); + ICollection g5 = GetPGFDB(Util.GetBinaryResource("pgf.pkl")); + ICollection g6 = GetWC6DB(Util.GetBinaryResource("wc6.pkl"), Util.GetBinaryResource("wc6full.pkl")); + ICollection g7 = GetWC7DB(Util.GetBinaryResource("wc7.pkl"), Util.GetBinaryResource("wc7full.pkl")); + ICollection b7 = GetWB7DB(Util.GetBinaryResource("wb7full.pkl")); + ICollection g8 = GetWC8DB(Util.GetBinaryResource("wc8.pkl")); foreach (var gift in paths.Where(Directory.Exists).SelectMany(MysteryUtil.GetGiftsFromFolder)) { + static void AddOrExpand(ref ICollection arr, T obj) + { + if (arr is HashSet) + arr.Add(obj); + else + arr = new HashSet(arr) {obj}; + } switch (gift) { - case PCD pcd: g4.Add(pcd); continue; - case PGF pgf: g5.Add(pgf); continue; - case WC6 wc6: g6.Add(wc6); continue; - case WC7 wc7: g7.Add(wc7); continue; - case WB7 wb7: b7.Add(wb7); continue; - case WC8 wc8: g8.Add(wc8); continue; + 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; } } + static T[] SetArray(ICollection arr) + { + if (arr is T[] x) + return x; + var result = new T[arr.Count]; + ((HashSet)arr).CopyTo(result, 0); + return result; + } + MGDB_G3 = Encounter_WC3; // hardcoded - MGDB_G4 = g4.ToArray(); - MGDB_G5 = g5.ToArray(); - MGDB_G6 = g6.ToArray(); - MGDB_G7 = g7.ToArray(); - MGDB_G7GG = b7.ToArray(); - MGDB_G8 = g8.ToArray(); + MGDB_G4 = SetArray(g4); + MGDB_G5 = SetArray(g5); + MGDB_G6 = SetArray(g6); + MGDB_G7 = SetArray(g7); + MGDB_G7GG = SetArray(b7); + MGDB_G8 = SetArray(g8); } public static IEnumerable GetAllEvents(bool sorted = true) diff --git a/PKHeX.Core/Legality/Encounters/Generator/Specific/MysteryGiftGenerator.cs b/PKHeX.Core/Legality/Encounters/Generator/Specific/MysteryGiftGenerator.cs index ddefd5e57..6fe691bc2 100644 --- a/PKHeX.Core/Legality/Encounters/Generator/Specific/MysteryGiftGenerator.cs +++ b/PKHeX.Core/Legality/Encounters/Generator/Specific/MysteryGiftGenerator.cs @@ -32,7 +32,7 @@ namespace PKHeX.Core return GetMatchingGifts(pkm, table, chain); } - private static IReadOnlyList GetTable(int generation, PKM pkm) => generation switch + private static IReadOnlyCollection GetTable(int generation, PKM pkm) => generation switch { 3 => MGDB_G3, 4 => MGDB_G4, @@ -43,7 +43,7 @@ namespace PKHeX.Core _ => Array.Empty() }; - private static IEnumerable GetMatchingPCD(PKM pkm, IReadOnlyList DB, IReadOnlyList chain) + private static IEnumerable GetMatchingPCD(PKM pkm, IReadOnlyCollection DB, IReadOnlyList chain) { if (PGT.IsRangerManaphy(pkm)) { @@ -55,7 +55,7 @@ namespace PKHeX.Core yield return g; } - private static IEnumerable GetMatchingGifts(PKM pkm, IReadOnlyList DB, IReadOnlyList chain) + private static IEnumerable GetMatchingGifts(PKM pkm, IReadOnlyCollection DB, IReadOnlyList chain) { foreach (var mg in DB) { diff --git a/PKHeX.Core/MysteryGifts/WC6Full.cs b/PKHeX.Core/MysteryGifts/WC6Full.cs index 7e9c6bc5e..5593215cb 100644 --- a/PKHeX.Core/MysteryGifts/WC6Full.cs +++ b/PKHeX.Core/MysteryGifts/WC6Full.cs @@ -5,6 +5,7 @@ namespace PKHeX.Core public sealed class WC6Full { public const int Size = 0x310; + private const int GiftStart = Size - WC6.Size; public readonly byte[] Data; public readonly WC6 Gift; @@ -14,7 +15,7 @@ namespace PKHeX.Core public WC6Full(byte[] data) { Data = data; - var wc6 = data.SliceEnd(Size - WC6.Size); + var wc6 = data.SliceEnd(GiftStart); Gift = new WC6(wc6); var now = DateTime.Now; Gift.RawDate = WC6.SetDate((uint)now.Year, (uint)now.Month, (uint)now.Day); @@ -22,5 +23,36 @@ namespace PKHeX.Core Gift.RestrictVersion = RestrictVersion; Gift.RestrictLanguage = RestrictLanguage; } + public static WC6[] GetArray(byte[] WC6Full, byte[] data) + { + var countfull = WC6Full.Length / Size; + var countgift = data.Length / WC6.Size; + var result = new WC6[countfull + countgift]; + + var now = DateTime.Now; + for (int i = 0; i < countfull; i++) + result[i] = ReadWC6(WC6Full, i * Size, now); + for (int i = 0; i < countgift; i++) + result[i + countfull] = ReadWC6Only(data, i * WC6.Size); + + return result; + } + + private static WC6 ReadWC6(byte[] data, int ofs, DateTime date) + { + var slice = data.Slice(ofs + GiftStart, WC6.Size); + return new WC6(slice) + { + RestrictVersion = data[ofs], + RestrictLanguage = data[ofs + 0x1FF], + RawDate = WC6.SetDate((uint)date.Year, (uint)date.Month, (uint)date.Day) + }; + } + + private static WC6 ReadWC6Only(byte[] data, int ofs) + { + var slice = data.Slice(ofs, WC6.Size); + return new WC6(slice); + } } } \ No newline at end of file diff --git a/PKHeX.Core/MysteryGifts/WC7Full.cs b/PKHeX.Core/MysteryGifts/WC7Full.cs index d9f82dfee..e6db44047 100644 --- a/PKHeX.Core/MysteryGifts/WC7Full.cs +++ b/PKHeX.Core/MysteryGifts/WC7Full.cs @@ -5,6 +5,7 @@ namespace PKHeX.Core public sealed class WC7Full { public const int Size = 0x310; + private const int GiftStart = Size - WC7.Size; public readonly byte[] Data; public readonly WC7 Gift; @@ -14,7 +15,7 @@ namespace PKHeX.Core public WC7Full(byte[] data) { Data = data; - var wc7 = data.SliceEnd(Size - WC7.Size); + var wc7 = data.SliceEnd(GiftStart); Gift = new WC7(wc7); var now = DateTime.Now; Gift.RawDate = WC7.SetDate((uint)now.Year, (uint)now.Month, (uint)now.Day); @@ -22,5 +23,37 @@ namespace PKHeX.Core Gift.RestrictVersion = RestrictVersion; Gift.RestrictLanguage = RestrictLanguage; } + + public static WC7[] GetArray(byte[] wc7Full, byte[] data) + { + var countfull = wc7Full.Length / Size; + var countgift = data.Length / WC7.Size; + var result = new WC7[countfull + countgift]; + + var now = DateTime.Now; + for (int i = 0; i < countfull; i++) + result[i] = ReadWC7(wc7Full, i * Size, now); + for (int i = 0; i < countgift; i++) + result[i + countfull] = ReadWC7Only(data, i * WC7.Size); + + return result; + } + + private static WC7 ReadWC7(byte[] data, int ofs, DateTime date) + { + var slice = data.Slice(ofs + GiftStart, WC7.Size); + return new WC7(slice) + { + RestrictVersion = data[ofs], + RestrictLanguage = data[ofs + 0x1FF], + RawDate = WC7.SetDate((uint) date.Year, (uint) date.Month, (uint) date.Day) + }; + } + + private static WC7 ReadWC7Only(byte[] data, int ofs) + { + var slice = data.Slice(ofs, WC7.Size); + return new WC7(slice); + } } } \ No newline at end of file