mojira.dev
MC-184263

item_used_on_block trigger has no way to check the original block

The bug

Unlike what the trigger name suggest, you can't detect what the original block was for the item_used_on_block trigger. The location condition is evaluated after the block change was made. This makes it impossible to detect some actions.

How to reproduce

  1. Create the following advancement.

    {
      "criteria": {
        "place": {
          "trigger": "minecraft:item_used_on_block",
          "conditions": {
            "location": {
              "block": {
                "block": "minecraft:dirt"
              }
            }
          }
        }
      },
      "rewards": {
        "function": "test:tilled_dirt"
      }
    }
  2. Create the following function

    advancement revoke @s only test:tilled_dirt
    say used item on dirt
  3. Use a hoe on dirt
    ❌ Notice that the advancement is not granted

  4. This advancement will be granted correctly when placing block on dirt, because the dirt itself does not change

  5. This can also be verified by checking the state of button presses.

Fix

An easy way to fix this is by adding a "block" predicate to this trigger. Triggers like bee_nest_destroyed can already check the original block.

Linked issues

Comments 3

The "Not Quite 'Nine' Lives" advancement relies on this bug with the following code:

{
  "criteria": {
    "charge_respawn_anchor": {
      "trigger": "minecraft:item_used_on_block",
      "conditions": {
        "location": {
          "block": {
            "block": "minecraft:respawn_anchor",
            "state": {
              "charges": "4"
            }
          }
        },
        "item": {
          "item": "minecraft:glowstone"
        }
      }
    }
  }
}

The advancement checks the resulting block after charging a Respawn Anchor from 3 which looks neat, but it also indeed causes other checks to become impossible.

Along with a fix for the bug, the advancement should also be changed to have the following code instead:

{
  "criteria": {
    "charge_respawn_anchor": {
      "trigger": "minecraft:item_used_on_block",
      "conditions": {
        "location": {
          "block": {
            "block": "minecraft:respawn_anchor",
            "state": {
              "charges": "3"
            }
          }
        },
        "item": {
          "item": "minecraft:glowstone"
        }
      }
    }
  }
}

After much analysis, I just realized that a block predicate is indeed better for checking the original block. As such, when it is added for the trigger, the "Not Quite 'Nine' Lives" advancement should be changed to look like this instead:

{
  "criteria": {
    "charge_respawn_anchor": {
      "trigger": "minecraft:item_used_on_block",
      "conditions": {
        "block": {
          "block": "minecraft:respawn_anchor",
          "state": {
            "charges": "3"
          }
        },
        "item": {
          "item": "minecraft:glowstone"
        }
      }
    }
  }
}

The location predicate should still check new blocks in advancement triggers since it would still be useful for certain cases such as this one:

{
    "criteria": {
        "redstone_components": {
            "trigger": "placed_block",
            "conditions": {
                "location": {
                    "block": {
                        "tag": "game:redstone_components"
                    }
                }
            }
        }
    }
}

This is a feature request.

Misode

(Unassigned)

Confirmed

(Unassigned)

20w20b, 20w21a

Retrieved