diff --git a/pom.xml b/pom.xml index 88ffc1d..d825fb4 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ xyz.dcaron.bridges RetractableBridges - 1.0-SNAPSHOT + 1.1.1-SNAPSHOT RetractableBridges diff --git a/src/main/java/xyz/dcaron/bridges/Bridge.java b/src/main/java/xyz/dcaron/bridges/Bridge.java index ed73380..1b13145 100644 --- a/src/main/java/xyz/dcaron/bridges/Bridge.java +++ b/src/main/java/xyz/dcaron/bridges/Bridge.java @@ -1,15 +1,20 @@ package xyz.dcaron.bridges; +import java.util.Optional; import java.util.Set; import org.bukkit.Material; import org.bukkit.block.BlockFace; +import org.bukkit.block.data.BlockData; +import org.bukkit.block.data.type.Slab; +import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; @EqualsAndHashCode +@AllArgsConstructor public class Bridge { @Getter @@ -24,18 +29,8 @@ public class Bridge { @Getter @Setter private Set blockedDirections; - - public Bridge(final String worldName, final int x, final int z, final int y, final int width, final int height, - final Material type, final Set blockedDirections) { - this.worldName = worldName; - this.x = x; - this.z = z; - this.y = y; - this.width = width; - this.height = height; - this.type = type; - this.blockedDirections = blockedDirections; - } + @Getter + private final Optional slabType; @Override public String toString() { @@ -50,4 +45,12 @@ public String toString() { return sb.toString(); } + public static Optional getSlabType(final BlockData data) { + + if (data instanceof Slab) { + return Optional.of(((Slab) data).getType()); + } + return Optional.empty(); + } + } diff --git a/src/main/java/xyz/dcaron/bridges/BridgeBlockListener.java b/src/main/java/xyz/dcaron/bridges/BridgeBlockListener.java index 69a6e57..e77a0bf 100644 --- a/src/main/java/xyz/dcaron/bridges/BridgeBlockListener.java +++ b/src/main/java/xyz/dcaron/bridges/BridgeBlockListener.java @@ -10,6 +10,7 @@ import org.bukkit.World; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; +import org.bukkit.block.data.type.Slab; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; @@ -85,6 +86,10 @@ public void onRedstoneBlockChange(final BlockRedstoneEvent event) { } + private boolean materialWithSlabToBlockEquals(final Block blockToCompare, Material material, Optional slabType) { + return blockToCompare.getType().equals(material) && Bridge.getSlabType(blockToCompare.getBlockData()).equals(slabType); + } + /** * Find a bridge above the adjacent block. A bridge is a rectangular area of * slabs or double slabs, parallel to the ground. It can have no holes or bits @@ -110,30 +115,34 @@ private Optional findBridge(final Block block, final BlockFace direction int y = aboveBlock.getY(); int z = aboveBlock.getZ(); int width = 1, height = 1; + final Material material = aboveBlock.getType(); + // Record the slab orientation if the block is a slab. + final Optional slabType = Bridge.getSlabType(aboveBlock.getBlockData()); + Block adjacentBlock = aboveBlock.getRelative(BlockFace.WEST); - while (adjacentBlock.getType().equals(material)) { + while (materialWithSlabToBlockEquals(adjacentBlock, material, slabType)) { x--; width++; adjacentBlock = adjacentBlock.getRelative(BlockFace.WEST); } adjacentBlock = aboveBlock.getRelative(BlockFace.NORTH); - while (adjacentBlock.getType().equals(material)) { + while (materialWithSlabToBlockEquals(adjacentBlock, material, slabType)) { z--; height++; adjacentBlock = adjacentBlock.getRelative(BlockFace.NORTH); } adjacentBlock = aboveBlock.getRelative(BlockFace.EAST); - while (adjacentBlock.getType().equals(material)) { + while (materialWithSlabToBlockEquals(adjacentBlock, material, slabType)) { width++; adjacentBlock = adjacentBlock.getRelative(BlockFace.EAST); } adjacentBlock = aboveBlock.getRelative(BlockFace.SOUTH); - while (adjacentBlock.getType().equals(material)) { + while (materialWithSlabToBlockEquals(adjacentBlock, material, slabType)) { height++; adjacentBlock = adjacentBlock.getRelative(BlockFace.SOUTH); } @@ -146,7 +155,7 @@ private Optional findBridge(final Block block, final BlockFace direction for (int dz = 0; dz < height; dz++) { Block edgeBlock = world.getBlockAt(x - 1, y, z + dz); - if (edgeBlock.getType().equals(material)) { + if (materialWithSlabToBlockEquals(edgeBlock, material, slabType)) { // A block is sticking out. return Optional.empty(); } else if (!edgeBlock.getType().isAir()) { @@ -154,7 +163,7 @@ private Optional findBridge(final Block block, final BlockFace direction } edgeBlock = world.getBlockAt(x + width, y, z + dz); - if (edgeBlock.getType().equals(material)) { + if (materialWithSlabToBlockEquals(edgeBlock, material, slabType)) { // A block is sticking out. return Optional.empty(); } else if (!edgeBlock.getType().isAir()) { @@ -164,7 +173,7 @@ private Optional findBridge(final Block block, final BlockFace direction for (int dx = 0; dx < width; dx++) { Block edgeBlock = world.getBlockAt(x + dx, y, z - 1); - if (edgeBlock.getType().equals(material)) { + if (materialWithSlabToBlockEquals(edgeBlock, material, slabType)) { // A block is sticking out. return Optional.empty(); } else if (!edgeBlock.getType().isAir()) { @@ -173,14 +182,14 @@ private Optional findBridge(final Block block, final BlockFace direction for (int dz = 0; dz < height; dz++) { final Block bridgeBlock = world.getBlockAt(x + dx, y, z + dz); - if (!bridgeBlock.getType().equals(material)) { + if (!materialWithSlabToBlockEquals(bridgeBlock, material, slabType)) { // There is a hole in the bridge. return Optional.empty(); } } edgeBlock = world.getBlockAt(x + dx, y, z + height); - if (edgeBlock.getType().equals(material)) { + if (materialWithSlabToBlockEquals(edgeBlock, material, slabType)) { // A block is sticking out. return Optional.empty(); } else if (!edgeBlock.getType().isAir()) { @@ -191,7 +200,7 @@ private Optional findBridge(final Block block, final BlockFace direction // The bridge is a proper rectangle. if (this.blockedInThreeDirections(blockedDirections) || this.opposingDirectionsAreBlocked(blockedDirections)) { - return Optional.of(new Bridge(world.getName(), x, z, y, width, height, material, blockedDirections)); + return Optional.of(new Bridge(world.getName(), x, z, y, width, height, material, blockedDirections, slabType)); } } diff --git a/src/main/java/xyz/dcaron/bridges/BridgeMover.java b/src/main/java/xyz/dcaron/bridges/BridgeMover.java index 7983341..0c5a7ae 100644 --- a/src/main/java/xyz/dcaron/bridges/BridgeMover.java +++ b/src/main/java/xyz/dcaron/bridges/BridgeMover.java @@ -154,7 +154,20 @@ private boolean tryToMove(final BlockFace direction, final World world, final Se // Its bridge moving time. BridgesPlugin.log("Moving bridge " + direction + " one row", Level.FINE); for (int i = 0; i < length; i++) { - world.getBlockAt(bridge.getX() + dx + i * xMult, bridge.getY(), bridge.getZ() + dz + i * zMult).setType(bridge.getType()); + final Block blockAhead = world.getBlockAt(bridge.getX() + dx + i * xMult, bridge.getY(), bridge.getZ() + dz + i * zMult); + + // Change the block type. + blockAhead.setType(bridge.getType()); + + // Loop hoisting will occurr here. + // Modify the block's remembered slab state. + bridge.getSlabType().ifPresent(slabType -> { + final BlockData data = blockAhead.getBlockData(); + if (data instanceof Slab) { + ((Slab) data).setType(slabType); + blockAhead.setBlockData(data); + } + }); } // Moves entities standing on the bridge.