From 9a1b2719ecdfa278e8c1211510dae33fd7036396 Mon Sep 17 00:00:00 2001 From: Kurt Date: Sat, 4 Dec 2021 12:24:32 -0800 Subject: [PATCH] Add simple legal item filtering for giveall Closes #3318 Gen8: if held item, only give if can be legally held; if dmax crystal, only give if available. Gen8b: if held item, only give if can be legally held Others: unimplemented; pull requests accepted. --- PKHeX.Core/Legality/Tables/Tables8.cs | 7 ++++ .../Saves/Substructures/Gen8/BS/MyItem8b.cs | 20 ++++++------ .../Saves/Substructures/Gen8/MyItem8.cs | 28 ++++++++++------ .../Substructures/Inventory/InventoryPouch.cs | 32 ++++++++++++------- .../Inventory/InventoryPouch3.cs | 4 +-- .../Inventory/InventoryPouch3GC.cs | 2 +- .../Inventory/InventoryPouch4.cs | 2 +- .../Inventory/InventoryPouch7.cs | 2 +- .../Inventory/InventoryPouch7b.cs | 2 +- .../Inventory/InventoryPouch8.cs | 6 ++-- .../Inventory/InventoryPouch8b.cs | 7 ++-- .../Inventory/InventoryPouchGB.cs | 2 +- .../Subforms/Save Editors/SAV_Inventory.cs | 4 +-- 13 files changed, 73 insertions(+), 45 deletions(-) diff --git a/PKHeX.Core/Legality/Tables/Tables8.cs b/PKHeX.Core/Legality/Tables/Tables8.cs index 64153674f..5122479e1 100644 --- a/PKHeX.Core/Legality/Tables/Tables8.cs +++ b/PKHeX.Core/Legality/Tables/Tables8.cs @@ -344,6 +344,13 @@ namespace PKHeX.Core }; #region Unreleased Items + + private const int DMAX_START = 1279; + private const int DMAX_END = 1578; + private const int DMAX_LEGAL_END = 1290; // ★Sgr7194 (Eevee) + public static bool IsDynamaxCrystal(ushort item) => item is >= DMAX_START and <= DMAX_END; + public static bool IsDynamaxCrystalAvailable(ushort item) => item is >= DMAX_START and <= DMAX_LEGAL_END; + internal static readonly bool[] ReleasedHeldItems_8 = GetPermitList(MaxItemID_8, HeldItems_SWSH, new ushort[] { 298, // Flame Plate diff --git a/PKHeX.Core/Saves/Substructures/Gen8/BS/MyItem8b.cs b/PKHeX.Core/Saves/Substructures/Gen8/BS/MyItem8b.cs index ab238f20e..8ad2331dd 100644 --- a/PKHeX.Core/Saves/Substructures/Gen8/BS/MyItem8b.cs +++ b/PKHeX.Core/Saves/Substructures/Gen8/BS/MyItem8b.cs @@ -63,14 +63,14 @@ namespace PKHeX.Core { var pouches = new[] { - MakePouch(InventoryType.Items), + MakePouch(InventoryType.Items, IsHeldItemLegal), MakePouch(InventoryType.KeyItems), - MakePouch(InventoryType.TMHMs), - MakePouch(InventoryType.Medicine), - MakePouch(InventoryType.Berries), - MakePouch(InventoryType.Balls), - MakePouch(InventoryType.BattleItems), - MakePouch(InventoryType.Treasure), + MakePouch(InventoryType.TMHMs, IsHeldItemLegal), + MakePouch(InventoryType.Medicine, IsHeldItemLegal), + MakePouch(InventoryType.Berries, IsHeldItemLegal), + MakePouch(InventoryType.Balls, IsHeldItemLegal), + MakePouch(InventoryType.BattleItems, IsHeldItemLegal), + MakePouch(InventoryType.Treasure, IsHeldItemLegal), }; return pouches.LoadAll(Data); } @@ -103,13 +103,15 @@ namespace PKHeX.Core } } - private InventoryPouch8b MakePouch(InventoryType type) + private InventoryPouch8b MakePouch(InventoryType type, Func? isLegal = null) { ushort[] legal = GetLegal(type); var max = GetMax(type); - return new InventoryPouch8b(type, legal, max, Offset); + return new InventoryPouch8b(type, legal, max, Offset, isLegal); } + public static bool IsHeldItemLegal(ushort item) => !Legal.HeldItems_BS.Contains(item) || Legal.ReleasedHeldItems_8b[item]; + private static int GetMax(InventoryType type) => type switch { InventoryType.Items => 999, diff --git a/PKHeX.Core/Saves/Substructures/Gen8/MyItem8.cs b/PKHeX.Core/Saves/Substructures/Gen8/MyItem8.cs index 872b96ff5..4b695742b 100644 --- a/PKHeX.Core/Saves/Substructures/Gen8/MyItem8.cs +++ b/PKHeX.Core/Saves/Substructures/Gen8/MyItem8.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; namespace PKHeX.Core { @@ -22,14 +23,14 @@ namespace PKHeX.Core { var pouch = new InventoryPouch[] { - new InventoryPouch8(InventoryType.Medicine, Legal.Pouch_Medicine_SWSH, 999, Medicine, PouchSize8.Medicine), - new InventoryPouch8(InventoryType.Balls, Legal.Pouch_Ball_SWSH, 999, Balls, PouchSize8.Balls), - new InventoryPouch8(InventoryType.BattleItems, Legal.Pouch_Battle_SWSH, 999, Battle, PouchSize8.Battle), - new InventoryPouch8(InventoryType.Berries, Legal.Pouch_Berries_SWSH, 999, Berries, PouchSize8.Berries), - new InventoryPouch8(InventoryType.Items, Legal.Pouch_Regular_SWSH, 999, Items, PouchSize8.Items), - new InventoryPouch8(InventoryType.TMHMs, Legal.Pouch_TMHM_SWSH, 999, TMs, PouchSize8.TMs), - new InventoryPouch8(InventoryType.MailItems, Legal.Pouch_Treasure_SWSH, 999, Treasures, PouchSize8.Treasures), - new InventoryPouch8(InventoryType.Candy, Legal.Pouch_Ingredients_SWSH, 999, Ingredients, PouchSize8.Ingredients), + new InventoryPouch8(InventoryType.Medicine, Legal.Pouch_Medicine_SWSH, 999, Medicine, PouchSize8.Medicine, IsItemLegal), + new InventoryPouch8(InventoryType.Balls, Legal.Pouch_Ball_SWSH, 999, Balls, PouchSize8.Balls, IsItemLegal), + new InventoryPouch8(InventoryType.BattleItems, Legal.Pouch_Battle_SWSH, 999, Battle, PouchSize8.Battle, IsItemLegal), + new InventoryPouch8(InventoryType.Berries, Legal.Pouch_Berries_SWSH, 999, Berries, PouchSize8.Berries, IsItemLegal), + new InventoryPouch8(InventoryType.Items, Legal.Pouch_Regular_SWSH, 999, Items, PouchSize8.Items, IsItemLegal), + new InventoryPouch8(InventoryType.TMHMs, Legal.Pouch_TMHM_SWSH, 999, TMs, PouchSize8.TMs, IsItemLegal), + new InventoryPouch8(InventoryType.MailItems, Legal.Pouch_Treasure_SWSH, 999, Treasures, PouchSize8.Treasures, IsItemLegal), + new InventoryPouch8(InventoryType.Candy, Legal.Pouch_Ingredients_SWSH, 999, Ingredients, PouchSize8.Ingredients, IsItemLegal), new InventoryPouch8(InventoryType.KeyItems, Legal.Pouch_Key_SWSH, 1, Key, PouchSize8.Key), }; return pouch.LoadAll(Data); @@ -41,5 +42,14 @@ namespace PKHeX.Core value.SaveAll(Data); } } + + public static bool IsItemLegal(ushort item) + { + if (Legal.IsDynamaxCrystal(item)) + return Legal.IsDynamaxCrystalAvailable(item); + if (!Legal.HeldItems_SWSH.Contains(item)) + return true; + return Legal.ReleasedHeldItems_8[item]; + } } -} \ No newline at end of file +} diff --git a/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch.cs b/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch.cs index 946007314..019d5e311 100644 --- a/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch.cs +++ b/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch.cs @@ -15,6 +15,8 @@ namespace PKHeX.Core /// Valid item IDs that may be stored in the pouch. public readonly ushort[] LegalItems; + public readonly Func? IsItemLegal; + /// Max quantity for a given item that can be stored in the pouch. public readonly int MaxCount; @@ -31,7 +33,7 @@ namespace PKHeX.Core /// Size of the backing byte array that represents the pouch. protected readonly int PouchDataSize; - protected InventoryPouch(InventoryType type, ushort[] legal, int maxCount, int offset, int size = -1) + protected InventoryPouch(InventoryType type, ushort[] legal, int maxCount, int offset, int size = -1, Func? isLegal = null) { Items = Array.Empty(); Type = type; @@ -39,6 +41,7 @@ namespace PKHeX.Core MaxCount = maxCount; Offset = offset; PouchDataSize = size > -1 ? size : legal.Length; + IsItemLegal = isLegal; } /// Reads the pouch from the backing . @@ -178,13 +181,13 @@ namespace PKHeX.Core item.Count = modification(item); } - public void GiveAllItems(IReadOnlyList newItems, Func getSuggestedItemCount, int count = -1) + public void GiveAllItems(ReadOnlySpan newItems, Func getSuggestedItemCount, int count = -1) { GiveAllItems(newItems, count); ModifyAllCount(getSuggestedItemCount); } - public void GiveAllItems(SaveFile sav, IReadOnlyList items, int count = -1) + public void GiveAllItems(SaveFile sav, ReadOnlySpan items, int count = -1) { GiveAllItems(items, count); ModifyAllCount(item => GetSuggestedItemCount(sav, item.Index, count)); @@ -192,19 +195,23 @@ namespace PKHeX.Core public void GiveAllItems(SaveFile sav, int count = -1) => GiveAllItems(sav, LegalItems, count); - private void GiveAllItems(IReadOnlyList newItems, int count = -1) + private void GiveAllItems(ReadOnlySpan newItems, int count = -1) { if (count < 0) count = MaxCount; var current = (InventoryItem[]) Items.Clone(); - var itemEnd = Math.Min(Items.Length, newItems.Count); - for (int i = 0; i < itemEnd; i++) - { - var item = Items[i] = GetEmpty(); - item.Index = newItems[i]; + var itemEnd = Math.Min(Items.Length, newItems.Length); + var iterate = newItems[..itemEnd]; - var match = Array.Find(current, z => z.Index == newItems[i]); + int ctr = 0; + foreach (var newItemID in iterate) + { + if (IsItemLegal?.Invoke(newItemID) == false) + continue; + + var item = Items[ctr++] = GetEmpty(newItemID); + var match = Array.Find(current, z => z.Index == newItemID); if (match == null) { item.SetNewDetails(count); @@ -214,6 +221,9 @@ namespace PKHeX.Core // load old values item.MergeOverwrite(match); } + + for (int i = ctr; i < Items.Length; i++) + Items[i] = GetEmpty(); } public bool IsValidItemAndCount(ITrainerInfo sav, int item, bool HasNew, bool HaX, ref int count) @@ -257,7 +267,7 @@ namespace PKHeX.Core return Math.Min(MaxCount, requestVal); } - public abstract InventoryItem GetEmpty(); + public abstract InventoryItem GetEmpty(int itemID = 0, int count = 0); } public static class InventoryPouchExtensions diff --git a/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch3.cs b/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch3.cs index 4415f1c35..84c789977 100644 --- a/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch3.cs +++ b/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch3.cs @@ -37,6 +37,6 @@ namespace PKHeX.Core } } - public override InventoryItem GetEmpty() => new(); + public override InventoryItem GetEmpty(int itemID = 0, int count = 0) => new() { Index = itemID, Count = count }; } -} \ No newline at end of file +} diff --git a/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch3GC.cs b/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch3GC.cs index ef423a8da..d481f7801 100644 --- a/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch3GC.cs +++ b/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch3GC.cs @@ -9,7 +9,7 @@ namespace PKHeX.Core { } - public override InventoryItem GetEmpty() => new(); + public override InventoryItem GetEmpty(int itemID = 0, int count = 0) => new() { Index = itemID, Count = count }; public override void GetPouch(byte[] data) { diff --git a/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch4.cs b/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch4.cs index b4fefd65f..814d24b58 100644 --- a/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch4.cs +++ b/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch4.cs @@ -16,7 +16,7 @@ namespace PKHeX.Core // u16 id // u16 count - public override InventoryItem GetEmpty() => new(); + public override InventoryItem GetEmpty(int itemID = 0, int count = 0) => new() { Index = itemID, Count = count }; public override void GetPouch(byte[] data) { diff --git a/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch7.cs b/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch7.cs index 4705e5955..61c80cdf9 100644 --- a/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch7.cs +++ b/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch7.cs @@ -12,7 +12,7 @@ namespace PKHeX.Core public InventoryPouch7(InventoryType type, ushort[] legal, int maxCount, int offset) : base(type, legal, maxCount, offset) { } - public override InventoryItem GetEmpty() => new InventoryItem7(); + public override InventoryItem GetEmpty(int itemID = 0, int count = 0) => new InventoryItem7 { Index = itemID, Count = count }; public override void GetPouch(byte[] data) { diff --git a/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch7b.cs b/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch7b.cs index 0464fdc58..076c590b7 100644 --- a/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch7b.cs +++ b/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch7b.cs @@ -11,7 +11,7 @@ namespace PKHeX.Core public bool SetNew { get; set; } private InventoryItem7b[] OriginalItems = Array.Empty(); - public override InventoryItem GetEmpty() => new InventoryItem7b(); + public override InventoryItem GetEmpty(int itemID = 0, int count = 0) => new InventoryItem7b { Index = itemID, Count = count }; public InventoryPouch7b(InventoryType type, ushort[] legal, int maxCount, int offset, int size) : base(type, legal, maxCount, offset, size) { } diff --git a/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch8.cs b/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch8.cs index 8d428a4f0..13feda0bc 100644 --- a/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch8.cs +++ b/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch8.cs @@ -11,10 +11,10 @@ namespace PKHeX.Core public bool SetNew { get; set; } private InventoryItem8[] OriginalItems = Array.Empty(); - public InventoryPouch8(InventoryType type, ushort[] legal, int maxCount, int offset, int size) - : base(type, legal, maxCount, offset, size) { } + public InventoryPouch8(InventoryType type, ushort[] legal, int maxCount, int offset, int size, Func? isLegal = null) + : base(type, legal, maxCount, offset, size, isLegal) { } - public override InventoryItem GetEmpty() => new InventoryItem8(); + public override InventoryItem GetEmpty(int itemID = 0, int count = 0) => new InventoryItem8 { Index = itemID, Count = count }; public override void GetPouch(byte[] data) { diff --git a/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch8b.cs b/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch8b.cs index 14fb454f7..547b581d9 100644 --- a/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch8b.cs +++ b/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouch8b.cs @@ -10,10 +10,11 @@ namespace PKHeX.Core public bool SetNew { get; set; } - public InventoryPouch8b(InventoryType type, ushort[] legal, int maxCount, int offset) - : base(type, legal, maxCount, offset) { } + public InventoryPouch8b(InventoryType type, ushort[] legal, int maxCount, int offset, + Func? isLegal) + : base(type, legal, maxCount, offset, isLegal: isLegal) { } - public override InventoryItem GetEmpty() => new InventoryItem8b { IsNew = true }; + public override InventoryItem GetEmpty(int itemID = 0, int count = 0) => new InventoryItem8b { Index = itemID, Count = count, IsNew = true }; public override void GetPouch(byte[] data) { diff --git a/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouchGB.cs b/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouchGB.cs index 64e78a176..9d1c4121d 100644 --- a/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouchGB.cs +++ b/PKHeX.Core/Saves/Substructures/Inventory/InventoryPouchGB.cs @@ -9,7 +9,7 @@ namespace PKHeX.Core { } - public override InventoryItem GetEmpty() => new(); + public override InventoryItem GetEmpty(int itemID = 0, int count = 0) => new() { Index = itemID, Count = count }; public override void GetPouch(byte[] data) { diff --git a/PKHeX.WinForms/Subforms/Save Editors/SAV_Inventory.cs b/PKHeX.WinForms/Subforms/Save Editors/SAV_Inventory.cs index d627f273c..ee97d5d59 100644 --- a/PKHeX.WinForms/Subforms/Save Editors/SAV_Inventory.cs +++ b/PKHeX.WinForms/Subforms/Save Editors/SAV_Inventory.cs @@ -227,9 +227,7 @@ namespace PKHeX.WinForms continue; // ignore item // create clean item data when saving - var item = pouch.GetEmpty(); - item.Index = itemindex; - item.Count = itemcnt; + var item = pouch.GetEmpty(itemindex, itemcnt); if (item is IItemFreeSpace f) f.IsFreeSpace = (bool)cells[ColumnFreeSpace].Value; if (item is IItemFavorite v)