From 1de01302d4014430384f2887b2af56fa655c1734 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Thu, 31 Oct 2024 19:51:36 -0700 Subject: [PATCH] re-add a dispense fix patch --- ...es-in-dispense-events-regarding-sta.patch} | 308 ++++++++---------- 1 file changed, 142 insertions(+), 166 deletions(-) rename patches/{unapplied/server/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch => server/1058-Fix-inconsistencies-in-dispense-events-regarding-sta.patch} (66%) diff --git a/patches/unapplied/server/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch b/patches/server/1058-Fix-inconsistencies-in-dispense-events-regarding-sta.patch similarity index 66% rename from patches/unapplied/server/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch rename to patches/server/1058-Fix-inconsistencies-in-dispense-events-regarding-sta.patch index 8b797606ed..30f853ff98 100644 --- a/patches/unapplied/server/0777-Fix-inconsistencies-in-dispense-events-regarding-sta.patch +++ b/patches/server/1058-Fix-inconsistencies-in-dispense-events-regarding-sta.patch @@ -9,19 +9,19 @@ 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 90e1914599b43c8bf813596b3b428d8be3bac1b5..6df0db8b4cdab23494ea34236949ece4989110a3 100644 +index dff30954e4c588ee4cc79d3f6dab6fb456934d65..ddb264443f2e38b6348226016f9139727c588898 100644 --- a/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/BoatDispenseItemBehavior.java -@@ -58,7 +58,7 @@ public class BoatDispenseItemBehavior extends DefaultDispenseItemBehavior { +@@ -49,7 +49,7 @@ public class BoatDispenseItemBehavior extends DefaultDispenseItemBehavior { + } - // Object object = this.isChestBoat ? new ChestBoat(worldserver, d1, d2 + d4, d3) : new EntityBoat(worldserver, d1, d2 + d4, d3); // 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); -@@ -68,12 +68,13 @@ public class BoatDispenseItemBehavior extends DefaultDispenseItemBehavior { +@@ -59,12 +59,13 @@ public class BoatDispenseItemBehavior extends DefaultDispenseItemBehavior { } if (event.isCancelled()) { @@ -36,22 +36,22 @@ index 90e1914599b43c8bf813596b3b428d8be3bac1b5..6df0db8b4cdab23494ea34236949ece4 + shrink = false; // Paper - shrink below // Chain to handler for new item ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); -@@ -89,8 +90,7 @@ public class BoatDispenseItemBehavior extends DefaultDispenseItemBehavior { - EntityType.createDefaultStackConfig(worldserver, stack, (Player) null).accept(object); - ((Boat) object).setVariant(this.type); - ((Boat) object).setYRot(enumdirection.toYRot()); -- if (!worldserver.addFreshEntity((Entity) object)) stack.grow(1); // CraftBukkit -- // itemstack.shrink(1); // CraftBukkit - handled during event processing -+ if (worldserver.addFreshEntity((Entity) object) && shrink) stack.shrink(1); // Paper - if entity add was successful and supposed to shrink - return stack; - } + 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 fb80b00b34ae5a4b1491c618a7fe1bdbbde0de9b..96db0b1041a4c0f054d4f3f2bdced960b119664e 100644 +index 8f9b86e50717746e55232293d9e5ac05b8616aa0..0d12605dc84dad49faa18bf1fd058c3c168623ee 100644 --- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java +++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java -@@ -110,7 +110,7 @@ public interface DispenseItemBehavior { +@@ -106,7 +106,7 @@ public interface DispenseItemBehavior { // CraftBukkit start ServerLevel worldserver = pointer.level(); @@ -60,7 +60,7 @@ index fb80b00b34ae5a4b1491c618a7fe1bdbbde0de9b..96db0b1041a4c0f054d4f3f2bdced960 org.bukkit.block.Block block = CraftBlock.at(worldserver, pointer.pos()); CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); -@@ -120,12 +120,13 @@ public interface DispenseItemBehavior { +@@ -116,12 +116,13 @@ public interface DispenseItemBehavior { } if (event.isCancelled()) { @@ -75,7 +75,7 @@ index fb80b00b34ae5a4b1491c618a7fe1bdbbde0de9b..96db0b1041a4c0f054d4f3f2bdced960 + shrink = false; // Paper - shrink below // Chain to handler for new item ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.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; } @@ -109,9 +109,9 @@ index fb80b00b34ae5a4b1491c618a7fe1bdbbde0de9b..96db0b1041a4c0f054d4f3f2bdced960 + shrink = false; // Paper - shrink below // Chain to handler for new item ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); -@@ -196,7 +198,7 @@ public interface DispenseItemBehavior { - ArmorStand entityarmorstand = (ArmorStand) EntityType.ARMOR_STAND.spawn(worldserver, consumer, blockposition, MobSpawnType.DISPENSER, false, false); + 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 @@ -119,7 +119,7 @@ index fb80b00b34ae5a4b1491c618a7fe1bdbbde0de9b..96db0b1041a4c0f054d4f3f2bdced960 } return stack; -@@ -216,7 +218,7 @@ public interface DispenseItemBehavior { +@@ -217,7 +219,7 @@ public interface DispenseItemBehavior { if (!list.isEmpty()) { // CraftBukkit start @@ -128,7 +128,7 @@ index fb80b00b34ae5a4b1491c618a7fe1bdbbde0de9b..96db0b1041a4c0f054d4f3f2bdced960 ServerLevel world = pointer.level(); org.bukkit.block.Block block = CraftBlock.at(world, pointer.pos()); CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); -@@ -227,12 +229,13 @@ public interface DispenseItemBehavior { +@@ -228,12 +230,13 @@ public interface DispenseItemBehavior { } if (event.isCancelled()) { @@ -143,49 +143,16 @@ index fb80b00b34ae5a4b1491c618a7fe1bdbbde0de9b..96db0b1041a4c0f054d4f3f2bdced960 + shrink = false; // Paper - shrink below // Chain to handler for new item ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); -@@ -243,6 +246,7 @@ public interface DispenseItemBehavior { + 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(itemstack1, SoundSource.BLOCKS); + ((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 { - } while (!entityhorseabstract.isBodyArmorItem(stack) || entityhorseabstract.isWearingBodyArmor() || !entityhorseabstract.isTamed()); - - // 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); -@@ -281,12 +285,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 = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); -@@ -296,6 +301,7 @@ public interface DispenseItemBehavior { - } - } - -+ if (shrink) stack.shrink(1); // Paper - shrink here - entityhorseabstract.setBodyArmorItem(CraftItemStack.asNMSCopy(event.getItem())); - // CraftBukkit end - this.setSuccess(true); -@@ -342,7 +348,7 @@ public interface DispenseItemBehavior { entityhorsechestedabstract = (AbstractChestedHorse) iterator1.next(); // CraftBukkit start } while (!entityhorsechestedabstract.isTamed()); @@ -194,7 +161,7 @@ index fb80b00b34ae5a4b1491c618a7fe1bdbbde0de9b..96db0b1041a4c0f054d4f3f2bdced960 ServerLevel world = pointer.level(); org.bukkit.block.Block block = CraftBlock.at(world, pointer.pos()); CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); -@@ -353,10 +359,13 @@ public interface DispenseItemBehavior { +@@ -281,10 +285,13 @@ public interface DispenseItemBehavior { } if (event.isCancelled()) { @@ -207,8 +174,8 @@ index fb80b00b34ae5a4b1491c618a7fe1bdbbde0de9b..96db0b1041a4c0f054d4f3f2bdced960 + shrink = false; // Paper - shrink below // Chain to handler for new item ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); -@@ -368,7 +377,7 @@ public interface DispenseItemBehavior { + 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 @@ -217,7 +184,7 @@ index fb80b00b34ae5a4b1491c618a7fe1bdbbde0de9b..96db0b1041a4c0f054d4f3f2bdced960 this.setSuccess(true); return stack; } -@@ -413,7 +422,7 @@ public interface DispenseItemBehavior { +@@ -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()); @@ -226,7 +193,7 @@ index fb80b00b34ae5a4b1491c618a7fe1bdbbde0de9b..96db0b1041a4c0f054d4f3f2bdced960 BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(x, y, z)); if (!DispenserBlock.eventFired) { -@@ -475,7 +484,7 @@ public interface DispenseItemBehavior { +@@ -409,7 +416,7 @@ public interface DispenseItemBehavior { // CraftBukkit start org.bukkit.block.Block bukkitBlock = CraftBlock.at(worldserver, pointer.pos()); @@ -235,7 +202,7 @@ index fb80b00b34ae5a4b1491c618a7fe1bdbbde0de9b..96db0b1041a4c0f054d4f3f2bdced960 BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); if (!DispenserBlock.eventFired) { -@@ -513,7 +522,7 @@ public interface DispenseItemBehavior { +@@ -447,7 +454,7 @@ public interface DispenseItemBehavior { // CraftBukkit start org.bukkit.block.Block bukkitBlock = CraftBlock.at(worldserver, pointer.pos()); @@ -244,7 +211,7 @@ index fb80b00b34ae5a4b1491c618a7fe1bdbbde0de9b..96db0b1041a4c0f054d4f3f2bdced960 BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); if (!DispenserBlock.eventFired) { -@@ -575,7 +584,7 @@ public interface DispenseItemBehavior { +@@ -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()); @@ -253,7 +220,7 @@ index fb80b00b34ae5a4b1491c618a7fe1bdbbde0de9b..96db0b1041a4c0f054d4f3f2bdced960 BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); if (!DispenserBlock.eventFired) { -@@ -641,7 +650,7 @@ public interface DispenseItemBehavior { +@@ -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); @@ -262,7 +229,7 @@ index fb80b00b34ae5a4b1491c618a7fe1bdbbde0de9b..96db0b1041a4c0f054d4f3f2bdced960 org.bukkit.block.Block block = CraftBlock.at(worldserver, pointer.pos()); CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); -@@ -651,12 +660,13 @@ public interface DispenseItemBehavior { +@@ -586,12 +593,13 @@ public interface DispenseItemBehavior { } if (event.isCancelled()) { @@ -277,8 +244,8 @@ index fb80b00b34ae5a4b1491c618a7fe1bdbbde0de9b..96db0b1041a4c0f054d4f3f2bdced960 + shrink = false; // Paper - shrink below // Chain to handler for new item ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); -@@ -672,7 +682,7 @@ public interface DispenseItemBehavior { + 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); @@ -287,7 +254,7 @@ index fb80b00b34ae5a4b1491c618a7fe1bdbbde0de9b..96db0b1041a4c0f054d4f3f2bdced960 return stack; } }); -@@ -699,7 +709,7 @@ public interface DispenseItemBehavior { +@@ -620,7 +628,7 @@ public interface DispenseItemBehavior { // CraftBukkit start org.bukkit.block.Block bukkitBlock = CraftBlock.at(worldserver, pointer.pos()); @@ -296,7 +263,7 @@ index fb80b00b34ae5a4b1491c618a7fe1bdbbde0de9b..96db0b1041a4c0f054d4f3f2bdced960 BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); if (!DispenserBlock.eventFired) { -@@ -748,7 +758,7 @@ public interface DispenseItemBehavior { +@@ -669,7 +677,7 @@ public interface DispenseItemBehavior { // CraftBukkit start org.bukkit.block.Block bukkitBlock = CraftBlock.at(worldserver, pointer.pos()); @@ -305,7 +272,7 @@ index fb80b00b34ae5a4b1491c618a7fe1bdbbde0de9b..96db0b1041a4c0f054d4f3f2bdced960 BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); if (!DispenserBlock.eventFired) { -@@ -810,7 +820,7 @@ public interface DispenseItemBehavior { +@@ -731,7 +739,7 @@ public interface DispenseItemBehavior { // CraftBukkit start org.bukkit.block.Block bukkitBlock = CraftBlock.at(worldserver, pointer.pos()); @@ -314,20 +281,66 @@ index fb80b00b34ae5a4b1491c618a7fe1bdbbde0de9b..96db0b1041a4c0f054d4f3f2bdced960 BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); if (!DispenserBlock.eventFired) { -diff --git a/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java b/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java -index 1b1c54ce8f187b968352d4aad05821ece182e20b..985954030654d521291cccbfc3ca49b67ee4357d 100644 ---- a/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java -+++ b/src/main/java/net/minecraft/core/dispenser/ProjectileDispenseBehavior.java -@@ -40,7 +40,7 @@ public class ProjectileDispenseBehavior extends DefaultDispenseItemBehavior { +@@ -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 - // this.projectileItem.shoot(iprojectile, (double) enumdirection.getStepX(), (double) enumdirection.getStepY(), (double) enumdirection.getStepZ(), this.dispenseConfig.power(), this.dispenseConfig.uncertainty()); + // 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 - org.bukkit.block.Block block = CraftBlock.at(worldserver, pointer.pos()); ++ 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); -@@ -50,12 +50,13 @@ public class ProjectileDispenseBehavior extends DefaultDispenseItemBehavior { +@@ -79,12 +79,13 @@ public class MinecartDispenseItemBehavior extends DefaultDispenseItemBehavior { } if (event.isCancelled()) { @@ -342,18 +355,57 @@ index 1b1c54ce8f187b968352d4aad05821ece182e20b..985954030654d521291cccbfc3ca49b6 + shrink = false; // Paper - shrink below // Chain to handler for new item ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); -@@ -69,7 +70,7 @@ public class ProjectileDispenseBehavior extends DefaultDispenseItemBehavior { - ((Entity) iprojectile).projectileSource = new org.bukkit.craftbukkit.projectiles.CraftBlockProjectileSource(pointer.blockEntity()); - // CraftBukkit end - worldserver.addFreshEntity(iprojectile); + 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 445560d94086452ca4fbaf7792ff2b04c3ed3b73..f32f8d5cb22feb885a53d3b56c04ad4219d2bafa 100644 +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 { @@ -366,7 +418,7 @@ index 445560d94086452ca4fbaf7792ff2b04c3ed3b73..f32f8d5cb22feb885a53d3b56c04ad42 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 f84987c36a16df19286d6f1badfb1ffb9cc7e770..6f2adf2334e35e8a617a4ced0c1af2abf32bbd8d 100644 +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 { @@ -378,79 +430,3 @@ index f84987c36a16df19286d6f1badfb1ffb9cc7e770..6f2adf2334e35e8a617a4ced0c1af2ab BlockDispenseEvent event = new BlockDispenseEvent(bukkitBlock, craftItem.clone(), new org.bukkit.util.Vector(blockposition.getX(), blockposition.getY(), blockposition.getZ())); if (!DispenserBlock.eventFired) { -diff --git a/src/main/java/net/minecraft/world/item/ArmorItem.java b/src/main/java/net/minecraft/world/item/ArmorItem.java -index d481ec2eace5fca7f80f6d9254121afd680e7309..fb518f87cc4ccd810fb32cade2fdd7e09ab0abfc 100644 ---- a/src/main/java/net/minecraft/world/item/ArmorItem.java -+++ b/src/main/java/net/minecraft/world/item/ArmorItem.java -@@ -55,7 +55,7 @@ public class ArmorItem extends Item implements Equipable { - } else { - LivingEntity entityliving = (LivingEntity) list.get(0); - EquipmentSlot enumitemslot = entityliving.getEquipmentSlotForItem(armor); -- ItemStack itemstack1 = armor.split(1); -+ ItemStack itemstack1 = armor.copyWithCount(1); // Paper - shrink below and single item in event - // CraftBukkit start - Level world = pointer.level(); - org.bukkit.block.Block block = CraftBlock.at(world, pointer.pos()); -@@ -67,12 +67,13 @@ public class ArmorItem extends Item implements Equipable { - } - - if (event.isCancelled()) { -- armor.grow(1); -+ // armor.grow(1); // Paper - shrink below - return false; - } - -+ boolean shrink = true; // Paper - if (!event.getItem().equals(craftItem)) { -- armor.grow(1); -+ shrink = false; // Paper - shrink below - // Chain to handler for new item - ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); - DispenseItemBehavior idispensebehavior = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); -@@ -89,6 +90,7 @@ public class ArmorItem extends Item implements Equipable { - ((Mob) entityliving).setPersistenceRequired(); - } - -+ if (shrink) armor.shrink(1); // Paper - return true; - } - } -diff --git a/src/main/java/net/minecraft/world/item/MinecartItem.java b/src/main/java/net/minecraft/world/item/MinecartItem.java -index 727319e86aa77b5a67b4c4f03b1e9aba9fe6bcde..66074445d3908b9bb1c8d70e1e27d057720ec8e5 100644 ---- a/src/main/java/net/minecraft/world/item/MinecartItem.java -+++ b/src/main/java/net/minecraft/world/item/MinecartItem.java -@@ -66,7 +66,7 @@ public class MinecartItem extends Item { - - // CraftBukkit start - // EntityMinecartAbstract entityminecartabstract = EntityMinecartAbstract.createMinecart(worldserver, d0, d1 + d3, d2, ((ItemMinecart) itemstack.getItem()).type); -- 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); - -@@ -76,12 +76,13 @@ public class MinecartItem extends Item { - } - - 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 = (DispenseItemBehavior) DispenserBlock.DISPENSER_REGISTRY.get(eventStack.getItem()); -@@ -94,8 +95,7 @@ public class MinecartItem extends Item { - itemstack1 = CraftItemStack.asNMSCopy(event.getItem()); - AbstractMinecart entityminecartabstract = AbstractMinecart.createMinecart(worldserver, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), ((MinecartItem) itemstack1.getItem()).type, itemstack1, (Player) 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 - actually handle here - // CraftBukkit end - return stack; - }