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:
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:
When you place a named block, it loses its name tag, making it impossible to detect if it was ever named. What you can do, however, is set a custom data value:
/setblock ~ ~ ~ diamond_block 1
Then, replace detect ~ ~-1 ~ diamond_block 0
with diamond_block 1
. You can use values 1 through 15, but values above 15 are not supported.
Note: In some versions of the game (and possibly the latest updates), blocks with custom data may have a missing texture, and the custom data may not be saved properly. You'll have to look into this yourself as I can't test it at the moment.
Best Answer
The
id
andlvl
tags for enchantments are intended to have the "short" datatype. However, item data generally does not auto-correct itself like it would with entity data.For example, if you summon the following entity, the
Invulnerable
tag was incorrectly declared as an integer even though it's meant to be a byte:The game will read the numerical value leniently, allowing you to declare the wrong datatype and it will still work. However, the game will appropriately save the tag's value as a byte, which is why you need to declare the correct datatype when testing for that data (which requires you to declare all data as it's saved and has no leniency in numerical datatypes):
But most item data will save the same way it was read. Since you declared the
id
andlvl
tags as integers, they will remain as integers. But under normal circumstances, such as enchanting, these tags are created as shorts.You will want to create them with the expected datatype. To declare a short, you append the numerical value with an "s":
And your
/testforblock
command will declare them as a short as well, which allows you to detect the provided item as well as items enchanted normally: