13
0
geforkt von Mirrors/Paper

Add more breakNaturally functionality (#7379)

Dieser Commit ist enthalten in:
Jake Potrebic 2022-12-14 19:37:16 -08:00
Ursprung a0b62c40db
Commit 96d7b7b6e4
6 geänderte Dateien mit 164 neuen und 104 gelöschten Zeilen

Datei anzeigen

@ -1,37 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Thu, 2 Jan 2020 12:25:16 -0600
Subject: [PATCH] Add effect to block break naturally
diff --git a/src/main/java/org/bukkit/block/Block.java b/src/main/java/org/bukkit/block/Block.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/block/Block.java
+++ b/src/main/java/org/bukkit/block/Block.java
@@ -0,0 +0,0 @@ public interface Block extends Metadatable {
*/
boolean breakNaturally(@Nullable ItemStack tool);
+ // Paper start
+ /**
+ * Breaks the block and spawns item drops as if a player had broken it
+ *
+ * @param triggerEffect Play the block break particle effect and sound
+ * @return true if the block was destroyed
+ */
+ boolean breakNaturally(boolean triggerEffect);
+
+ /**
+ * Breaks the block and spawns item drops as if a player had broken it
+ * with a specific tool
+ *
+ * @param tool The tool or item in hand used for digging
+ * @param triggerEffect Play the block break particle effect and sound
+ * @return true if the block was destroyed
+ */
+ boolean breakNaturally(@NotNull ItemStack tool, boolean triggerEffect);
+ // Paper end
+
/**
* Simulate bone meal application to this block (if possible).
*

Datei anzeigen

@ -11,7 +11,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
@@ -0,0 +0,0 @@ public interface Block extends Metadatable, net.kyori.adventure.translation.Tran
* @return true if the block was destroyed
*/
boolean breakNaturally(@NotNull ItemStack tool, boolean triggerEffect);
boolean breakNaturally(@NotNull ItemStack tool, boolean triggerEffect, boolean dropExperience);
+
+ /**
+ * Causes the block to be ticked, this is different from {@link Block#randomTick()},

Datei anzeigen

@ -0,0 +1,68 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Thu, 2 Jan 2020 12:25:16 -0600
Subject: [PATCH] Improve Block#breakNaturally API
Adds bool param to trigger world particle effects
Adds bool param to trigger exp drops for blocks
Co-authored-by: William Blake Galbreath <Blake.Galbreath@GMail.com>
diff --git a/src/main/java/org/bukkit/block/Block.java b/src/main/java/org/bukkit/block/Block.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/block/Block.java
+++ b/src/main/java/org/bukkit/block/Block.java
@@ -0,0 +0,0 @@ public interface Block extends Metadatable {
*/
boolean breakNaturally(@Nullable ItemStack tool);
+ // Paper start
+ /**
+ * Breaks the block and spawns item drops as if a player had broken it
+ *
+ * @param triggerEffect Play the block break particle effect and sound
+ * @return true if the block was destroyed
+ * @see #breakNaturally(boolean, boolean) to trigger exp drops
+ */
+ default boolean breakNaturally(boolean triggerEffect) {
+ return this.breakNaturally(triggerEffect, false);
+ }
+
+ /**
+ * Breaks the block and spawns item drops as if a player had broken it
+ *
+ * @param triggerEffect Play the block break particle effect and sound
+ * @param dropExperience drop exp if the block normally does so
+ * @return true if the block was destroyed
+ */
+ boolean breakNaturally(boolean triggerEffect, boolean dropExperience);
+
+ /**
+ * Breaks the block and spawns item drops as if a player had broken it
+ * with a specific tool
+ *
+ * @param tool The tool or item in hand used for digging
+ * @param triggerEffect Play the block break particle effect and sound
+ * @return true if the block was destroyed
+ * @see #breakNaturally(ItemStack, boolean, boolean) to trigger exp drops
+ */
+ default boolean breakNaturally(@NotNull ItemStack tool, boolean triggerEffect) {
+ return this.breakNaturally(tool, triggerEffect, false);
+ }
+
+ /**
+ * Breaks the block and spawns item drops as if a player had broken it
+ * with a specific tool
+ *
+ * @param tool The tool or item in hand used for digging
+ * @param triggerEffect Play the block break particle effect and sound
+ * @param dropExperience drop exp if the block normally does so
+ * @return true if the block was destroyed
+ */
+ boolean breakNaturally(@NotNull ItemStack tool, boolean triggerEffect, boolean dropExperience);
+ // Paper end
+
/**
* Simulate bone meal application to this block (if possible).
*

Datei anzeigen

@ -1,37 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <Blake.Galbreath@GMail.com>
Date: Thu, 2 Jan 2020 12:25:07 -0600
Subject: [PATCH] Add effect to block break naturally
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -0,0 +0,0 @@ public class CraftBlock implements Block {
@Override
public boolean breakNaturally(ItemStack item) {
+ // Paper start
+ return breakNaturally(item, false);
+ }
+
+ @Override
+ public boolean breakNaturally(boolean triggerEffect) {
+ return breakNaturally(null, triggerEffect);
+ }
+
+ @Override
+ public boolean breakNaturally(ItemStack item, boolean triggerEffect) {
+ // 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();
@@ -0,0 +0,0 @@ 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);
+ if (triggerEffect) world.levelEvent(org.bukkit.Effect.STEP_SOUND.getId(), position, net.minecraft.world.level.block.Block.getId(block.defaultBlockState())); // Paper
result = true;
}

Datei anzeigen

@ -1,29 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Tue, 21 Dec 2021 16:28:17 -0800
Subject: [PATCH] Fix fluid-logging on Block#breakNaturally
Leaves fluid if the block broken was fluid-logged which is what
happens if a player breaks a fluid-logged block
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -0,0 +0,0 @@ public class CraftBlock implements Block {
net.minecraft.world.level.block.state.BlockState iblockdata = this.getNMS();
net.minecraft.world.level.block.Block block = iblockdata.getBlock();
net.minecraft.world.item.ItemStack nmsItem = CraftItemStack.asNMSCopy(item);
+ net.minecraft.world.level.material.FluidState fluidState = this.world.getFluidState(this.position); // Paper
boolean result = false;
// Modelled off EntityHuman#hasBlock
@@ -0,0 +0,0 @@ public class CraftBlock implements Block {
}
// 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;
+ return this.world.setBlock(position, fluidState.createLegacyBlock(), 3) && result; // Paper - leave liquid if waterlogged
}
@Override

Datei anzeigen

@ -0,0 +1,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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/level/block/IceBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/IceBlock.java
@@ -0,0 +0,0 @@ public class IceBlock extends HalfTransparentBlock {
@Override
public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack stack) {
super.playerDestroy(world, player, pos, state, blockEntity, stack);
+ // Paper start
+ this.afterDestroy(world, pos, stack);
+ }
+ public void afterDestroy(Level world, BlockPos pos, ItemStack stack) {
+ // Paper end
if (EnchantmentHelper.getItemEnchantmentLevel(Enchantments.SILK_TOUCH, stack) == 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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -0,0 +0,0 @@ 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();
@@ -0,0 +0,0 @@ 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