| 
									
										
										
										
											2024-01-04 15:18:59 -05:00
										 |  |  | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | 
					
						
							|  |  |  | From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> | 
					
						
							|  |  |  | Date: Sat, 30 Dec 2023 15:00:06 -0500 | 
					
						
							|  |  |  | Subject: [PATCH] Properly handle experience dropping on block break | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This causes spawnAfterBreak to spawn xp by default, removing the need to manually add xp wherever this method is used. | 
					
						
							|  |  |  | For classes that use custom xp amounts, they can drop the resources with disabling | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
 | 
					
						
							| 
									
										
										
										
											2024-01-24 22:13:08 +01:00
										 |  |  | index 5d675d4a5380c3a67e5a320cdb7bffe8a823d855..aa5437860c0471dcc0e6b01cb97e1cbadb752fab 100644
 | 
					
						
							| 
									
										
										
										
											2024-01-04 15:18:59 -05:00
										 |  |  | --- a/src/main/java/net/minecraft/world/level/Level.java
 | 
					
						
							|  |  |  | +++ b/src/main/java/net/minecraft/world/level/Level.java
 | 
					
						
							| 
									
										
										
										
											2024-01-24 22:13:08 +01:00
										 |  |  | @@ -630,7 +630,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
 | 
					
						
							| 
									
										
										
										
											2024-01-04 15:18:59 -05:00
										 |  |  |              if (drop) { | 
					
						
							|  |  |  |                  BlockEntity tileentity = iblockdata.hasBlockEntity() ? this.getBlockEntity(pos) : null; | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | -                Block.dropResources(iblockdata, this, pos, tileentity, breakingEntity, ItemStack.EMPTY);
 | 
					
						
							| 
									
										
										
										
											2024-01-13 16:35:59 +01:00
										 |  |  | +                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
 | 
					
						
							| 
									
										
										
										
											2024-01-04 15:18:59 -05:00
										 |  |  |              } | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  |              boolean flag1 = this.setBlock(pos, fluid.createLegacyBlock(), 3, maxUpdateDepth); | 
					
						
							|  |  |  | diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java
 | 
					
						
							| 
									
										
										
										
											2024-01-23 12:06:27 +01:00
										 |  |  | index 660ede322b4f4ccad241820d8ffd4540ebb18fbc..63217d3db86b467f3358730eb8b9b3c941558bab 100644
 | 
					
						
							| 
									
										
										
										
											2024-01-04 15:18:59 -05:00
										 |  |  | --- a/src/main/java/net/minecraft/world/level/block/Block.java
 | 
					
						
							|  |  |  | +++ b/src/main/java/net/minecraft/world/level/block/Block.java
 | 
					
						
							| 
									
										
										
										
											2024-01-23 12:06:27 +01:00
										 |  |  | @@ -320,23 +320,31 @@ public class Block extends BlockBehaviour implements ItemLike {
 | 
					
						
							| 
									
										
										
										
											2024-01-04 15:18:59 -05:00
										 |  |  |              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)); | 
					
						
							|  |  |  |              } | 
					
						
							| 
									
										
										
										
											2024-01-13 16:35:59 +01:00
										 |  |  | +            Block block = state.getBlock(); // Paper - Properly handle xp dropping
 | 
					
						
							| 
									
										
										
										
											2024-01-04 15:18:59 -05:00
										 |  |  |              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); | 
					
						
							| 
									
										
										
										
											2024-01-13 16:35:59 +01:00
										 |  |  | +            event.setExpToDrop(block.getExpDrop(state, (ServerLevel) world, pos, net.minecraft.world.item.ItemStack.EMPTY, true)); // Paper - Properly handle xp dropping
 | 
					
						
							| 
									
										
										
										
											2024-01-04 15:18:59 -05:00
										 |  |  |              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);
 | 
					
						
							| 
									
										
										
										
											2024-01-13 16:35:59 +01:00
										 |  |  | +            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
 | 
					
						
							| 
									
										
										
										
											2024-01-04 15:18:59 -05:00
										 |  |  |          } | 
					
						
							|  |  |  |          return true; | 
					
						
							|  |  |  |      } | 
					
						
							| 
									
										
										
										
											2024-01-19 13:22:30 +01:00
										 |  |  |      // Paper end - Add BlockBreakBlockEvent | 
					
						
							| 
									
										
										
										
											2024-01-04 15:18:59 -05:00
										 |  |  |   | 
					
						
							|  |  |  |      public static void dropResources(BlockState state, Level world, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool) { | 
					
						
							| 
									
										
										
										
											2024-01-13 16:35:59 +01:00
										 |  |  | +    // Paper start - Properly handle xp dropping
 | 
					
						
							| 
									
										
										
										
											2024-01-04 15:18:59 -05:00
										 |  |  | +        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) {
 | 
					
						
							| 
									
										
										
										
											2024-01-13 16:35:59 +01:00
										 |  |  | +    // Paper end - Properly handle xp dropping
 | 
					
						
							| 
									
										
										
										
											2024-01-04 15:18:59 -05:00
										 |  |  |          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);
 | 
					
						
							| 
									
										
										
										
											2024-01-13 16:35:59 +01:00
										 |  |  | +            state.spawnAfterBreak((ServerLevel) world, pos, tool, dropExperience); // Paper - Properly handle xp dropping
 | 
					
						
							| 
									
										
										
										
											2024-01-04 15:18:59 -05:00
										 |  |  |          } | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  |      } | 
					
						
							| 
									
										
										
										
											2024-01-23 12:06:27 +01:00
										 |  |  | @@ -420,7 +428,7 @@ public class Block extends BlockBehaviour implements ItemLike {
 | 
					
						
							| 
									
										
										
										
											2024-01-04 15:18:59 -05:00
										 |  |  |          player.awardStat(Stats.BLOCK_MINED.get(this)); | 
					
						
							|  |  |  |          player.causeFoodExhaustion(0.005F, org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.BLOCK_MINED); // CraftBukkit - EntityExhaustionEvent | 
					
						
							| 
									
										
										
										
											2024-01-14 16:31:39 +01:00
										 |  |  |          if (includeDrops) { // Paper - fix drops not preventing stats/food exhaustion | 
					
						
							| 
									
										
										
										
											2024-01-04 15:18:59 -05:00
										 |  |  | -        Block.dropResources(state, world, pos, blockEntity, player, tool);
 | 
					
						
							| 
									
										
										
										
											2024-01-13 16:35:59 +01:00
										 |  |  | +        Block.dropResources(state, world, pos, blockEntity, player, tool, dropExp); // Paper - Properly handle xp dropping
 | 
					
						
							| 
									
										
										
										
											2024-01-14 16:31:39 +01:00
										 |  |  |          } // Paper - fix drops not preventing stats/food exhaustion | 
					
						
							| 
									
										
										
										
											2024-01-04 15:18:59 -05:00
										 |  |  |      } | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
 | 
					
						
							| 
									
										
										
										
											2024-01-25 10:54:46 +01:00
										 |  |  | index ab174986ad558916427a70f59c6907f17b0d01df..20de3aeb4991dcfd0bbf813075a4c76e277b7598 100644
 | 
					
						
							| 
									
										
										
										
											2024-01-04 15:18:59 -05:00
										 |  |  | --- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
 | 
					
						
							|  |  |  | +++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
 | 
					
						
							| 
									
										
										
										
											2024-01-25 10:54:46 +01:00
										 |  |  | @@ -1183,6 +1183,7 @@ public abstract class BlockBehaviour implements FeatureElement {
 | 
					
						
							| 
									
										
										
										
											2024-01-04 15:18:59 -05:00
										 |  |  |   | 
					
						
							|  |  |  |          public void spawnAfterBreak(ServerLevel world, BlockPos pos, ItemStack tool, boolean dropExperience) { | 
					
						
							|  |  |  |              this.getBlock().spawnAfterBreak(this.asState(), world, pos, tool, dropExperience); | 
					
						
							| 
									
										
										
										
											2024-01-13 16:35:59 +01:00
										 |  |  | +            if (dropExperience) {getBlock().popExperience(world, pos, this.getBlock().getExpDrop(asState(), world, pos, tool, true));} // Paper - Properly handle xp dropping
 | 
					
						
							| 
									
										
										
										
											2024-01-04 15:18:59 -05:00
										 |  |  |          } | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  |          public List<ItemStack> getDrops(LootParams.Builder builder) { | 
					
						
							|  |  |  | diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
 | 
					
						
							| 
									
										
										
										
											2024-01-13 16:35:59 +01:00
										 |  |  | index e5506a7d074a9f89d41f4d5d7549a458779bef20..4b42ef2a876ea210d948238e63fd7a2b7035bb5b 100644
 | 
					
						
							| 
									
										
										
										
											2024-01-04 15:18:59 -05:00
										 |  |  | --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
 | 
					
						
							|  |  |  | +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
 | 
					
						
							|  |  |  | @@ -503,7 +503,7 @@ public class CraftBlock implements Block {
 | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  |          // 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);
 | 
					
						
							| 
									
										
										
										
											2024-01-13 16:35:59 +01:00
										 |  |  | +            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
 | 
					
						
							| 
									
										
										
										
											2024-01-04 15:18:59 -05:00
										 |  |  |              // Paper start - improve Block#breanNaturally | 
					
						
							|  |  |  |              if (triggerEffect) { | 
					
						
							|  |  |  |                  if (iblockdata.getBlock() instanceof net.minecraft.world.level.block.BaseFireBlock) { |