--- a/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java +++ b/net/minecraft/core/dispenser/DefaultDispenseItemBehavior.java @@ -6,9 +6,23 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.DispenserBlock; +// CraftBukkit start +import org.bukkit.craftbukkit.block.CraftBlock; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.craftbukkit.util.CraftVector; +import org.bukkit.event.block.BlockDispenseEvent; +// CraftBukkit end public class DefaultDispenseItemBehavior implements DispenseItemBehavior { + // CraftBukkit start + private boolean dropper; + + public DefaultDispenseItemBehavior(boolean dropper) { + this.dropper = dropper; + } + // CraftBukkit end + public DefaultDispenseItemBehavior() {} @Override @@ -26,16 +39,27 @@ Position position = DispenserBlock.getDispensePosition(blocksource); ItemStack itemstack1 = itemstack.split(1); - spawnItem(blocksource.level(), itemstack1, 6, direction, position); + // CraftBukkit start + if (!spawnItem(sourceblock.level(), itemstack1, 6, enumdirection, sourceblock, dropper)) { + itemstack.grow(1); + } + // CraftBukkit end return itemstack; } - public static void spawnItem(Level level, ItemStack itemstack, int i, Direction direction, Position position) { - double d0 = position.x(); - double d1 = position.y(); - double d2 = position.z(); + public static void spawnItem(Level level, ItemStack stack, int speed, Direction facing, IPosition position) { + // CraftBukkit start + ItemEntity entityitem = prepareItem(level, stack, speed, facing, position); + level.addFreshEntity(entityitem); + } - if (direction.getAxis() == Direction.Axis.Y) { + private static ItemEntity prepareItem(Level world, ItemStack itemstack, int i, Direction enumdirection, IPosition iposition) { + // CraftBukkit end + double d0 = iposition.x(); + double d1 = iposition.y(); + double d2 = iposition.z(); + + if (enumdirection.getAxis() == Direction.Axis.Y) { d1 -= 0.125D; } else { d1 -= 0.15625D; @@ -44,12 +68,48 @@ ItemEntity itementity = new ItemEntity(level, d0, d1, d2, itemstack); double d3 = level.random.nextDouble() * 0.1D + 0.2D; - itementity.setDeltaMovement(level.random.triangle((double) direction.getStepX() * d3, 0.0172275D * (double) i), level.random.triangle(0.2D, 0.0172275D * (double) i), level.random.triangle((double) direction.getStepZ() * d3, 0.0172275D * (double) i)); - level.addFreshEntity(itementity); + entityitem.setDeltaMovement(world.random.triangle((double) enumdirection.getStepX() * d3, 0.0172275D * (double) i), world.random.triangle(0.2D, 0.0172275D * (double) i), world.random.triangle((double) enumdirection.getStepZ() * d3, 0.0172275D * (double) i)); + // CraftBukkit start + return entityitem; } - protected void playSound(BlockSource blocksource) { - blocksource.level().levelEvent(1000, blocksource.pos(), 0); + // CraftBukkit - void -> boolean return, IPosition -> ISourceBlock last argument, dropper + public static boolean spawnItem(Level world, ItemStack itemstack, int i, Direction enumdirection, SourceBlock sourceblock, boolean dropper) { + if (itemstack.isEmpty()) return true; + IPosition iposition = DispenserBlock.getDispensePosition(sourceblock); + ItemEntity entityitem = prepareItem(world, itemstack, i, enumdirection, iposition); + + org.bukkit.block.Block block = CraftBlock.at(world, sourceblock.pos()); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); + + BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), CraftVector.toBukkit(entityitem.getDeltaMovement())); + if (!DispenserBlock.eventFired) { + world.getCraftServer().getPluginManager().callEvent(event); + } + + if (event.isCancelled()) { + return false; + } + + entityitem.setItem(CraftItemStack.asNMSCopy(event.getItem())); + entityitem.setDeltaMovement(CraftVector.toNMS(event.getVelocity())); + + if (!dropper && !event.getItem().getType().equals(craftItem.getType())) { + // Chain to handler for new item + ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); + DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); + if (idispensebehavior != DispenseItemBehavior.NOOP && idispensebehavior.getClass() != DefaultDispenseItemBehavior.class) { + idispensebehavior.dispense(sourceblock, eventStack); + } else { + world.addFreshEntity(entityitem); + } + return false; + } + + world.addFreshEntity(entityitem); + + return true; + // CraftBukkit end } protected void playAnimation(BlockSource blocksource, Direction direction) {