Your NBT data is malformed. You have to provide a list of attributes, even if you only want to specify one, and for each attribute you want to specify you have to give its name and base value.
- You start constructing your NBT data with your attribute, which is a compound. Compounds are marked as
{...}
.
- An attribute needs two elements, its
Name
and Base
.
- Each element has a value and you construct an element with a value with
element:value
. So in this case you do Name:"generic.movementSpeed"
and Base:0d
. You put the generic.movementSpeed
in quotation marks, because it is of type String (computer talk for text) and you put the d
behind the number because it is of type Double (computer talk for a decimal number).
- To put several elements (with values) inside a compound you separate them with a comma.
Overall you get:
{Name:"generic.movementSpeed",Base:0d}
Now that you have your attribute you have to consider that Minecraft expects an element called Attributes
with a value that is a list of all attributes. You create a list with [...]
. Put your attribute compound into it to form a list with one element (which is your attribute compound, which itself has two elements), so you just surround your attribute with [...]
. Now put this as the value of the element Attributes
:
Attributes:[{Name:"generic.movementSpeed",Base:0d}]
When checking with nbt=...
Minecraft always expects a single NBT compound, so add another {...}
around this. If you want to check any creeper for this you can do:
\execute as @e[type=creeper,nbt={Attributes:[{Name:"generic.movementSpeed",Base:0d}]}] run ...
Or you do it split up into an as
and an at
like you did in your first command. The second and third commands you specified would not work as expected, because you never specify an as
, thus the command will check the currently executing entity whether it is a creeper with the NBT attribute. And this is normally the player who runs the command.
For doing something (like summoning a zombie) at the position of those creepers replace the run ...
with at @s run ...
.
HOWEVER, note that this will check for creepers that have this movement speed attribute, NOT for creepers that are currently moving with this speed. So to check for any still standing creepers this won't work.
I assume this entire question comes down to "how to print NBT tags A and B of multiple entities like {A1,B1},{A2,B2},{A3,B3}
instead of A1,A2,A3,B1,B2,B3
". The best way I know to do that is to copy the data over somewhere else in a way that already groups it. Previously you needed a dummy item, because they allow any data in their tag
tag. But since 1.15 there is a feature called "storage" that is made specifically for storing custom NBT. So you could create an array of compounds in there.
Unlike the old answer with dummy items, this method requires no preparation at all.
You need to iterate over the horses and create new entries in the array, then fill them (this is also where you can apply sorting, for example by distance). For each horse, do this (until you're out of tagged horses, you can for example do this in a recursive function):
/execute if entity @e[type=horse,tag=!copied] run data modify storage horses HorseAttributes append value {Health:0d,Speed:0d,Jump:0d}
/execute as @e[type=horse,tag=!copied,sort=nearest,limit=1] store result storage horses HorseAttributes[-1].Health double 0.0000005 run data get entity @s Attributes[{Name:"generic.maxHealth"}].Base 2000000
/execute as @e[type=horse,tag=!copied,sort=nearest,limit=1] store result storage horses HorseAttributes[-1].Speed double 0.0000005 run data get entity @s Attributes[{Name:"generic.movementSpeed"}].Base 2000000
/execute as @e[type=horse,tag=!copied,sort=nearest,limit=1] store result storage horses HorseAttributes[-1].Jump double 0.000000001 run data get entity @s Attributes[{Name:"horse.jumpStrength"}].Base 1000000000
/tag @e[type=horse,tag=!copied,sort=nearest,limit=1] add copied
The reason for first scaling the values up and then down again when copying is that for some reason they only get handled as integers. But if you multiply them with a high value first and later divide them by the same number, you get more precision (jumpStrength
for example rounds down to 0 almost every time otherwise). The numbers are chosen to give as much accuracy as possible without ever overflowing (different attributes have different maximum values, that's why they differ).
The array index -1
targets the last compound in the list, the one that was just created.
Now, finally, the output:
/tellraw @s {"storage":"horses","nbt":"HorseAttributes"}
The output can for example look like this:
[{Speed:0.2102355d,Health:21.0d,Jump:0.682921423d},{Speed:0.28055749999999996d,Health:24.0d,Jump:0.819681399d},{Speed:0.2159845d,Health:20.0d,Jump:0.653335773d},{Speed:0.2855935d,Health:25.0d,Jump:0.681110673d},{Speed:0.1827385d,Health:17.0d,Jump:0.750580213d}]
Best Answer
In short, you need to put
profession:"minecraft:farmer"
. An explanation of how I found that out:The Chunk Format wiki page is very helpful for this kind of thing. If you scroll down to the list of entities and expand the Villager entry, and then the villager profession portion (which is nested within the villager entry) you can see the data tree for the villager. You can see that
VillagerData
is a compound tag, and one of the possible nested tags isprofession
(note the lowercase p) which needs a String data type (see this), so the value needs to be enclosed in quotation marks. One of the possible values isminecraft:farmer
, so therefore you would want to use/execute as @e[type=villager,nbt={VillagerData:{profession:"minecraft:farmer"}}] run tp @s @p
I took the liberty of combining your
as @e
andif entity
statements, because it is more concise and readable, and clarifying that@s
(the villager) is being teleported to@p
(the nearest player to the executing location). You could even get really crazy and shorten it even more to be/tp @e[type=villager,nbt={VillagerData:{profession:"minecraft:farmer"}}] @p
.