diff --git a/src/main/java/ru/redguy/extendedpistons/WorldListener.java b/src/main/java/ru/redguy/extendedpistons/WorldListener.java index 3e3fd33..87a8ec3 100644 --- a/src/main/java/ru/redguy/extendedpistons/WorldListener.java +++ b/src/main/java/ru/redguy/extendedpistons/WorldListener.java @@ -1,6 +1,5 @@ package ru.redguy.extendedpistons; -import com.google.common.collect.Sets; import com.sk89q.worldguard.bukkit.RegionContainer; import com.sk89q.worldguard.bukkit.RegionQuery; import com.sk89q.worldguard.bukkit.WorldGuardPlugin; @@ -13,7 +12,10 @@ import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; -import org.bukkit.event.block.*; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockPistonExtendEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.block.BlockRedstoneEvent; import org.bukkit.inventory.DoubleChestInventory; import org.bukkit.material.PistonBaseMaterial; @@ -36,6 +38,139 @@ public class WorldListener implements Listener { } } + /*@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onPhysic(BlockPhysicsEvent e) { + if (!(e.getBlock().getType().equals(Material.PISTON_STICKY_BASE) || e.getBlock().getType().equals(Material.PISTON_BASE))) + return; + if (!(e.getBlock().isBlockPowered() || e.getBlock().isBlockIndirectlyPowered())) { + if (!e.getBlock().getType().equals(Material.PISTON_STICKY_BASE)) return; + if (!ExtendedPistons.INSTANCE.isStickyPistonPulls()) return; + Block block = e.getBlock(); + BlockState state = block.getState(); + PistonBaseMaterial piston; + try { + piston = (PistonBaseMaterial) state.getData(); + } catch (ClassCastException ex) { + return; + } + Bukkit.getScheduler().runTask(ExtendedPistons.INSTANCE, () -> { + if (!(e.getBlock().isBlockPowered() || e.getBlock().isBlockIndirectlyPowered())) return; + int maxBlocks = findNearbyPlayerMaxBlocks(block.getLocation()); + + PistonExtendsChecker checker = new PistonExtendsChecker(e.getBlock().getWorld(), block.getLocation(), piston.getFacing(), false, maxBlocks); + boolean isMovable = checker.a(); + List blocks = checker.getMovedBlocksObjects(); + List toBreak = checker.getBrokenBlocksObjects(); + + if (isMovable) { + if (!isBlocksAllowedToInteract(copyWithAdd(blocks, toBreak), piston.getFacing())) + return; + for (Block block1 : toBreak) { + block1.breakNaturally(); + } + for (Block b : blocks) { + Block b2 = b.getRelative(piston.getFacing().getOppositeFace()); + b2.setType(b.getType()); + b2.setData(b.getData()); //Deprecated but powerful + if (b.getType().equals(Material.CHEST)) { + Chest oldChest = (Chest) b.getState(); + Chest newChest = (Chest) b2.getState(); + newChest.getBlockInventory().setContents(oldChest.getBlockInventory().getContents()); + oldChest.getBlockInventory().clear(); + } else if (b.getType().equals(Material.FURNACE) || b.getType().equals(Material.BURNING_FURNACE)) { + Furnace oldFurnace = (Furnace) b.getState(); + Furnace newFurnace = (Furnace) b2.getState(); + newFurnace.getInventory().setContents(oldFurnace.getInventory().getContents()); + oldFurnace.getInventory().clear(); + } + b.setType(Material.AIR); + } + } + }); + } else { + Block block = e.getBlock(); + BlockState state = block.getState(); + PistonBaseMaterial piston; + try { + piston = (PistonBaseMaterial) state.getData(); + } catch (ClassCastException ex) { + return; + } + Bukkit.getScheduler().runTask(ExtendedPistons.INSTANCE, () -> { + if (e.getBlock().isBlockPowered() || e.getBlock().isBlockIndirectlyPowered()) return; + int maxBlocks = findNearbyPlayerMaxBlocks(block.getLocation()); + + PistonExtendsChecker checker = new PistonExtendsChecker(e.getBlock().getWorld(), block.getLocation(), piston.getFacing(), true, maxBlocks); + boolean isMovable = checker.a(); + List blocks = checker.getMovedBlocksObjects(); + List toBreak = checker.getBrokenBlocksObjects(); + + upper: + for (Block b : blocks) { + if (b.getType().equals(Material.CHEST)) { + Block b2 = b.getRelative(piston.getFacing()); + ArrayList faces = new ArrayList() {{ + add(BlockFace.NORTH); + add(BlockFace.SOUTH); + add(BlockFace.WEST); + add(BlockFace.EAST); + }}; + faces.remove(piston.getFacing().getOppositeFace()); + int chests = 0; + for (BlockFace blockFace : faces) { + Block b3 = b2.getRelative(blockFace); + if (b3.getType() == Material.CHEST) { + chests++; + Chest chest = (Chest) b3.getState(); + if (chest.getInventory() instanceof DoubleChestInventory) { + isMovable = false; + break upper; + } + } + } + if (chests > 1) { + isMovable = false; + break; + } else if (chests == 1) { + if (b.getType() == Material.CHEST) { + Chest chest = (Chest) b.getState(); + if (chest.getInventory() instanceof DoubleChestInventory) { + isMovable = false; + break; + } + } + } + } + } + + if (isMovable) { + if (!isBlocksAllowedToInteract(copyWithAdd(blocks, toBreak), piston.getFacing())) return; + Collections.reverse(blocks); + for (Block block1 : toBreak) { + block1.breakNaturally(); + } + for (Block b : blocks) { + Block b2 = b.getRelative(piston.getFacing()); + b2.setType(b.getType()); + b2.setData(b.getData()); //Deprecated but powerful + if (b.getType().equals(Material.CHEST)) { + Chest oldChest = (Chest) b.getState(); + Chest newChest = (Chest) b2.getState(); + newChest.getBlockInventory().setContents(oldChest.getBlockInventory().getContents()); + oldChest.getBlockInventory().clear(); + } else if (b.getType().equals(Material.FURNACE) || b.getType().equals(Material.BURNING_FURNACE)) { + Furnace oldFurnace = (Furnace) b.getState(); + Furnace newFurnace = (Furnace) b2.getState(); + newFurnace.getInventory().setContents(oldFurnace.getInventory().getContents()); + oldFurnace.getInventory().clear(); + } + b.setType(Material.AIR); + } + } + }); + } + }*/ + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onBlockBreak(BlockBreakEvent e) { Material blockType = e.getBlock().getType(); @@ -82,7 +217,7 @@ public class WorldListener implements Listener { List toBreak = checker.getBrokenBlocksObjects(); if (isMovable) { - if(!isBlocksAllowedToInteract(copyWithAdd(blocks,toBreak),piston.getFacing())) continue; + if (!isBlocksAllowedToInteract(copyWithAdd(blocks, toBreak), piston.getFacing())) continue; for (Block block1 : toBreak) { block1.breakNaturally(); } @@ -156,7 +291,7 @@ public class WorldListener implements Listener { upper: for (Block b : blocks) { - if(b.getType().equals(Material.CHEST)) { + if (b.getType().equals(Material.CHEST)) { Block b2 = b.getRelative(piston.getFacing()); ArrayList faces = new ArrayList() {{ add(BlockFace.NORTH); @@ -193,7 +328,7 @@ public class WorldListener implements Listener { } if (isMovable) { - if(!isBlocksAllowedToInteract(copyWithAdd(blocks,toBreak),piston.getFacing())) return; + if (!isBlocksAllowedToInteract(copyWithAdd(blocks, toBreak), piston.getFacing())) return; Collections.reverse(blocks); for (Block block1 : toBreak) { block1.breakNaturally(); @@ -223,9 +358,12 @@ public class WorldListener implements Listener { @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onRedstone(BlockRedstoneEvent e) { - HashMap states = new HashMap<>(); + HashMap> states = new HashMap<>(); for (BlockFace face : new BlockFace[]{BlockFace.SELF, BlockFace.UP, BlockFace.DOWN, BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST}) { - states.put(face, e.getBlock().getRelative(face).getState()); + states.put(face, new HashMap<>()); + for (BlockFace blockFace : new BlockFace[]{BlockFace.UP, BlockFace.SELF, BlockFace.DOWN}) { + states.get(face).put(blockFace,e.getBlock().getRelative(face).getRelative(blockFace).getState()); + } } Bukkit.getScheduler().runTask(ExtendedPistons.INSTANCE, () -> { if (e.getOldCurrent() != 0 && e.getNewCurrent() == 0) { @@ -247,43 +385,54 @@ public class WorldListener implements Listener { checkedBlockFaces.add(BlockFace.WEST); } for (BlockFace face : checkedBlockFaces) { - Block block = e.getBlock().getRelative(face); - BlockState state = states.get(face); - if (state.getType().equals(Material.PISTON_STICKY_BASE)) { - PistonBaseMaterial piston; - try { - piston = (PistonBaseMaterial) state.getData(); - } catch (ClassCastException ex) { - continue; - } - int maxBlocks = findNearbyPlayerMaxBlocks(block.getLocation()); - - PistonExtendsChecker checker = new PistonExtendsChecker(e.getBlock().getWorld(), block.getLocation(), piston.getFacing(), false, maxBlocks); - boolean isMovable = checker.a(); - List blocks = checker.getMovedBlocksObjects(); - List toBreak = checker.getBrokenBlocksObjects(); - - if (isMovable) { - if(!isBlocksAllowedToInteract(copyWithAdd(blocks,toBreak),piston.getFacing())) continue; - for (Block block1 : toBreak) { - block1.breakNaturally(); + ArrayList subs = new ArrayList() {{ + add(BlockFace.SELF); + }}; + if (e.getBlock().getType().equals(Material.LEVER)) { + subs.add(BlockFace.UP); + subs.add(BlockFace.DOWN); + } + for (BlockFace sub : subs) { + Block block = e.getBlock().getRelative(face); + block = block.getRelative(sub); + BlockState state = states.get(face).get(sub); + if (state.getType().equals(Material.PISTON_STICKY_BASE)) { + PistonBaseMaterial piston; + try { + piston = (PistonBaseMaterial) state.getData(); + } catch (ClassCastException ex) { + continue; } - for (Block b : blocks) { - Block b2 = b.getRelative(piston.getFacing().getOppositeFace()); - b2.setType(b.getType()); - b2.setData(b.getData()); //Deprecated but powerful - if (b.getType().equals(Material.CHEST)) { - Chest oldChest = (Chest) b.getState(); - Chest newChest = (Chest) b2.getState(); - newChest.getBlockInventory().setContents(oldChest.getBlockInventory().getContents()); - oldChest.getBlockInventory().clear(); - } else if (b.getType().equals(Material.FURNACE) || b.getType().equals(Material.BURNING_FURNACE)) { - Furnace oldFurnace = (Furnace) b.getState(); - Furnace newFurnace = (Furnace) b2.getState(); - newFurnace.getInventory().setContents(oldFurnace.getInventory().getContents()); - oldFurnace.getInventory().clear(); + int maxBlocks = findNearbyPlayerMaxBlocks(block.getLocation()); + + PistonExtendsChecker checker = new PistonExtendsChecker(e.getBlock().getWorld(), block.getLocation(), piston.getFacing(), false, maxBlocks); + boolean isMovable = checker.a(); + List blocks = checker.getMovedBlocksObjects(); + List toBreak = checker.getBrokenBlocksObjects(); + + if (isMovable) { + if (!isBlocksAllowedToInteract(copyWithAdd(blocks, toBreak), piston.getFacing())) + continue; + for (Block block1 : toBreak) { + block1.breakNaturally(); + } + for (Block b : blocks) { + Block b2 = b.getRelative(piston.getFacing().getOppositeFace()); + b2.setType(b.getType()); + b2.setData(b.getData()); //Deprecated but powerful + if (b.getType().equals(Material.CHEST)) { + Chest oldChest = (Chest) b.getState(); + Chest newChest = (Chest) b2.getState(); + newChest.getBlockInventory().setContents(oldChest.getBlockInventory().getContents()); + oldChest.getBlockInventory().clear(); + } else if (b.getType().equals(Material.FURNACE) || b.getType().equals(Material.BURNING_FURNACE)) { + Furnace oldFurnace = (Furnace) b.getState(); + Furnace newFurnace = (Furnace) b2.getState(); + newFurnace.getInventory().setContents(oldFurnace.getInventory().getContents()); + oldFurnace.getInventory().clear(); + } + b.setType(Material.AIR); } - b.setType(Material.AIR); } } } @@ -307,82 +456,93 @@ public class WorldListener implements Listener { checkedBlockFaces.add(BlockFace.WEST); } for (BlockFace face : checkedBlockFaces) { - Block block = e.getBlock().getRelative(face); - if (block.getType().equals(Material.PISTON_BASE) || block.getType().equals(Material.PISTON_STICKY_BASE)) { - BlockState state = states.get(face); - PistonBaseMaterial piston; - try { - piston = (PistonBaseMaterial) state.getData(); - } catch (ClassCastException ex) { - continue; - } - int maxBlocks = findNearbyPlayerMaxBlocks(block.getLocation()); - - PistonExtendsChecker checker = new PistonExtendsChecker(e.getBlock().getWorld(), block.getLocation(), piston.getFacing(), true, maxBlocks); - boolean isMovable = checker.a(); - List blocks = checker.getMovedBlocksObjects(); - List toBreak = checker.getBrokenBlocksObjects(); - - upper: - for (Block b : blocks) { - if(b.getType().equals(Material.CHEST)) { - Block b2 = b.getRelative(piston.getFacing()); - ArrayList faces = new ArrayList() {{ - add(BlockFace.NORTH); - add(BlockFace.SOUTH); - add(BlockFace.WEST); - add(BlockFace.EAST); - }}; - faces.remove(piston.getFacing().getOppositeFace()); - int chests = 0; - for (BlockFace blockFace : faces) { - Block b3 = b2.getRelative(blockFace); - if (b3.getType() == Material.CHEST) { - chests++; - Chest chest = (Chest) b3.getState(); - if (chest.getInventory() instanceof DoubleChestInventory) { - isMovable = false; - break upper; - } - } - } - if (chests > 1) { - isMovable = false; - break; - } else if (chests == 1) { - if (b.getType() == Material.CHEST) { - Chest chest = (Chest) b.getState(); - if (chest.getInventory() instanceof DoubleChestInventory) { - isMovable = false; - break; - } - } - } + ArrayList subs = new ArrayList() {{ + add(BlockFace.SELF); + }}; + if (e.getBlock().getType().equals(Material.LEVER)) { + subs.add(BlockFace.UP); + subs.add(BlockFace.DOWN); + } + for (BlockFace sub : subs) { + Block block = e.getBlock().getRelative(face); + block = block.getRelative(sub); + if (block.getType().equals(Material.PISTON_BASE) || block.getType().equals(Material.PISTON_STICKY_BASE)) { + BlockState state = states.get(face).get(sub); + PistonBaseMaterial piston; + try { + piston = (PistonBaseMaterial) state.getData(); + } catch (ClassCastException ex) { + continue; } - } + int maxBlocks = findNearbyPlayerMaxBlocks(block.getLocation()); - if (isMovable) { - if(!isBlocksAllowedToInteract(copyWithAdd(blocks,toBreak),piston.getFacing())) return; - Collections.reverse(blocks); - for (Block block1 : toBreak) { - block1.breakNaturally(); - } + PistonExtendsChecker checker = new PistonExtendsChecker(e.getBlock().getWorld(), block.getLocation(), piston.getFacing(), true, maxBlocks); + boolean isMovable = checker.a(); + List blocks = checker.getMovedBlocksObjects(); + List toBreak = checker.getBrokenBlocksObjects(); + + upper: for (Block b : blocks) { - Block b2 = b.getRelative(piston.getFacing()); - b2.setType(b.getType()); - b2.setData(b.getData()); //Deprecated but powerful if (b.getType().equals(Material.CHEST)) { - Chest oldChest = (Chest) b.getState(); - Chest newChest = (Chest) b2.getState(); - newChest.getBlockInventory().setContents(oldChest.getBlockInventory().getContents()); - oldChest.getBlockInventory().clear(); - } else if (b.getType().equals(Material.FURNACE) || b.getType().equals(Material.BURNING_FURNACE)) { - Furnace oldFurnace = (Furnace) b.getState(); - Furnace newFurnace = (Furnace) b2.getState(); - newFurnace.getInventory().setContents(oldFurnace.getInventory().getContents()); - oldFurnace.getInventory().clear(); + Block b2 = b.getRelative(piston.getFacing()); + ArrayList faces = new ArrayList() {{ + add(BlockFace.NORTH); + add(BlockFace.SOUTH); + add(BlockFace.WEST); + add(BlockFace.EAST); + }}; + faces.remove(piston.getFacing().getOppositeFace()); + int chests = 0; + for (BlockFace blockFace : faces) { + Block b3 = b2.getRelative(blockFace); + if (b3.getType() == Material.CHEST) { + chests++; + Chest chest = (Chest) b3.getState(); + if (chest.getInventory() instanceof DoubleChestInventory) { + isMovable = false; + break upper; + } + } + } + if (chests > 1) { + isMovable = false; + break; + } else if (chests == 1) { + if (b.getType() == Material.CHEST) { + Chest chest = (Chest) b.getState(); + if (chest.getInventory() instanceof DoubleChestInventory) { + isMovable = false; + break; + } + } + } + } + } + + if (isMovable) { + if (!isBlocksAllowedToInteract(copyWithAdd(blocks, toBreak), piston.getFacing())) + return; + Collections.reverse(blocks); + for (Block block1 : toBreak) { + block1.breakNaturally(); + } + for (Block b : blocks) { + Block b2 = b.getRelative(piston.getFacing()); + b2.setType(b.getType()); + b2.setData(b.getData()); //Deprecated but powerful + if (b.getType().equals(Material.CHEST)) { + Chest oldChest = (Chest) b.getState(); + Chest newChest = (Chest) b2.getState(); + newChest.getBlockInventory().setContents(oldChest.getBlockInventory().getContents()); + oldChest.getBlockInventory().clear(); + } else if (b.getType().equals(Material.FURNACE) || b.getType().equals(Material.BURNING_FURNACE)) { + Furnace oldFurnace = (Furnace) b.getState(); + Furnace newFurnace = (Furnace) b2.getState(); + newFurnace.getInventory().setContents(oldFurnace.getInventory().getContents()); + oldFurnace.getInventory().clear(); + } + b.setType(Material.AIR); } - b.setType(Material.AIR); } } } @@ -395,9 +555,9 @@ public class WorldListener implements Listener { Optional op = Bukkit.getOnlinePlayers().stream().min(Comparator.comparingDouble(p -> p.getLocation().distance(location))); if (op.isPresent()) { String[] groups = ExtendedPistons.INSTANCE.permsService.getPlayerGroups(op.get()); - Optional intOp = Arrays.stream(groups).map(group -> (ExtendedPistons.INSTANCE.conf.isSet("piston-move-limitations." + group) && ExtendedPistons.INSTANCE.conf.isInt("piston-move-limitations." + group))?ExtendedPistons.INSTANCE.conf.getInt("piston-move-limitations." + group):0).max(Comparator.comparingInt(i -> i)); - if(intOp.isPresent()) { - return intOp.get()==0?12:intOp.get(); + Optional intOp = Arrays.stream(groups).map(group -> (ExtendedPistons.INSTANCE.conf.isSet("piston-move-limitations." + group) && ExtendedPistons.INSTANCE.conf.isInt("piston-move-limitations." + group)) ? ExtendedPistons.INSTANCE.conf.getInt("piston-move-limitations." + group) : 0).max(Comparator.comparingInt(i -> i)); + if (intOp.isPresent()) { + return intOp.get() == 0 ? 12 : intOp.get(); } } return 12; @@ -408,11 +568,11 @@ public class WorldListener implements Listener { RegionContainer container = wg.getRegionContainer(); RegionQuery query = container.createQuery(); for (Block block : blocks) { - boolean state = query.testState(block.getLocation(),(Player)null, DefaultFlag.PISTONS); - if(!state) + boolean state = query.testState(block.getLocation(), (Player) null, DefaultFlag.PISTONS); + if (!state) return false; - state = query.testState(block.getRelative(bf).getLocation(),(Player)null, DefaultFlag.PISTONS); - if(!state) + state = query.testState(block.getRelative(bf).getLocation(), (Player) null, DefaultFlag.PISTONS); + if (!state) return false; } return true;