How to detect if a mob has been hit in minecraft with command blocks?

Solution 1:

Since automated scoreboard statistics (namely stat.damageTaken) only increments for players, you will need to rely on NBT data for non-player entities.

The HurtTime tag will be set to 10 when a mob is struck, decreasing by 1 per tick until it reaches 0 again.

  1. Adding the label for mobs that were struck.

    /scoreboard players tag @e[type=Creeper,tag=!Hurt] add Hurt {HurtTime:10s}
    
  2. Remove the label when the value is 9.

    /scoreboard players tag @e[type=Creeper,tag=Hurt] remove Hurt {HurtTime:9s}
    
  3. Target the mob based on the "Hurt" tag.

    /execute @e[type=Creeper,tag=Hurt] ~ ~ ~ /effect @a minecraft:slowness
    

Solution 2:

1.13 Update

The answer in 1.12 and below still applies. Note that commands were overhauled in 1.13. Please note the following:

  • /scoreboard players tag is now /tag.
  • /testfor is now a branch of /execute, using the (if|unless) parameters.
  • The NBT selector has been moved inside the target selector, using the nbt argument.
  • This answer was written before the entity IDs were changed in 1.11. In this change, we see that ZombieVillager and Creeper are now zombie_villager and creeper.

Here are the old commands that used to work but now don't.

/scoreboard players tag @e[type=Creeper,tag=!Hurt] add Hurt {HurtTime:10s}
/scoreboard players tag @e[type=Creeper,tag=Hurt] remove Hurt {HurtTime:9s}
/execute @e[type=Creeper,tag=Hurt] ~ ~ ~ /effect @a minecraft:slowness

And here are the new 1.13+ commands!

/tag @e[type=creeper,tag=!hurt,nbt={HurtTime:10s}] add hurt
/scoreboard players tag @e[type=creeper,tag=hurt,nbt={HurtTime:9s}] remove hurt
/execute if entity @e[type=creeper,tag=hurt] run say No Hurting Creepers!