--- a/net/minecraft/server/DispenserRegistry.java +++ b/net/minecraft/server/DispenserRegistry.java @@ -8,6 +8,15 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +// CraftBukkit start +import java.util.List; +import org.bukkit.Location; +import org.bukkit.TreeType; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.event.block.BlockDispenseEvent; +import org.bukkit.event.world.StructureGrowEvent; +// CraftBukkit end + public class DispenserRegistry { public static final PrintStream a = System.out; @@ -71,7 +80,7 @@ BlockDispenser.REGISTRY.a(Items.SPLASH_POTION, new IDispenseBehavior() { public ItemStack a(ISourceBlock isourceblock, final ItemStack itemstack) { return (new DispenseBehaviorProjectile() { - protected IProjectile a(World world, IPosition iposition, ItemStack itemstack) { + protected IProjectile a(World world, IPosition iposition, ItemStack itemstack1) { // CraftBukkit - decompile issue return new EntityPotion(world, iposition.getX(), iposition.getY(), iposition.getZ(), itemstack1.cloneItemStack()); } @@ -88,7 +97,7 @@ BlockDispenser.REGISTRY.a(Items.LINGERING_POTION, new IDispenseBehavior() { public ItemStack a(ISourceBlock isourceblock, final ItemStack itemstack) { return (new DispenseBehaviorProjectile() { - protected IProjectile a(World world, IPosition iposition, ItemStack itemstack) { + protected IProjectile a(World world, IPosition iposition, ItemStack itemstack1) { // CraftBukkit - decompile issue return new EntityPotion(world, iposition.getX(), iposition.getY(), iposition.getZ(), itemstack1.cloneItemStack()); } @@ -108,14 +117,46 @@ double d0 = isourceblock.getX() + (double) enumdirection.getAdjacentX(); double d1 = (double) ((float) (isourceblock.getBlockPosition().getY() + enumdirection.getAdjacentY()) + 0.2F); double d2 = isourceblock.getZ() + (double) enumdirection.getAdjacentZ(); - Entity entity = ItemMonsterEgg.a(isourceblock.getWorld(), ItemMonsterEgg.h(itemstack), d0, d1, d2); + // Entity entity = ItemMonsterEgg.a(isourceblock.getWorld(), ItemMonsterEgg.h(itemstack), d0, d1, d2); + + // CraftBukkit start + World world = isourceblock.getWorld(); + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d0, d1, d2)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + itemstack.add(1); + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + itemstack.add(1); + // 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.a(isourceblock, eventStack); + return itemstack; + } + } + + itemstack1 = CraftItemStack.asNMSCopy(event.getItem()); + + Entity entity = ItemMonsterEgg.spawnCreature(isourceblock.getWorld(), ItemMonsterEgg.h(itemstack), event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DISPENSE_EGG); if (entity instanceof EntityLiving && itemstack.hasName()) { entity.setCustomName(itemstack.getName()); } ItemMonsterEgg.a(isourceblock.getWorld(), (EntityHuman) null, itemstack, entity); - itemstack.subtract(1); + // itemstack.subtract(1);// Handled during event processing + // CraftBukkit end return itemstack; } }); @@ -125,10 +166,39 @@ double d0 = isourceblock.getX() + (double) enumdirection.getAdjacentX(); double d1 = (double) ((float) isourceblock.getBlockPosition().getY() + 0.2F); double d2 = isourceblock.getZ() + (double) enumdirection.getAdjacentZ(); - EntityFireworks entityfireworks = new EntityFireworks(isourceblock.getWorld(), d0, d1, d2, itemstack); + // CraftBukkit start + World world = isourceblock.getWorld(); + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d0, d1, d2)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + itemstack.add(1); + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + itemstack.add(1); + // 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.a(isourceblock, eventStack); + return itemstack; + } + } + + itemstack1 = CraftItemStack.asNMSCopy(event.getItem()); + EntityFireworks entityfireworks = new EntityFireworks(isourceblock.getWorld(), event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), itemstack1); isourceblock.getWorld().addEntity(entityfireworks); - itemstack.subtract(1); + // itemstack.subtract(1); // Handled during event processing + // CraftBukkit end return itemstack; } @@ -149,8 +219,38 @@ double d4 = random.nextGaussian() * 0.05D + (double) enumdirection.getAdjacentY(); double d5 = random.nextGaussian() * 0.05D + (double) enumdirection.getAdjacentZ(); - world.addEntity(new EntitySmallFireball(world, d0, d1, d2, d3, d4, d5)); - itemstack.subtract(1); + // CraftBukkit start + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d3, d4, d5)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + itemstack.add(1); + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + itemstack.add(1); + // 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.a(isourceblock, eventStack); + return itemstack; + } + } + + EntitySmallFireball fireball = new EntitySmallFireball(world, d0, d1, d2, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ()); + fireball.projectileSource = new org.bukkit.craftbukkit.projectiles.CraftBlockProjectileSource((TileEntityDispenser) isourceblock.getTileEntity()); + + world.addEntity(fireball); + // itemstack.subtract(1); // Handled during event processing + // CraftBukkit end return itemstack; } @@ -171,7 +271,53 @@ ItemBucket itembucket = (ItemBucket) itemstack.getItem(); BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.e().get(BlockDispenser.FACING)); - return itembucket.a((EntityHuman) null, isourceblock.getWorld(), blockposition) ? new ItemStack(Items.BUCKET) : this.b.a(isourceblock, itemstack); + // CraftBukkit start + World world = isourceblock.getWorld(); + int x = blockposition.getX(); + int y = blockposition.getY(); + int z = blockposition.getZ(); + if (world.isEmpty(blockposition) || !world.getType(blockposition).getMaterial().isBuildable()) { + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(x, y, z)); + 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.a(isourceblock, eventStack); + return itemstack; + } + } + + itembucket = (ItemBucket) CraftItemStack.asNMSCopy(event.getItem()).getItem(); + } + // CraftBukkit end + + if (itembucket.a((EntityHuman) null, isourceblock.getWorld(), blockposition)) { + // CraftBukkit start - Handle stacked buckets + Item item = Items.BUCKET; + itemstack.subtract(1); + if (itemstack.isEmpty()) { + itemstack.setItem(Items.BUCKET); + itemstack.setCount(1); + } else if (((TileEntityDispenser) isourceblock.getTileEntity()).addItem(new ItemStack(item)) < 0) { + this.b.a(isourceblock, new ItemStack(item)); + } + // CraftBukkit end + return itemstack; + } else { + return this.b.a(isourceblock, itemstack); + } } }; @@ -198,6 +344,30 @@ item = Items.LAVA_BUCKET; } + // 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(blockposition.getX(), blockposition.getY(), blockposition.getZ())); + 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.a(isourceblock, eventStack); + return itemstack; + } + } + // CraftBukkit end + world.setAir(blockposition); itemstack.subtract(1); if (itemstack.isEmpty()) { @@ -215,14 +385,42 @@ protected ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { World world = isourceblock.getWorld(); + // CraftBukkit start + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(block, 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.a(isourceblock, eventStack); + return itemstack; + } + } + // CraftBukkit end + this.b = true; BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.e().get(BlockDispenser.FACING)); if (world.isEmpty(blockposition)) { - world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); - if (itemstack.isDamaged(1, world.random, (EntityPlayer) null)) { - itemstack.setCount(0); + // CraftBukkit start - Ignition by dispensing flint and steel + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition.getX(), blockposition.getY(), blockposition.getZ(), isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()).isCancelled()) { + world.setTypeUpdate(blockposition, Blocks.FIRE.getBlockData()); + if (itemstack.isDamaged(1, world.random, (EntityPlayer) null)) { + itemstack.setCount(0); + } } + // CraftBukkit end } else if (world.getType(blockposition).getBlock() == Blocks.TNT) { Blocks.TNT.postBreak(world, blockposition, Blocks.TNT.getBlockData().set(BlockTNT.EXPLODE, Boolean.valueOf(true))); world.setAir(blockposition); @@ -240,6 +438,32 @@ World world = isourceblock.getWorld(); BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.e().get(BlockDispenser.FACING)); + // CraftBukkit start + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(block, 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.a(isourceblock, eventStack); + return itemstack; + } + } + + world.captureTreeGeneration = true; + // CraftBukkit end + if (ItemDye.a(itemstack, world, blockposition)) { if (!world.isClientSide) { world.triggerEffect(2005, blockposition, 0); @@ -247,6 +471,26 @@ } else { this.b = false; } + // CraftBukkit start + world.captureTreeGeneration = false; + if (world.capturedBlockStates.size() > 0) { + TreeType treeType = BlockSapling.treeType; + BlockSapling.treeType = null; + Location location = new Location(world.getWorld(), blockposition.getX(), blockposition.getY(), blockposition.getZ()); + List blocks = (List) world.capturedBlockStates.clone(); + world.capturedBlockStates.clear(); + StructureGrowEvent structureEvent = null; + if (treeType != null) { + structureEvent = new StructureGrowEvent(location, treeType, false, null, blocks); + org.bukkit.Bukkit.getPluginManager().callEvent(structureEvent); + } + if (structureEvent == null || !structureEvent.isCancelled()) { + for (org.bukkit.block.BlockState blockstate : blocks) { + blockstate.update(true); + } + } + } + // CraftBukkit end return itemstack; } else { @@ -258,11 +502,40 @@ protected ItemStack b(ISourceBlock isourceblock, ItemStack itemstack) { World world = isourceblock.getWorld(); BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.e().get(BlockDispenser.FACING)); - EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, (EntityLiving) null); + // EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, (EntityLiving) null); + + // CraftBukkit start + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector((double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + itemstack.add(1); + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + itemstack.add(1); + // 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.a(isourceblock, eventStack); + return itemstack; + } + } + + EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), (EntityLiving) null); + // CraftBukkit end world.addEntity(entitytntprimed); world.a((EntityHuman) null, entitytntprimed.locX, entitytntprimed.locY, entitytntprimed.locZ, SoundEffects.hW, SoundCategory.BLOCKS, 1.0F, 1.0F); - itemstack.subtract(1); + // itemstack.subtract(1); // CraftBukkit - handled above return itemstack; } }); @@ -273,6 +546,30 @@ BlockPosition blockposition = isourceblock.getBlockPosition().shift(enumdirection); BlockSkull blockskull = Blocks.SKULL; + // 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(blockposition.getX(), blockposition.getY(), blockposition.getZ())); + 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.a(isourceblock, eventStack); + return itemstack; + } + } + // CraftBukkit end + this.b = true; if (world.isEmpty(blockposition) && blockskull.b(world, blockposition, itemstack)) { if (!world.isClientSide) { @@ -321,6 +618,30 @@ BlockPosition blockposition = isourceblock.getBlockPosition().shift((EnumDirection) isourceblock.e().get(BlockDispenser.FACING)); BlockPumpkin blockpumpkin = (BlockPumpkin) Blocks.PUMPKIN; + // 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(blockposition.getX(), blockposition.getY(), blockposition.getZ())); + 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.a(isourceblock, eventStack); + return itemstack; + } + } + // CraftBukkit end + this.b = true; if (world.isEmpty(blockposition) && blockpumpkin.b(world, blockposition)) { if (!world.isClientSide) { @@ -407,6 +728,30 @@ EnumDirection enumdirection = (EnumDirection) isourceblock.e().get(BlockDispenser.FACING); BlockPosition blockposition = isourceblock.getBlockPosition().shift(enumdirection); + // 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(blockposition.getX(), blockposition.getY(), blockposition.getZ())); + 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.a(isourceblock, eventStack); + return itemstack; + } + } + // CraftBukkit end + this.b = world.a(block, blockposition, false, EnumDirection.DOWN, (Entity) null); if (this.b) { EnumDirection enumdirection1 = world.isEmpty(blockposition.down()) ? enumdirection : EnumDirection.UP; @@ -475,12 +820,40 @@ d3 = 0.0D; } - EntityBoat entityboat = new EntityBoat(world, d0, d1 + d3, d2); + // EntityBoat entityboat = new EntityBoat(world, d0, d1 + d3, d2); + // CraftBukkit start + ItemStack itemstack1 = itemstack.cloneAndSubtract(1); + org.bukkit.block.Block block = world.getWorld().getBlockAt(isourceblock.getBlockPosition().getX(), isourceblock.getBlockPosition().getY(), isourceblock.getBlockPosition().getZ()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d0, d1 + d3, d2)); + if (!BlockDispenser.eventFired) { + world.getServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + itemstack.add(1); + return itemstack; + } + + if (!event.getItem().equals(craftItem)) { + itemstack.add(1); + // 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.a(isourceblock, eventStack); + return itemstack; + } + } + + EntityBoat entityboat = new EntityBoat(world, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ()); + // CraftBukkit end entityboat.setType(this.c); entityboat.yaw = enumdirection.l(); - world.addEntity(entityboat); - itemstack.subtract(1); + if (!world.addEntity(entityboat)) itemstack.add(1); // CraftBukkit + // itemstack.subtract(1); // CraftBukkit - handled during event processing return itemstack; }