Skip to content

Commit

Permalink
Slab data bug fix #2.
Browse files Browse the repository at this point in the history
  • Loading branch information
Dalton Caron committed Jun 29, 2022
1 parent bf1ae24 commit 7e4a2a8
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 24 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>xyz.dcaron.bridges</groupId>
<artifactId>RetractableBridges</artifactId>
<version>1.0-SNAPSHOT</version>
<version>1.1.1-SNAPSHOT</version>

<name>RetractableBridges</name>
<!-- FIXME change it to the project's website -->
Expand Down
27 changes: 15 additions & 12 deletions src/main/java/xyz/dcaron/bridges/Bridge.java
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -24,18 +29,8 @@ public class Bridge {
@Getter
@Setter
private Set<BlockFace> 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<BlockFace> 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<Slab.Type> slabType;

@Override
public String toString() {
Expand All @@ -50,4 +45,12 @@ public String toString() {
return sb.toString();
}

public static Optional<Slab.Type> getSlabType(final BlockData data) {

if (data instanceof Slab) {
return Optional.of(((Slab) data).getType());
}
return Optional.empty();
}

}
29 changes: 19 additions & 10 deletions src/main/java/xyz/dcaron/bridges/BridgeBlockListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -85,6 +86,10 @@ public void onRedstoneBlockChange(final BlockRedstoneEvent event) {

}

private boolean materialWithSlabToBlockEquals(final Block blockToCompare, Material material, Optional<Slab.Type> 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
Expand All @@ -110,30 +115,34 @@ private Optional<Bridge> 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<Slab.Type> 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);
}
Expand All @@ -146,15 +155,15 @@ private Optional<Bridge> 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()) {
blockedDirections.add(BlockFace.WEST);
}

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()) {
Expand All @@ -164,7 +173,7 @@ private Optional<Bridge> 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()) {
Expand All @@ -173,14 +182,14 @@ private Optional<Bridge> 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()) {
Expand All @@ -191,7 +200,7 @@ private Optional<Bridge> 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));
}
}

Expand Down
15 changes: 14 additions & 1 deletion src/main/java/xyz/dcaron/bridges/BridgeMover.java
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit 7e4a2a8

Please sign in to comment.