Minecraft Blogs / Tutorial

Custom Crafting with NBT edited Items

  • 456 views, 15 today
  • 5
  • 3
imalittlhigh's Avatar imalittlhigh
Level 61 : High Grandmaster Sweetheart
109
https://github.com/imalittlhigh/updated_custom_crafting_project

This pack is a template for custom crafting with nbt edited items.
No required resourcepack.
No item nuking if you misplace them in the table.
Very customizable recipes (you can specify any nbt value the ingredients need to have and the output has ofc)


What you need to understand to create your own recipes:
The crafting station is a dropper.
The button on top can not actually be pressed, its an interaction you interact with.
You can not have one recipe with different outcomes you can choose.
The outcome will spawn on top of the dropper when you press the "button" not in your inventory.


Getting the Custom Crafting Table
Craft a Book to upgrade a Crafting Table:

Custom Crafting with NBT edited Items

Then right klick on a Crafting Table to convert it.

You can ofc change the recipe in the Datapack. (its in updated_crafting_crafting/recipes/craftingtable.json)





Adding a new recipe:
1: create new recipe predicate
2: create new recipe outcome loot_table
3: create new recipe function
4: integrate new function into recipes function


Adding an easy one ingredient recipe
Step 1: Adding the recipe predicate.
Simply copy the file updated_crafting:predicates/recipes/test_recipe
Or create a new .json file in that folder

This is what you need to edit in the file:

"updated_crafting:predicates/recipes/test_recipe"

{
   "condition": "minecraft:location_check",
  "predicate": {
    "block": {
      "blocks": [
        "minecraft:dropper"
       ],

You add your recipe here.
Modify the slot that item must be placed in.
If you want more ingredients, have a look at the more advanced recipes further down.

      "nbt": "{Items:[{Slot:4b,id:\"minecraft:cobblestone\"}]}"
      }
   }
}




Step 2: Adding new loot_table.
Copy the file updated_crafting:loot_tables/recipes/test_recipe
Or create your own .json file.
I will not elaborate further, since there are a lot of good resources on how to create loot tables.



Step 3: Adding new recipe function.
Copy the funciton updated_crafting:functions/craft/recipe/test
Or create your own .mcfunction file.

This is what you need to edit in the function:

"updated_crafting/functions/craft/recipes/test"

This line gets the amount of items in a slot of the dropper (here slot 5) and saves it in a score.

You need one of these lines for every occupied slot of your recipe.
If you want to change the slot, simply modify the highlighted numbers (0-8). Both need to be the same in the same line!

execute
store result score $ucp.count.4 ucp_dummy run data get block ~ ~ ~ Items[{Slot:4b}].Count


Here the recipes output will be spawned, if the count of the items in the slots of the dropper are at least what the recipe calls for.
You need to check for the count of every occupied slot of your recipe here (more on that later).
Modify this number, to be the amount of the item in the slot, that is needed for the recipe.
Choose the recipes output, by modifying the loot_table or creating a new one.
If you want to change the slot, simply modify the highlighted numbers (0-8)

execute if score $ucp.count.4 ucp_dummy matches 1.. run loot spawn ~ ~1 ~ loot updated_crafting:recipes/test_recipe


You can simply copy the line above up to run and paste it here.

execute if score $ucp.count.4 ucp_dummy matches 1.. run data modify storage ucp:crafting success set value true


This line removes the amount of items in the slot, needed to craft, from the total count that is in the slot.
This needs to match the amount you chose for the corresponding slot above.

scoreboard players remove $ucp.count.4 ucp_dummy 1


This line saves the new count of items in the slot to a storage.
You need one of these lines per used slot.
Both slots need to be the same in one line!

execute store result storage ucp:crafting count[4] byte 1 run scoreboard players get $ucp.count.4 ucp_dummy


This line sets the count of the items in the slot to the reduced count after crafting.
You need one of these lines per used slot.
Both slots need to be the same in one line!

execute if data storage ucp:crafting success run data modify block ~ ~ ~ Items[{Slot:4b}].Count set from storage ucp:crafting count[4]


This line displays a particle, when the recipe is successfully crafted. You do not need to modify it.

execute if data storage ucp:crafting success positioned ~ ~1.2 ~ run particle cloud ~ ~ ~ 0 0 0 0 1





Step 4: Integrating the new recipe in the recipes function.
Navigate to: updated_crafting:functions/craft/recipes

This is what you need to edit in that function:


You need to add the new recipe here.
Just modify the recipe path.

Very important:
If you have recipes that use the same ingredients in the same slot, you must place the more complex recipe above the simpler one!
If you don't do that, you will not be able to craft the complexer recipe, since it will only craft the simpler one.
An example of such recipes comes after this functions code.

execute
if predicate updated_crafting:recipes/test2_recipe unless data storage ucp:crafting success run function updated_crafting:craft/recipes/test2
execute if predicate updated_crafting:recipes/full_recipe unless data storage ucp:crafting success run function updated_crafting:craft/recipes/full
execute if predicate updated_crafting:recipes/test_recipe unless data storage ucp:crafting success run function updated_crafting:craft/recipes/test

execute if predicate updated_crafting:recipes/nbtex_recipe unless data storage ucp:crafting success run function updated_crafting:craft/recipes/nbtex


You don't need to modify anything in this function from here.

data remove storage ucp:crafting success
data merge storage ucp:crafting {count:[0b,0b,0b,0b,0b,0b,0b,0b,0b]}
scoreboard players reset $ucp.count.0 ucp_dummy
scoreboard players reset $ucp.count.1 ucp_dummy
scoreboard players reset $ucp.count.2 ucp_dummy
scoreboard players reset $ucp.count.3 ucp_dummy
scoreboard players reset $ucp.count.4 ucp_dummy
scoreboard players reset $ucp.count.5 ucp_dummy
scoreboard players reset $ucp.count.6 ucp_dummy
scoreboard players reset $ucp.count.7 ucp_dummy
scoreboard players reset $ucp.count.8 ucp_dummy




The recipe on the left is "test", the one we have modified here. The one on the right is "test2"
These two recipes have overlapping ingredients:

Custom Crafting with NBT edited Items

So you need to put recipe "test2" above "test" in the recipes function, so "test2" will be craftable.



Adding more complex recipes
The recipe predicate:
(i will only focus on the "nbt" tag here, the rest is the same as in the simple recipe)
Also I have changed the look of the tag. In the .json file it will not have line-breaks after each slot.

"updated_crafting:predicates/recipes/full_recipe"

The slots correspond to the slots in the Dropper (0 is top left, 8 is bottom right)
The id is the item that needs to be in that slot.
You must not add to a count in this predicate.

"nbt"
: "{Items:[
  {
Slot:0b,id:\"minecraft:cobblestone\"},
  {
Slot:1b,id:\"minecraft:cobblestone\"},
  {
Slot:2b,id:\"minecraft:cobblestone\"},
  {
Slot:3b,id:\"minecraft:cobblestone\"},
  {
Slot:4b,id:\"minecraft:cobblestone\"},
  {
Slot:5b,id:\"minecraft:cobblestone\"},
  {
Slot:6b,id:\"minecraft:cobblestone\"},
  {
Slot:7b,id:\"minecraft:cobblestone\"},
  {
Slot:8b,id:\"minecraft:cobblestone\"}
]}"




Step 2: Adding new loot_table
I will also not explain that here ^^



Step 3: Adding new recipe function


"updated_crafting:functions/craft/recipes/full"

This is the same as the simple recipe, just with every slot occupied.
You need one of these lines for each occupied slot.

execute
store result score $ucp.count.0 ucp_dummy run data get block ~ ~ ~ Items[{Slot:0b}].Count
execute store result score $ucp.count.1 ucp_dummy run data get block ~ ~ ~ Items[{Slot:1b}].Count
execute store result score $ucp.count.2 ucp_dummy run data get block ~ ~ ~ Items[{Slot:2b}].Count
execute store result score $ucp.count.3 ucp_dummy run data get block ~ ~ ~ Items[{Slot:3b}].Count
execute store result score $ucp.count.4 ucp_dummy run data get block ~ ~ ~ Items[{Slot:4b}].Count
execute store result score $ucp.count.5 ucp_dummy run data get block ~ ~ ~ Items[{Slot:5b}].Count
execute store result score $ucp.count.6 ucp_dummy run data get block ~ ~ ~ Items[{Slot:6b}].Count
execute store result score $ucp.count.7 ucp_dummy run data get block ~ ~ ~ Items[{Slot:7b}].Count
execute store result score $ucp.count.8 ucp_dummy run data get block ~ ~ ~ Items[{Slot:8b}].Count


You need to test for every slot if the count matches what you want the ingredient count to be.
That is what all the if score is in this line.
You need to change the outcome recipe.

execute if score $ucp.count.0 ucp_dummy matches 1.. if score $ucp.count.1 ucp_dummy matches 1.. if score $ucp.count.2 ucp_dummy matches 1.. if score $ucp.count.3 ucp_dummy matches 1.. if score $ucp.count.4 ucp_dummy matches 1.. if score $ucp.count.5 ucp_dummy matches 1.. if score $ucp.count.6 ucp_dummy matches 1.. if score $ucp.count.7 ucp_dummy matches 1.. if score $ucp.count.8 ucp_dummy matches 1.. run loot spawn ~ ~1 ~ loot updated_crafting:recipes/full_recipe


This is just the same as above, just not running a loot command, but a data command

execute if score $ucp.count.0 ucp_dummy matches 1.. if score $ucp.count.1 ucp_dummy matches 1.. if score $ucp.count.2 ucp_dummy matches 1.. if score $ucp.count.3 ucp_dummy matches 1.. if score $ucp.count.4 ucp_dummy matches 1.. if score $ucp.count.5 ucp_dummy matches 1.. if score $ucp.count.6 ucp_dummy matches 1.. if score $ucp.count.7 ucp_dummy matches 1.. if score $ucp.count.8 ucp_dummy matches 1.. run data modify storage ucp:crafting success set value true


You need to adjust the count of the ingredients per slot needed to craft one of the recipe.

scoreboard players remove $ucp.count.0 ucp_dummy 1
scoreboard players remove $ucp.count.1 ucp_dummy 1
scoreboard players remove $ucp.count.2 ucp_dummy 1
scoreboard players remove $ucp.count.3 ucp_dummy 1
scoreboard players remove $ucp.count.4 ucp_dummy 1
scoreboard players remove $ucp.count.5 ucp_dummy 1
scoreboard players remove $ucp.count.6 ucp_dummy 1
scoreboard players remove $ucp.count.7 ucp_dummy 1
scoreboard players remove $ucp.count.8 ucp_dummy 1


You need one of these for each occupied slot.

execute store result storage ucp:crafting count[0] byte 1 run scoreboard players get $ucp.count.0 ucp_dummy
execute store result storage ucp:crafting count[1] byte 1 run scoreboard players get $ucp.count.1 ucp_dummy
execute store result storage ucp:crafting count[2] byte 1 run scoreboard players get $ucp.count.2 ucp_dummy
execute store result storage ucp:crafting count[3] byte 1 run scoreboard players get $ucp.count.3 ucp_dummy
execute store result storage ucp:crafting count[4] byte 1 run scoreboard players get $ucp.count.4 ucp_dummy
execute store result storage ucp:crafting count[5] byte 1 run scoreboard players get $ucp.count.5 ucp_dummy
execute store result storage ucp:crafting count[6] byte 1 run scoreboard players get $ucp.count.6 ucp_dummy
execute store result storage ucp:crafting count[7] byte 1 run scoreboard players get $ucp.count.7 ucp_dummy
execute store result storage ucp:crafting count[8] byte 1 run scoreboard players get $ucp.count.8 ucp_dummy


You need one of these for each occupied slot.

execute if data storage ucp:crafting success run data modify block ~ ~ ~ Items[{Slot:0b}].Count set from storage ucp:crafting count[0]
execute if data storage ucp:crafting success run data modify block ~ ~ ~ Items[{Slot:1b}].Count set from storage ucp:crafting count[1]
execute if data storage ucp:crafting success run data modify block ~ ~ ~ Items[{Slot:2b}].Count set from storage ucp:crafting count[2]
execute if data storage ucp:crafting success run data modify block ~ ~ ~ Items[{Slot:3b}].Count set from storage ucp:crafting count[3]
execute if data storage ucp:crafting success run data modify block ~ ~ ~ Items[{Slot:4b}].Count set from storage ucp:crafting count[4]
execute if data storage ucp:crafting success run data modify block ~ ~ ~ Items[{Slot:5b}].Count set from storage ucp:crafting count[5]
execute if data storage ucp:crafting success run data modify block ~ ~ ~ Items[{Slot:6b}].Count set from storage ucp:crafting count[6]
execute if data storage ucp:crafting success run data modify block ~ ~ ~ Items[{Slot:7b}].Count set from storage ucp:crafting count[7]
execute if data storage ucp:crafting success run data modify block ~ ~ ~ Items[{Slot:8b}].Count set from storage ucp:crafting count[8]


This is just the particle effect if crafting was successful

execute if data storage ucp:crafting success positioned ~ ~1.2 ~ run particle cloud ~ ~ ~ 0 0 0 0 1





Step 4: integrate into recipes function.
You do that the same way you do with the simple recipe we added.


Adding nbt edited ingredients
I will only focus on Step 1 here, since the rest is the same as with the other recipes.
I will also only show the "nbt" tag of the .json file.


"updated_crafting:predicates/recipes/nbtex_recipe"

As you can see, all nbt data of the ingredient item is inside the "tag" of the Item in the dropper.
You can put ANY nbt an item can have here as a requirement.
I recommend working with custom tags (here: custom.book:1b) but I added the CustomModelData here as well, as an example of other tags that can be used.
I assume you know how to work with item tags if you're interested in this so I won't explain what you need to edit to customize it.
This is also only an example for one slot, you can ofc use custom tags in all slots if you want to.
If you are using strings in your tag, you need to escape them (like with the id:) its not always easy to know how much to escape, if the strings get very convoluted, just try to guess until you get it right =)

"nbt"
: "{Items:[{Slot:0b,id:\"minecraft:book\",tag:{CustomModelData:12345,custom.book:1b}}]}"

Tags

Create an account or sign in to comment.

Planet Minecraft

Website

© 2010 - 2024
www.planetminecraft.com

Welcome