3

I would like to make villagers angry on command. I assume I need to use /data modify, but I do not know the proper <targetPath>. I have the following so far:

execute as @e[type=villager] run data modify entity @s Target set from entity @a[sort=nearest,limit=1] {Gossips:[{Type:"minor_negative",Value:5}]}

I also have a potential contender, but this required a manual entry of the "Target", which obviously is not possible

execute as @e[type=villager] run data merge entity @s {Gossips:[{Type:"major_positive",Value:20,Target:<>}

I had hoped these two could be used in conjunction, to set the gossip then assign the target, but that does not seem to be the case.

Specifically, I would like to do this when their workstation is broken, which I know I can do with level 1 villagers easily (by testing if they drop from 1 to 0) but if anyone has a way of doing that for other levels it would be greatly appreciated.

2 Answers 2

1

Detecting a broken station

Looking a bit on how villagers work, their data path stores where their station is placed under Brain.memories."minecraft:job_site".value.pos. If that is empty, it has none; if that has something, it has a station. We can use the store command to store in a score if they had a station in a previous tick. So we create a score called HasStation and set each villager score's to the result of the data. Before that, we check if the villager doesn't have the data and has his score set to 1:

execute as @e[type=minecraft:villager] unless data entity @s Brain.memories."minecraft:job_site".value.pos if score @s HasStation matches 1 run say I lost my station
execute as @e[type=minecraft:villager] store success score @s HasStation run data get entity @s Brain.memories."minecraft:job_site".value.pos

Just modify the run say ... to something of your desire.

Detecting who broke it

You can also attach the station breaking to a player, but that is a bit more hard-coded. You simply create a scoreboard for each minecraft.custom.break.[station_block] and, whenever that goes to 1, send it to a single scoreboard (so instead of having 100 scoreboards for each block, you have a single one).

Then, when the first command of the two runs, there will be a player which score is above 0. Simply target the closest to for its UUID and attach it to the Target of the Gossip. Something like:

execute as @e[type=minecraft:villager] unless data entity @s Brain.memories."minecraft:job_site".value.pos if score @s HasStation matches 1 run data merge entity @s {Gossips:[{Type:"major_negative",Value:20,Target:[I;1,1,1,1]}]}
execute as @e[type=minecraft:villager] unless data entity @s Brain.memories."minecraft:job_site".value.pos if score @s HasStation matches 1 run data modify entity @s Gossips[0].Target set from entity @p[scores={destroyedStation=1..}] UUID
execute as @e[type=minecraft:villager] unless data entity @s Brain.memories."minecraft:job_site".value.pos if score @s HasStation matches 1 run scoreboard players remove @p[scores={destroyedStation=1..}] destroyedStation 1
execute as @e[type=minecraft:villager] store success score @s HasStation run data get entity @s Brain.memories."minecraft:job_site".value.pos

Since all three starting lines have the same if statement, it would be wise to create a function for it.

1
  • Ill just assume villagers are dumb and get angry at the nearest player even if there are potentially more than one, but thanks for the first part
    – Aceplante
    Aug 7 at 4:44
0

So I had to figure it out myself. Here are the commands I used:

execute as @e[type=villager] run data merge entity @s {Gossips:[{Type:"major_positive",Value:20,Target:[I;1,1,1,1]}]}

execute as @e[type=minecraft:villager] run data modify entity @s Gossips[0].Target set from entity @p UUID
6
  • So, I tested and editing the UUID after creating the gossip didn't work + if you already have a gossip of a type from a certain UUID only the biggest one prevails instead of adding up. Also, what about the part of the question on how to detect lost stations? I can post that part if you want (I was still working on the nbt part)
    – BunnyMerz
    Aug 6 at 17:22
  • I can easily do it for level 1 villagers going back to 0, but if you have a way of detecting when any villagers has their workstation broken (specifically the leveled up ones), that would be appreciated
    – Aceplante
    Aug 7 at 4:24
  • Did it. What about the nbt part, did it work on your tests?
    – BunnyMerz
    Aug 7 at 4:38
  • All bounties are final and cannot be refunded. You also can't award your own answer. Thus, if you found the other answer helpful, you can award it at your discretion.
    – Timmy Jim
    Aug 7 at 5:58
  • He kind of helped with a different issue, but not the initial question I asked. That I had to figure out myself without help. Therefore, if I can not award my answer the bounty, then I need it refunded since I did not get an answer.
    – Aceplante
    Aug 7 at 16:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .