Is there any way in Minecraft to detect who deposited a diamond into a chest using command blocks?
If you know who has each diamond
If you know who has each diamond, you can give each diamond a custom NBT tag. For example, if there are 5 players, you can use a custom NBT tag named something like PlayerOwns
, and when given to the player, you can set it to the player's number. For example, player 1 will get diamond with the custom tag set to 1.
For example:
/give Player1 diamond{PlayerOwns:3b}
and the same with the other players.
You can then test for the item using:
/execute if block x y z chest{Items:[{id:"minecraft:diamond",tag:{PlayerOwns:3b}}]} run say Player 3 wins!
Notes
- Be careful not to use a tag that is used for other purposes! Choose a tag name that won't be used by Minecraft. For example, don't name your custom tag
CanPlaceOn
, because that will mess up the system. - Remember to specify the data type at the end. In the examples above, I use a
TAG_Byte
because it uses the least storage and goes up to 255 players. You need to specify the data type at the end of your entry for both setting and testing, like4b
for Byte or175s
for Short (up to 32767). - A tip for best practice is to use the correct type of number tag for your needs. For example, Byte tags are preferred for smallest numbers, because they take up the smallest amount of space, but they only support numbers from
-128
to127
.
Here are some links if you would like to check out more about these:
- List of NBT tag types
If you don't know who has each diamond
Step 1: Give each player a unique scoreboard ID. See this related question for how to do that.
Step 2: Run /execute as @e[type=item,nbt={Item:{id:"minecraft:diamond"}}] run data merge entity @s {Item:{tag:{Unclaimed:1b}}
in a repeating, always active command block. This gives each diamond item on the ground a custom Unclaimed
tag, allowing you implement Step 3 without 30+ command blocks per player
Step 3: Once for each player who could be playing the map, run in a repeating command block:
/clear @a[scores={Id=1}] diamond{Unclaimed:1b} 1
and then, in a conditional chain command block that the repeating command block is pointing to
/give @a[scores={Id=1}] diamond{PlayerOwns:1b} 1
Repeat this for each player, using scores={Id=2}
and PlayerOwns:2b
for the second player and so on.
Step 4: Now that each diamond has a tag describing whose it is, you can use the technique described in ExpertCoder14's answer to determine who put a diamond in the chest.
This has a known bug that if Alice puts a diamond in a container, and then Bob takes the diamond out of the container (and never drops and picks it up again), the diamond is still interpreted as belonging to Alice -- but I actually like that if I understand what you're doing correctly; if you stole someone else's diamond from a chest instead of mining your own, that means you're trying to cheat ... karma!