I want to make an arena where mobs will fight each other and a player can bet on one side or the other. For example: There are 2 skeletons in dyed armor; red and blue. Each color representing a team. When they spawn I want them to fight each and then when one dies I want it to announce which team is the winner and give the player the "money" due. I'm just not sure how to get the skeletons to attack each other without a player instigating it.
1 Answer
In 1.8.8, the only way to get a skeleton to attack another skeleton is to manipulate their targets using custom UUIDs (Universally Unique Identifier), along with the ownerName
tag on particular projectile entities, namely Snowball
and ThrownPotion
.
Please be aware that you should not create multiple entities with the same UUID, as they are meant to be unique. In 1.8, you will run into targeting issues, while in 1.9 entities with duplicate UUIDs will be deleted when loading the chunk.
Targeting
As an example, the two skeletons to summon, each with a UUID:
1.8:
/summon Skeleton ~ ~1 ~ {UUIDLeast:1l,UUIDMost:1l,CustomName:"A",Equipment:[{id:"minecraft:bow"}]}
/summon Skeleton ~ ~1 ~ {UUIDLeast:2l,UUIDMost:2l,CustomName:"B",Equipment:[{id:"minecraft:bow"}]}
1.9:
/summon Skeleton ~ ~1 ~ {UUIDLeast:1l,UUIDMost:1l,CustomName:"A",HandItems:[{id:"minecraft:bow"}]}
/summon Skeleton ~ ~1 ~ {UUIDLeast:2l,UUIDMost:2l,CustomName:"B",HandItems:[{id:"minecraft:bow"}]}
When a projectile that uses the ownerName
tag strikes a mob, that mob will target the entity that has the UUID specified in that tag. For example, the following will cause skeleton A to attack skeleton B, because it assumes that skeleton B has thrown the snowball:
/execute @e[type=Skeleton,name=A] ~ ~ ~ summon Snowball ~ ~4 ~ {Motion:[0.0,-1.0,0.0],ownerName:"00000000-0000-0002-0000-000000000002"}
And likewise, the following causes B to attack A:
/execute @e[type=Skeleton,name=B] ~ ~ ~ summon Snowball ~ ~4 ~ {Motion:[0.0,-1.0,0.0],ownerName:"00000000-0000-0001-0000-000000000001"}
In 1.9, you can cause one mob to ride another, and the "rider" will take control of movement. However, the rider is the one that attacks. If a zombie is riding a skeleton, the zombie will make the skeleton move into melee range and the zombie itself will attack, meaning ranged battle is not possible with that method.
Just as an example, the following will cause the skeleton to move into melee attack range of villagers in 1.9:
/summon Skeleton ~ ~1 ~ {Passengers:[{id:"Zombie"}]}
Detecting Death
No target selector can target dead/dying mobs, nor will automatically-incrementing objective-types (such as deathCount
) track mobs. There are some workarounds to this, the easiest of which is testing for the mere existence of the mob and inverting the signal.
The following would simply test for the mob's existence, while you would invert the signal. If the mob was found, the signal will be off. If the mob dies, it will no longer be found and the signal is on:
/testfor @e[type=Skeleton,name=A]
/tellraw @a ["Skeleton A won!"]
/testfor @e[type=Skeleton,name=B]
/tellraw @a ["Skeleton B won!"]
Note that if you unload chunk that the skeleton is at while the mechanism is still loaded, the command block will return false since it cannot find the skeleton.