Minecraft – Selecting previous target in a second command block

minecraft-commandsminecraft-java-edition

I'm trying to make a system that prevents players from using certain items.

In one command block, I have the following command clear @a diamond_sword executing constantly through a clock.

Off the side of that command block I have a red stone comparator to catch the output and emit a signal if the command is executed successfully (It managed to clear a Diamond Sword from a player's inventory).

That comparator is supposed to trigger another command block who uses /tell to send a message to that player who had his Diamond Sword removed a message like:
"You are not allowed to use Diamond Swords."

What command can I use in the second command block to send that message only to the players who have Diamond Swords cleared off their inventory?

/tell @p ... doesn't work, as it merely selects the nearest player.
/tell @r ... will target a random player, and
/tell @a ... will message everyone.

How can I make it target the last target of the previous command block (The one with the /clear command)?

Best Answer

You want to do this with scoreboards. My solution won't prevent getting diamond swords, but it will prevent crafting them and using them, i.e. a player can have a diamond sword in their inventory, as long as they never use it. How it gets there without crafting it, though, is pretty much impossible without cheats.

First, you need to set up 2 scoreboard objectives, one for crafting, and one for using:

/scoreboard objectives add craftedDiamondSword stat.craftItem.276
/scoreboard objectives add usedDiamondSword stat.useItem.276

Next, you need to set up two nearly identical chains of command blocks, one for each scoreboard objective. This will run on a clock like you already have. I'll only give the commands for using, so just replace that in the second chain with the crafting objective.

First, clear those players inventories:

clear @a[score_usedDiamondSword_min=1] 276

Next, tell the players that used a diamond sword to not use it, and reset their score:

tell @a[score_usedDiamondSword_min=1] Don't use diamond swords!
scoreboard players set @a[score_usedDiamondSword_min=1] usedDiamondSword 0

This last command block doesn't really need the [score_usedDiamondSword_min=1] but it's useful.

I got this to work in a single line of command blocks with redstone over top for the uses chain, but it wouldn't work for the crafting. The solution is to pipe the result from the clear command block into the tell and set scoreboard command blocks with comparators. Here's a pic of the two setups:

Diamond Sword clearer

Use whatever clock you want.

Additionally, if you never, ever want players to have a diamond sword, even in their inventory, and even if they don't use it, you can still clear from @a, and then just say to not use diamond swords if one is found.


Update for added 1.8 functionality:

The 1.8 snapshots have added the option to match players against the Inventory NBT tag when setting or incrementing a scoreboard objective. This means we can set up a dummy scoreboard objective to track whenever someone has a Diamond Sword in their inventory, regardless if they've used it or crafted it. First, set up the scoreboard objective:

/scoreboard objectives add hasDiamondSword dummy

Next, we need to run two command blocks on the same clock; one to set players scores, and another to check those player's scores and clear the diamond swords:

scoreboard players add @a hasDiamondSword 1 {Inventory:[{id:"minecraft:diamond_sword"}]}
clear @a[score_hasDiamondSword_min=1] minecraft:diamond_sword

The second command is fairly similar to the old commands, except instead of using the old ID number, I'm using the name instead. The first is a bit more complicated, so let's walk through it. Basically it says add to all players on their hasDiamondSword objective the value 1 if that player has an inventory and that inventory contains a diamond sword. So, for anyone that has a diamond sword in their inventory, their hasDiamondSword objective will be incremented.

Finally, like in the old version, we need to tell the players to not use diamond swords, and to reset their hasDiamondSword objective:

tell @a[score_hasDiamondSword_min=1] Don't use diamond swords!
scoreboard players set @a[score_hasDiamondSword_min=1] hasDiamondSword 0

I stacked these two command blocks (with the tell on bottom) and fed them with a comparator from the clear command block. This is what it all looks like in the end:

command block setup