diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AndroidBlockBreakEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AndroidBlockBreakEvent.java new file mode 100644 index 0000000000..fa72ee6125 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AndroidBlockBreakEvent.java @@ -0,0 +1,71 @@ +package io.github.thebusybiscuit.slimefun4.api.events; + +import io.github.thebusybiscuit.slimefun4.implementation.items.androids.AndroidInstance; +import io.github.thebusybiscuit.slimefun4.implementation.items.androids.ProgrammableAndroid; +import org.bukkit.block.Block; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; + +/** + * This {@link Event} is fired before an {@link ProgrammableAndroid android} breaks a {@link Block}. + * If this {@link Event} is cancelled, the {@link Block} will not be broken. + * + * @author JustAHuman, poma123 (creator of this classes predecessor) + */ +public class AndroidBlockBreakEvent extends Event implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + + private final Block block; + private final AndroidInstance android; + private boolean cancelled = false; + + /** + * @param block + * The {@link Block} to be broken + * @param android + * The {@link AndroidInstance} that triggered this {@link AndroidBlockBreakEvent event} + */ + @ParametersAreNonnullByDefault + public AndroidBlockBreakEvent(Block block, AndroidInstance android) { + this.block = block; + this.android = android; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + @Override + public boolean isCancelled() { + return this.cancelled; + } + + /** + * @return The broken {@link Block} + */ + public @Nonnull Block getBlock() { + return this.block; + } + + /** + * @return The {@link AndroidInstance android} who triggered this {@link AndroidBlockBreakEvent event} + */ + public @Nonnull AndroidInstance getAndroid() { + return this.android; + } + + @Override + public @Nonnull HandlerList getHandlers() { + return getHandlerList(); + } + + public static @Nonnull HandlerList getHandlerList() { + return handlers; + } +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AndroidMineEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AndroidMineEvent.java index 66d3c2c158..ce5ccb164d 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AndroidMineEvent.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AndroidMineEvent.java @@ -15,69 +15,30 @@ * This {@link Event} is fired before a {@link MinerAndroid} mines a {@link Block}. * If this {@link Event} is cancelled, the {@link Block} will not be mined. * - * @author poma123 - * + * @author poma123, JustAHuman */ -public class AndroidMineEvent extends Event implements Cancellable { +public class AndroidMineEvent extends AndroidBlockBreakEvent { private static final HandlerList handlers = new HandlerList(); - private final Block block; - private final AndroidInstance android; - private boolean cancelled; - /** * @param block - * The mined {@link Block} + * The {@link Block} to be mined * @param android - * The {@link AndroidInstance} that triggered this {@link Event} + * The {@link AndroidInstance} that triggered this {@link AndroidMineEvent event} */ @ParametersAreNonnullByDefault public AndroidMineEvent(Block block, AndroidInstance android) { - this.block = block; - this.android = android; - } - - /** - * This method returns the mined {@link Block} - * - * @return the mined {@link Block} - */ - @Nonnull - public Block getBlock() { - return block; - } - - /** - * This method returns the {@link AndroidInstance} who - * triggered this {@link Event} - * - * @return the involved {@link AndroidInstance} - */ - @Nonnull - public AndroidInstance getAndroid() { - return android; + super(block, android); } @Override - public boolean isCancelled() { - return cancelled; - } - - @Override - public void setCancelled(boolean cancel) { - cancelled = cancel; + public @Nonnull HandlerList getHandlers() { + return getHandlerList(); } - @Nonnull - public static HandlerList getHandlerList() { + public static @Nonnull HandlerList getHandlerList() { return handlers; } - @Nonnull - @Override - public HandlerList getHandlers() { - return getHandlerList(); - } - } \ No newline at end of file diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AndroidWoodcutEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AndroidWoodcutEvent.java new file mode 100644 index 0000000000..7166032c85 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AndroidWoodcutEvent.java @@ -0,0 +1,36 @@ +package io.github.thebusybiscuit.slimefun4.api.events; + +import io.github.thebusybiscuit.slimefun4.implementation.items.androids.AndroidInstance; +import org.bukkit.block.Block; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; + +public class AndroidWoodcutEvent extends AndroidBlockBreakEvent { + + private static final HandlerList handlers = new HandlerList(); + + /** + * @param block + * The {@link Block} to be chopped + * @param android + * The {@link AndroidInstance} that triggered this {@link Event} + */ + @ParametersAreNonnullByDefault + public AndroidWoodcutEvent(Block block, AndroidInstance android) { + super(block, android); + } + + @Override + public @Nonnull HandlerList getHandlers() { + return getHandlerList(); + } + + @Nonnull + public static HandlerList getHandlerList() { + return handlers; + } + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/WoodcutterAndroid.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/WoodcutterAndroid.java index 0133cb3b25..eba5165b2e 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/WoodcutterAndroid.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/WoodcutterAndroid.java @@ -7,6 +7,7 @@ import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; +import io.github.thebusybiscuit.slimefun4.api.events.AndroidWoodcutEvent; import org.bukkit.Bukkit; import org.bukkit.Effect; import org.bukkit.Material; @@ -55,10 +56,22 @@ protected boolean chopTree(Block b, BlockMenu menu, BlockFace face) { if (!list.isEmpty()) { Block log = list.get(list.size() - 1); + // We only want to break non-Slimefun blocks + if (BlockStorage.hasBlockInfo(log)) { + return false; + } + log.getWorld().playEffect(log.getLocation(), Effect.STEP_SOUND, log.getType()); OfflinePlayer owner = Bukkit.getOfflinePlayer(UUID.fromString(BlockStorage.getLocationInfo(b.getLocation(), "owner"))); if (Slimefun.getProtectionManager().hasPermission(owner, log.getLocation(), Interaction.BREAK_BLOCK)) { + AndroidWoodcutEvent event = new AndroidWoodcutEvent(log, new AndroidInstance(this, b)); + Bukkit.getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return false; + } + breakLog(log, b, menu, face); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/LumberAxe.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/LumberAxe.java index faf6e0a44d..daf3329681 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/LumberAxe.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/LumberAxe.java @@ -1,17 +1,21 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.tools; +import java.util.HashSet; import java.util.List; +import java.util.Set; import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; import org.bukkit.Axis; +import org.bukkit.Bukkit; import org.bukkit.Effect; import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.Tag; import org.bukkit.block.Block; import org.bukkit.block.data.Orientable; +import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.inventory.ItemStack; import io.github.bakedlibs.dough.blocks.Vein; @@ -37,6 +41,7 @@ */ public class LumberAxe extends SlimefunItem implements NotPlaceable { + private static final Set IGNORE_EVENTS = new HashSet<>(); private static final int MAX_BROKEN = 100; private static final int MAX_STRIPPED = 20; @@ -50,13 +55,22 @@ public LumberAxe(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeT @Nonnull private ToolUseHandler onBlockBreak() { return (e, tool, fortune, drops) -> { + if (IGNORE_EVENTS.contains(e)) { + return; + } + if (!e.getPlayer().isSneaking() && Tag.LOGS.isTagged(e.getBlock().getType())) { List logs = Vein.find(e.getBlock(), MAX_BROKEN, b -> Tag.LOGS.isTagged(b.getType())); logs.remove(e.getBlock()); for (Block b : logs) { if (!BlockStorage.hasBlockInfo(b) && Slimefun.getProtectionManager().hasPermission(e.getPlayer(), b, Interaction.BREAK_BLOCK)) { - breakLog(b); + BlockBreakEvent event = new BlockBreakEvent(b, e.getPlayer()); + IGNORE_EVENTS.add(event); + Bukkit.getPluginManager().callEvent(event); + if (!event.isCancelled()) { + breakLog(b, event.isDropItems()); + } } } } @@ -99,11 +113,13 @@ private void stripLog(@Nonnull Block b) { b.setBlockData(orientable); } - private void breakLog(@Nonnull Block b) { + private void breakLog(@Nonnull Block b, boolean dropItems) { b.getWorld().playEffect(b.getLocation(), Effect.STEP_SOUND, b.getType()); - for (ItemStack drop : b.getDrops(getItem())) { - b.getWorld().dropItemNaturally(b.getLocation(), drop); + if (dropItems) { + for (ItemStack drop : b.getDrops(getItem())) { + b.getWorld().dropItemNaturally(b.getLocation(), drop); + } } b.setType(Material.AIR);