Skip to content

Commit

Permalink
Merge pull request #883 from QwQ-dev/explosive_tool_and_exotic_garden
Browse files Browse the repository at this point in the history
Fix #853
  • Loading branch information
StarWishsama authored May 27, 2024
2 parents 9fdaeaf + 1b08db0 commit 1236a23
Showing 1 changed file with 96 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,18 @@
import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem;
import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.Nonnull;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Bukkit;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.block.BlockBreakEvent;
Expand All @@ -34,10 +40,8 @@
* This {@link SlimefunItem} is a super class for items like the {@link ExplosivePickaxe} or {@link ExplosiveShovel}.
*
* @author TheBusyBiscuit
*
* @see ExplosivePickaxe
* @see ExplosiveShovel
*
*/
public class ExplosiveTool extends SimpleSlimefunItem<ToolUseHandler> implements NotPlaceable, DamageableItem {

Expand Down Expand Up @@ -104,6 +108,17 @@ private void breakBlocks(
ExplosiveToolBreakBlocksEvent event = new ExplosiveToolBreakBlocksEvent(p, b, blocksToDestroy, item, this);
Bukkit.getServer().getPluginManager().callEvent(event);

/*
* 修复: https://github.com/SlimefunGuguProject/Slimefun4/issues/853
*
* 为了修复该问题应该对该列表进行排序,确保头颅先被处理,具体为什么可以看下方 breakBlock 方法。
*/
if (Bukkit.getPluginManager().isPluginEnabled("ExoticGarden")) {
blocksToDestroy.sort((block1, block2) -> Boolean.compare(
block2.getType().equals(Material.PLAYER_HEAD),
block1.getType().equals(Material.PLAYER_HEAD)));
}

if (!event.isCancelled()) {
for (Block block : blocksToDestroy) {
breakBlock(e, p, item, block, drops);
Expand Down Expand Up @@ -149,38 +164,87 @@ protected boolean canBreak(@Nonnull Player p, @Nonnull Block b) {
}

@ParametersAreNonnullByDefault
private void breakBlock(BlockBreakEvent e, Player p, ItemStack item, Block b, List<ItemStack> drops) {
Slimefun.getProtectionManager().logAction(p, b, Interaction.BREAK_BLOCK);
Material material = b.getType();

b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, material);
var loc = b.getLocation();
SlimefunItem sfItem = StorageCacheUtils.getSfItem(loc);

if (sfItem != null && !sfItem.useVanillaBlockBreaking()) {
/*
* Fixes #2989
* We create a dummy here to pass onto the BlockBreakHandler.
* This will set the correct block context.
*/
BlockBreakEvent dummyEvent = new BlockBreakEvent(b, e.getPlayer());

/*
* Fixes #3036 and handling in general.
* Call the BlockBreakHandler if the block has one to allow for proper handling.
*/
sfItem.callItemHandler(BlockBreakHandler.class, handler -> handler.onPlayerBreak(dummyEvent, item, drops));

// Make sure the event wasn't cancelled by the BlockBreakHandler.
if (!dummyEvent.isCancelled()) {
drops.addAll(sfItem.getDrops(p));
b.setType(Material.AIR);
Slimefun.getDatabaseManager().getBlockDataController().removeBlock(loc);
private void breakBlock(BlockBreakEvent event, Player player, ItemStack item, Block block, List<ItemStack> drops) {
Slimefun.getProtectionManager().logAction(player, block, Interaction.BREAK_BLOCK);
Material material = block.getType();

block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, material);
Location blockLocation = block.getLocation();

Optional<SlimefunItem> optionalBlockSfItem = Optional.ofNullable(StorageCacheUtils.getSfItem(blockLocation));

/*
* 修复: https://github.com/SlimefunGuguProject/Slimefun4/issues/853
*
* 该问题源于 ExoticGarden MagicalEssence/ExoticGardenFruit useVanillaBlockBreaking 为 true,
* 将调用 breakNaturally 方法而非将其作为 SlimefunItem 进行处理。
*
* 此前将 blocks 进行排序,以确保头颅为最先处理的对象,检查头颅的 Y - 1 方块是否为叶子,
* 若为叶子则尝试获取该处的 SlimefunItem,若能获取得到则此处应为异域花园植物,将叶子处直接设置为 AIR 并移除该处 Slimefun 方块数据。
*/
AtomicBoolean isUseVanillaBlockBreaking = new AtomicBoolean(true);

if (Bukkit.getPluginManager().isPluginEnabled("ExoticGarden")
&& block.getType().equals(Material.PLAYER_HEAD)) {
Location leavesLocation = blockLocation.clone();
leavesLocation.setY(leavesLocation.getY() - 1);

Block leaveBlock = leavesLocation.getBlock();
Material leaveBlockType = leaveBlock.getType();

if (Tag.LEAVES.isTagged(leaveBlockType)) {
Optional<SlimefunItem> optionalLeavesBlockSfItem =
Optional.ofNullable(StorageCacheUtils.getSfItem(leavesLocation));

optionalBlockSfItem.ifPresent(blockSfItem -> optionalLeavesBlockSfItem.ifPresent(leavesSfItem -> {
Collection<ItemStack> sfItemDrops = blockSfItem.getDrops();
Collection<ItemStack> leavesSfItemDrops = leavesSfItem.getDrops();

if (Arrays.equals(sfItemDrops.toArray(), leavesSfItemDrops.toArray())) {
leaveBlock.setType(Material.AIR);
Slimefun.getDatabaseManager().getBlockDataController().removeBlock(leavesLocation);

isUseVanillaBlockBreaking.set(false);
}
}));
}
} else {
b.breakNaturally(item);
}

damageItem(p, item);
optionalBlockSfItem.ifPresent(sfItem -> {
if (isUseVanillaBlockBreaking.get()) {
isUseVanillaBlockBreaking.set(sfItem.useVanillaBlockBreaking());
}

if (isUseVanillaBlockBreaking.get()) {
block.breakNaturally(item);
} else {
/*
* Fixes #2989
* We create a dummy here to pass onto the BlockBreakHandler.
* This will set the correct block context.
*/
BlockBreakEvent dummyEvent = new BlockBreakEvent(block, event.getPlayer());

/*
* Fixes #3036 and handling in general.
* Call the BlockBreakHandler if the block has one to allow for proper handling.
*/
sfItem.callItemHandler(
BlockBreakHandler.class, handler -> handler.onPlayerBreak(dummyEvent, item, drops));

// Make sure the event wasn't cancelled by the BlockBreakHandler.
if (!dummyEvent.isCancelled()) {
drops.addAll(sfItem.getDrops(player));
block.setType(Material.AIR);
Slimefun.getDatabaseManager().getBlockDataController().removeBlock(blockLocation);
}
}
});

if (optionalBlockSfItem.isEmpty()) {
block.breakNaturally(item);
}

damageItem(player, item);
}
}

0 comments on commit 1236a23

Please sign in to comment.