diff --git a/src/actions/core/buy-item-action.tsx b/src/actions/core/buy-item-action.tsx index 80497c3..ce1df5c 100644 --- a/src/actions/core/buy-item-action.tsx +++ b/src/actions/core/buy-item-action.tsx @@ -20,6 +20,9 @@ defineLocalAction({ ), execute({item, qty}) { + if (!passesLimitCount(item)) { + return; + } game.shop.buyQuantity = item.allowQuantityPurchase ? (qty ?? 1) : 1; game.shop.buyItemOnClick(item, true); }, @@ -30,10 +33,11 @@ defineLocalAction({ { label: 'Item', localID: 'item', - mediaFilter: (item: ShopPurchase) => item.getBuyLimit(game.currentGamemode) > game.shop.getPurchaseCount(item), + mediaFilter: passesLimitCount, registry: 'shop.purchases', required: true, type: 'MediaItem', + validateIgnoreMediaFilter: true, }, { label: 'Quantity', @@ -45,3 +49,7 @@ defineLocalAction({ }, ], }); + +function passesLimitCount(item: ShopPurchase): boolean { + return item.getBuyLimit(game.currentGamemode) > game.shop.getPurchaseCount(item); +} diff --git a/src/option-types/media-item-option.mts b/src/option-types/media-item-option.mts index 64c7559..d31e31c 100644 --- a/src/option-types/media-item-option.mts +++ b/src/option-types/media-item-option.mts @@ -70,11 +70,19 @@ defineOption({ }); export default function isMediaItemOption(v: NodeOptionBase & Obj): v is MediaItemNodeOption { - const {type, itemRender, mediaFilter, registry, multi} = v as Partial; + const { + type, + itemRender, + mediaFilter, + registry, + multi, + validateIgnoreMediaFilter, + } = v as Partial; return type === 'MediaItem' && isUndefinedOr(mediaFilter, 'function') && isUndefinedOr(itemRender, 'function') + && isUndefinedOr(validateIgnoreMediaFilter, 'boolean') && ( typeof registry === 'function' || ( @@ -109,14 +117,14 @@ function validateMulti( function validateItem( item: T, reg: TNamespaceRegistry, - {mediaFilter}: MediaItemNodeOption, + {mediaFilter, validateIgnoreMediaFilter}: MediaItemNodeOption, otherOpts: Obj, errors: string[] ): void { if (!reg.registeredObjects.has(item.id)) { errors.push(`Item not found in selected registry: ${item.name}`); } - if (mediaFilter && !mediaFilter(item, otherOpts)) { + if (mediaFilter && !validateIgnoreMediaFilter && !mediaFilter(item, otherOpts)) { errors.push(`Item doesn't pass filter: ${item.name}`); } } diff --git a/src/public_api/option.d.ts b/src/public_api/option.d.ts index 0dea603..ebe34ae 100644 --- a/src/public_api/option.d.ts +++ b/src/public_api/option.d.ts @@ -108,6 +108,12 @@ export interface MediaItemNodeOption extends NodeOptionBase { type: 'MediaItem'; + /** + * Validation will ignore media filter items that don't pass if this is set to `true` + * @default false + */ + validateIgnoreMediaFilter?: boolean; + /** Filter out irrelevant items in the registry */ mediaFilter?(item: any, optionValues: Obj): boolean; }