From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jake Potrebic <jake.m.potrebic@gmail.com> Date: Sun, 11 Dec 2022 23:47:22 -0800 Subject: [PATCH] Fix inconsistencies in dispense events regarding stack size The javadocs for BlockDispenseEvent suggest the ItemStack is a single item which is being dispensed. Before this fix, sometimes it was the whole stack before a single item had been taken. This fixes that so the stack size is always 1. diff --git a/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java index dff30954e4c588ee4cc79d3f6dab6fb456934d65..ddb264443f2e38b6348226016f9139727c588898 100644 --- a/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java @@ -49,7 +49,7 @@ public class BoatDispenseItemBehavior extends DefaultDispenseItemBehavior { } // CraftBukkit start - ItemStack itemstack1 = stack.split(1); + ItemStack itemstack1 = stack.copyWithCount(1); // Paper - shrink at end and single item in event org.bukkit.block.Block block = CraftBlock.at(worldserver, pointer.pos()); CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); @@ -59,12 +59,13 @@ public class BoatDispenseItemBehavior extends DefaultDispenseItemBehavior { } if (event.isCancelled()) { - stack.grow(1); + // stack.grow(1); // Paper - shrink below return stack; } + boolean shrink = true; // Paper if (!event.getItem().equals(craftItem)) { - stack.grow(1); + shrink = false; // Paper - shrink below // Chain to handler for new item ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior @@ -80,8 +81,7 @@ public class BoatDispenseItemBehavior extends DefaultDispenseItemBehavior { abstractboat.setInitialPos(event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ()); // CraftBukkit EntityType.createDefaultStackConfig(worldserver, stack, (Player) null).accept(abstractboat); abstractboat.setYRot(enumdirection.toYRot()); - if (!worldserver.addFreshEntity(abstractboat)) stack.grow(1); // CraftBukkit - // itemstack.shrink(1); // CraftBukkit - handled during event processing + if (worldserver.addFreshEntity(abstractboat) && shrink) stack.shrink(1); // Paper - if entity add was successful and supposed to shrink } return stack; diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java index 8f9b86e50717746e55232293d9e5ac05b8616aa0..0d12605dc84dad49faa18bf1fd058c3c168623ee 100644 --- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java @@ -106,7 +106,7 @@ public interface DispenseItemBehavior { // CraftBukkit start ServerLevel worldserver = pointer.level(); - ItemStack itemstack1 = stack.split(1); + ItemStack itemstack1 = stack.copyWithCount(1); // Paper - shrink below and single item in event org.bukkit.block.Block block = CraftBlock.at(worldserver, pointer.pos()); CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); @@ -116,12 +116,13 @@ public interface DispenseItemBehavior { } if (event.isCancelled()) { - stack.grow(1); + // stack.grow(1); // Paper - shrink below return stack; } + boolean shrink = true; // Paper if (!event.getItem().equals(craftItem)) { - stack.grow(1); + shrink = false; // Paper - shrink below // Chain to handler for new item ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior @@ -142,7 +143,7 @@ public interface DispenseItemBehavior { return ItemStack.EMPTY; } - // itemstack.shrink(1); // Handled during event processing + if (shrink) stack.shrink(1); // Paper - actually handle here // CraftBukkit end pointer.level().gameEvent((Entity) null, (Holder) GameEvent.ENTITY_PLACE, pointer.pos()); return stack; @@ -164,7 +165,7 @@ public interface DispenseItemBehavior { ServerLevel worldserver = pointer.level(); // CraftBukkit start - ItemStack itemstack1 = stack.split(1); + ItemStack itemstack1 = stack.copyWithCount(1); // Paper - shrink below and single item in event org.bukkit.block.Block block = CraftBlock.at(worldserver, pointer.pos()); CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); @@ -174,12 +175,13 @@ public interface DispenseItemBehavior { } if (event.isCancelled()) { - stack.grow(1); + // stack.grow(1); // Paper - shrink below return stack; } + boolean shrink = true; // Paper if (!event.getItem().equals(craftItem)) { - stack.grow(1); + shrink = false; // Paper - shrink below // Chain to handler for new item ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior @@ -197,7 +199,7 @@ public interface DispenseItemBehavior { ArmorStand entityarmorstand = (ArmorStand) EntityType.ARMOR_STAND.spawn(worldserver, consumer, blockposition, EntitySpawnReason.DISPENSER, false, false); if (entityarmorstand != null) { - // itemstack.shrink(1); // CraftBukkit - Handled during event processing + if (shrink) stack.shrink(1); // Paper - actually handle here } return stack; @@ -217,7 +219,7 @@ public interface DispenseItemBehavior { if (!list.isEmpty()) { // CraftBukkit start - ItemStack itemstack1 = stack.split(1); + ItemStack itemstack1 = stack.copyWithCount(1); // Paper - shrink below and single item in event ServerLevel world = pointer.level(); org.bukkit.block.Block block = CraftBlock.at(world, pointer.pos()); CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); @@ -228,12 +230,13 @@ public interface DispenseItemBehavior { } if (event.isCancelled()) { - stack.grow(1); + // stack.grow(1); // Paper - shrink below return stack; } + boolean shrink = true; // Paper if (!event.getItem().equals(craftItem)) { - stack.grow(1); + shrink = false; // Paper - shrink below // Chain to handler for new item ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior @@ -244,6 +247,7 @@ public interface DispenseItemBehavior { } ((Saddleable) list.get(0)).equipSaddle(CraftItemStack.asNMSCopy(event.getItem()), SoundSource.BLOCKS); // Paper - track changed items in dispense event // CraftBukkit end + if (shrink) stack.shrink(1); // Paper - actually handle here this.setSuccess(true); return stack; } else { @@ -270,7 +274,7 @@ public interface DispenseItemBehavior { entityhorsechestedabstract = (AbstractChestedHorse) iterator1.next(); // CraftBukkit start } while (!entityhorsechestedabstract.isTamed()); - ItemStack itemstack1 = stack.split(1); + ItemStack itemstack1 = stack.copyWithCount(1); // Paper - shrink below ServerLevel world = pointer.level(); org.bukkit.block.Block block = CraftBlock.at(world, pointer.pos()); CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); @@ -281,10 +285,13 @@ public interface DispenseItemBehavior { } if (event.isCancelled()) { + // stack.grow(1); // Paper - shrink below (this was actually missing and should be here, added it commented out to be consistent) return stack; } + boolean shrink = true; // Paper if (!event.getItem().equals(craftItem)) { + shrink = false; // Paper - shrink below // Chain to handler for new item ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior @@ -296,7 +303,7 @@ public interface DispenseItemBehavior { entityhorsechestedabstract.getSlot(499).set(CraftItemStack.asNMSCopy(event.getItem())); // CraftBukkit end - // itemstack.shrink(1); // CraftBukkit - handled above + if (shrink) stack.shrink(1); // Paper - actually handle here this.setSuccess(true); return stack; } @@ -344,7 +351,7 @@ public interface DispenseItemBehavior { if (willEmptyContentsSolidBucketItem || willEmptyBucketItem) { // Paper end - correctly check if the bucket place will succeed org.bukkit.block.Block block = CraftBlock.at(worldserver, pointer.pos()); - CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack.copyWithCount(1)); // Paper - single item in event BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(x, y, z)); if (!DispenserBlock.eventFired) { @@ -409,7 +416,7 @@ public interface DispenseItemBehavior { // CraftBukkit start org.bukkit.block.Block bukkitBlock = CraftBlock.at(worldserver, pointer.pos()); - CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack.copyWithCount(1)); // Paper - single item in event BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); if (!DispenserBlock.eventFired) { @@ -447,7 +454,7 @@ public interface DispenseItemBehavior { // CraftBukkit start org.bukkit.block.Block bukkitBlock = CraftBlock.at(worldserver, pointer.pos()); - CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack); // Paper - ignore stack size on damageable items BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); if (!DispenserBlock.eventFired) { @@ -509,7 +516,7 @@ public interface DispenseItemBehavior { BlockPos blockposition = pointer.pos().relative((Direction) pointer.state().getValue(DispenserBlock.FACING)); // CraftBukkit start org.bukkit.block.Block block = CraftBlock.at(worldserver, pointer.pos()); - CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack.copyWithCount(1)); // Paper - single item in event BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); if (!DispenserBlock.eventFired) { @@ -576,7 +583,7 @@ public interface DispenseItemBehavior { // CraftBukkit start // EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(worldserver, (double) blockposition.getX() + 0.5D, (double) blockposition.getY(), (double) blockposition.getZ() + 0.5D, (EntityLiving) null); - ItemStack itemstack1 = stack.split(1); + ItemStack itemstack1 = stack.copyWithCount(1); // Paper - shrink at end and single item in event org.bukkit.block.Block block = CraftBlock.at(worldserver, pointer.pos()); CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); @@ -586,12 +593,13 @@ public interface DispenseItemBehavior { } if (event.isCancelled()) { - stack.grow(1); + // stack.grow(1); // Paper - shrink below return stack; } + boolean shrink = true; // Paper if (!event.getItem().equals(craftItem)) { - stack.grow(1); + shrink = false; // Paper - shrink below // Chain to handler for new item ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior @@ -607,7 +615,7 @@ public interface DispenseItemBehavior { worldserver.addFreshEntity(entitytntprimed); worldserver.playSound((Player) null, entitytntprimed.getX(), entitytntprimed.getY(), entitytntprimed.getZ(), SoundEvents.TNT_PRIMED, SoundSource.BLOCKS, 1.0F, 1.0F); worldserver.gameEvent((Entity) null, (Holder) GameEvent.ENTITY_PLACE, blockposition); - // itemstack.shrink(1); // CraftBukkit - handled above + if (shrink) stack.shrink(1); // Paper - actually handle here return stack; } }); @@ -620,7 +628,7 @@ public interface DispenseItemBehavior { // CraftBukkit start org.bukkit.block.Block bukkitBlock = CraftBlock.at(worldserver, pointer.pos()); - CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack.copyWithCount(1)); // Paper - single item in event BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); if (!DispenserBlock.eventFired) { @@ -669,7 +677,7 @@ public interface DispenseItemBehavior { // CraftBukkit start org.bukkit.block.Block bukkitBlock = CraftBlock.at(worldserver, pointer.pos()); - CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack.copyWithCount(1)); // Paper - single item in event BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); if (!DispenserBlock.eventFired) { @@ -731,7 +739,7 @@ public interface DispenseItemBehavior { // CraftBukkit start org.bukkit.block.Block bukkitBlock = CraftBlock.at(worldserver, pointer.pos()); - CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack.copyWithCount(1)); // Paper - only single item in event BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); if (!DispenserBlock.eventFired) { @@ -813,7 +821,7 @@ public interface DispenseItemBehavior { ItemStack itemstack1 = stack; ServerLevel world = pointer.level(); org.bukkit.block.Block block = CraftBlock.at(world, pointer.pos()); - CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); // Paper - ignore stack size on damageable items BlockDispenseEvent event = new BlockDispenseArmorEvent(block, craftItem.clone(), (org.bukkit.craftbukkit.entity.CraftLivingEntity) list.get(0).getBukkitEntity()); if (!DispenserBlock.eventFired) { diff --git a/src/main/java/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java index a43ea83dbbd5946096cdde31af766674bda6c3be..bf8c511739265c6a9cd277752e844481598f8966 100644 --- a/src/main/java/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/EquipmentDispenseItemBehavior.java @@ -42,7 +42,7 @@ public class EquipmentDispenseItemBehavior extends DefaultDispenseItemBehavior { } else { LivingEntity entityliving = (LivingEntity) list.getFirst(); EquipmentSlot enumitemslot = entityliving.getEquipmentSlotForItem(stack); - ItemStack itemstack1 = stack.split(1); + ItemStack itemstack1 = stack.copyWithCount(1); // Paper - shrink below and single item in event // CraftBukkit start Level world = pointer.level(); @@ -55,12 +55,13 @@ public class EquipmentDispenseItemBehavior extends DefaultDispenseItemBehavior { } if (event.isCancelled()) { - stack.grow(1); + // stack.grow(1); // Paper - shrink below return false; } + boolean shrink = true; // Paper if (!event.getItem().equals(craftItem)) { - stack.grow(1); + shrink = false; // Paper - shrink below // Chain to handler for new item ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior @@ -79,6 +80,7 @@ public class EquipmentDispenseItemBehavior extends DefaultDispenseItemBehavior { entityinsentient.setPersistenceRequired(); } + if (shrink) stack.shrink(1); // Paper - shrink here return true; } } diff --git a/src/main/java/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java index aae9ec8f3bd39685b37251bef3f9ac846d65c192..3588896b7413be73ade6b3f8fd111d02c48ec550 100644 --- a/src/main/java/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/MinecartDispenseItemBehavior.java @@ -69,7 +69,7 @@ public class MinecartDispenseItemBehavior extends DefaultDispenseItemBehavior { Vec3 vec3d1 = new Vec3(d0, d1 + d3, d2); // CraftBukkit start // EntityMinecartAbstract entityminecartabstract = EntityMinecartAbstract.createMinecart(worldserver, vec3d1.x, vec3d1.y, vec3d1.z, this.entityType, EntitySpawnReason.DISPENSER, itemstack, (EntityHuman) null); - ItemStack itemstack1 = stack.split(1); + ItemStack itemstack1 = stack.copyWithCount(1); // Paper - shrink below and single item in event org.bukkit.block.Block block2 = CraftBlock.at(worldserver, pointer.pos()); CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); @@ -79,12 +79,13 @@ public class MinecartDispenseItemBehavior extends DefaultDispenseItemBehavior { } if (event.isCancelled()) { - stack.grow(1); + // stack.grow(1); // Paper - shrink below return stack; } + boolean shrink = true; // Paper if (!event.getItem().equals(craftItem)) { - stack.grow(1); + shrink = false; // Paper - shrink below // Chain to handler for new item ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior @@ -98,8 +99,7 @@ public class MinecartDispenseItemBehavior extends DefaultDispenseItemBehavior { AbstractMinecart entityminecartabstract = AbstractMinecart.createMinecart(worldserver, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), this.entityType, EntitySpawnReason.DISPENSER, itemstack1, (Player) null); if (entityminecartabstract != null) { - if (!worldserver.addFreshEntity(entityminecartabstract)) stack.grow(1); - // itemstack.shrink(1); // CraftBukkit - handled during event processing + if (worldserver.addFreshEntity(entityminecartabstract) && shrink) stack.shrink(1); // Paper - if entity add was successful and supposed to shrink // CraftBukkit end } diff --git a/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java b/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java index 281439e430fb8e587549da783bdd93432f8f957f..54c72cf472e06e214eb61bd8615a0bb27690c807 100644 --- a/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java @@ -38,7 +38,7 @@ public class ProjectileDispenseBehavior extends DefaultDispenseItemBehavior { // CraftBukkit start // IProjectile.spawnProjectileUsingShoot(this.projectileItem.asProjectile(worldserver, iposition, itemstack, enumdirection), worldserver, itemstack, (double) enumdirection.getStepX(), (double) enumdirection.getStepY(), (double) enumdirection.getStepZ(), this.dispenseConfig.power(), this.dispenseConfig.uncertainty()); // CraftBukkit - call when finish the BlockDispenseEvent - ItemStack itemstack1 = stack.split(1); + ItemStack itemstack1 = stack.copyWithCount(1); // Paper - shrink below and single item in event org.bukkit.block.Block block = CraftBlock.at(worldserver, pointer.pos()); CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); @@ -48,12 +48,13 @@ public class ProjectileDispenseBehavior extends DefaultDispenseItemBehavior { } if (event.isCancelled()) { - stack.grow(1); + // stack.grow(1); // Paper - shrink below return stack; } + boolean shrink = true; // Paper if (!event.getItem().equals(craftItem)) { - stack.grow(1); + shrink = false; // Paper - shrink below // Chain to handler for new item ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); DispenseItemBehavior idispensebehavior = DispenserBlock.getDispenseBehavior(pointer, eventStack); // Paper - Fix NPE with equippable and items without behavior @@ -68,7 +69,7 @@ public class ProjectileDispenseBehavior extends DefaultDispenseItemBehavior { Projectile iprojectile = Projectile.spawnProjectileUsingShoot(this.projectileItem.asProjectile(worldserver, iposition, CraftItemStack.unwrap(event.getItem()), enumdirection), worldserver, itemstack1, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), this.dispenseConfig.power(), this.dispenseConfig.uncertainty()); // Paper - track changed items in the dispense event; unwrap is safe here because all uses of the stack make their own copies iprojectile.projectileSource = new org.bukkit.craftbukkit.projectiles.CraftBlockProjectileSource(pointer.blockEntity()); } - // itemstack.shrink(1); // CraftBukkit - Handled during event processing + if (shrink) stack.shrink(1); // Paper - actually handle here // CraftBukkit end return stack; } diff --git a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java index afad4fa3ca1a3186c4569ea073f776dac16817e1..65ed3d77a51b8299517e0c165403b0c5ac413475 100644 --- a/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java @@ -38,7 +38,7 @@ public class ShearsDispenseItemBehavior extends OptionalDispenseItemBehavior { ServerLevel worldserver = pointer.level(); // CraftBukkit start org.bukkit.block.Block bukkitBlock = CraftBlock.at(worldserver, pointer.pos()); - CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack); // Paper - ignore stack size on damageable items BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); if (!DispenserBlock.eventFired) { diff --git a/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java b/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java index 16b435216dc7c6a3f8c1c0f9e2323e6afb3a6cb9..8f9fde5489c0e1d0a91203536caddec5a9c96f6c 100644 --- a/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/ShulkerBoxDispenseBehavior.java @@ -34,7 +34,7 @@ public class ShulkerBoxDispenseBehavior extends OptionalDispenseItemBehavior { // CraftBukkit start org.bukkit.block.Block bukkitBlock = CraftBlock.at(pointer.level(), pointer.pos()); - CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack); + CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack.copyWithCount(1)); // Paper - single item in event BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); if (!DispenserBlock.eventFired) {