aboutsummaryrefslogtreecommitdiffhomepage
path: root/patches/server/0978-Properly-handle-experience-dropping-on-block-break.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/server/0978-Properly-handle-experience-dropping-on-block-break.patch')
-rw-r--r--patches/server/0978-Properly-handle-experience-dropping-on-block-break.patch94
1 files changed, 94 insertions, 0 deletions
diff --git a/patches/server/0978-Properly-handle-experience-dropping-on-block-break.patch b/patches/server/0978-Properly-handle-experience-dropping-on-block-break.patch
new file mode 100644
index 0000000000..f7d4494ec0
--- /dev/null
+++ b/patches/server/0978-Properly-handle-experience-dropping-on-block-break.patch
@@ -0,0 +1,94 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Owen1212055 <[email protected]>
+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
+index 6d98b910b1079f1b4a95c430e5500d55fbc68ec2..c0ae70e3490b56aaa464460e3c41175b27136f6b 100644
+--- a/src/main/java/net/minecraft/world/level/Level.java
++++ b/src/main/java/net/minecraft/world/level/Level.java
+@@ -625,7 +625,8 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
+ if (drop) {
+ 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); // 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);
+diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java
+index c4bf01177b2dfcc88f6992dc85de216d448a79f8..6896d46fce2e466ebee23ac2dc00312ec1beefdb 100644
+--- a/src/main/java/net/minecraft/world/level/block/Block.java
++++ b/src/main/java/net/minecraft/world/level/block/Block.java
+@@ -321,23 +321,31 @@ public class Block extends BlockBehaviour implements ItemLike {
+ for (ItemStack drop : Block.getDrops(state, serverLevel, pos, blockEntity)) {
+ items.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(drop));
+ }
++ 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(levelAccessor, pos), org.bukkit.craftbukkit.block.CraftBlock.at(levelAccessor, source), items);
++ event.setExpToDrop(block.getExpDrop(state, serverLevel, pos, net.minecraft.world.item.ItemStack.EMPTY, true)); // Paper - Properly handle xp dropping
+ event.callEvent();
+ for (org.bukkit.inventory.ItemStack drop : event.getDrops()) {
+ popResource(serverLevel, pos, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(drop));
+ }
+- state.spawnAfterBreak(serverLevel, pos, ItemStack.EMPTY, true);
++ state.spawnAfterBreak(serverLevel, pos, ItemStack.EMPTY, false); // Paper - Properly handle xp dropping
++ block.popExperience(serverLevel, pos, event.getExpToDrop()); // Paper - Properly handle xp dropping
+ }
+ return true;
+ }
+ // Paper end - Add BlockBreakBlockEvent
+
+ public static void dropResources(BlockState state, Level world, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool) {
++ // 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 - 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 - Properly handle xp dropping
+ }
+
+ }
+@@ -421,7 +429,7 @@ public class Block extends BlockBehaviour implements ItemLike {
+ player.awardStat(Stats.BLOCK_MINED.get(this));
+ player.causeFoodExhaustion(0.005F, org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.BLOCK_MINED); // CraftBukkit - EntityExhaustionEvent
+ if (includeDrops) { // Paper - fix drops not preventing stats/food exhaustion
+- Block.dropResources(state, world, pos, blockEntity, player, tool);
++ Block.dropResources(state, world, pos, blockEntity, player, tool, dropExp); // Paper - Properly handle xp dropping
+ } // Paper - fix drops not preventing stats/food exhaustion
+ }
+
+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
+index e57e3a26b0fb856e1ab693df5783fe8b9bee9719..64300077fce6eb28b6bddd42b3467eaa4c80c9f5 100644
+--- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
++++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
+@@ -1183,6 +1183,7 @@ public abstract class BlockBehaviour implements FeatureElement {
+
+ 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 - Properly handle xp dropping
+ }
+
+ 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
+index e5506a7d074a9f89d41f4d5d7549a458779bef20..4b42ef2a876ea210d948238e63fd7a2b7035bb5b 100644
+--- 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);
++ 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) {