Minecraft – How to mark a entity after it executes a command successfully

minecraft-commandsminecraft-java-edition

What I'm trying to do is make a custom crafting system. It works currently, however the issue is that it will not work with more than 1 crafter since it specifies all of the crafters. I have it executing this:

/execute @e[type=ArmorStand,name=craft] ~ ~ ~ /testforblocks -15 56 -225 -15 56 -225 ~ ~ ~

It compares the block which is the example dropper to the dropper which the ArmorStand "Craft" is in. I then have a conditional command block with this:

/execute @e[type=ArmorStand,name=craft] ~ ~ ~ /blockdata ~ ~ ~ {Items:[0:{Slot:4b,id:"minecraft:spawn_egg",Count:1b,tag:{RepairCost:0,display:{Name:"Sponge"},EntityTag:{id:"Blaze"}},Damage:0s}]}

It just changes the blockdata of that block to have a Blaze egg named "Sponge." The issue with this is fairly obvious. The @e selector will get all of the entities that are of type ArmorStand, and are named craft. I don't want that. I want it to effect only that ONE crafter.

I know that it IS possible to do something like this with scoreboards, however I'm not sure how you would set it up to use only that entity which successfully executed the command, since I don't believe /execute ... detect can take any sort of data tag or compare blocks.

Best Answer

You will want to use CommandStats, which are a set of triggers stored on an entity that will modify a target's score based on the success of commands run by the entity.

For example, you will want to use the "SuccessCount" trigger, which stores the number of successful iterations of a command (and in the case of /testforblocks, will either be 0 for failure or 1 for success). You could also use "AffectedBlocks", which returns the number of matched blocks (0 for failure or the number of blocks found via /testforblocks).

Prerequisites

Objective to hold the return value from CommandStats triggers:

/scoreboard objectives add Results dummy

You have a couple options for applying the triggers to the entities. The most direct way would be to use the CommandStats compound directly when summoning:

/summon ArmorStand ~ ~1 ~ {CustomName:"craft",CommandStats:{SuccessCountName:"@e[type=ArmorStand,c=1]",SuccessCountObjective:"Results"}}

Or you could use the /stats command. The second selector is not translated in this command, and is stored as literally written in the CommandStats compound like above:

/stats entity @e[type=ArmorStand,name=craft] set SuccessCount @e[type=ArmorStand,c=1] Results

In order for these triggers to modify a target's score, that target must be tracked in the objective prior.

/scoreboard players set @e[type=ArmorStand,name=craft] Results 0

Detection

  1. Your initial command.

    /execute @e[type=ArmorStand,name=craft] ~ ~ ~ /testforblocks -15 56 -225 -15 56 -225 ~ ~ ~
    
  2. Now the armor stand will have a "Results" score of 1 if it succeeded or 0 if it failed. You can then target the relevant armor stands.

    /execute @e[type=ArmorStand,name=craft,score_Results_min=1] ~ ~ ~ /blockdata ~ ~ ~ {Items:[0:{Slot:4b,id:"minecraft:spawn_egg",Count:1b,tag:{RepairCost:0,display:{Name:"Sponge"},EntityTag:{id:"Blaze"}},Damage:0s}]}
    

There is no need to reset their score to 0 because it will do so the next time /testforblocks fails.