summaryrefslogtreecommitdiffhomepage
path: root/patches/server/0349-Improve-Block-breakNaturally-API.patch
blob: 0e3a106ed7015763c0bfa45f0036546b13afc988 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Thu, 2 Jan 2020 12:25:07 -0600
Subject: [PATCH] Improve Block#breakNaturally API

Adds bool parameter to play world effect on block break

Adds bool parameter to drop xp from blocks

Fixes fluid-logged blocks not leaving fluid behind if
broken

Handles special cases for ice and turtle eggs

== AT ==
public net.minecraft.world.level.block.TurtleEggBlock decreaseEggs(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;)V

Co-authored-by: William Blake Galbreath <Blake.Galbreath@GMail.com>

diff --git a/src/main/java/net/minecraft/world/level/block/IceBlock.java b/src/main/java/net/minecraft/world/level/block/IceBlock.java
index 943b5ee11fb066afcfb3717befe4dab35db5b600..5ecf02ce83b7496c977adfeb203b8eadb05f9da5 100644
--- a/src/main/java/net/minecraft/world/level/block/IceBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/IceBlock.java
@@ -25,6 +25,11 @@ public class IceBlock extends HalfTransparentBlock {
     @Override
     public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) {
         super.playerDestroy(world, player, pos, state, blockEntity, tool);
+        // Paper start
+        this.afterDestroy(world, pos, tool);
+    }
+    public void afterDestroy(Level world, BlockPos pos, ItemStack tool) {
+        // Paper end
         if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, tool) == 0) {
             if (world.dimensionType().ultraWarm()) {
                 world.removeBlock(pos, false);
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index 97f0f5fac4e1ddf1f39981687d08adf6a5662457..cbe5f0a6ba85d2acafa9d0d9b1575d3ccbd11cae 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -479,6 +479,18 @@ public class CraftBlock implements Block {
 
     @Override
     public boolean breakNaturally(ItemStack item) {
+        // Paper start
+        return this.breakNaturally(item, false);
+    }
+
+    @Override
+    public boolean breakNaturally(boolean triggerEffect, boolean dropExperience) {
+        return this.breakNaturally(null, triggerEffect, dropExperience);
+    }
+
+    @Override
+    public boolean breakNaturally(ItemStack item, boolean triggerEffect, boolean dropExperience) {
+        // Paper end
         // Order matters here, need to drop before setting to air so skulls can get their data
         net.minecraft.world.level.block.state.BlockState iblockdata = this.getNMS();
         net.minecraft.world.level.block.Block block = iblockdata.getBlock();
@@ -488,11 +500,35 @@ 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(), position, this.world.getBlockEntity(position), null, nmsItem);
+            // Paper start - improve Block#breanNaturally
+            if (triggerEffect) {
+                if (iblockdata.getBlock() instanceof net.minecraft.world.level.block.BaseFireBlock) {
+                    this.world.levelEvent(net.minecraft.world.level.block.LevelEvent.SOUND_EXTINGUISH_FIRE, this.position, 0);
+                } else {
+                    this.world.levelEvent(net.minecraft.world.level.block.LevelEvent.PARTICLES_DESTROY_BLOCK, this.position, net.minecraft.world.level.block.Block.getId(iblockdata));
+                }
+            }
+            if (dropExperience) block.popExperience(this.world.getMinecraftWorld(), this.position, block.getExpDrop(iblockdata, this.world.getMinecraftWorld(), this.position, nmsItem, true));
+            // Paper end
             result = true;
         }
 
         // SPIGOT-6778: Directly call setBlock instead of setTypeAndData, so that the tile entiy is not removed and custom remove logic is run.
-        return this.world.setBlock(position, Blocks.AIR.defaultBlockState(), 3) && result;
+        // Paper start - improve breakNaturally
+        boolean destroyed = this.world.removeBlock(this.position, false);
+        if (destroyed) {
+            block.destroy(this.world, this.position, iblockdata);
+        }
+        if (result) {
+            // special cases
+            if (block instanceof net.minecraft.world.level.block.IceBlock iceBlock) {
+                iceBlock.afterDestroy(this.world.getMinecraftWorld(), this.position, nmsItem);
+            } else if (block instanceof net.minecraft.world.level.block.TurtleEggBlock turtleEggBlock) {
+                turtleEggBlock.decreaseEggs(this.world.getMinecraftWorld(), this.position, iblockdata);
+            }
+        }
+        return destroyed && result;
+        // Paper end
     }
 
     @Override