Prevents piston-pushing of any wall or roof block

Fixes https://github.com/BentoBoxWorld/Greenhouses/issues/77
This commit is contained in:
tastybento 2021-02-17 16:49:42 -08:00
parent 29f04ef673
commit 999ea07ef0
4 changed files with 39 additions and 15 deletions

View File

@ -249,4 +249,18 @@ public class Greenhouse implements DataObject {
public Map<Material, Integer> 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
);
}
}

View File

@ -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);
});
}

View File

@ -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);
}
}

View File

@ -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);