From fac0eca52b4f39b2893c64c5a0015a8652da9a17 Mon Sep 17 00:00:00 2001
From: Justin Lawen <justin@lesserhydra.com>
Date: Wed, 1 May 2019 15:18:14 -0500
Subject: [PATCH] SPIGOT-4838: BlockDispenseEvent not called when shears
 dispensed from dispenser

---
 nms-patches/IDispenseBehavior.patch | 38 ++++++++++++++++++++++++++---
 1 file changed, 34 insertions(+), 4 deletions(-)

diff --git a/nms-patches/IDispenseBehavior.patch b/nms-patches/IDispenseBehavior.patch
index fa63b50665..b5417291cd 100644
--- a/nms-patches/IDispenseBehavior.patch
+++ b/nms-patches/IDispenseBehavior.patch
@@ -117,7 +117,9 @@
 +                    itemstack.add(1);
 +                    return itemstack;
 +                }
-+
+ 
+-                isourceblock.getWorld().addEntity(new EntityFireworks(isourceblock.getWorld(), d0, d1, d2, itemstack));
+-                itemstack.subtract(1);
 +                if (!event.getItem().equals(craftItem)) {
 +                    itemstack.add(1);
 +                    // Chain to handler for new item
@@ -128,9 +130,7 @@
 +                        return itemstack;
 +                    }
 +                }
- 
--                isourceblock.getWorld().addEntity(new EntityFireworks(isourceblock.getWorld(), d0, d1, d2, itemstack));
--                itemstack.subtract(1);
++
 +                itemstack1 = CraftItemStack.asNMSCopy(event.getItem());
 +                isourceblock.getWorld().addEntity(new EntityFireworks(isourceblock.getWorld(), event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), itemstack1));
 +                // itemstack.subtract(1); // Handled during event processing
@@ -482,3 +482,33 @@
                  this.dispensed = true;
                  if (world.isEmpty(blockposition) && blockpumpkincarved.a((IWorldReader) world, blockposition)) {
                      if (!world.isClientSide) {
+@@ -380,6 +692,29 @@
+             @Override
+             protected ItemStack a(ISourceBlock isourceblock, ItemStack itemstack) {
+                 World world = isourceblock.getWorld();
++                // CraftBukkit start
++                org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ());
++                CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack);
++
++                BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0));
++                if (!BlockDispenser.eventFired) {
++                    world.getServer().getPluginManager().callEvent(event);
++                }
++
++                if (event.isCancelled()) {
++                    return itemstack;
++                }
++
++                if (!event.getItem().equals(craftItem)) {
++                    // Chain to handler for new item
++                    ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem());
++                    IDispenseBehavior idispensebehavior = (IDispenseBehavior) BlockDispenser.REGISTRY.get(eventStack.getItem());
++                    if (idispensebehavior != IDispenseBehavior.NONE && idispensebehavior != this) {
++                        idispensebehavior.dispense(isourceblock, eventStack);
++                        return itemstack;
++                    }
++                }
++                // CraftBukkit end
+ 
+                 if (!world.e()) {
+                     this.dispensed = false;