[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 |
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. |
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 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? |