0

I have a function in a datapack which is supposed to check for the presence of four stacks of flesh and four stacks of bones on four soul sand and four quartz blocks respectively. To do this, I've been giving the first flesh the tag "flesh1", the second "flesh2", and so one, and same with the bones. Then, it gives the executing entity the tag 'fleshAndBonesPresent'.

Unfortunately, when I run this I don't get the tag, and when I try to kill the entity with the tag "flesh1" it says no entity is found. Trying to have an entity without the flesh1, flesh2, or flesh3 tags (but with the fourth one) say "hi" (or trying to kill them) also doesn't work. Here's the function. I'm putting in the whole thing because it's pretty short and having all of it will probably help you understand my question better:

execute if block ~ ~-1 ~ minecraft:soul_sand as @e[type=item,nbt={Item:{id:"minecraft:rotten_flesh",Count:64b}},distance=..4] run tag @s add flesh1
execute if block ~ ~-1 ~ minecraft:soul_sand as @e[type=item,nbt={Item:{id:"minecraft:rotten_flesh",Count:64b}},distance=..4,tag=!flesh1] run tag @s add flesh2
execute if block ~ ~-1 ~ minecraft:soul_sand as @e[type=item,nbt={Item:{id:"minecraft:rotten_flesh",Count:64b}},distance=..4,tag=!flesh1,tag=!flesh2] run tag @s add flesh3
execute if block ~ ~-1 ~ minecraft:soul_sand as @e[type=item,nbt={Item:{id:"minecraft:rotten_flesh",Count:64b}},distance=..4,tag=!flesh1,tag=!flesh2,tag=!flesh3] run tag @s add flesh4

execute if block ~ ~-1 ~ minecraft:quartz_block as @e[type=item,nbt={Item:{id:"minecraft:bone",Count:64b}},distance=..2] run tag @s add bone1
execute if block ~ ~-1 ~ minecraft:quartz_block as @e[type=item,nbt={Item:{id:"minecraft:bone",Count:64b}},distance=..2,tag=!bone1] run tag @s add bone2
execute if block ~ ~-1 ~ minecraft:quartz_block as @e[type=item,nbt={Item:{id:"minecraft:bone",Count:64b}},distance=..2,tag=!bone1,tag=!bone2] run tag @s add bone3
execute if block ~ ~-1 ~ minecraft:quartz_block as @e[type=item,nbt={Item:{id:"minecraft:bone",Count:64b}},distance=..2,tag=!bone1,tag=!bone2,tag=!bone3] run tag @s add bone4

execute if entity @e[tag=flesh1] if entity @e[tag=flesh2] if entity @e[tag=flesh3] if entity @e[tag=flesh4] if entity @e[tag=bone1] if entity @e[tag=bone2] if entity @e[tag=bone3] if entity @e[tag=bone4] run tag @s add fleshAndBonesPresent

I was trying to kill the entities from the chat after I ran the function. I've checked the wiki on tag use and it says that to select entities without a certain series of tags to use multiple tag=! selector arguments. I don't really know what's wrong but it's pretty frustrating so any help/advice is appreciated. Here's a picture of the setup (yes it is a ritual): My setup

Edit: As you can see in the comments, using execute store result score was promising, but didn't work.

  • 1
    I recommend using simpler commands first, for example first check if they even have those NBT tags (in chat), then check for the blocks and so on. Also I'm pretty sure there are easier ways than essentially duplicating every command four times. You should be able to use /execute store success to count the number of entities fulfilling a condition. – Fabian Röling Apr 26 at 1:47
  • 1
    Just execute if entity and all your conditions. You might need a "run" before that, but you definitely don't need it after it (excerpt if you also want to do something with the items). – Fabian Röling Apr 26 at 2:44
  • 1
    I was thinking about something like /execute store success score @s <scoreboard> run execute at @e[type=item,nbt={…}] if block ~ ~-1 ~ <block> That should give you the number of items that have that NBT tag and are on a block. Also, have you considered that items sink into soulsand? Maybe that's why the condition never succeeds, you start at the bottom of the item, go 1.0 blocks down and end up slightly under the soulsand, so checking for that block fails. – Fabian Röling Apr 26 at 20:09
  • 1
    success tracks how many times a command succeeds, so if you split up the execution with execute and @e, you can get more than 1. That was exactly what I meant. Actually I made a mistake, which happened because I didn't even start the game. :D You do indeed just get 1 or 0 with a command like that, but for example /execute store success score @s <score> run execute if entity @e[type=item] gives you 3 if there are 3 items. Minecraft seems to have a problem with applying the result value properly in many other cases, that's probably a bug. Edit: I also made a mistake here. Experimenting… – Fabian Röling Apr 26 at 23:32
  • 1
    One way that I didn't even consider anymore, because it's usually not needed anymore, is increasing the score by 1 for every entity one by one. That was how it had to be done in 1.12 and before, but usually 1.13 has better ways to do it, I'm just having a lot of difficulty figuring out how exactly. /execute store success behaves very weirdly. I'll write an approach in an answer, because this comment chain is getting pretty long. – Fabian Röling Apr 27 at 0:01
1

Instead of trying to debug this complicated arrangement of tags, I basically rewrote your function, maybe that already fixes your problem:

scoreboard players set @s itemCounter 0
execute at @e[type=item,nbt={Item:{id:"minecraft:rotten_flesh",Count:64b}},distance=..4] if block ~ ~-0.5 ~ soul_sand run scoreboard players add @s itemCounter 1
execute if score @s itemCounter matches 4 run tag @s add fleshPresent

scoreboard players set @s itemCounter 0
execute at @e[type=item,nbt={Item:{id:"minecraft:bone",Count:64b}},distance=..2] if block ~ ~-0.5 ~ quartz_block run scoreboard players add @s itemCounter 1
execute if score @s itemCounter matches 4 run tag @s add bonesPresent

This uses the old method of making every entity you're testing for increase a shared score by 1 each. This is not as nice for performance as I would have hoped, usually 1.13 has nicer ways to do things like this, but maybe someone else has an idea how to do it better.

What I assume went wrong in your original function:

  • The items sink into soul sand, so you have to check for ~ ~ ~ instead of ~ ~-1 ~ to test for the block they are in, instead of the one they are on, which would be the one below the soul sand.
  • You started with if block …, which means that the block would be checked for whoever runs the function. Since you didn't mention who executes this function, I assume it's the player. But it actually doesn't matter much, because you're testing for being on quartz and also for being on soul sand, which one entity can't be both at the same time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.