1.16.5 - Detect what item player has in offhand slot

I want to create an item throwing system, that when I press F, the item goes 5 blocks for the direction I'm looking at.

The problem is when I try to detect what item is in my offhand. I tried spawning a stone and then using /data modify entity @e[type=item,sort=nearest,limit=1] Item merge from entity @s Inventory[-106], but it doesn't recognize -106 as a slot.

I tested some things and discovered that if my inventory is empty and I put an item in my offhand, the slot is 0b, but if I have the offhand item + another item in any slot of my inventory, the offhand slot becomes 1b, if I have the offhand item + 2 another occupied slots, it becomes 2b, and so on.


Solution 1:

I tested some things and discovered that if my inventory is empty and I put an item in my offhand, the slot is 0b, but if I have the offhand item + another item in any slot of my inventory, the offhand slot becomes 1b, if I have the offhand item + 2 another occupied slots, it becomes 2b, and so on.

This is because you are testing for the slot in the wrong manner:

The Inventory tag is a List tag containing each item the player has in their inventory. When you type Inventory[0], that means, "the first item in the list."

The order of the items in the list is dependent on the order they entered the inventory. For example, if you put a stone in your offhand and then a diamond sword in your centremost hotbar slot, the list will look like this:

Inventory: [
  {Slot: -106b, Count: 1b, id: "minecraft:stone"},
  {Slot: 4b, Count: 1b, id: "minecraft:diamond_sword"},
]

If you then write Inventory[-106], that means, the 106th-last item of the list, which means, start at the end of the list, and count 106 elements backwards. But with the list above, that doesn't make sense, does it? There are only two elements in this list, so Inventory[-106] will return nothing.

So the order of the elements in the Inventory list is affected by when the items entered the inventory. But in that case, what is affected by the actual slot you put them in?

Take a look at the code snippet above, and notice how each of the list items has its own Slot tag. This tag is what is reflected by the slot the item is in, not the position of the entire element in the list.

So instead of referencing the position of the element in the Inventory list, reference it by the correct Slot tag:

Inventory[{Slot:-106b}]