Mob mainhand and offhand item detection
Summoning a husk with an nbt of HandItems:[{id:"minecraft:stick"},{}]
spawns a husk holding a stick in its mainhand but using it on an execute
command to check the entity also works on a husk holding a stick in its offhand. The command that I used:
/execute as @e[type=husk,nbt={HandItems:[{id:"minecraft:stick"},{}]}] run say I have a stick in my mainhand!
But
/execute as @e[type=husk,nbt={HandItems:[{},{id:"minecraft:stick"}]}] run say I have a stick in my mainhand!
also works.
I want to check if a husk is holding a stick in its mainhand but I can't figure out the exact command to do what I want.
Solution 1:
Firstly, you forgot the stack size:
/summon husk ~ ~ ~ {HandItems:[{id:"stick",Count:1},{}]}
Secondly, there are two very similar syntaxes, which causes this unintuitive behaviour: When summoning an entity, [{},{}]
creates a list with two entries. But when checking for NBT, the same syntax checks for the presence of the two entries in the list. And both {}
, meaning any entry, and {id:"minecraft:stick"}
, meaning an entry with key id
and value "minecraft:stick"
are matched, so the command runs.
How to actually check for the correct index: Normally you could just use /execute if data
, but due to an oversight in the NBT path syntax, a path like HandItems[1]{id:"minecraft:stick"}
does not work. What you need to do instead is copying the NBT somewhere else and then checking there.
The proper way to do this is to create a datapack and run a function as
the husk, that way you can check the NBT without interfering with anything in the world by using storage
:
data modify storage temp Mainhand set from entity @s HandItems[0]
execute if data storage temp Mainhand{id:"minecraft:stick"} run say I have a stick in my mainhand!
data remove storage temp Mainhand
The hacky way to do this does not require a datapack, but it modifies the held item. The tag
tag of items can contain any arbitrary NBT, so you can copy the entire item NBT into a sub-tag of the item NBT. Yes, that's stupid, but it doesn't require a datapack. If you just want something copy-paste ready, this is for you:
/execute as @e[type=husk] run data modify entity @s HandItems[0].tag.temp set from entity @s HandItems[0]
/execute as @e[type=husk,nbt={HandItems:[{tag:{temp:{id:"minecraft:stick"}}}]}] run say I have a stick in my mainhand!
/execute as @e[type=husk] run data remove entity @s HandItems[0].tag.temp
Thanks to vdvman1 and PeerHeer in the Minecraft commands Discord group for their help with this answer!