Farmer's Delight

Farmer's Delight

97M Downloads

Refactor cooking recipe containers into recipe data

Treeways opened this issue ยท 4 comments

commented

Minecraft version

1.20.1

Farmer's Delight version

1.2.3

Forge version

47.1.47

Description

Cooking recipes are added via datapack, but their containers are still hardcoded. This would be much more convenient to have in datapack, so it can be read during KubeJS recipe porting.

Here's an analysis of the issue from the perspective of the codebase.


Notice how there is no container key in this cooking recipe's data file:

{
"type": "farmersdelight:cooking",
"cookingtime": 200,
"experience": 1.0,
"ingredients": [
{
"tag": "forge:raw_fishes"
},
{
"tag": "forge:pasta"
},
{
"tag": "forge:crops/tomato"
},
{
"item": "minecraft:ink_sac"
}
],
"recipe_book_tab": "meals",
"result": {
"item": "farmersdelight:squid_ink_pasta"
}
}

When registering bowl items, they are registered as a bowlFoodItem to take bowls as recipe remainders. There is seemingly no input for the container from the recipe data:

public static final RegistryObject<Item> SQUID_INK_PASTA = ITEMS.register("squid_ink_pasta",
() -> new ConsumableItem(bowlFoodItem(FoodValues.SQUID_INK_PASTA), true));

public static Item.Properties bowlFoodItem(FoodProperties food) {
return new Item.Properties().food(food).craftRemainder(Items.BOWL).stacksTo(16).tab(FarmersDelight.CREATIVE_TAB);
}

And vice-versa for drinkItem:

public static final RegistryObject<Item> HOT_COCOA = ITEMS.register("hot_cocoa",
() -> new HotCocoaItem(drinkItem()));

public static Item.Properties drinkItem() {
return new Item.Properties().craftRemainder(Items.GLASS_BOTTLE).stacksTo(16).tab(FarmersDelight.CREATIVE_TAB);
}

The only exception is the Stuffed Pumpkin Block:

"type": "farmersdelight:cooking",
"container": {
"item": "minecraft:pumpkin"
},

public static final RegistryObject<Item> STUFFED_PUMPKIN_BLOCK = ITEMS.register("stuffed_pumpkin_block",
() -> new BlockItem(ModBlocks.STUFFED_PUMPKIN_BLOCK.get(), basicItem().stacksTo(1)));

Also:

// TODO: Consider whether to leave this as-is, or open it to datapacks for modded cases.
public static final Map<Item, Item> INGREDIENT_REMAINDER_OVERRIDES = Map.ofEntries(
entry(Items.POWDER_SNOW_BUCKET, Items.BUCKET),
entry(Items.AXOLOTL_BUCKET, Items.BUCKET),
entry(Items.COD_BUCKET, Items.BUCKET),
entry(Items.PUFFERFISH_BUCKET, Items.BUCKET),
entry(Items.SALMON_BUCKET, Items.BUCKET),
entry(Items.TROPICAL_FISH_BUCKET, Items.BUCKET),
entry(Items.SUSPICIOUS_STEW, Items.BOWL),
entry(Items.MUSHROOM_STEW, Items.BOWL),
entry(Items.RABBIT_STEW, Items.BOWL),
entry(Items.BEETROOT_SOUP, Items.BOWL),
entry(Items.POTION, Items.GLASS_BOTTLE),
entry(Items.SPLASH_POTION, Items.GLASS_BOTTLE),
entry(Items.LINGERING_POTION, Items.GLASS_BOTTLE),
entry(Items.EXPERIENCE_BOTTLE, Items.GLASS_BOTTLE)
);

Steps to reproduce

No response

Mod list

Farmer's Delight

Logs

No response

Minimal instance

  • I have tested this on a minimal instance

Performance and shader mods

  • I am using performance or shader mods
commented

However, contrary to what my (lengthy...) code analysis suggests, it looks like container support is quite easy to add via datapack out of the box.

The following data works just fine (and this is purely as a test):

image

kubejs/data/farmersdelight/recipes/cooking/squid_ink_pasta.json

{
    "type": "farmersdelight:cooking",
    "container": {
        "item": "minecraft:glass_bottle"
    },
    "cookingtime": 200,
    "experience": 1.0,
    "ingredients": [
      {
        "tag": "forge:raw_fishes"
      },
      {
        "tag": "forge:pasta"
      },
      {
        "tag": "forge:crops/tomato"
      },
      {
        "item": "minecraft:ink_sac"
      }
    ],
    "recipe_book_tab": "meals",
    "result": {
      "item": "farmersdelight:squid_ink_pasta"
    }
}
commented

Item containers are not an FD addition; they're a hardcoded item property from vanilla. When a contained item is consumed, it gives that item back.

The container field in cooking recipe specs allows the recipe to "override" which container item is needed to extract the food from the Cooking Pot. This allows items to require a container without necessarily giving it back when consumed, such as the Stuffed Pumpkin, where the pumpkin is also eaten per serving.

It does not affect the item which is given back by the food itself. Doing so would require food items to host NBT data, thus making them unstackable or complicated for the end user.

commented

The method you saw in the code snippets above are simplifications for item registry. Containers can't be added outside of item registration, as all vanilla systems utilize this item property for that.

commented

Ah, that makes sense. So then it should be safe to assume that a food item's cooking recipes are generated with their remainder.

I'll just hook into the food's remainder with KubeJS in my script, then. Thank you for clarifying!