[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) {
 | 
					             if (this.random.nextFloat() < f) {
 | 
				
			||||||
-                player.getCooldowns().addCooldown(Items.SHIELD, 100);
 | 
					-                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);
 | 
					+                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;
 | 
					+                if (!shieldDisableEvent.callEvent()) return;
 | 
				
			||||||
+                player.getCooldowns().addCooldown(Items.SHIELD, shieldDisableEvent.getCooldown());
 | 
					+                player.getCooldowns().addCooldown(Items.SHIELD, shieldDisableEvent.getCooldown());
 | 
				
			||||||
+                // Paper end
 | 
					+                // Paper end - Add PlayerShieldDisableEvent
 | 
				
			||||||
                 this.level().broadcastEntityEvent(player, (byte) 30);
 | 
					                 this.level().broadcastEntityEvent(player, (byte) 30);
 | 
				
			||||||
             }
 | 
					             }
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
| 
						 | 
					@ -41,7 +41,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
         super.blockUsingShield(attacker);
 | 
					         super.blockUsingShield(attacker);
 | 
				
			||||||
         if (attacker.canDisableShield()) {
 | 
					         if (attacker.canDisableShield()) {
 | 
				
			||||||
-            this.disableShield(true);
 | 
					-            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);
 | 
					         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) {
 | 
					     public void disableShield(boolean sprinting) {
 | 
				
			||||||
+        // Paper start - add player shield disable event
 | 
					+        // Paper start - Add PlayerShieldDisableEvent
 | 
				
			||||||
+        disableShield(sprinting, null);
 | 
					+        disableShield(sprinting, null);
 | 
				
			||||||
+    }
 | 
					+    }
 | 
				
			||||||
+
 | 
					+
 | 
				
			||||||
+    public void disableShield(boolean sprinting, @Nullable LivingEntity attacker) {
 | 
					+    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;
 | 
					         float f = 0.25F + (float) EnchantmentHelper.getBlockEfficiency(this) * 0.05F;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
         if (sprinting) {
 | 
					         if (sprinting) {
 | 
				
			||||||
| 
						 | 
					@ -65,7 +65,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
         if (this.random.nextFloat() < f) {
 | 
					         if (this.random.nextFloat() < f) {
 | 
				
			||||||
-            this.getCooldowns().addCooldown(Items.SHIELD, 100);
 | 
					-            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;
 | 
					+            final org.bukkit.entity.Entity finalAttacker = attacker != null ? attacker.getBukkitEntity() : null;
 | 
				
			||||||
+            if (finalAttacker != 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);
 | 
					+                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 {
 | 
					+            } else {
 | 
				
			||||||
+                this.getCooldowns().addCooldown(Items.SHIELD, 100);
 | 
					+                this.getCooldowns().addCooldown(Items.SHIELD, 100);
 | 
				
			||||||
+            }
 | 
					+            }
 | 
				
			||||||
+            // Paper end - add player shield disable event
 | 
					+            // Paper end - Add PlayerShieldDisableEvent
 | 
				
			||||||
             this.stopUsingItem();
 | 
					             this.stopUsingItem();
 | 
				
			||||||
             this.level().broadcastEntityEvent(this, (byte) 30);
 | 
					             this.level().broadcastEntityEvent(this, (byte) 30);
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,15 +13,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
                 if (ishearable.readyForShearing()) {
 | 
					                 if (ishearable.readyForShearing()) {
 | 
				
			||||||
                     // CraftBukkit start
 | 
					                     // CraftBukkit start
 | 
				
			||||||
-                    if (CraftEventFactory.callBlockShearEntityEvent(entityliving, bukkitBlock, craftItem).isCancelled()) {
 | 
					-                    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());
 | 
					+                    org.bukkit.event.block.BlockShearEntityEvent event = CraftEventFactory.callBlockShearEntityEvent(entityliving, bukkitBlock, craftItem, ishearable.generateDefaultDrops());
 | 
				
			||||||
+                    if (event.isCancelled()) {
 | 
					+                    if (event.isCancelled()) {
 | 
				
			||||||
+                        // Paper end
 | 
					+                        // Paper end - Add drops to shear events
 | 
				
			||||||
                         continue;
 | 
					                         continue;
 | 
				
			||||||
                     }
 | 
					                     }
 | 
				
			||||||
                     // CraftBukkit end
 | 
					                     // CraftBukkit end
 | 
				
			||||||
-                    ishearable.shear(SoundSource.BLOCKS);
 | 
					-                    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);
 | 
					                     worldserver.gameEvent((Entity) null, GameEvent.SHEAR, blockposition);
 | 
				
			||||||
                     return true;
 | 
					                     return true;
 | 
				
			||||||
                 }
 | 
					                 }
 | 
				
			||||||
| 
						 | 
					@ -33,15 +33,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
 import net.minecraft.sounds.SoundSource;
 | 
					 import net.minecraft.sounds.SoundSource;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
 public interface Shearable {
 | 
					 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);
 | 
					     void shear(SoundSource shearedSoundCategory);
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
     boolean readyForShearing();
 | 
					     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() {
 | 
					+    default java.util.List<net.minecraft.world.item.ItemStack> generateDefaultDrops() {
 | 
				
			||||||
+        return java.util.Collections.emptyList();
 | 
					+        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
 | 
					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
 | 
					index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 | 
				
			||||||
| 
						 | 
					@ -65,7 +65,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
+            // Paper end - custom shear drops
 | 
					+            // Paper end - custom shear drops
 | 
				
			||||||
             // CraftBukkit end
 | 
					             // CraftBukkit end
 | 
				
			||||||
-            this.shear(SoundSource.PLAYERS);
 | 
					-            this.shear(SoundSource.PLAYERS);
 | 
				
			||||||
+            this.shear(SoundSource.PLAYERS, drops); // Paper
 | 
					+            this.shear(SoundSource.PLAYERS, drops); // Paper - custom shear drops
 | 
				
			||||||
             this.gameEvent(GameEvent.SHEAR, player);
 | 
					             this.gameEvent(GameEvent.SHEAR, player);
 | 
				
			||||||
             if (!this.level().isClientSide) {
 | 
					             if (!this.level().isClientSide) {
 | 
				
			||||||
                 itemstack.hurtAndBreak(1, player, (entityhuman1) -> {
 | 
					                 itemstack.hurtAndBreak(1, player, (entityhuman1) -> {
 | 
				
			||||||
| 
						 | 
					@ -106,7 +106,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
-                    }
 | 
					-                    }
 | 
				
			||||||
-                    this.level().addFreshEntity(entityitem);
 | 
					-                    this.level().addFreshEntity(entityitem);
 | 
				
			||||||
-                    // CraftBukkit end
 | 
					-                    // 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) {
 | 
					+                for (final ItemStack drop : drops) {
 | 
				
			||||||
+                    ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(1.0D), this.getZ(), drop);
 | 
					+                    ItemEntity entityitem = new ItemEntity(this.level(), this.getX(), this.getY(1.0D), this.getZ(), drop);
 | 
				
			||||||
+                    this.spawnAtLocation(entityitem);
 | 
					+                    this.spawnAtLocation(entityitem);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,7 +13,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
     public int getXpNeededForNextLevel() {
 | 
					     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);
 | 
				
			||||||
+        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
 | 
					     // 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) {
 | 
					     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
 | 
					+                // Paper start - correctly check if the bucket place will succeed
 | 
				
			||||||
+                /* Taken from SolidBucketItem#emptyContents */
 | 
					+                /* Taken from SolidBucketItem#emptyContents */
 | 
				
			||||||
+                boolean willEmptyContentsSolidBucketItem = dispensiblecontaineritem instanceof net.minecraft.world.item.SolidBucketItem && worldserver.isInWorldBounds(blockposition) && iblockdata.isAir();
 | 
					+                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)));
 | 
					+                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) {
 | 
					+                if (willEmptyContentsSolidBucketItem || willEmptyBucketItem) {
 | 
				
			||||||
+                // Paper end - correctly check if the bucket place will succeed
 | 
					+                // Paper end - correctly check if the bucket place will succeed
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -52,7 +52,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
+                    //} else if (data.getBlock() instanceof TrapDoorBlock) {
 | 
					+                    //} else if (data.getBlock() instanceof TrapDoorBlock) {
 | 
				
			||||||
+                    //    this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
 | 
					+                    //    this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos));
 | 
				
			||||||
+                    //}
 | 
					+                    //}
 | 
				
			||||||
+                    // Paper end
 | 
					+                    // Paper end - Don't resync blocks
 | 
				
			||||||
                 } else if (!iblockdata.isAir()) {
 | 
					                 } else if (!iblockdata.isAir()) {
 | 
				
			||||||
                     iblockdata.attack(this.level, pos, this.player);
 | 
					                     iblockdata.attack(this.level, pos, this.player);
 | 
				
			||||||
                     f = iblockdata.getDestroyProgress(this.player, this.player.level(), pos);
 | 
					                     f = iblockdata.getDestroyProgress(this.player, this.player.level(), pos);
 | 
				
			||||||
| 
						 | 
					@ -87,7 +87,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
                 if (isSwordNoBreak) {
 | 
					                 if (isSwordNoBreak) {
 | 
				
			||||||
                     return false;
 | 
					                     return false;
 | 
				
			||||||
                 }
 | 
					                 }
 | 
				
			||||||
+                // Paper start - Dont resync blocks
 | 
					+                // Paper start - Don't resync blocks
 | 
				
			||||||
                 // Let the client know the block still exists
 | 
					                 // 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));
 | 
				
			||||||
+                //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()) {
 | 
					+                //for (Direction dir : Direction.values()) {
 | 
				
			||||||
+                //    this.player.connection.send(new ClientboundBlockUpdatePacket(this.level, pos.relative(dir)));
 | 
					+                //    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
 | 
					                 // Update any tile entity data for this block
 | 
				
			||||||
                 if (!captureSentBlockEntities) { // Paper - Toggle this location for capturing as this is used for api
 | 
					                 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
 | 
					+                // Paper start - Don't resync blocks
 | 
				
			||||||
+                // boolean bottom = iblockdata.getValue(DoorBlock.HALF) == DoubleBlockHalf.LOWER;
 | 
					+                // boolean bottom = iblockdata.getValue(DoorBlock.HALF) == DoubleBlockHalf.LOWER;
 | 
				
			||||||
+                // player.connection.send(new ClientboundBlockUpdatePacket(world, bottom ? blockposition.above() : blockposition.below()));
 | 
					+                // 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) {
 | 
					             } else if (iblockdata.getBlock() instanceof CakeBlock) {
 | 
				
			||||||
                 player.getBukkitEntity().sendHealthUpdate(); // SPIGOT-1341 - reset health for cake
 | 
					                 player.getBukkitEntity().sendHealthUpdate(); // SPIGOT-1341 - reset health for cake
 | 
				
			||||||
             } else if (this.interactItemStack.getItem() instanceof DoubleHighBlockItem) {
 | 
					             } 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
 | 
					                 // 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()));
 | 
				
			||||||
+                //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)
 | 
					                 // 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()));
 | 
				
			||||||
+                //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
 | 
					             // 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) {
 | 
					             } 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));
 | 
					                 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()) {
 | 
					-                    for (Direction dir : Direction.values()) {
 | 
				
			||||||
-                        ((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, placedPos.relative(dir)));
 | 
					-                        ((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();
 | 
					+                    // BlockPos placedPos = ((CraftBlock) placeEvent.getBlock()).getPosition();
 | 
				
			||||||
+                    // for (Direction dir : Direction.values()) {
 | 
					+                    // for (Direction dir : Direction.values()) {
 | 
				
			||||||
+                    //     ((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, placedPos.relative(dir)));
 | 
					+                    //     ((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
 | 
					                     SignItem.openSign = null; // SPIGOT-6758 - Reset on early return
 | 
				
			||||||
                 } else {
 | 
					                 } else {
 | 
				
			||||||
                     // Change the stack to its new contents if it hasn't been tampered with.
 | 
					                     // 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;
 | 
					                 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);
 | 
				
			||||||
+                Block.dropResources(iblockdata, this, pos, tileentity, breakingEntity, ItemStack.EMPTY, false); // Don't drop xp
 | 
					+                Block.dropResources(iblockdata, this, pos, tileentity, breakingEntity, ItemStack.EMPTY, false); // Paper - Properly handle xp dropping
 | 
				
			||||||
+                iblockdata.getBlock().popExperience((ServerLevel) this, pos, xp, breakingEntity); // Paper - handle drop experience logic, custom amount
 | 
					+                iblockdata.getBlock().popExperience((ServerLevel) this, pos, xp, breakingEntity); // Paper - Properly handle xp dropping; custom amount
 | 
				
			||||||
             }
 | 
					             }
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
             boolean flag1 = this.setBlock(pos, fluid.createLegacyBlock(), 3, maxUpdateDepth);
 | 
					             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)) {
 | 
					             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));
 | 
					                 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);
 | 
					             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();
 | 
					             event.callEvent();
 | 
				
			||||||
             for (var drop : event.getDrops()) {
 | 
					             for (var drop : event.getDrops()) {
 | 
				
			||||||
                 popResource(world.getMinecraftWorld(), pos, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(drop));
 | 
					                 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, true);
 | 
				
			||||||
+            state.spawnAfterBreak(world.getMinecraftWorld(), pos, ItemStack.EMPTY, false);
 | 
					+            state.spawnAfterBreak(world.getMinecraftWorld(), pos, ItemStack.EMPTY, false); // Paper - Properly handle xp dropping
 | 
				
			||||||
+            block.popExperience((ServerLevel) world, pos, event.getExpToDrop());
 | 
					+            block.popExperience((ServerLevel) world, pos, event.getExpToDrop()); // Paper - Properly handle xp dropping
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
         return true;
 | 
					         return true;
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
     // Paper end
 | 
					     // Paper end
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
     public static void dropResources(BlockState state, Level world, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool) {
 | 
					     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);
 | 
					+        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) {
 | 
					+    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) {
 | 
					         if (world instanceof ServerLevel) {
 | 
				
			||||||
             Block.getDrops(state, (ServerLevel) world, pos, blockEntity, entity, tool).forEach((itemstack1) -> {
 | 
					             Block.getDrops(state, (ServerLevel) world, pos, blockEntity, entity, tool).forEach((itemstack1) -> {
 | 
				
			||||||
                 Block.popResource(world, pos, itemstack1);
 | 
					                 Block.popResource(world, pos, itemstack1);
 | 
				
			||||||
             });
 | 
					             });
 | 
				
			||||||
-            state.spawnAfterBreak((ServerLevel) world, pos, tool, true);
 | 
					-            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
 | 
					         player.causeFoodExhaustion(0.005F, org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.BLOCK_MINED); // CraftBukkit - EntityExhaustionEvent
 | 
				
			||||||
         if (includeDrops) { // Paper
 | 
					         if (includeDrops) { // Paper
 | 
				
			||||||
-        Block.dropResources(state, world, pos, blockEntity, player, tool);
 | 
					-        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
 | 
					         } // Paper
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
| 
						 | 
					@ -75,7 +75,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
         public void spawnAfterBreak(ServerLevel world, BlockPos pos, ItemStack tool, boolean dropExperience) {
 | 
					         public void spawnAfterBreak(ServerLevel world, BlockPos pos, ItemStack tool, boolean dropExperience) {
 | 
				
			||||||
             this.getBlock().spawnAfterBreak(this.asState(), world, pos, tool, 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) {
 | 
					         public List<ItemStack> getDrops(LootParams.Builder builder) {
 | 
				
			||||||
| 
						 | 
					@ -88,7 +88,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
         // Modelled off EntityHuman#hasBlock
 | 
					         // Modelled off EntityHuman#hasBlock
 | 
				
			||||||
         if (block != Blocks.AIR && (item == null || !iblockdata.requiresCorrectToolForDrops() || nmsItem.isCorrectToolForDrops(iblockdata))) {
 | 
					         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);
 | 
				
			||||||
+            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
 | 
					             // Paper start - improve Block#breanNaturally
 | 
				
			||||||
             if (triggerEffect) {
 | 
					             if (triggerEffect) {
 | 
				
			||||||
                 if (iblockdata.getBlock() instanceof net.minecraft.world.level.block.BaseFireBlock) {
 | 
					                 if (iblockdata.getBlock() instanceof net.minecraft.world.level.block.BaseFireBlock) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,14 +17,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
             return;
 | 
					             return;
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
-        java.util.List<org.bukkit.inventory.ItemStack> loot = new java.util.ArrayList<org.bukkit.inventory.ItemStack>(this.getInventory().getContainerSize());
 | 
					-        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();
 | 
					         boolean keepInventory = this.level().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || this.isSpectator();
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
         if (!keepInventory) {
 | 
					         if (!keepInventory) {
 | 
				
			||||||
             for (ItemStack item : this.getInventory().getContents()) {
 | 
					             for (ItemStack item : this.getInventory().getContents()) {
 | 
				
			||||||
                 if (!item.isEmpty() && !EnchantmentHelper.hasVanishingCurse(item)) {
 | 
					                 if (!item.isEmpty() && !EnchantmentHelper.hasVanishingCurse(item)) {
 | 
				
			||||||
-                    loot.add(CraftItemStack.asCraftMirror(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
 | 
					     @Override
 | 
				
			||||||
-    public ItemEntity drop(ItemStack stack, boolean throwRandomly, boolean retainOwnership) {
 | 
					-    public ItemEntity drop(ItemStack stack, boolean throwRandomly, boolean retainOwnership) {
 | 
				
			||||||
-        ItemEntity entityitem = super.drop(stack, throwRandomly, 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
 | 
					+    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 - 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) {
 | 
					         if (entityitem == null) {
 | 
				
			||||||
             return null;
 | 
					             return null;
 | 
				
			||||||
| 
						 | 
					@ -57,7 +57,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
     @Nullable
 | 
					     @Nullable
 | 
				
			||||||
     public ItemEntity spawnAtLocation(ItemStack stack, float yOffset) {
 | 
					     public ItemEntity spawnAtLocation(ItemStack stack, float yOffset) {
 | 
				
			||||||
+        // Paper start
 | 
					+        // Paper start - Restore vanilla drops behavior
 | 
				
			||||||
+        return this.spawnAtLocation(stack, yOffset, null);
 | 
					+        return this.spawnAtLocation(stack, yOffset, null);
 | 
				
			||||||
+    }
 | 
					+    }
 | 
				
			||||||
+    public record DefaultDrop(Item item, org.bukkit.inventory.ItemStack stack, @Nullable java.util.function.Consumer<ItemStack> dropConsumer) {
 | 
					+    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
 | 
					+    @Nullable
 | 
				
			||||||
+    public ItemEntity spawnAtLocation(ItemStack stack, float yOffset, @Nullable java.util.function.Consumer<? super ItemEntity> delayedAddConsumer) {
 | 
					+    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()) {
 | 
					         if (stack.isEmpty()) {
 | 
				
			||||||
             return null;
 | 
					             return null;
 | 
				
			||||||
         } else if (this.level().isClientSide) {
 | 
					         } else if (this.level().isClientSide) {
 | 
				
			||||||
| 
						 | 
					@ -84,14 +84,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
             // CraftBukkit start - Capture drops for death event
 | 
					             // CraftBukkit start - Capture drops for death event
 | 
				
			||||||
             if (this instanceof net.minecraft.world.entity.LivingEntity && !((net.minecraft.world.entity.LivingEntity) this).forceDrops) {
 | 
					             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
 | 
					-                ((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 -> {
 | 
					+                ((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 itemEntity = new ItemEntity(this.level, this.getX(), this.getY() + (double) yOffset, this.getZ(), itemStack); // stack is copied before consumer
 | 
				
			||||||
+                    itemEntity.setDefaultPickUpDelay();
 | 
					+                    itemEntity.setDefaultPickUpDelay();
 | 
				
			||||||
+                    this.level.addFreshEntity(itemEntity);
 | 
					+                    this.level.addFreshEntity(itemEntity);
 | 
				
			||||||
+                    if (delayedAddConsumer != null) delayedAddConsumer.accept(itemEntity);
 | 
					+                    if (delayedAddConsumer != null) delayedAddConsumer.accept(itemEntity);
 | 
				
			||||||
+                }));
 | 
					+                }));
 | 
				
			||||||
+                // Paper end
 | 
					+                // Paper end - Restore vanilla drops behavior
 | 
				
			||||||
                 return null;
 | 
					                 return null;
 | 
				
			||||||
             }
 | 
					             }
 | 
				
			||||||
             // CraftBukkit end
 | 
					             // CraftBukkit end
 | 
				
			||||||
| 
						 | 
					@ -112,7 +112,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
     public int expToDrop;
 | 
					     public int expToDrop;
 | 
				
			||||||
     public boolean forceDrops;
 | 
					     public boolean forceDrops;
 | 
				
			||||||
-    public ArrayList<org.bukkit.inventory.ItemStack> drops = new ArrayList<org.bukkit.inventory.ItemStack>();
 | 
					-    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 final org.bukkit.craftbukkit.attribute.CraftAttributeMap craftAttributes;
 | 
				
			||||||
     public boolean collides = true;
 | 
					     public boolean collides = true;
 | 
				
			||||||
     public Set<UUID> collidableExemptions = new HashSet<>();
 | 
					     public Set<UUID> collidableExemptions = new HashSet<>();
 | 
				
			||||||
| 
						 | 
					@ -125,7 +125,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
     protected void dropCustomDeathLoot(DamageSource source, int lootingMultiplier, boolean allowDrops) {
 | 
					     protected void dropCustomDeathLoot(DamageSource source, int lootingMultiplier, boolean allowDrops) {
 | 
				
			||||||
         super.dropCustomDeathLoot(source, lootingMultiplier, allowDrops);
 | 
					         super.dropCustomDeathLoot(source, lootingMultiplier, allowDrops);
 | 
				
			||||||
-        ItemEntity entityitem = this.spawnAtLocation((ItemLike) Items.NETHER_STAR);
 | 
					-        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) {
 | 
					         if (entityitem != null) {
 | 
				
			||||||
-            entityitem.setExtendedLifetime();
 | 
					-            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(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
 | 
					         return this.brokenByAnything(damageSource); // Paper
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
| 
						 | 
					@ -151,7 +151,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
             itemstack = (ItemStack) this.handItems.get(i);
 | 
					             itemstack = (ItemStack) this.handItems.get(i);
 | 
				
			||||||
             if (!itemstack.isEmpty()) {
 | 
					             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(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);
 | 
					                 this.handItems.set(i, ItemStack.EMPTY);
 | 
				
			||||||
             }
 | 
					             }
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
| 
						 | 
					@ -160,7 +160,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
             itemstack = (ItemStack) this.armorItems.get(i);
 | 
					             itemstack = (ItemStack) this.armorItems.get(i);
 | 
				
			||||||
             if (!itemstack.isEmpty()) {
 | 
					             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(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);
 | 
					                 this.armorItems.set(i, ItemStack.EMPTY);
 | 
				
			||||||
             }
 | 
					             }
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
| 
						 | 
					@ -173,11 +173,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
     public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim) {
 | 
					     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<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<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
 | 
					         // Paper start
 | 
				
			||||||
         return CraftEventFactory.callEntityDeathEvent(victim, drops, com.google.common.util.concurrent.Runnables.doNothing());
 | 
					         return CraftEventFactory.callEntityDeathEvent(victim, drops, com.google.common.util.concurrent.Runnables.doNothing());
 | 
				
			||||||
     }
 | 
					     }
 | 
				
			||||||
| 
						 | 
					@ -190,7 +190,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
         // Paper end
 | 
					         // Paper end
 | 
				
			||||||
         CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity();
 | 
					         CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity();
 | 
				
			||||||
-        EntityDeathEvent event = new EntityDeathEvent(entity, drops, victim.getExpReward());
 | 
					-        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
 | 
					         populateFields(victim, event); // Paper - make cancellable
 | 
				
			||||||
         CraftWorld world = (CraftWorld) entity.getWorld();
 | 
					         CraftWorld world = (CraftWorld) entity.getWorld();
 | 
				
			||||||
         Bukkit.getServer().getPluginManager().callEvent(event);
 | 
					         Bukkit.getServer().getPluginManager().callEvent(event);
 | 
				
			||||||
| 
						 | 
					@ -199,15 +199,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
         lootCheck.run(); // Paper - advancement triggers before destroying items
 | 
					         lootCheck.run(); // Paper - advancement triggers before destroying items
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
-        for (org.bukkit.inventory.ItemStack stack : event.getDrops()) {
 | 
					-        for (org.bukkit.inventory.ItemStack stack : event.getDrops()) {
 | 
				
			||||||
+        // Paper start
 | 
					+        // Paper start - Restore vanilla drops behavior
 | 
				
			||||||
+        for (Entity.DefaultDrop drop : drops) {
 | 
					+        for (Entity.DefaultDrop drop : drops) {
 | 
				
			||||||
+            if (drop == null) continue;;
 | 
					+            if (drop == null) continue;;
 | 
				
			||||||
+            final org.bukkit.inventory.ItemStack stack = drop.stack();
 | 
					+            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;
 | 
					             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
 | 
					-            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
 | 
					             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<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();
 | 
					         CraftPlayer entity = victim.getBukkitEntity();
 | 
				
			||||||
-        PlayerDeathEvent event = new PlayerDeathEvent(entity, drops, victim.getExpReward(), 0, deathMessage);
 | 
					-        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.setKeepInventory(keepInventory);
 | 
				
			||||||
         event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel
 | 
					         event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel
 | 
				
			||||||
         populateFields(victim, event); // Paper - make cancellable
 | 
					         populateFields(victim, event); // Paper - make cancellable
 | 
				
			||||||
| 
						 | 
					@ -227,15 +227,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
         victim.newExp = event.getNewExp();
 | 
					         victim.newExp = event.getNewExp();
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
-        for (org.bukkit.inventory.ItemStack stack : event.getDrops()) {
 | 
					-        for (org.bukkit.inventory.ItemStack stack : event.getDrops()) {
 | 
				
			||||||
+        // Paper start
 | 
					+        // Paper start - Restore vanilla drops behavior
 | 
				
			||||||
+        for (Entity.DefaultDrop drop : drops) {
 | 
					+        for (Entity.DefaultDrop drop : drops) {
 | 
				
			||||||
+            if (drop == null) continue;
 | 
					+            if (drop == null) continue;
 | 
				
			||||||
+            final org.bukkit.inventory.ItemStack stack = drop.stack();
 | 
					+            final org.bukkit.inventory.ItemStack stack = drop.stack();
 | 
				
			||||||
+            // Paper end
 | 
					+            // Paper end - Restore vanilla drops behavior
 | 
				
			||||||
             if (stack == null || stack.getType() == Material.AIR) continue;
 | 
					             if (stack == null || stack.getType() == Material.AIR) continue;
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
-            world.dropItem(entity.getLocation(), stack);
 | 
					-            world.dropItem(entity.getLocation(), stack);
 | 
				
			||||||
+            drop.runConsumer(world, entity.getLocation()); // Paper
 | 
					+            drop.runConsumer(world, entity.getLocation()); // Paper - Restore vanilla drops behavior
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
         return event;
 | 
					         return event;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 | 
				
			||||||
+            // Paper start - Validate resource location
 | 
					+            // Paper start - Validate resource location
 | 
				
			||||||
+            ResourceLocation resourceLocation = ResourceLocation.tryParse(nbt.getString("Name"));
 | 
					+            ResourceLocation resourceLocation = ResourceLocation.tryParse(nbt.getString("Name"));
 | 
				
			||||||
+            Optional<? extends Holder<Block>> optional = resourceLocation != null ? blockLookup.get(ResourceKey.create(Registries.BLOCK, resourceLocation)) : Optional.empty();
 | 
					+            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()) {
 | 
					             if (optional.isEmpty()) {
 | 
				
			||||||
                 return Blocks.AIR.defaultBlockState();
 | 
					                 return Blocks.AIR.defaultBlockState();
 | 
				
			||||||
             } else {
 | 
					             } else {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue