mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-26 22:10:21 +00:00
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.
This commit is contained in:
parent
4cb80b5463
commit
9a1b2719ec
13 changed files with 73 additions and 45 deletions
|
@ -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
|
||||
|
|
|
@ -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<ushort, bool>? 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,
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ namespace PKHeX.Core
|
|||
/// <summary> Valid item IDs that may be stored in the pouch. </summary>
|
||||
public readonly ushort[] LegalItems;
|
||||
|
||||
public readonly Func<ushort, bool>? IsItemLegal;
|
||||
|
||||
/// <summary> Max quantity for a given item that can be stored in the pouch. </summary>
|
||||
public readonly int MaxCount;
|
||||
|
||||
|
@ -31,7 +33,7 @@ namespace PKHeX.Core
|
|||
/// <summary> Size of the backing byte array that represents the pouch. </summary>
|
||||
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<ushort, bool>? isLegal = null)
|
||||
{
|
||||
Items = Array.Empty<InventoryItem>();
|
||||
Type = type;
|
||||
|
@ -39,6 +41,7 @@ namespace PKHeX.Core
|
|||
MaxCount = maxCount;
|
||||
Offset = offset;
|
||||
PouchDataSize = size > -1 ? size : legal.Length;
|
||||
IsItemLegal = isLegal;
|
||||
}
|
||||
|
||||
/// <summary> Reads the pouch from the backing <see cref="data"/>. </summary>
|
||||
|
@ -178,13 +181,13 @@ namespace PKHeX.Core
|
|||
item.Count = modification(item);
|
||||
}
|
||||
|
||||
public void GiveAllItems(IReadOnlyList<ushort> newItems, Func<InventoryItem, int> getSuggestedItemCount, int count = -1)
|
||||
public void GiveAllItems(ReadOnlySpan<ushort> newItems, Func<InventoryItem, int> getSuggestedItemCount, int count = -1)
|
||||
{
|
||||
GiveAllItems(newItems, count);
|
||||
ModifyAllCount(getSuggestedItemCount);
|
||||
}
|
||||
|
||||
public void GiveAllItems(SaveFile sav, IReadOnlyList<ushort> items, int count = -1)
|
||||
public void GiveAllItems(SaveFile sav, ReadOnlySpan<ushort> 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<ushort> newItems, int count = -1)
|
||||
private void GiveAllItems(ReadOnlySpan<ushort> 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
|
||||
|
|
|
@ -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 };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace PKHeX.Core
|
|||
public bool SetNew { get; set; }
|
||||
private InventoryItem7b[] OriginalItems = Array.Empty<InventoryItem7b>();
|
||||
|
||||
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) { }
|
||||
|
|
|
@ -11,10 +11,10 @@ namespace PKHeX.Core
|
|||
public bool SetNew { get; set; }
|
||||
private InventoryItem8[] OriginalItems = Array.Empty<InventoryItem8>();
|
||||
|
||||
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<ushort, bool>? 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)
|
||||
{
|
||||
|
|
|
@ -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<ushort, bool>? 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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue