Open Three-of-Ten-201 opened 1 month ago
Wait, I thought usingConvertsTo
was only for when you eat the food. Not anything to do with crafting. Can you confirm this is a thing in vanilla by trying out items with custom usingConvertsTo
?
Yes, the usingConvertsTo
is the item that you get for eating the food. It has indeed nothing to do with crafting. However, as soon as a custom item has a food component with a usingConvertsTo
property, you can no longer use it to craft things.
usingConvertsTo
does not seem to be relevant, it is just that the item has a food-component and the recipe does not
Im guessing this is a similar issue as to when items have enchantments, lost durability and so on
Another example where the PredicateChoice PR would be useful
no food component, as recipe intends:
food component with/without usingConvertsTo
:( no result)
Okay, I did some more tests on that. Here's what I found:
RecipeChoice.ExactChoice
then it will give the correct output (assuming that the input item has the correct food properties of course)usingConvertsTo
property, it won't give you an output even if the input item has exactly the usingConvertsTo
defined in the recipe (and the other properties are also correct)RecipeChoice.ExactChoice
, the crafting table will output the correct result even if the input has a food component and a usingConvertsTo
propertySo we have two "variables":
usingConvertsTo
usingConvertsTo
The test results are:
expected
and provided
, it doesn't craft expected
and not provided
, it doesn't craft (works as expected)not expected
, but provided
, it craftsnot expected
and not provided
, it crafts (works as expected)So you can have custom food items AND custom recipes with them, it just doesn't work when the ingredient has usingConvertsTo
?
Not able to reproduce the part where if the recipe expects an ingredient with food
-component that has usingConvertsTo
it will never work
On my end it seems to work fine
https://github.com/user-attachments/assets/c345b050-cc74-4cb3-9c62-75e93e0a4a8f
All it would do is compare itemmeta 1:1, and since these match, it is correct Still PredicateChoice or some other form of way to specify an item in a recipe is heavily needed Custom Items in recipes are painful to deal with because of the need for ExactChoice, thus breaking with enchantments, durability and other such component/meta differences
Not able to reproduce the part where if the recipe expects an ingredient with
food
-component that hasusingConvertsTo
it will never work On my end it seems to work fine
Still doesn't work for me.
For context: I have an item (cooked rice) that converts to a bowl when eaten (because the cooked rice is crafted with a bowl). I wanted to create a recipe for sushi that uses the cooked rice, dried kelp and cooked salmon.
I created the recipe using ExactChoice, it showed up correctly in the recipe book, but when I input the items, it doesn't give me an output at all.
I know that this is almost exactly the same you showed in the video (apart from the fact that it worked there), but I wonder what I did wrong/what is wrong with the recipe or the items.
Crafting with my other food items that don't have usingConvertsTo
works absolutely fine.
Also, when I remove the usingConvertsTo
from the cooked rice item, it works just fine.
So this is a rather annoying issue.
The equality check (far far down the line) compares two Optional
diff --git a/src/main/java/net/minecraft/world/food/FoodProperties.java b/src/main/java/net/minecraft/world/food/FoodProperties.java
index c60cdb3ef4..57347bcb43 100644
--- a/src/main/java/net/minecraft/world/food/FoodProperties.java
+++ b/src/main/java/net/minecraft/world/food/FoodProperties.java
@@ -16,6 +16,20 @@ import net.minecraft.world.level.ItemLike;
public record FoodProperties(
int nutrition, float saturation, boolean canAlwaysEat, float eatSeconds, Optional<ItemStack> usingConvertsTo, List<FoodProperties.PossibleEffect> effects
) {
+ // Paper start - correct equality check
+ @Override
+ public boolean equals(final Object o) {
+ if (this == o) return true;
+ if (!(o instanceof final FoodProperties that)) return false;
+ return nutrition == that.nutrition &&
+ Float.compare(saturation, that.saturation) == 0 &&
+ Float.compare(eatSeconds, that.eatSeconds) == 0 &&
+ canAlwaysEat == that.canAlwaysEat &&
+ ItemStack.isSameItemSameComponentsOptional(usingConvertsTo, that.usingConvertsTo) &&
+ java.util.Objects.equals(effects, that.effects);
+ }
+ // Paper end - correct equality check
+
public static final float DEFAULT_EAT_SECONDS = 1.6F;
public static final Codec<FoodProperties> DIRECT_CODEC = RecordCodecBuilder.create(
instance -> instance.group(
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
index 2c312c0b74..60a5f02353 100644
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
@@ -878,6 +878,13 @@ public final class ItemStack implements DataComponentHolder {
return !stack.is(otherStack.getItem()) ? false : (stack.isEmpty() && otherStack.isEmpty() ? true : Objects.equals(stack.components, otherStack.components));
}
+ // Paper start - isSameItemSameComponentsOptional
+ public static boolean isSameItemSameComponentsOptional(Optional<ItemStack> stack, Optional<ItemStack> otherStack) {
+ if (stack.isEmpty() && otherStack.isEmpty()) return true;
+ return stack.isPresent() && otherStack.isPresent() && isSameItemSameComponents(stack.get(), otherStack.get());
+ }
+ // Paper end - isSameItemSameComponentsOptional
+
public static MapCodec<ItemStack> lenientOptionalFieldOf(String fieldName) {
return ItemStack.CODEC.lenientOptionalFieldOf(fieldName).xmap((optional) -> {
return (ItemStack) optional.orElse(ItemStack.EMPTY);
would e.g. fix this.
Expected behavior
Shaped and shapeless crafting recipes output their corresponding result regardless of the 'usingConvertsTo' properties of the ingredients.
Observed/Actual behavior
Shaped and shapeless crafting recipes register and show up correctly in the recipe book. However, putting the ingredients into the crafting table doesn't give an output item at all if one of the ingredients contains a food component with a 'usingConvertsTo' property.
Steps/models to reproduce
Example:
Plugin and Datapack List
Datapacks:
Plugins:
Paper version
Other
My plugin (the only one on the server) doesn't change or interfere with the behaviour of the crafting table or the 'usingConvertsTo' property in any way. I just discovered this issue while messing around with custom food items.
Furthermore, I tried to use a rabbit stew item as an ingredient, which should also have a 'usingConvertsTo' property (converts to minecraft:bowl) and this worked. So, it seems to be only for custom items.