diff --git a/src/main/java/world/bentobox/greenhouses/data/Greenhouse.java b/src/main/java/world/bentobox/greenhouses/data/Greenhouse.java index 2badd4e..a0f81ad 100644 --- a/src/main/java/world/bentobox/greenhouses/data/Greenhouse.java +++ b/src/main/java/world/bentobox/greenhouses/data/Greenhouse.java @@ -249,4 +249,18 @@ public class Greenhouse implements DataObject { public Map getMissingBlocks() { return missingBlocks; } + + /** + * Check if a location is a wall or roof block + * @param l - location + * @return true if wall or roof block + */ + public boolean isRoofOrWallBlock(Location l) { + return ((l.getBlockY() == getCeilingHeight() - 1) + || l.getBlockX() == (int)getBoundingBox().getMinX() + || l.getBlockX() == (int)getBoundingBox().getMaxX() - 1 + || l.getBlockZ() == (int)getBoundingBox().getMinZ() + || l.getBlockZ() == (int)getBoundingBox().getMaxZ() - 1 + ); + } } diff --git a/src/main/java/world/bentobox/greenhouses/listeners/GreenhouseEvents.java b/src/main/java/world/bentobox/greenhouses/listeners/GreenhouseEvents.java index 5c15d33..c5eb3ec 100644 --- a/src/main/java/world/bentobox/greenhouses/listeners/GreenhouseEvents.java +++ b/src/main/java/world/bentobox/greenhouses/listeners/GreenhouseEvents.java @@ -161,17 +161,11 @@ public class GreenhouseEvents implements Listener { @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled=true) public void onBlockBreak(final BlockBreakEvent e) { User user = User.getInstance(e.getPlayer()); - addon.getManager().getMap().getGreenhouse(e.getBlock().getLocation()).ifPresent(g -> { - // Check to see if wall or roof block broken - if ((e.getBlock().getLocation().getBlockY() == g.getCeilingHeight() - 1) - || e.getBlock().getLocation().getBlockX() == (int)g.getBoundingBox().getMinX() - || e.getBlock().getLocation().getBlockX() == (int)g.getBoundingBox().getMaxX() - 1 - || e.getBlock().getLocation().getBlockZ() == (int)g.getBoundingBox().getMinZ() - || e.getBlock().getLocation().getBlockZ() == (int)g.getBoundingBox().getMaxZ() - 1 - ) { - user.sendMessage("greenhouses.event.broke", BIOME, Util.prettifyText(g.getOriginalBiome().name())); - addon.getManager().removeGreenhouse(g); - } + addon.getManager().getMap().getGreenhouse(e.getBlock().getLocation()) + .filter(g -> g.isRoofOrWallBlock(e.getBlock().getLocation())) + .ifPresent(g -> { + user.sendMessage("greenhouses.event.broke", BIOME, Util.prettifyText(g.getOriginalBiome().name())); + addon.getManager().removeGreenhouse(g); }); } diff --git a/src/main/java/world/bentobox/greenhouses/listeners/GreenhouseGuard.java b/src/main/java/world/bentobox/greenhouses/listeners/GreenhouseGuard.java index c194359..13c533f 100644 --- a/src/main/java/world/bentobox/greenhouses/listeners/GreenhouseGuard.java +++ b/src/main/java/world/bentobox/greenhouses/listeners/GreenhouseGuard.java @@ -2,10 +2,13 @@ package world.bentobox.greenhouses.listeners; import java.util.Optional; +import org.bukkit.Location; +import org.bukkit.block.Block; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.block.BlockFromToEvent; +import org.bukkit.event.block.BlockPistonExtendEvent; import world.bentobox.greenhouses.Greenhouses; import world.bentobox.greenhouses.data.Greenhouse; @@ -18,7 +21,7 @@ public class GreenhouseGuard implements Listener { } // Stop lava flow or water into or out of a greenhouse - @EventHandler(priority = EventPriority.NORMAL) + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onFlow(final BlockFromToEvent e) { // Flow may be allowed anyway if (addon.getSettings().isAllowFlowIn() && addon.getSettings().isAllowFlowOut()) { @@ -52,6 +55,21 @@ public class GreenhouseGuard implements Listener { e.setCancelled(true); } + /** + * Prevents pistons from pushing greenhouse wall or roof blocks + * @param e - event + */ + @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) + public void onPistonPush(BlockPistonExtendEvent e) { + e.setCancelled(e.getBlocks().stream() + .map(Block::getLocation) + .filter(this::inGreenhouse) + .findFirst() + .isPresent()); + } + private boolean inGreenhouse(Location l) { + return addon.getManager().getMap().getGreenhouse(l).map(g -> g.isRoofOrWallBlock(l)).orElse(false); + } } diff --git a/src/test/java/world/bentobox/greenhouses/listeners/GreenhouseEventsTest.java b/src/test/java/world/bentobox/greenhouses/listeners/GreenhouseEventsTest.java index 9985aa1..4a6af13 100644 --- a/src/test/java/world/bentobox/greenhouses/listeners/GreenhouseEventsTest.java +++ b/src/test/java/world/bentobox/greenhouses/listeners/GreenhouseEventsTest.java @@ -31,7 +31,6 @@ import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.PlayerInventory; -import org.bukkit.util.BoundingBox; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -430,8 +429,7 @@ public class GreenhouseEventsTest { */ @Test public void testOnBlockBreak() { - BoundingBox bb = BoundingBox.of(location, location2); - when(gh1.getBoundingBox()).thenReturn(bb); + when(gh1.isRoofOrWallBlock(any())).thenReturn(true); // Location is a wall block Block block = mock(Block.class); when(block.getLocation()).thenReturn(location);