How can I check for lore and custom enchants on items currently being held by a player

Solution 1:

I am going to use a sword as for this example. With name, lore, and enchants.

Here is the command I used to obtain the sword:

/give @p minecraft:diamond_sword 1 0 {display:{Name:"The Sword",Lore:["Lore Example","Lore Example 2"]},ench:[{id:16s,lvl:3s},{id:19s,lvl:3s},{id:70s,lvl:1s}]}

Now we will create a command block chain that will add a scoreboard tag to any players who have the sword in their hand. The first command block removes the tag from all players. This is required incase you have selected the sword and got the tag, then put the sword away, it then removes the tag. The second command block tags the players who currently have the sword selected.

These command blocks have to remain loaded. I recommend putting them in the spawn chunk. I also recommend stopping command block output to prevent chat spam for op players. Use command:

/gamerule commandBlockOutput false

First command block is Repeat Unconditional Always Active

scoreboard players tag @a remove HoldingSword

Second command block is Chain Unconditional Always Active

scoreboard players tag @a HoldingSword {SelectedItem:{id:"minecraft:diamond_sword",tag:{display:{Name:"The Sword",Lore:["Lore Example","Lore Example 2"]},ench:[{id:16s,lvl:3s},{id:19s,lvl:3s},{id:70s,lvl:1s}]}}}

You do not have to check every tag for the system to work. Here is an alternate second command block command that has one lore item removed and two enchantments removed:

scoreboard players tag @a add HoldingSword {SelectedItem:{id:"minecraft:diamond_sword",tag:{display:{Name:"The Sword",Lore:["Lore Example 2"]},ench:[{id:70s,lvl:1s}]}}}

However, as long as an item meets all the criteria of the selected item, it will also tag the player. As an example to that last command, this sword would also get tagged:

/give @p minecraft:diamond_sword 1 0 {display:{Name:"The Sword",Lore:["Lore Example 2"]},ench:[{id:70s,lvl:1s}]}

Lets take it to the extreme, you could check for that sword with:

scoreboard players tag @a add HoldingSword {SelectedItem:{tag:{display:{Lore:["Lore Example 2"]}}}}

This will tag any player holding any item that has "Lore Example 2" as one of it's lore lines. Including this fish:

/give @p minecraft:fish 1 0 {display:{Lore:["Lore Example 2"]}}

Now to target those players for other commands use the target selector with a tag argument:

@a[tag=HoldingSword]

For fun, lets make them all say hello:

/execute @a[tag=HoldingSword] ~ ~ ~ say hello

One final note: Notice in the enchantment sections of the commands id and lvl have an s after their value({id:70s,lvl:1s}). This is important for the give command and the scoreboard command. Most give generators do not specify this which stores the value as an integer. When items are enchanted at the table or anvil, they are stored as shorts not integers. If you do not add the s to the scoreboard command, it will not detect naturally enchanted items. It will only detect items that were obtained with the give command which also did not have the s.