AlmostReliable / morejs

A Minecraft mod to extend KubeJS with additional events.
https://www.curseforge.com/minecraft/mc-mods/morejs
GNU Lesser General Public License v3.0
12 stars 1 forks source link

Custom potion brewing ignores item type when using Ingredient.customNBT #2

Closed malcolmriley closed 1 year ago

malcolmriley commented 1 year ago

Version

Forge 1.19.2 - 0.0.7

Describe the bug!

I am using MoreJS with KubeJS Forge 1902.6.0-build.142, but the issue affects other versions as well.

When attempting to add a custom-item brewing recipe per the recommendation on the MoreJS wiki, the resulting recipe ignores item types, instead permitting any kind of item to be used as long as it has the appropriate NBT.

The issue can be replicated with the following minimal example script:

MoreJSEvents.registerPotionBrewing(event => {

    /*
    Intent: Make diamonds by brewing dirt into a potion of swiftness item.
    Outcome: The recipe ignores the item type, permitting any item with the correct NBT to be used.
    */
    event.addCustomBrewing('minecraft:dirt', Ingredient.customNBT('minecraft:potion', nbt => nbt.contains('Potion') && nbt.Potion === 'minecraft:swiftness'), 'minecraft:diamond');

});

My expectation was that such a recipe would only accept minecraft:potion with the correct NBT, instead, the recipe accepts any item, such as minecraft:tipped_arrow or items from other mods with acceptable NBT.

The reason why I believed this to be a bug instead of intended behavior is that the KubeJS class Ingredient.customNBT() method, when called under other circumstances, correctly examines item type as well as NBT.

Crash Report

(Not applicable)

Log

(Not applicable)

Additional Context

No

Modifications

The issue is replicable with only the aforementioned mods installed (KubeJS, MoreJS and supporting libraries).

Did the issue happen in singleplayer or on a server?

Singleplayer

malcolmriley commented 1 year ago

If it helps, I believe I know the cause of this behavior.

The KubeJS Ingredient.customNBT() method wraps the provided predicate in a safety check, and passes to Ingredient.custom(). This method checks whether a custom predicate map is initialized, and calls a platform method to create a new IngredientWithCustomPredicate that will later refer to the map as a predicate lookup. If this map is not currently initialized, a different method is called instead. This second method produces an Ingredient subclass which unfortunately ignores the "parent" ingredient entirely, which means it cannot distinguish between item types.

This causes problems when using Ingredient in startup events (such as the the MoreJS potion brewing event) because the recipe predicate map is uninitialized during startup, and is instead initialized during the resource management cycle. In other words, since the actual Ingredient instance used in the recipe is initialized during startup when the predicate lookup map isn't initialized, the resulting recipe will use the unideal form that ignores item types.

LLytho commented 1 year ago

This is some KubeJS problem. I told Lat and he will take a look.

malcolmriley commented 1 year ago

Splendid, thank you.

stale[bot] commented 1 year ago

This submission has been automatically marked as abandoned because it has not had recent activity. It will be closed in 3 days. If you want to prevent that, leave a new comment.

stale[bot] commented 1 year ago

Due to no recent activity, this submission is closed now.