[SPIGOT-2684] Bone meal and flint and steel always activate BlockDispenseEvent, regardless of whether they are actually used Created: 19/Sep/16  Updated: 21/Sep/16  Resolved: 19/Sep/16

Status: Resolved
Project: Spigot
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: zombachu Assignee: Unassigned
Resolution: Won't Fix Votes: 0
Labels: BlockDispenseEvent, bug, dispenser


 Description   

Sorry if this behavior is intended, but it feels like a bug to me that BlockDispenseEvent is always emitted for the items in the title, even when those items aren't actually used and they don't affect the world.



 Comments   
Comment by zombachu [ 21/Sep/16 ]

My proposed fix would solve my issue, since if BlockDispenseEvent only activated when bone meal/flint and steel was used then I could simply listen to the event and subtract 1 from circulation. There wouldn't be any need for scheduler shenanigans (as it would be guaranteed that an item was used and I wouldn't have to count differences in the inventory myself), which means that hoppers/other things that could alter the inventory within the tick wouldn't be an issue.

As for affecting other plugins, that's still an issue (also, relevant xkcd) but I think that the current behavior of BlockDispenseEvent should be considered in context of other events. I believe that mostly every other event operates like what I proposed for this one. BlockPlaceEvent and BlockPistonExtendEvent, to name a couple, aren't emitted when an attempt is made, but instead are only called after the requisite built-in checks are made.

For BlockPlaceEvent, stuff like attempting to place a block where a mob is present or attempting to place a torch on leaves doesn't trigger the event. For BlockPistonExtendEvent, for example, no event is emitted when a piston is powered when it's unable to extend due to the push limit being met. Plugins that listen to attempts involving the two events given as examples do so with PlayerInteractEvent and BlockRedstoneEvent, respectively. I don't see why BlockDispenseEvent should be different in this regard.

Also, after SPIGOT-2683 pumpkins and skulls now fall under this issue as well. Should I create another issue for those items or should I keep the discussion here?

Comment by md_5 [ 20/Sep/16 ]

Changing it would affect plugins that want to trigger some other action when a dispense attempt is made.
Your proposed fix above does not help your issue because you can't track if the dummy item was added back.

Comment by zombachu [ 20/Sep/16 ]

Right now I'm working on a plugin that tracks the number items in circulation to later create a supply-and-demand-based economy. When a player crafts an item it adds it to the circulation, and when it's used up it's removed from circulation. I'm currently working on handling dispenser things, and I ran into the issue described above (and also SPIGOT-2683, but you already resolved that one (thanks btw <3)).

BlockDispenseEvent always fires when a dispenser tries to use bone meal or a flint and steel, even if the game won't permit it to actually be used. In my current case, I would usually just subtract 1 item from circulation whenever BlockDispense event is fired with these items, but with the current behavior it's not a guarantee that it's actually used. My current workaround is to count the contents of the dispenser whenever BlockDispense event is fired, and to set a task to run on the next tick to count the contents again to see if the item was used. As also mentioned above, I'm not sure if this is even a workaround that works 100% of the time, as I think it may be possible for a hopper to inject an additional item into the dispenser's inventory in between the two checks, making it appear like it doesn't use an item when it actually does.

I admit that my use case is fairly niche, but the current behavior of BlockDispenseEvent affects other logging plugins like blockloggers as well. I can't think of any cases where changing the behavior to what I'm petitioning (to only fire when bone meal/flint and steel is actually used) would break anything, however. (Protection plugins would still work fine, etc)

Comment by md_5 [ 19/Sep/16 ]

What are you hoping to achieve?

Comment by zombachu [ 19/Sep/16 ]

@md_5

Right now there's no way (afaik) to check when a dispenser uses bone meal or a flint and steel besides listening to the event and awkwardly checking the contents of the dispenser with a scheduler later. I'm not too familiar with the ticking engine, so would it be possible for a dispenser to actually use a bone meal, then for something to add a new one to its inventory before the scheduled task checks it? Also, is there a better workaround than this?

Generated at Fri Apr 11 15:29:57 UTC 2025 using Jira 10.3.3#10030003-sha1:d220e3fefc8dfc6d47f522d3b9a20c1455e12b7b.