diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java index 30593427e..75a9cdba8 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java @@ -14,6 +14,7 @@ import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; +import org.bukkit.block.data.BlockData; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -25,6 +26,7 @@ import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import io.github.bakedlibs.dough.protection.Interaction; +import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; import io.github.thebusybiscuit.slimefun4.api.events.ExplosiveToolBreakBlocksEvent; import io.github.thebusybiscuit.slimefun4.api.events.SlimefunBlockBreakEvent; import io.github.thebusybiscuit.slimefun4.api.events.SlimefunBlockPlaceEvent; @@ -53,6 +55,8 @@ import me.mrCookieSlime.Slimefun.api.BlockStorage; */ public class BlockListener implements Listener { + private static final BlockFace[] CARDINAL_BLOCKFACES = new BlockFace[]{BlockFace.WEST, BlockFace.EAST, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.DOWN, BlockFace.UP}; + public BlockListener(@Nonnull Slimefun plugin) { plugin.getServer().getPluginManager().registerEvents(this, plugin); } @@ -152,6 +156,9 @@ public class BlockListener implements Listener { } callBlockHandler(e, item, drops, sfItem); + + checkForSensitiveBlocks(e.getBlock(), 0); + dropItems(e, drops); } } @@ -222,6 +229,52 @@ public class BlockListener implements Listener { } } + /** + * This method checks recursively for any sensitive blocks + * that are no longer supported due to this block breaking + * + * @param block + * The {@link Block} in question + * @param c + * The amount of times this has been recursively called + */ + @ParametersAreNonnullByDefault + private void checkForSensitiveBlocks(Block block, Integer c) { + if (c >= Bukkit.getServer().getMaxChainedNeighborUpdates()) { + return; + } + for (BlockFace face : CARDINAL_BLOCKFACES) { + block.setType(Material.AIR, false); + if (!isSupported(block.getRelative(face).getBlockData(), block.getRelative(face))) { + Block relative = block.getRelative(face); + for (ItemStack drop : relative.getDrops()) { + block.getWorld().dropItemNaturally(relative.getLocation(), drop); + } + checkForSensitiveBlocks(relative, ++c); + } + } + } + + /** + * This method checks if the {@link BlockData} would be + * supported at the given {@link Block}. + * + * @param blockData + * The {@link BlockData} to check + * @param block + * The {@link Block} the {@link BlockData} would be at + * @return + * Whether the {@link BlockData} would be supported at the given {@link Block} + */ + private boolean isSupported(BlockData blockData, Block block) { + if (Slimefun.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_19)) { + return blockData.isSupported(block); + } else { + // TODO: Make 1.16-1.18 version. BlockData::isSupported is 1.19+. + return true; + } + } + /** * This method checks for a sensitive {@link Block}. * Sensitive {@link Block Blocks} are pressure plates or saplings, which should be broken