[ci skip] Add more patch identifying comments
This commit is contained in:
		
					parent
					
						
							
								0fb2a8eea3
							
						
					
				
			
			
				commit
				
					
						2307466a54
					
				
			
		
					 8 changed files with 63 additions and 63 deletions
				
			
		| 
						 | 
				
			
			@ -24,11 +24,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
 
 | 
			
		||||
             if (this.random.nextFloat() < f) {
 | 
			
		||||
-                player.getCooldowns().addCooldown(Items.SHIELD, 100);
 | 
			
		||||
+                // Paper start
 | 
			
		||||
+                // Paper start - Add PlayerShieldDisableEvent
 | 
			
		||||
+                final io.papermc.paper.event.player.PlayerShieldDisableEvent shieldDisableEvent = new io.papermc.paper.event.player.PlayerShieldDisableEvent((org.bukkit.entity.Player) player.getBukkitEntity(), getBukkitEntity(), 100);
 | 
			
		||||
+                if (!shieldDisableEvent.callEvent()) return;
 | 
			
		||||
+                player.getCooldowns().addCooldown(Items.SHIELD, shieldDisableEvent.getCooldown());
 | 
			
		||||
+                // Paper end
 | 
			
		||||
+                // Paper end - Add PlayerShieldDisableEvent
 | 
			
		||||
                 this.level().broadcastEntityEvent(player, (byte) 30);
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
| 
						 | 
				
			
			@ -41,7 +41,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
         super.blockUsingShield(attacker);
 | 
			
		||||
         if (attacker.canDisableShield()) {
 | 
			
		||||
-            this.disableShield(true);
 | 
			
		||||
+            this.disableShield(true, attacker); // Paper
 | 
			
		||||
+            this.disableShield(true, attacker); // Paper - Add PlayerShieldDisableEvent
 | 
			
		||||
         }
 | 
			
		||||
 
 | 
			
		||||
     }
 | 
			
		||||
| 
						 | 
				
			
			@ -49,14 +49,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
         this.attack(target);
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
+    @io.papermc.paper.annotation.DoNotUse // Paper - add player shield disable event
 | 
			
		||||
+    @io.papermc.paper.annotation.DoNotUse // Paper - Add PlayerShieldDisableEvent
 | 
			
		||||
     public void disableShield(boolean sprinting) {
 | 
			
		||||
+        // Paper start - add player shield disable event
 | 
			
		||||
+        // Paper start - Add PlayerShieldDisableEvent
 | 
			
		||||
+        disableShield(sprinting, null);
 | 
			
		||||
+    }
 | 
			
		||||
+
 | 
			
		||||
+    public void disableShield(boolean sprinting, @Nullable LivingEntity attacker) {
 | 
			
		||||
+        // Paper end - add player shield disable event
 | 
			
		||||
+        // Paper end - Add PlayerShieldDisableEvent
 | 
			
		||||
         float f = 0.25F + (float) EnchantmentHelper.getBlockEfficiency(this) * 0.05F;
 | 
			
		||||
 
 | 
			
		||||
         if (sprinting) {
 | 
			
		||||
| 
						 | 
				
			
			@ -65,7 +65,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
 
 | 
			
		||||
         if (this.random.nextFloat() < f) {
 | 
			
		||||
-            this.getCooldowns().addCooldown(Items.SHIELD, 100);
 | 
			
		||||
+            // Paper start - add player shield disable event
 | 
			
		||||
+            // Paper start - Add PlayerShieldDisableEvent
 | 
			
		||||
+            final org.bukkit.entity.Entity finalAttacker = attacker != null ? attacker.getBukkitEntity() : null;
 | 
			
		||||
+            if (finalAttacker != null) {
 | 
			
		||||
+                final io.papermc.paper.event.player.PlayerShieldDisableEvent shieldDisableEvent = new io.papermc.paper.event.player.PlayerShieldDisableEvent((org.bukkit.entity.Player) getBukkitEntity(), finalAttacker, 100);
 | 
			
		||||
| 
						 | 
				
			
			@ -74,7 +74,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
+            } else {
 | 
			
		||||
+                this.getCooldowns().addCooldown(Items.SHIELD, 100);
 | 
			
		||||
+            }
 | 
			
		||||
+            // Paper end - add player shield disable event
 | 
			
		||||
+            // Paper end - Add PlayerShieldDisableEvent
 | 
			
		||||
             this.stopUsingItem();
 | 
			
		||||
             this.level().broadcastEntityEvent(this, (byte) 30);
 | 
			
		||||
         }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,15 +13,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
                 if (ishearable.readyForShearing()) {
 | 
			
		||||
                     // CraftBukkit start
 | 
			
		||||
-                    if (CraftEventFactory.callBlockShearEntityEvent(entityliving, bukkitBlock, craftItem).isCancelled()) {
 | 
			
		||||
+                    // Paper start
 | 
			
		||||
+                    // Paper start - Add drops to shear events
 | 
			
		||||
+                    org.bukkit.event.block.BlockShearEntityEvent event = CraftEventFactory.callBlockShearEntityEvent(entityliving, bukkitBlock, craftItem, ishearable.generateDefaultDrops());
 | 
			
		||||
+                    if (event.isCancelled()) {
 | 
			
		||||
+                        // Paper end
 | 
			
		||||
+                        // Paper end - Add drops to shear events
 | 
			
		||||
                         continue;
 | 
			
		||||
                     }
 | 
			
		||||
                     // CraftBukkit end
 | 
			
		||||
-                    ishearable.shear(SoundSource.BLOCKS);
 | 
			
		||||
+                    ishearable.shear(SoundSource.BLOCKS, CraftItemStack.asNMSCopy(event.getDrops())); // Paper
 | 
			
		||||
+                    ishearable.shear(SoundSource.BLOCKS, CraftItemStack.asNMSCopy(event.getDrops())); // Paper - Add drops to shear events
 | 
			
		||||
                     worldserver.gameEvent((Entity) null, GameEvent.SHEAR, blockposition);
 | 
			
		||||
                     return true;
 | 
			
		||||
                 }
 | 
			
		||||
| 
						 | 
				
			
			@ -33,15 +33,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
 import net.minecraft.sounds.SoundSource;
 | 
			
		||||
 
 | 
			
		||||
 public interface Shearable {
 | 
			
		||||
+    default void shear(SoundSource soundCategory, java.util.List<net.minecraft.world.item.ItemStack> drops) { this.shear(soundCategory); } // Paper
 | 
			
		||||
+    default void shear(SoundSource soundCategory, java.util.List<net.minecraft.world.item.ItemStack> drops) { this.shear(soundCategory); } // Paper - Add drops to shear events
 | 
			
		||||
     void shear(SoundSource shearedSoundCategory);
 | 
			
		||||
 
 | 
			
		||||
     boolean readyForShearing();
 | 
			
		||||
+    // Paper start - ensure all implementing entities override this
 | 
			
		||||
+    // Paper start - custom shear drops; ensure all implementing entities override this
 | 
			
		||||
+    default java.util.List<net.minecraft.world.item.ItemStack> generateDefaultDrops() {
 | 
			
		||||
+        return java.util.Collections.emptyList();
 | 
			
		||||
+    }
 | 
			
		||||
+    // Paper end
 | 
			
		||||
+    // Paper end - custom shear drops
 | 
			
		||||
 }
 | 
			
		||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java b/src/main/java/net/minecraft/world/entity/animal/MushroomCow.java
 | 
			
		||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
			
		||||
| 
						 | 
				
			
			@ -65,7 +65,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
+            // Paper end - custom shear drops
 | 
			
		||||
             // CraftBukkit end
 | 
			
		||||
-            this.shear(SoundSource.PLAYERS);
 | 
			
		||||
+            this.shear(SoundSource.PLAYERS, drops); // Paper
 | 
			
		||||
+            this.shear(SoundSource.PLAYERS, drops); // Paper - custom shear drops
 | 
			
		||||
             this.gameEvent(GameEvent.SHEAR, player);
 | 
			
		||||
             if (!this.level().isClientSide) {
 | 
			
		||||
                 itemstack.hurtAndBreak(1, player, (entityhuman1) -> {
 | 
			
		||||
| 
						 | 
				
			
			@ -106,7 +106,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
-                    }
 | 
			
		||||
-                    this.level().addFreshEntity(entityitem);
 | 
			
		||||
-                    // CraftBukkit end
 | 
			
		||||
+                // Paper start - custom shear drops (moved drop generation to separate method)
 | 
			
		||||
+                // Paper start - custom shear drops; moved drop generation to separate method
 | 
			
		||||
+                for (final ItemStack drop : drops) {
 | 
			
		||||
+                    ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(1.0D), this.getZ(), drop);
 | 
			
		||||
+                    this.spawnAtLocation(entityitem);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
 
 | 
			
		||||
     public int getXpNeededForNextLevel() {
 | 
			
		||||
-        return this.experienceLevel >= 30 ? 112 + (this.experienceLevel - 30) * 9 : (this.experienceLevel >= 15 ? 37 + (this.experienceLevel - 15) * 5 : 7 + this.experienceLevel * 2);
 | 
			
		||||
+        return this.experienceLevel >= 30 ? 112 + (this.experienceLevel - 30) * 9 : (this.experienceLevel >= 15 ? 37 + (this.experienceLevel - 15) * 5 : 7 + this.experienceLevel * 2); // Paper - diff on change
 | 
			
		||||
+        return this.experienceLevel >= 30 ? 112 + (this.experienceLevel - 30) * 9 : (this.experienceLevel >= 15 ? 37 + (this.experienceLevel - 15) * 5 : 7 + this.experienceLevel * 2); // Paper - diff on change; calculateTotalExperiencePoints
 | 
			
		||||
     }
 | 
			
		||||
     // Paper start - send SoundEffect to everyone who can see fromEntity
 | 
			
		||||
     private static void sendSoundEffect(Player fromEntity, double x, double y, double z, SoundEvent soundEffect, SoundSource soundCategory, float volume, float pitch) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,7 +19,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
+                // 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();
 | 
			
		||||
+                /* Take from BucketItem#emptyContents */
 | 
			
		||||
+                /* Taken from BucketItem#emptyContents */
 | 
			
		||||
+                boolean willEmptyBucketItem = dispensiblecontaineritem instanceof final BucketItem bucketItem && bucketItem.content instanceof net.minecraft.world.level.material.FlowingFluid && (iblockdata.isAir() || iblockdata.canBeReplaced(bucketItem.content) || (iblockdata.getBlock() instanceof LiquidBlockContainer liquidBlockContainer && liquidBlockContainer.canPlaceLiquid(null, worldserver, blockposition, iblockdata, bucketItem.content)));
 | 
			
		||||
+                if (willEmptyContentsSolidBucketItem || willEmptyBucketItem) {
 | 
			
		||||
+                // Paper end - correctly check if the bucket place will succeed
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,7 +52,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
+                    //} else if (data.getBlock() instanceof TrapDoorBlock) {
 | 
			
		||||
+                    //    this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
 | 
			
		||||
+                    //}
 | 
			
		||||
+                    // Paper end
 | 
			
		||||
+                    // Paper end - Don't resync blocks
 | 
			
		||||
                 } else if (!iblockdata.isAir()) {
 | 
			
		||||
                     iblockdata.attack(this.level, pos, this.player);
 | 
			
		||||
                     f = iblockdata.getDestroyProgress(this.player, this.player.level(), pos);
 | 
			
		||||
| 
						 | 
				
			
			@ -87,7 +87,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
                 if (isSwordNoBreak) {
 | 
			
		||||
                     return false;
 | 
			
		||||
                 }
 | 
			
		||||
+                // Paper start - Dont resync blocks
 | 
			
		||||
+                // Paper start - Don't resync blocks
 | 
			
		||||
                 // Let the client know the block still exists
 | 
			
		||||
-                this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
 | 
			
		||||
+                //this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
 | 
			
		||||
| 
						 | 
				
			
			@ -99,7 +99,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
+                //for (Direction dir : Direction.values()) {
 | 
			
		||||
+                //    this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos.relative(dir)));
 | 
			
		||||
+                //}
 | 
			
		||||
+                // Paper end
 | 
			
		||||
+                // Paper end - Don't resync blocks
 | 
			
		||||
 
 | 
			
		||||
                 // Update any tile entity data for this block
 | 
			
		||||
                 if (!captureSentBlockEntities) { // Paper - Toggle this location for capturing as this is used for api
 | 
			
		||||
| 
						 | 
				
			
			@ -112,17 +112,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
+                // Paper start - Don't resync blocks
 | 
			
		||||
+                // boolean bottom = iblockdata.getValue(DoorBlock.HALF) == DoubleBlockHalf.LOWER;
 | 
			
		||||
+                // player.connection.send(new ClientboundBlockUpdatePacket(world, bottom ? blockposition.above() : blockposition.below()));
 | 
			
		||||
+                // Paper end
 | 
			
		||||
+                // Paper end - Don't resync blocks
 | 
			
		||||
             } else if (iblockdata.getBlock() instanceof CakeBlock) {
 | 
			
		||||
                 player.getBukkitEntity().sendHealthUpdate(); // SPIGOT-1341 - reset health for cake
 | 
			
		||||
             } else if (this.interactItemStack.getItem() instanceof DoubleHighBlockItem) {
 | 
			
		||||
                 // send a correcting update to the client, as it already placed the upper half of the bisected item
 | 
			
		||||
-                player.connection.send(new ClientboundBlockUpdatePacket(world, blockposition.relative(hitResult.getDirection()).above()));
 | 
			
		||||
+                //player.connection.send(new ClientboundBlockUpdatePacket(world, blockposition.relative(hitResult.getDirection()).above())); // Paper - don't resync blocks
 | 
			
		||||
+                //player.connection.send(new ClientboundBlockUpdatePacket(world, blockposition.relative(hitResult.getDirection()).above())); // Paper - Don't resync blocks
 | 
			
		||||
 
 | 
			
		||||
                 // send a correcting update to the client for the block above as well, this because of replaceable blocks (such as grass, sea grass etc)
 | 
			
		||||
-                player.connection.send(new ClientboundBlockUpdatePacket(world, blockposition.above()));
 | 
			
		||||
+                //player.connection.send(new ClientboundBlockUpdatePacket(world, blockposition.above())); // Paper - don't resync blocks
 | 
			
		||||
+                //player.connection.send(new ClientboundBlockUpdatePacket(world, blockposition.above())); // Paper - Don't resync blocks
 | 
			
		||||
             // Paper start  - extend Player Interact cancellation // TODO: consider merging this into the extracted method
 | 
			
		||||
             } else if (iblockdata.getBlock() instanceof net.minecraft.world.level.block.StructureBlock) {
 | 
			
		||||
                 player.connection.send(new net.minecraft.network.protocol.game.ClientboundContainerClosePacket(this.player.containerMenu.containerId));
 | 
			
		||||
| 
						 | 
				
			
			@ -160,12 +160,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
-                    for (Direction dir : Direction.values()) {
 | 
			
		||||
-                        ((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, placedPos.relative(dir)));
 | 
			
		||||
-                    }
 | 
			
		||||
+                    // Paper start - don't resync blocks
 | 
			
		||||
+                    // Paper start - Don't resync blocks
 | 
			
		||||
+                    // BlockPos placedPos = ((CraftBlock) placeEvent.getBlock()).getPosition();
 | 
			
		||||
+                    // for (Direction dir : Direction.values()) {
 | 
			
		||||
+                    //     ((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, placedPos.relative(dir)));
 | 
			
		||||
+                    // }
 | 
			
		||||
+                    // Paper end
 | 
			
		||||
+                    // Paper end - Don't resync blocks
 | 
			
		||||
                     SignItem.openSign = null; // SPIGOT-6758 - Reset on early return
 | 
			
		||||
                 } else {
 | 
			
		||||
                     // Change the stack to its new contents if it hasn't been tampered with.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,8 +15,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
                 BlockEntity tileentity = iblockdata.hasBlockEntity() ? this.getBlockEntity(pos) : null;
 | 
			
		||||
 
 | 
			
		||||
-                Block.dropResources(iblockdata, this, pos, tileentity, breakingEntity, ItemStack.EMPTY);
 | 
			
		||||
+                Block.dropResources(iblockdata, this, pos, tileentity, breakingEntity, ItemStack.EMPTY, false); // Don't drop xp
 | 
			
		||||
+                iblockdata.getBlock().popExperience((ServerLevel) this, pos, xp, breakingEntity); // Paper - handle drop experience logic, custom amount
 | 
			
		||||
+                Block.dropResources(iblockdata, this, pos, tileentity, breakingEntity, ItemStack.EMPTY, false); // Paper - Properly handle xp dropping
 | 
			
		||||
+                iblockdata.getBlock().popExperience((ServerLevel) this, pos, xp, breakingEntity); // Paper - Properly handle xp dropping; custom amount
 | 
			
		||||
             }
 | 
			
		||||
 
 | 
			
		||||
             boolean flag1 = this.setBlock(pos, fluid.createLegacyBlock(), 3, maxUpdateDepth);
 | 
			
		||||
| 
						 | 
				
			
			@ -28,33 +28,33 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
             for (net.minecraft.world.item.ItemStack drop : net.minecraft.world.level.block.Block.getDrops(state, world.getMinecraftWorld(), pos, blockEntity)) {
 | 
			
		||||
                 items.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(drop));
 | 
			
		||||
             }
 | 
			
		||||
+            Block block = state.getBlock();
 | 
			
		||||
+            Block block = state.getBlock(); // Paper - Properly handle xp dropping
 | 
			
		||||
             io.papermc.paper.event.block.BlockBreakBlockEvent event = new io.papermc.paper.event.block.BlockBreakBlockEvent(org.bukkit.craftbukkit.block.CraftBlock.at(world, pos), org.bukkit.craftbukkit.block.CraftBlock.at(world, source), items);
 | 
			
		||||
+            event.setExpToDrop(block.getExpDrop(state, (ServerLevel) world, pos, net.minecraft.world.item.ItemStack.EMPTY, true));
 | 
			
		||||
+            event.setExpToDrop(block.getExpDrop(state, (ServerLevel) world, pos, net.minecraft.world.item.ItemStack.EMPTY, true)); // Paper - Properly handle xp dropping
 | 
			
		||||
             event.callEvent();
 | 
			
		||||
             for (var drop : event.getDrops()) {
 | 
			
		||||
                 popResource(world.getMinecraftWorld(), pos, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(drop));
 | 
			
		||||
             }
 | 
			
		||||
-            state.spawnAfterBreak(world.getMinecraftWorld(), pos, ItemStack.EMPTY, true);
 | 
			
		||||
+            state.spawnAfterBreak(world.getMinecraftWorld(), pos, ItemStack.EMPTY, false);
 | 
			
		||||
+            block.popExperience((ServerLevel) world, pos, event.getExpToDrop());
 | 
			
		||||
+            state.spawnAfterBreak(world.getMinecraftWorld(), pos, ItemStack.EMPTY, false); // Paper - Properly handle xp dropping
 | 
			
		||||
+            block.popExperience((ServerLevel) world, pos, event.getExpToDrop()); // Paper - Properly handle xp dropping
 | 
			
		||||
         }
 | 
			
		||||
         return true;
 | 
			
		||||
     }
 | 
			
		||||
     // Paper end
 | 
			
		||||
 
 | 
			
		||||
     public static void dropResources(BlockState state, Level world, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool) {
 | 
			
		||||
+    // Paper start
 | 
			
		||||
+    // Paper start - Properly handle xp dropping
 | 
			
		||||
+        dropResources(state, world, pos, blockEntity, entity, tool, true);
 | 
			
		||||
+    }
 | 
			
		||||
+    public static void dropResources(BlockState state, Level world, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool, boolean dropExperience) {
 | 
			
		||||
+    // Paper end
 | 
			
		||||
+    // Paper end - Properly handle xp dropping
 | 
			
		||||
         if (world instanceof ServerLevel) {
 | 
			
		||||
             Block.getDrops(state, (ServerLevel) world, pos, blockEntity, entity, tool).forEach((itemstack1) -> {
 | 
			
		||||
                 Block.popResource(world, pos, itemstack1);
 | 
			
		||||
             });
 | 
			
		||||
-            state.spawnAfterBreak((ServerLevel) world, pos, tool, true);
 | 
			
		||||
+            state.spawnAfterBreak((ServerLevel) world, pos, tool, dropExperience); // Paper
 | 
			
		||||
+            state.spawnAfterBreak((ServerLevel) world, pos, tool, dropExperience); // Paper - Properly handle xp dropping
 | 
			
		||||
         }
 | 
			
		||||
 
 | 
			
		||||
     }
 | 
			
		||||
| 
						 | 
				
			
			@ -63,7 +63,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
         player.causeFoodExhaustion(0.005F, org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.BLOCK_MINED); // CraftBukkit - EntityExhaustionEvent
 | 
			
		||||
         if (includeDrops) { // Paper
 | 
			
		||||
-        Block.dropResources(state, world, pos, blockEntity, player, tool);
 | 
			
		||||
+        Block.dropResources(state, world, pos, blockEntity, player, tool, dropExp); // Paper
 | 
			
		||||
+        Block.dropResources(state, world, pos, blockEntity, player, tool, dropExp); // Paper - Properly handle xp dropping
 | 
			
		||||
         } // Paper
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -75,7 +75,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
 
 | 
			
		||||
         public void spawnAfterBreak(ServerLevel world, BlockPos pos, ItemStack tool, boolean dropExperience) {
 | 
			
		||||
             this.getBlock().spawnAfterBreak(this.asState(), world, pos, tool, dropExperience);
 | 
			
		||||
+            if (dropExperience) {getBlock().popExperience(world, pos, this.getBlock().getExpDrop(asState(), world, pos, tool, true));} // Paper - spawn experience
 | 
			
		||||
+            if (dropExperience) {getBlock().popExperience(world, pos, this.getBlock().getExpDrop(asState(), world, pos, tool, true));} // Paper - Properly handle xp dropping
 | 
			
		||||
         }
 | 
			
		||||
 
 | 
			
		||||
         public List<ItemStack> getDrops(LootParams.Builder builder) {
 | 
			
		||||
| 
						 | 
				
			
			@ -88,7 +88,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
         // Modelled off EntityHuman#hasBlock
 | 
			
		||||
         if (block != Blocks.AIR && (item == null || !iblockdata.requiresCorrectToolForDrops() || nmsItem.isCorrectToolForDrops(iblockdata))) {
 | 
			
		||||
-            net.minecraft.world.level.block.Block.dropResources(iblockdata, this.world.getMinecraftWorld(), this.position, this.world.getBlockEntity(this.position), null, nmsItem);
 | 
			
		||||
+            net.minecraft.world.level.block.Block.dropResources(iblockdata, this.world.getMinecraftWorld(), this.position, this.world.getBlockEntity(this.position), null, nmsItem, false); // Paper
 | 
			
		||||
+            net.minecraft.world.level.block.Block.dropResources(iblockdata, this.world.getMinecraftWorld(), this.position, this.world.getBlockEntity(this.position), null, nmsItem, false); // Paper - Properly handle xp dropping
 | 
			
		||||
             // Paper start - improve Block#breanNaturally
 | 
			
		||||
             if (triggerEffect) {
 | 
			
		||||
                 if (iblockdata.getBlock() instanceof net.minecraft.world.level.block.BaseFireBlock) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,14 +17,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
             return;
 | 
			
		||||
         }
 | 
			
		||||
-        java.util.List<org.bukkit.inventory.ItemStack> loot = new java.util.ArrayList<org.bukkit.inventory.ItemStack>(this.getInventory().getContainerSize());
 | 
			
		||||
+        List<DefaultDrop> loot = new java.util.ArrayList<>(this.getInventory().getContainerSize()); // Paper
 | 
			
		||||
+        List<DefaultDrop> loot = new java.util.ArrayList<>(this.getInventory().getContainerSize()); // Paper - Restore vanilla drops behavior
 | 
			
		||||
         boolean keepInventory = this.level().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || this.isSpectator();
 | 
			
		||||
 
 | 
			
		||||
         if (!keepInventory) {
 | 
			
		||||
             for (ItemStack item : this.getInventory().getContents()) {
 | 
			
		||||
                 if (!item.isEmpty() && !EnchantmentHelper.hasVanishingCurse(item)) {
 | 
			
		||||
-                    loot.add(CraftItemStack.asCraftMirror(item));
 | 
			
		||||
+                    loot.add(new DefaultDrop(item, stack -> this.drop(stack, true, false, false))); // Paper - drop function taken from Inventory#dropAll (don't fire drop event)
 | 
			
		||||
+                    loot.add(new DefaultDrop(item, stack -> this.drop(stack, true, false, false))); // Paper - Restore vanilla drops behavior; drop function taken from Inventory#dropAll (don't fire drop event)
 | 
			
		||||
                 }
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
| 
						 | 
				
			
			@ -44,8 +44,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
     @Override
 | 
			
		||||
-    public ItemEntity drop(ItemStack stack, boolean throwRandomly, boolean retainOwnership) {
 | 
			
		||||
-        ItemEntity entityitem = super.drop(stack, throwRandomly, retainOwnership);
 | 
			
		||||
+    public ItemEntity drop(ItemStack stack, boolean throwRandomly, boolean retainOwnership, boolean callDropEvent) { // Paper - override method with most params
 | 
			
		||||
+        ItemEntity entityitem = super.drop(stack, throwRandomly, retainOwnership, callDropEvent); // Paper - override method with most params
 | 
			
		||||
+    public ItemEntity drop(ItemStack stack, boolean throwRandomly, boolean retainOwnership, boolean callDropEvent) { // Paper - Restore vanilla drops behavior; override method with most params
 | 
			
		||||
+        ItemEntity entityitem = super.drop(stack, throwRandomly, retainOwnership, callDropEvent); // Paper - Restore vanilla drops behavior; override method with most params
 | 
			
		||||
 
 | 
			
		||||
         if (entityitem == null) {
 | 
			
		||||
             return null;
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +57,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
 
 | 
			
		||||
     @Nullable
 | 
			
		||||
     public ItemEntity spawnAtLocation(ItemStack stack, float yOffset) {
 | 
			
		||||
+        // Paper start
 | 
			
		||||
+        // Paper start - Restore vanilla drops behavior
 | 
			
		||||
+        return this.spawnAtLocation(stack, yOffset, null);
 | 
			
		||||
+    }
 | 
			
		||||
+    public record DefaultDrop(Item item, org.bukkit.inventory.ItemStack stack, @Nullable java.util.function.Consumer<ItemStack> dropConsumer) {
 | 
			
		||||
| 
						 | 
				
			
			@ -75,7 +75,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
+    }
 | 
			
		||||
+    @Nullable
 | 
			
		||||
+    public ItemEntity spawnAtLocation(ItemStack stack, float yOffset, @Nullable java.util.function.Consumer<? super ItemEntity> delayedAddConsumer) {
 | 
			
		||||
+        // Paper end
 | 
			
		||||
+        // Paper end - Restore vanilla drops behavior
 | 
			
		||||
         if (stack.isEmpty()) {
 | 
			
		||||
             return null;
 | 
			
		||||
         } else if (this.level().isClientSide) {
 | 
			
		||||
| 
						 | 
				
			
			@ -84,14 +84,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
             // CraftBukkit start - Capture drops for death event
 | 
			
		||||
             if (this instanceof net.minecraft.world.entity.LivingEntity && !((net.minecraft.world.entity.LivingEntity) this).forceDrops) {
 | 
			
		||||
-                ((net.minecraft.world.entity.LivingEntity) this).drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack)); // Paper - mirror so we can destroy it later
 | 
			
		||||
+                // Paper start
 | 
			
		||||
+                // Paper start - Restore vanilla drops behavior
 | 
			
		||||
+                ((net.minecraft.world.entity.LivingEntity) this).drops.add(new net.minecraft.world.entity.Entity.DefaultDrop(stack, itemStack -> {
 | 
			
		||||
+                    ItemEntity itemEntity = new ItemEntity(this.level, this.getX(), this.getY() + (double) yOffset, this.getZ(), itemStack); // stack is copied before consumer
 | 
			
		||||
+                    itemEntity.setDefaultPickUpDelay();
 | 
			
		||||
+                    this.level.addFreshEntity(itemEntity);
 | 
			
		||||
+                    if (delayedAddConsumer != null) delayedAddConsumer.accept(itemEntity);
 | 
			
		||||
+                }));
 | 
			
		||||
+                // Paper end
 | 
			
		||||
+                // Paper end - Restore vanilla drops behavior
 | 
			
		||||
                 return null;
 | 
			
		||||
             }
 | 
			
		||||
             // CraftBukkit end
 | 
			
		||||
| 
						 | 
				
			
			@ -112,7 +112,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
     public int expToDrop;
 | 
			
		||||
     public boolean forceDrops;
 | 
			
		||||
-    public ArrayList<org.bukkit.inventory.ItemStack> drops = new ArrayList<org.bukkit.inventory.ItemStack>();
 | 
			
		||||
+    public ArrayList<DefaultDrop> drops = new ArrayList<>(); // Paper
 | 
			
		||||
+    public ArrayList<DefaultDrop> drops = new ArrayList<>(); // Paper - Restore vanilla drops behavior
 | 
			
		||||
     public final org.bukkit.craftbukkit.attribute.CraftAttributeMap craftAttributes;
 | 
			
		||||
     public boolean collides = true;
 | 
			
		||||
     public Set<UUID> collidableExemptions = new HashSet<>();
 | 
			
		||||
| 
						 | 
				
			
			@ -125,7 +125,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
     protected void dropCustomDeathLoot(DamageSource source, int lootingMultiplier, boolean allowDrops) {
 | 
			
		||||
         super.dropCustomDeathLoot(source, lootingMultiplier, allowDrops);
 | 
			
		||||
-        ItemEntity entityitem = this.spawnAtLocation((ItemLike) Items.NETHER_STAR);
 | 
			
		||||
+        ItemEntity entityitem = this.spawnAtLocation(new net.minecraft.world.item.ItemStack(Items.NETHER_STAR), 0, ItemEntity::setExtendedLifetime); // Paper - spawnAtLocation returns null so modify the item entity with a consumer
 | 
			
		||||
+        ItemEntity entityitem = this.spawnAtLocation(new net.minecraft.world.item.ItemStack(Items.NETHER_STAR), 0, ItemEntity::setExtendedLifetime); // Paper - Restore vanilla drops behavior; spawnAtLocation returns null so modify the item entity with a consumer
 | 
			
		||||
 
 | 
			
		||||
         if (entityitem != null) {
 | 
			
		||||
-            entityitem.setExtendedLifetime();
 | 
			
		||||
| 
						 | 
				
			
			@ -142,7 +142,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
         }
 | 
			
		||||
 
 | 
			
		||||
-        this.drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); // CraftBukkit - add to drops
 | 
			
		||||
+        this.drops.add(new DefaultDrop(itemstack, stack -> Block.popResource(this.level(), this.blockPosition(), stack))); // CraftBukkit - add to drops // Paper - spawn drops correctly
 | 
			
		||||
+        this.drops.add(new DefaultDrop(itemstack, stack -> Block.popResource(this.level(), this.blockPosition(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior
 | 
			
		||||
         return this.brokenByAnything(damageSource); // Paper
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -151,7 +151,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
             itemstack = (ItemStack) this.handItems.get(i);
 | 
			
		||||
             if (!itemstack.isEmpty()) {
 | 
			
		||||
-                this.drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)); // CraftBukkit - add to drops // Paper - mirror so we can destroy it later - though this call site was safe
 | 
			
		||||
+                this.drops.add(new DefaultDrop(itemstack, stack -> Block.popResource(this.level(), this.blockPosition().above(), stack))); // CraftBukkit - add to drops // Paper - mirror so we can destroy it later - though this call site was safe & spawn drops correctly
 | 
			
		||||
+                this.drops.add(new DefaultDrop(itemstack, stack -> Block.popResource(this.level(), this.blockPosition().above(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior; mirror so we can destroy it later - though this call site was safe & spawn drops correctly
 | 
			
		||||
                 this.handItems.set(i, ItemStack.EMPTY);
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
| 
						 | 
				
			
			@ -160,7 +160,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
             itemstack = (ItemStack) this.armorItems.get(i);
 | 
			
		||||
             if (!itemstack.isEmpty()) {
 | 
			
		||||
-                this.drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)); // CraftBukkit - add to drops // Paper - mirror so we can destroy it later - though this call site was safe
 | 
			
		||||
+                this.drops.add(new DefaultDrop(itemstack, stack -> Block.popResource(this.level(), this.blockPosition().above(), stack))); // CraftBukkit - add to drops // Paper - mirror so we can destroy it later - though this call site was safe & spawn drops correctly
 | 
			
		||||
+                this.drops.add(new DefaultDrop(itemstack, stack -> Block.popResource(this.level(), this.blockPosition().above(), stack))); // CraftBukkit - add to drops // Paper - Restore vanilla drops behavior; mirror so we can destroy it later - though this call site was safe & spawn drops correctly
 | 
			
		||||
                 this.armorItems.set(i, ItemStack.EMPTY);
 | 
			
		||||
             }
 | 
			
		||||
         }
 | 
			
		||||
| 
						 | 
				
			
			@ -173,11 +173,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
 
 | 
			
		||||
     public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim) {
 | 
			
		||||
-        return CraftEventFactory.callEntityDeathEvent(victim, new ArrayList<org.bukkit.inventory.ItemStack>(0));
 | 
			
		||||
+        return CraftEventFactory.callEntityDeathEvent(victim, new ArrayList<>(0)); // Paper
 | 
			
		||||
+        return CraftEventFactory.callEntityDeathEvent(victim, new ArrayList<>(0)); // Paper - Restore vanilla drops behavior
 | 
			
		||||
     }
 | 
			
		||||
 
 | 
			
		||||
-    public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, List<org.bukkit.inventory.ItemStack> drops) {
 | 
			
		||||
+    public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, List<Entity.DefaultDrop> drops) { // Paper
 | 
			
		||||
+    public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, List<Entity.DefaultDrop> drops) { // Paper - Restore vanilla drops behavior
 | 
			
		||||
         // Paper start
 | 
			
		||||
         return CraftEventFactory.callEntityDeathEvent(victim, drops, com.google.common.util.concurrent.Runnables.doNothing());
 | 
			
		||||
     }
 | 
			
		||||
| 
						 | 
				
			
			@ -190,7 +190,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
         // Paper end
 | 
			
		||||
         CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity();
 | 
			
		||||
-        EntityDeathEvent event = new EntityDeathEvent(entity, drops, victim.getExpReward());
 | 
			
		||||
+        EntityDeathEvent event = new EntityDeathEvent(entity, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward()); // Paper
 | 
			
		||||
+        EntityDeathEvent event = new EntityDeathEvent(entity, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward()); // Paper - Restore vanilla drops behavior
 | 
			
		||||
         populateFields(victim, event); // Paper - make cancellable
 | 
			
		||||
         CraftWorld world = (CraftWorld) entity.getWorld();
 | 
			
		||||
         Bukkit.getServer().getPluginManager().callEvent(event);
 | 
			
		||||
| 
						 | 
				
			
			@ -199,15 +199,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
         lootCheck.run(); // Paper - advancement triggers before destroying items
 | 
			
		||||
 
 | 
			
		||||
-        for (org.bukkit.inventory.ItemStack stack : event.getDrops()) {
 | 
			
		||||
+        // Paper start
 | 
			
		||||
+        // Paper start - Restore vanilla drops behavior
 | 
			
		||||
+        for (Entity.DefaultDrop drop : drops) {
 | 
			
		||||
+            if (drop == null) continue;;
 | 
			
		||||
+            final org.bukkit.inventory.ItemStack stack = drop.stack();
 | 
			
		||||
+            // Paper end
 | 
			
		||||
+            // Paper end - Restore vanilla drops behavior
 | 
			
		||||
             if (stack == null || stack.getType() == Material.AIR || stack.getAmount() == 0) continue;
 | 
			
		||||
 
 | 
			
		||||
-            world.dropItem(entity.getLocation(), stack); // Paper - note: dropItem already clones due to this being bukkit -> NMS
 | 
			
		||||
+            drop.runConsumer(world, entity.getLocation()); // Paper
 | 
			
		||||
+            drop.runConsumer(world, entity.getLocation()); // Paper - Restore vanilla drops behavior
 | 
			
		||||
             if (stack instanceof CraftItemStack) stack.setAmount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe, but don't nuke bukkit stacks of manually added items
 | 
			
		||||
         }
 | 
			
		||||
 
 | 
			
		||||
| 
						 | 
				
			
			@ -215,10 +215,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
     }
 | 
			
		||||
 
 | 
			
		||||
-    public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, List<org.bukkit.inventory.ItemStack> drops, net.kyori.adventure.text.Component deathMessage, boolean keepInventory) { // Paper - Adventure
 | 
			
		||||
+    public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, List<Entity.DefaultDrop> drops, net.kyori.adventure.text.Component deathMessage, boolean keepInventory) { // Paper - Adventure & improve drops
 | 
			
		||||
+    public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, List<Entity.DefaultDrop> drops, net.kyori.adventure.text.Component deathMessage, boolean keepInventory) { // Paper - Adventure & Restore vanilla drops behavior
 | 
			
		||||
         CraftPlayer entity = victim.getBukkitEntity();
 | 
			
		||||
-        PlayerDeathEvent event = new PlayerDeathEvent(entity, drops, victim.getExpReward(), 0, deathMessage);
 | 
			
		||||
+        PlayerDeathEvent event = new PlayerDeathEvent(entity, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(), 0, deathMessage); // Paper - improve drops
 | 
			
		||||
+        PlayerDeathEvent event = new PlayerDeathEvent(entity, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(), 0, deathMessage); // Paper - Restore vanilla drops behavior
 | 
			
		||||
         event.setKeepInventory(keepInventory);
 | 
			
		||||
         event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel
 | 
			
		||||
         populateFields(victim, event); // Paper - make cancellable
 | 
			
		||||
| 
						 | 
				
			
			@ -227,15 +227,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
         victim.newExp = event.getNewExp();
 | 
			
		||||
 
 | 
			
		||||
-        for (org.bukkit.inventory.ItemStack stack : event.getDrops()) {
 | 
			
		||||
+        // Paper start
 | 
			
		||||
+        // Paper start - Restore vanilla drops behavior
 | 
			
		||||
+        for (Entity.DefaultDrop drop : drops) {
 | 
			
		||||
+            if (drop == null) continue;
 | 
			
		||||
+            final org.bukkit.inventory.ItemStack stack = drop.stack();
 | 
			
		||||
+            // Paper end
 | 
			
		||||
+            // Paper end - Restore vanilla drops behavior
 | 
			
		||||
             if (stack == null || stack.getType() == Material.AIR) continue;
 | 
			
		||||
 
 | 
			
		||||
-            world.dropItem(entity.getLocation(), stack);
 | 
			
		||||
+            drop.runConsumer(world, entity.getLocation()); // Paper
 | 
			
		||||
+            drop.runConsumer(world, entity.getLocation()); // Paper - Restore vanilla drops behavior
 | 
			
		||||
         }
 | 
			
		||||
 
 | 
			
		||||
         return event;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
			
		|||
+            // Paper start - Validate resource location
 | 
			
		||||
+            ResourceLocation resourceLocation = ResourceLocation.tryParse(nbt.getString("Name"));
 | 
			
		||||
+            Optional<? extends Holder<Block>> optional = resourceLocation != null ? blockLookup.get(ResourceKey.create(Registries.BLOCK, resourceLocation)) : Optional.empty();
 | 
			
		||||
+            // Paper end
 | 
			
		||||
+            // Paper end - Validate resource location
 | 
			
		||||
             if (optional.isEmpty()) {
 | 
			
		||||
                 return Blocks.AIR.defaultBlockState();
 | 
			
		||||
             } else {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue