forked from SteamWar/SteamWar
Use PistonStructureResolver in PistonCalculator
Numbering now comes directly from the vanilla resolver instead of a custom breadth-first search, so the order matches the real move order (including backtracking through slime/honey chains). The display of more than 12 blocks is removed; a blocked piston is shown in red. Refs: #158
This commit is contained in:
+27
-116
@@ -23,15 +23,17 @@ import de.steamwar.bausystem.BauSystem;
|
||||
import de.steamwar.bausystem.Permission;
|
||||
import de.steamwar.entity.*;
|
||||
import de.steamwar.linkage.Linked;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.level.block.piston.PistonStructureResolver;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.block.PistonMoveReaction;
|
||||
import org.bukkit.block.TileState;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.block.data.type.Piston;
|
||||
import org.bukkit.craftbukkit.CraftWorld;
|
||||
import org.bukkit.entity.Display;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.TextDisplay;
|
||||
@@ -170,7 +172,7 @@ public class PistonCalculator implements Listener {
|
||||
private boolean pulling = false;
|
||||
private List<Location> movedBlocks = new ArrayList<>();
|
||||
private List<Location> brokenBlocks = new ArrayList<>();
|
||||
private Set<Location> immovableBlocks = new HashSet<>();
|
||||
private boolean blocked = false;
|
||||
|
||||
public PistOrder(Block piston) {
|
||||
this.piston = piston;
|
||||
@@ -179,7 +181,7 @@ public class PistonCalculator implements Listener {
|
||||
public void calculate() {
|
||||
movedBlocks.clear();
|
||||
brokenBlocks.clear();
|
||||
immovableBlocks.clear();
|
||||
blocked = false;
|
||||
|
||||
if (piston.isEmpty()) {
|
||||
Bukkit.getScheduler().runTaskLater(BauSystem.getInstance(), () -> {
|
||||
@@ -199,7 +201,7 @@ public class PistonCalculator implements Listener {
|
||||
|
||||
pulling = piston.getType() == Material.STICKY_PISTON && (piston.getRelative(pistonData.getFacing()).getType() == Material.AIR || pistonData.isExtended());
|
||||
|
||||
calculate(piston, pistonData.getFacing(), (pulling ? pistonData.getFacing().getOppositeFace() : pistonData.getFacing()));
|
||||
resolve(pistonData.getFacing());
|
||||
|
||||
Collections.reverse(movedBlocks);
|
||||
Collections.reverse(brokenBlocks);
|
||||
@@ -207,86 +209,23 @@ public class PistonCalculator implements Listener {
|
||||
visualize();
|
||||
}
|
||||
|
||||
private void calculate(Block origin, BlockFace facing, BlockFace direction) {
|
||||
Block calcOrigin = origin;
|
||||
if (facing != direction) calcOrigin = origin.getRelative(facing, 3);
|
||||
|
||||
List<Block> toCalc = new LinkedList<>();
|
||||
calcDirection(origin, null, calcOrigin, facing != direction ? origin.getRelative(facing) : null, facing, direction, toCalc);
|
||||
|
||||
while (!toCalc.isEmpty()) {
|
||||
Block current = toCalc.remove(0);
|
||||
if (!movedBlocks.contains(current.getLocation())) {
|
||||
movedBlocks.add(current.getLocation());
|
||||
}
|
||||
|
||||
Material type = current.getType();
|
||||
if (type != Material.SLIME_BLOCK && type != Material.HONEY_BLOCK) continue;
|
||||
Material oppositeType = type == Material.SLIME_BLOCK ? Material.HONEY_BLOCK : Material.SLIME_BLOCK;
|
||||
|
||||
for (BlockFace face : FACES) {
|
||||
Block block = current.getRelative(face);
|
||||
if (block.getType().isAir()) continue;
|
||||
if (isImmovable(block) || block.getPistonMoveReaction() == PistonMoveReaction.BREAK) continue;
|
||||
if (face != direction || face == direction.getOppositeFace()) {
|
||||
switch (block.getType()) {
|
||||
case BLACK_GLAZED_TERRACOTTA:
|
||||
case GRAY_GLAZED_TERRACOTTA:
|
||||
case BLUE_GLAZED_TERRACOTTA:
|
||||
case BROWN_GLAZED_TERRACOTTA:
|
||||
case CYAN_GLAZED_TERRACOTTA:
|
||||
case GREEN_GLAZED_TERRACOTTA:
|
||||
case LIGHT_BLUE_GLAZED_TERRACOTTA:
|
||||
case LIGHT_GRAY_GLAZED_TERRACOTTA:
|
||||
case LIME_GLAZED_TERRACOTTA:
|
||||
case MAGENTA_GLAZED_TERRACOTTA:
|
||||
case ORANGE_GLAZED_TERRACOTTA:
|
||||
case PINK_GLAZED_TERRACOTTA:
|
||||
case PURPLE_GLAZED_TERRACOTTA:
|
||||
case RED_GLAZED_TERRACOTTA:
|
||||
case WHITE_GLAZED_TERRACOTTA:
|
||||
case YELLOW_GLAZED_TERRACOTTA:
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (block.getType() != oppositeType) {
|
||||
if (!movedBlocks.contains(block.getLocation())) toCalc.add(block);
|
||||
calcDirection(null, origin, block, null, facing, direction, toCalc);
|
||||
}
|
||||
}
|
||||
private void resolve(BlockFace facing) {
|
||||
PistonStructureResolver resolver = new PistonStructureResolver(
|
||||
((CraftWorld) piston.getWorld()).getHandle(),
|
||||
new BlockPos(piston.getX(), piston.getY(), piston.getZ()),
|
||||
Direction.valueOf(facing.name()),
|
||||
!pulling
|
||||
);
|
||||
if (!resolver.resolve()) {
|
||||
blocked = true;
|
||||
return;
|
||||
}
|
||||
|
||||
movedBlocks.remove(origin.getLocation());
|
||||
if (facing != direction) movedBlocks.remove(origin.getRelative(facing, 1).getLocation());
|
||||
if (pulling) immovableBlocks.remove(origin.getRelative(facing).getLocation());
|
||||
resolver.getToPush().forEach(pos -> movedBlocks.add(toLocation(pos)));
|
||||
resolver.getToDestroy().forEach(pos -> brokenBlocks.add(toLocation(pos)));
|
||||
}
|
||||
|
||||
private void calcDirection(Block origin, Block blockOrigin, Block calcOrigin, Block ignore, BlockFace facing, BlockFace direction, List<Block> toCalc) {
|
||||
for (int i = 1; i < 24; i++) {
|
||||
Block block = calcOrigin.getRelative(direction, i);
|
||||
if (block.equals(ignore)) return;
|
||||
if (block.getPistonMoveReaction() == PistonMoveReaction.BREAK) {
|
||||
if (!brokenBlocks.contains(block.getLocation())) {
|
||||
brokenBlocks.add(block.getLocation());
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (isImmovable(block)) {
|
||||
immovableBlocks.add(block.getLocation());
|
||||
return;
|
||||
}
|
||||
if (block.getType().isAir()) return;
|
||||
if (facing == direction && block.equals(blockOrigin)) {
|
||||
immovableBlocks.add(block.getLocation());
|
||||
return;
|
||||
}
|
||||
if (facing != direction && (block.equals(origin) || block.getRelative(facing.getOppositeFace()).equals(origin))) {
|
||||
return;
|
||||
}
|
||||
if (!movedBlocks.contains(block.getLocation())) toCalc.add(block);
|
||||
}
|
||||
private Location toLocation(BlockPos pos) {
|
||||
return new Location(piston.getWorld(), pos.getX(), pos.getY(), pos.getZ());
|
||||
}
|
||||
|
||||
private void visualize() {
|
||||
@@ -321,21 +260,11 @@ public class PistonCalculator implements Listener {
|
||||
textDisplay.setBrightness(new Display.Brightness(15, 15));
|
||||
}
|
||||
|
||||
for (Location location : immovableBlocks) {
|
||||
CWireframe wireframe = new CWireframe(server);
|
||||
wireframe.setPos1(location);
|
||||
wireframe.setPos2(location);
|
||||
wireframe.setWidth(1 / 32f);
|
||||
wireframe.setBlock(Material.RED_CONCRETE.createBlockData());
|
||||
}
|
||||
|
||||
CWireframe wireframe = new CWireframe(server);
|
||||
wireframe.setPos1(piston.getLocation());
|
||||
wireframe.setPos2(piston.getLocation());
|
||||
if (!immovableBlocks.isEmpty()) {
|
||||
if (blocked) {
|
||||
wireframe.setBlock(Material.RED_CONCRETE.createBlockData());
|
||||
} else if (movedBlocks.size() > 12) {
|
||||
wireframe.setBlock(Material.YELLOW_CONCRETE.createBlockData());
|
||||
} else {
|
||||
wireframe.setBlock(Material.LIME_CONCRETE.createBlockData());
|
||||
}
|
||||
@@ -348,7 +277,11 @@ public class PistonCalculator implements Listener {
|
||||
} else {
|
||||
text.append("§ePush\n");
|
||||
}
|
||||
text.append("§f").append(movedBlocks.size()).append(" §eBlocks");
|
||||
if (blocked) {
|
||||
text.append("§cBlocked");
|
||||
} else {
|
||||
text.append("§f").append(movedBlocks.size()).append(" §eBlocks");
|
||||
}
|
||||
textDisplay.setText(text.toString());
|
||||
textDisplay.setBillboard(Display.Billboard.CENTER);
|
||||
textDisplay.setAlignment(TextDisplay.TextAlignment.CENTER);
|
||||
@@ -358,26 +291,4 @@ public class PistonCalculator implements Listener {
|
||||
textDisplay.setBrightness(new Display.Brightness(15, 15));
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isImmovable(Block block) {
|
||||
if (block.isEmpty() || block.isLiquid()) {
|
||||
return false;
|
||||
}
|
||||
BlockData blockData = block.getBlockData();
|
||||
if (blockData instanceof Piston) {
|
||||
return ((Piston) blockData).isExtended();
|
||||
}
|
||||
if (block.getState() instanceof TileState) {
|
||||
return true;
|
||||
}
|
||||
PistonMoveReaction reaction = block.getPistonMoveReaction();
|
||||
if (reaction == PistonMoveReaction.IGNORE) return true;
|
||||
if (reaction == PistonMoveReaction.BLOCK) return true;
|
||||
switch (block.getType()) {
|
||||
case OBSIDIAN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user