mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-27 15:00:13 +01:00
Properly track the changed item from dispense events
This commit is contained in:
parent
193d6ee2ca
commit
27979040fd
3 changed files with 54 additions and 33 deletions
|
@ -36,7 +36,7 @@
|
|||
|
||||
public interface DispenseItemBehavior {
|
||||
|
||||
@@ -90,14 +104,42 @@
|
||||
@@ -90,14 +104,46 @@
|
||||
Direction enumdirection = (Direction) pointer.state().getValue(DispenserBlock.FACING);
|
||||
EntityType<?> entitytypes = ((SpawnEggItem) stack.getItem()).getType(pointer.level().registryAccess(), stack);
|
||||
|
||||
|
@ -65,10 +65,15 @@
|
|||
+ idispensebehavior.dispense(pointer, eventStack);
|
||||
+ return stack;
|
||||
+ }
|
||||
+ // Paper start - track changed items in the dispense event
|
||||
+ itemstack1 = CraftItemStack.unwrap(event.getItem()); // unwrap is safe because the stack won't be modified
|
||||
+ entitytypes = ((SpawnEggItem) itemstack1.getItem()).getType(worldserver.registryAccess(), itemstack1);
|
||||
+ // Paper end - track changed item from dispense event
|
||||
+ }
|
||||
+
|
||||
try {
|
||||
entitytypes.spawn(pointer.level(), stack, (Player) null, pointer.pos().relative(enumdirection), EntitySpawnReason.DISPENSER, enumdirection != Direction.UP, false);
|
||||
- entitytypes.spawn(pointer.level(), stack, (Player) null, pointer.pos().relative(enumdirection), EntitySpawnReason.DISPENSER, enumdirection != Direction.UP, false);
|
||||
+ entitytypes.spawn(pointer.level(), itemstack1, (Player) null, pointer.pos().relative(enumdirection), EntitySpawnReason.DISPENSER, enumdirection != Direction.UP, false); // Paper - track changed item in dispense event
|
||||
} catch (Exception exception) {
|
||||
- null.LOGGER.error("Error while dispensing spawn egg from dispenser at {}", pointer.pos(), exception);
|
||||
+ DispenseItemBehavior.LOGGER.error("Error while dispensing spawn egg from dispenser at {}", pointer.pos(), exception); // CraftBukkit - decompile error
|
||||
|
@ -81,7 +86,7 @@
|
|||
pointer.level().gameEvent((Entity) null, (Holder) GameEvent.ENTITY_PLACE, pointer.pos());
|
||||
return stack;
|
||||
}
|
||||
@@ -116,13 +158,41 @@
|
||||
@@ -116,13 +162,42 @@
|
||||
Direction enumdirection = (Direction) pointer.state().getValue(DispenserBlock.FACING);
|
||||
BlockPos blockposition = pointer.pos().relative(enumdirection);
|
||||
ServerLevel worldserver = pointer.level();
|
||||
|
@ -113,9 +118,11 @@
|
|||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
+ final ItemStack newStack = CraftItemStack.unwrap(event.getItem()); // Paper - use event itemstack (unwrap is fine here because the stack won't be modified)
|
||||
Consumer<ArmorStand> consumer = EntityType.appendDefaultStackConfig((entityarmorstand) -> {
|
||||
entityarmorstand.setYRot(enumdirection.toYRot());
|
||||
}, worldserver, stack, (Player) null);
|
||||
- }, worldserver, stack, (Player) null);
|
||||
+ }, worldserver, newStack, (Player) null); // Paper - track changed items in the dispense event
|
||||
ArmorStand entityarmorstand = (ArmorStand) EntityType.ARMOR_STAND.spawn(worldserver, consumer, blockposition, EntitySpawnReason.DISPENSER, false, false);
|
||||
|
||||
if (entityarmorstand != null) {
|
||||
|
@ -124,7 +131,7 @@
|
|||
}
|
||||
|
||||
return stack;
|
||||
@@ -141,7 +211,34 @@
|
||||
@@ -141,7 +216,34 @@
|
||||
});
|
||||
|
||||
if (!list.isEmpty()) {
|
||||
|
@ -155,12 +162,12 @@
|
|||
+ return stack;
|
||||
+ }
|
||||
+ }
|
||||
+ ((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
|
||||
this.setSuccess(true);
|
||||
return stack;
|
||||
} else {
|
||||
@@ -166,9 +263,35 @@
|
||||
@@ -166,9 +268,35 @@
|
||||
}
|
||||
|
||||
entityhorsechestedabstract = (AbstractChestedHorse) iterator1.next();
|
||||
|
@ -198,7 +205,7 @@
|
|||
this.setSuccess(true);
|
||||
return stack;
|
||||
}
|
||||
@@ -202,6 +325,44 @@
|
||||
@@ -202,8 +330,50 @@
|
||||
BlockPos blockposition = pointer.pos().relative((Direction) pointer.state().getValue(DispenserBlock.FACING));
|
||||
ServerLevel worldserver = pointer.level();
|
||||
|
||||
|
@ -207,6 +214,7 @@
|
|||
+ int y = blockposition.getY();
|
||||
+ int z = blockposition.getZ();
|
||||
+ BlockState iblockdata = worldserver.getBlockState(blockposition);
|
||||
+ ItemStack dispensedItem = stack; // Paper - track changed item from the dispense event
|
||||
+ // Paper start - correctly check if the bucket place will succeed
|
||||
+ /* Taken from SolidBucketItem#emptyContents */
|
||||
+ boolean willEmptyContentsSolidBucketItem = dispensiblecontaineritem instanceof net.minecraft.world.item.SolidBucketItem && worldserver.isInWorldBounds(blockposition) && iblockdata.isAir();
|
||||
|
@ -236,14 +244,20 @@
|
|||
+ }
|
||||
+ }
|
||||
+
|
||||
+ dispensiblecontaineritem = (DispensibleContainerItem) CraftItemStack.asNMSCopy(event.getItem()).getItem();
|
||||
+ // Paper start - track changed item from dispense event
|
||||
+ dispensedItem = CraftItemStack.unwrap(event.getItem()); // unwrap is safe here as the stack isn't mutated
|
||||
+ dispensiblecontaineritem = (DispensibleContainerItem) dispensedItem.getItem();
|
||||
+ // Paper end - track changed item from dispense event
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
if (dispensiblecontaineritem.emptyContents((Player) null, worldserver, blockposition, (BlockHitResult) null)) {
|
||||
dispensiblecontaineritem.checkExtraContent((Player) null, worldserver, stack, blockposition);
|
||||
- dispensiblecontaineritem.checkExtraContent((Player) null, worldserver, stack, blockposition);
|
||||
+ dispensiblecontaineritem.checkExtraContent((Player) null, worldserver, dispensedItem, blockposition); // Paper - track changed item from dispense event
|
||||
return this.consumeWithRemainder(pointer, stack, new ItemStack(Items.BUCKET));
|
||||
@@ -229,7 +390,7 @@
|
||||
} else {
|
||||
return this.defaultDispenseItemBehavior.dispense(pointer, stack);
|
||||
@@ -229,7 +399,7 @@
|
||||
Block block = iblockdata.getBlock();
|
||||
|
||||
if (block instanceof BucketPickup ifluidsource) {
|
||||
|
@ -252,7 +266,7 @@
|
|||
|
||||
if (itemstack1.isEmpty()) {
|
||||
return super.execute(pointer, stack);
|
||||
@@ -237,6 +398,32 @@
|
||||
@@ -237,6 +407,32 @@
|
||||
worldserver.gameEvent((Entity) null, (Holder) GameEvent.FLUID_PICKUP, blockposition);
|
||||
Item item = itemstack1.getItem();
|
||||
|
||||
|
@ -285,11 +299,10 @@
|
|||
return this.consumeWithRemainder(pointer, stack, new ItemStack(item));
|
||||
}
|
||||
} else {
|
||||
@@ -248,6 +435,30 @@
|
||||
@Override
|
||||
@@ -249,16 +445,44 @@
|
||||
protected ItemStack execute(BlockSource pointer, ItemStack stack) {
|
||||
ServerLevel worldserver = pointer.level();
|
||||
+
|
||||
|
||||
+ // CraftBukkit start
|
||||
+ org.bukkit.block.Block bukkitBlock = CraftBlock.at(worldserver, pointer.pos());
|
||||
+ CraftItemStack craftItem = CraftItemStack.asCraftMirror(stack);
|
||||
|
@ -313,10 +326,10 @@
|
|||
+ }
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
|
||||
+
|
||||
this.setSuccess(true);
|
||||
Direction enumdirection = (Direction) pointer.state().getValue(DispenserBlock.FACING);
|
||||
@@ -255,10 +466,14 @@
|
||||
BlockPos blockposition = pointer.pos().relative(enumdirection);
|
||||
BlockState iblockdata = worldserver.getBlockState(blockposition);
|
||||
|
||||
if (BaseFireBlock.canBePlacedAt(worldserver, blockposition, enumdirection)) {
|
||||
|
@ -334,7 +347,7 @@
|
|||
TntBlock.explode(worldserver, blockposition);
|
||||
worldserver.removeBlock(blockposition, false);
|
||||
} else {
|
||||
@@ -283,13 +498,64 @@
|
||||
@@ -283,13 +507,64 @@
|
||||
this.setSuccess(true);
|
||||
ServerLevel worldserver = pointer.level();
|
||||
BlockPos blockposition = pointer.pos().relative((Direction) pointer.state().getValue(DispenserBlock.FACING));
|
||||
|
@ -399,7 +412,7 @@
|
|||
return stack;
|
||||
}
|
||||
});
|
||||
@@ -298,12 +564,41 @@
|
||||
@@ -298,12 +573,41 @@
|
||||
protected ItemStack execute(BlockSource pointer, ItemStack stack) {
|
||||
ServerLevel worldserver = pointer.level();
|
||||
BlockPos blockposition = pointer.pos().relative((Direction) pointer.state().getValue(DispenserBlock.FACING));
|
||||
|
@ -443,7 +456,7 @@
|
|||
return stack;
|
||||
}
|
||||
});
|
||||
@@ -313,7 +608,31 @@
|
||||
@@ -313,7 +617,31 @@
|
||||
ServerLevel worldserver = pointer.level();
|
||||
Direction enumdirection = (Direction) pointer.state().getValue(DispenserBlock.FACING);
|
||||
BlockPos blockposition = pointer.pos().relative(enumdirection);
|
||||
|
@ -456,11 +469,11 @@
|
|||
+ if (!DispenserBlock.eventFired) {
|
||||
+ worldserver.getCraftServer().getPluginManager().callEvent(event);
|
||||
+ }
|
||||
+
|
||||
|
||||
+ if (event.isCancelled()) {
|
||||
+ return stack;
|
||||
+ }
|
||||
|
||||
+
|
||||
+ if (!event.getItem().equals(craftItem)) {
|
||||
+ // Chain to handler for new item
|
||||
+ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem());
|
||||
|
@ -475,7 +488,7 @@
|
|||
if (worldserver.isEmptyBlock(blockposition) && WitherSkullBlock.canSpawnMob(worldserver, blockposition, stack)) {
|
||||
worldserver.setBlock(blockposition, (BlockState) Blocks.WITHER_SKELETON_SKULL.defaultBlockState().setValue(SkullBlock.ROTATION, RotationSegment.convertToSegment(enumdirection)), 3);
|
||||
worldserver.gameEvent((Entity) null, (Holder) GameEvent.BLOCK_PLACE, blockposition);
|
||||
@@ -326,7 +645,7 @@
|
||||
@@ -326,7 +654,7 @@
|
||||
stack.shrink(1);
|
||||
this.setSuccess(true);
|
||||
} else {
|
||||
|
@ -484,7 +497,7 @@
|
|||
}
|
||||
|
||||
return stack;
|
||||
@@ -339,6 +658,30 @@
|
||||
@@ -339,6 +667,30 @@
|
||||
BlockPos blockposition = pointer.pos().relative((Direction) pointer.state().getValue(DispenserBlock.FACING));
|
||||
CarvedPumpkinBlock blockpumpkincarved = (CarvedPumpkinBlock) Blocks.CARVED_PUMPKIN;
|
||||
|
||||
|
@ -515,7 +528,7 @@
|
|||
if (worldserver.isEmptyBlock(blockposition) && blockpumpkincarved.canSpawnGolem(worldserver, blockposition)) {
|
||||
if (!worldserver.isClientSide) {
|
||||
worldserver.setBlock(blockposition, blockpumpkincarved.defaultBlockState(), 3);
|
||||
@@ -348,7 +691,7 @@
|
||||
@@ -348,7 +700,7 @@
|
||||
stack.shrink(1);
|
||||
this.setSuccess(true);
|
||||
} else {
|
||||
|
@ -524,7 +537,7 @@
|
|||
}
|
||||
|
||||
return stack;
|
||||
@@ -377,6 +720,30 @@
|
||||
@@ -377,6 +729,30 @@
|
||||
BlockPos blockposition = pointer.pos().relative((Direction) pointer.state().getValue(DispenserBlock.FACING));
|
||||
BlockState iblockdata = worldserver.getBlockState(blockposition);
|
||||
|
||||
|
@ -555,7 +568,7 @@
|
|||
if (iblockdata.is(BlockTags.BEEHIVES, (blockbase_blockdata) -> {
|
||||
return blockbase_blockdata.hasProperty(BeehiveBlock.HONEY_LEVEL) && blockbase_blockdata.getBlock() instanceof BeehiveBlock;
|
||||
}) && (Integer) iblockdata.getValue(BeehiveBlock.HONEY_LEVEL) >= 5) {
|
||||
@@ -402,6 +769,13 @@
|
||||
@@ -402,6 +778,13 @@
|
||||
this.setSuccess(true);
|
||||
if (iblockdata.is(Blocks.RESPAWN_ANCHOR)) {
|
||||
if ((Integer) iblockdata.getValue(RespawnAnchorBlock.CHARGE) != 4) {
|
||||
|
@ -569,7 +582,7 @@
|
|||
RespawnAnchorBlock.charge((Entity) null, worldserver, blockposition, iblockdata);
|
||||
stack.shrink(1);
|
||||
} else {
|
||||
@@ -426,6 +800,31 @@
|
||||
@@ -426,6 +809,31 @@
|
||||
this.setSuccess(false);
|
||||
return stack;
|
||||
} else {
|
||||
|
@ -601,7 +614,7 @@
|
|||
Iterator iterator1 = list.iterator();
|
||||
|
||||
Armadillo armadillo;
|
||||
@@ -454,6 +853,13 @@
|
||||
@@ -454,6 +862,13 @@
|
||||
Optional<BlockState> optional = HoneycombItem.getWaxed(iblockdata);
|
||||
|
||||
if (optional.isPresent()) {
|
||||
|
@ -615,7 +628,7 @@
|
|||
worldserver.setBlockAndUpdate(blockposition, (BlockState) optional.get());
|
||||
worldserver.levelEvent(3003, blockposition, 0);
|
||||
stack.shrink(1);
|
||||
@@ -481,6 +887,12 @@
|
||||
@@ -481,6 +896,12 @@
|
||||
if (!worldserver.getBlockState(blockposition1).is(BlockTags.CONVERTABLE_TO_MUD)) {
|
||||
return this.defaultDispenseItemBehavior.dispense(pointer, stack);
|
||||
} else {
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
+
|
||||
+ // SPIGOT-7923: Avoid create projectiles with empty item
|
||||
+ if (!itemstack1.isEmpty()) {
|
||||
+ Projectile iprojectile = Projectile.spawnProjectileUsingShoot(this.projectileItem.asProjectile(worldserver, iposition, itemstack1, enumdirection), worldserver, itemstack1, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), this.dispenseConfig.power(), this.dispenseConfig.uncertainty());
|
||||
+ 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
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
public class ShulkerBoxDispenseBehavior extends OptionalDispenseItemBehavior {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
@@ -26,6 +32,30 @@
|
||||
@@ -26,8 +32,37 @@
|
||||
BlockPos blockposition = pointer.pos().relative(enumdirection);
|
||||
Direction enumdirection1 = pointer.level().isEmptyBlock(blockposition.below()) ? enumdirection : Direction.UP;
|
||||
|
||||
|
@ -42,5 +42,13 @@
|
|||
+ // CraftBukkit end
|
||||
+
|
||||
try {
|
||||
this.setSuccess(((BlockItem) item).place(new DirectionalPlaceContext(pointer.level(), blockposition, enumdirection, stack, enumdirection1)).consumesAction());
|
||||
- this.setSuccess(((BlockItem) item).place(new DirectionalPlaceContext(pointer.level(), blockposition, enumdirection, stack, enumdirection1)).consumesAction());
|
||||
+ // Paper start - track changed items in the dispense event
|
||||
+ this.setSuccess(((BlockItem) item).place(new DirectionalPlaceContext(pointer.level(), blockposition, enumdirection, CraftItemStack.asNMSCopy(event.getItem()), enumdirection1)).consumesAction());
|
||||
+ if (this.isSuccess()) {
|
||||
+ stack.shrink(1); // vanilla shrink is in the place function above, manually handle it here
|
||||
+ }
|
||||
+ // Paper end - track changed items in the dispense event
|
||||
} catch (Exception exception) {
|
||||
ShulkerBoxDispenseBehavior.LOGGER.error("Error trying to place shulker box at {}", blockposition, exception);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue