Improved algorithm for /thru.

This commit is contained in:
sk89q 2011-01-26 11:23:24 -08:00
parent 7dbb23051a
commit 26e72abc3e

View File

@ -88,6 +88,27 @@ public abstract class LocalPlayer {
y++; y++;
} }
} }
/**
* Set the player on the ground.
*
* @param searchPos
*/
public void setOnGround(WorldVector searchPos) {
LocalWorld world = searchPos.getWorld();
int x = searchPos.getBlockX();
int y = Math.max(0, searchPos.getBlockY());
int z = searchPos.getBlockZ();
while (y >= 0) {
if (!BlockType.canPassThrough(world.getBlockType(new Vector(x, y, z)))) {
setPosition(new Vector(x + 0.5, y + 1, z + 0.5));
return;
}
y--;
}
}
/** /**
* Find a position for the player to stand that is not inside a block. * Find a position for the player to stand that is not inside a block.
@ -412,28 +433,45 @@ public abstract class LocalPlayer {
* @return whether the player was pass through * @return whether the player was pass through
*/ */
public boolean passThroughForwardWall(int range) { public boolean passThroughForwardWall(int range) {
boolean foundNext = false;
int searchDist = 0; int searchDist = 0;
TargetBlock hitBlox = new TargetBlock(this, range, 0.2); TargetBlock hitBlox = new TargetBlock(this, range, 0.2);
LocalWorld world = getPosition().getWorld(); LocalWorld world = getPosition().getWorld();
BlockWorldVector block; BlockWorldVector block;
boolean firstBlock = true;
int freeToFind = 2;
boolean inFree = false;
while ((block = hitBlox.getNextBlock()) != null) { while ((block = hitBlox.getNextBlock()) != null) {
boolean free = BlockType.canPassThrough(world.getBlockType(block));
if (firstBlock) {
firstBlock = false;
if (!free) {
freeToFind--;
continue;
}
}
searchDist++; searchDist++;
if (searchDist > 20) { if (searchDist > 20) {
return false; return false;
} }
if (BlockType.canPassThrough(world.getBlockType(block))) {
if (foundNext) { if (inFree != free) {
Vector v = new Vector(block.getX(), block.getY() - 1, block.getZ()); if (free) {
if (BlockType.canPassThrough(world.getBlockType(v))) { freeToFind--;
setPosition(v.add(0.5, 0, 0.5));
return true;
}
} }
} else {
foundNext = true;
} }
if (freeToFind == 0) {
setOnGround(block);
return true;
}
inFree = free;
} }
return false; return false;
} }