From 917f8a18420e30da17e6784a1b20316a6aae35f4 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Sat, 29 Jun 2019 17:52:40 -0400 Subject: [PATCH] Pass through wall improvements This change simplifies the algorithm greatly. Additionally, this fixes a bug where if standing in a non-solid block i.e. a glass pane, //thru, and the nav wand would not work. --- .../platform/AbstractPlayerActor.java | 91 +++++++++++-------- 1 file changed, 51 insertions(+), 40 deletions(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java index f51f992ac..c25c33f39 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java @@ -394,51 +394,62 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable { } } + private boolean canPassThroughBlock(Location curBlock) { + BlockVector3 blockPos = curBlock.toVector().toBlockPoint(); + BlockState block = curBlock.getExtent().getBlock(blockPos); + return !block.getBlockType().getMaterial().isMovementBlocker(); + } + /** - * Get the player's view yaw. - * - * @return yaw + * Advances the block target block until the current block is a wall + * @return true if a wall is found */ - - @Override - public boolean passThroughForwardWall(int range) { - int searchDist = 0; - TargetBlock hitBlox = new TargetBlock(this, range, 0.2); - Extent world = getLocation().getExtent(); - Location block; - boolean firstBlock = true; - int freeToFind = 2; - boolean inFree = false; - - while ((block = hitBlox.getNextBlock()) != null) { - boolean free = !world.getBlock(block.toVector().toBlockPoint()).getBlockType().getMaterial().isMovementBlocker(); - - if (firstBlock) { - firstBlock = false; - - if (!free) { - --freeToFind; - continue; - } - } - - ++searchDist; - if (searchDist > 20) { - return false; - } - - if (inFree != free) { - if (free) { - --freeToFind; - } - } - - if (freeToFind == 0) { - setOnGround(block); + private boolean advanceToWall(TargetBlock hitBlox) { + Location curBlock; + while ((curBlock = hitBlox.getCurrentBlock()) != null) { + if (!canPassThroughBlock(curBlock)) { return true; } - inFree = free; + hitBlox.getNextBlock(); + } + + return false; + } + + /** + * Advances the block target block until the current block is a free + * @return true if a free spot is found + */ + private boolean advanceToFree(TargetBlock hitBlox) { + Location curBlock; + while ((curBlock = hitBlox.getCurrentBlock()) != null) { + if (canPassThroughBlock(curBlock)) { + return true; + } + + hitBlox.getNextBlock(); + } + + return false; + } + + @Override + public boolean passThroughForwardWall(int range) { + TargetBlock hitBlox = new TargetBlock(this, range, 0.2); + + if (!advanceToWall(hitBlox)) { + return false; + } + + if (!advanceToFree(hitBlox)) { + return false; + } + + Location foundBlock = hitBlox.getCurrentBlock(); + if (foundBlock != null) { + setOnGround(foundBlock); + return true; } return false;