Attempt to fix ladder climb up check.

Adds concept to ignore certain flags for isOnGround checking.
This commit is contained in:
asofold 2013-02-03 19:16:55 +01:00
parent 7bc9b709cd
commit f5676cc635
4 changed files with 47 additions and 10 deletions

View File

@ -1318,6 +1318,23 @@ public class BlockProperties {
* @return * @return
*/ */
public static final boolean isOnGround(final BlockCache access, final double minX, double minY, final double minZ, final double maxX, final double maxY, final double maxZ){ public static final boolean isOnGround(final BlockCache access, final double minX, double minY, final double minZ, final double maxX, final double maxY, final double maxZ){
return isOnGround(access, minX, minY, minZ, maxX, maxY, maxZ, 0L);
}
/**
* Similar to collides(... , F_GROUND), but also checks the block above (against spider).<br>
* NOTE: This does not return true if stuck, to check for that use collidesBlock for the players location.
* @param access
* @param minX
* @param minY
* @param minZ
* @param maxX
* @param maxY
* @param maxZ
* @param ignoreFlags Blocks with these flags are not counted as ground.
* @return
*/
public static final boolean isOnGround(final BlockCache access, final double minX, double minY, final double minZ, final double maxX, final double maxY, final double maxZ, final long ignoreFlags){
final int maxBlockY = access.getMaxBlockY(); final int maxBlockY = access.getMaxBlockY();
final int iMinX = Location.locToBlock(minX); final int iMinX = Location.locToBlock(minX);
final int iMaxX = Location.locToBlock(maxX); final int iMaxX = Location.locToBlock(maxX);
@ -1330,14 +1347,14 @@ public class BlockProperties {
for (int z = iMinZ; z <= iMaxZ; z++){ for (int z = iMinZ; z <= iMaxZ; z++){
for (int y = iMinY; y <= iMaxY; y++){ for (int y = iMinY; y <= iMaxY; y++){
final int id = access.getTypeId(x, y, z); final int id = access.getTypeId(x, y, z);
if ((blockFlags[id] & F_GROUND) != 0){ if ((blockFlags[id] & F_GROUND) != 0 && (blockFlags[id] & ignoreFlags) == 0){
// Might collide. // Might collide.
if (collidesBlock(access, minX, minY, minZ, maxX, maxY, maxZ, x, y, z, id)){ if (collidesBlock(access, minX, minY, minZ, maxX, maxY, maxZ, x, y, z, id)){
if (y >= maxBlockY) return true; if (y >= maxBlockY) return true;
final int aboveId = access.getTypeId(x, y + 1, z); final int aboveId = access.getTypeId(x, y + 1, z);
final long flags = blockFlags[aboveId]; final long flags = blockFlags[aboveId];
if ((flags & (F_IGN_PASSABLE)) != 0); // Ignore these. if ((flags & F_IGN_PASSABLE) != 0); // Ignore these.
else if ((flags & (F_GROUND)) != 0){ else if ((flags & F_GROUND) != 0 && (flags & ignoreFlags) == 0){
// Check against spider type hacks. // Check against spider type hacks.
if (collidesBlock(access, minX, minY, minZ, maxX, Math.max(maxY, 1.49 + y), maxZ, x, y + 1, z, aboveId)){ if (collidesBlock(access, minX, minY, minZ, maxX, Math.max(maxY, 1.49 + y), maxZ, x, y + 1, z, aboveId)){
// TODO: This might be seen as a violation for many block types. // TODO: This might be seen as a violation for many block types.

View File

@ -368,6 +368,7 @@ public class PlayerLocation {
// Finally check possible jump height. // Finally check possible jump height.
// TODO: This too is inaccurate. // TODO: This too is inaccurate.
if (isOnGround(jumpHeigth)){ if (isOnGround(jumpHeigth)){
// Here ladders are ok.
return true; return true;
} }
return false; return false;
@ -415,7 +416,7 @@ public class PlayerLocation {
onGround = true; onGround = true;
} }
// Note: Might check for half-block height too (getTypeId), but that is much more seldom. // Note: Might check for half-block height too (getTypeId), but that is much more seldom.
else onGround = BlockProperties.isOnGround(blockCache, minX - d0, minY - yOnGround, minZ - d0, maxX + d0, minY + 0.25, maxZ + d0); else onGround = BlockProperties.isOnGround(blockCache, minX - d0, minY - yOnGround, minZ - d0, maxX + d0, minY + 0.25, maxZ + d0, 0L);
} }
else onGround = false; else onGround = false;
if (!onGround) { if (!onGround) {
@ -432,7 +433,11 @@ public class PlayerLocation {
* @return * @return
*/ */
public boolean isOnGround(final double yOnGround){ public boolean isOnGround(final double yOnGround){
return isOnGround(yOnGround, 0D, 0D); return isOnGround(yOnGround, 0D, 0D, 0L);
}
public boolean isOnGround(final double jumpHeight, final long ignoreFlags) {
return isOnGround(yOnGround, 0D, 0D, ignoreFlags);
} }
@ -444,7 +449,19 @@ public class PlayerLocation {
* @return * @return
*/ */
public boolean isOnGround(final double yOnGround, final double xzMargin, final double yMargin) { public boolean isOnGround(final double yOnGround, final double xzMargin, final double yMargin) {
return BlockProperties.isOnGround(blockCache, minX - xzMargin, minY - yOnGround - yMargin, minZ - xzMargin, maxX + xzMargin, minY + yMargin, maxZ + xzMargin); return BlockProperties.isOnGround(blockCache, minX - xzMargin, minY - yOnGround - yMargin, minZ - xzMargin, maxX + xzMargin, minY + yMargin, maxZ + xzMargin, 0L);
}
/**
* Simple block-on-ground check for given margin (no entities). Meant for checking bigger margin than the normal yOnGround.
* @param yOnGround Margin below the player.
* @param xzMargin
* @param yMargin Extra margin added below and above.
* @param ignoreFlags Flags to not regard as ground.
* @return
*/
public boolean isOnGround(final double yOnGround, final double xzMargin, final double yMargin, final long ignoreFlags) {
return BlockProperties.isOnGround(blockCache, minX - xzMargin, minY - yOnGround - yMargin, minZ - xzMargin, maxX + xzMargin, minY + yMargin, maxZ + xzMargin, ignoreFlags);
} }
/** /**

View File

@ -890,7 +890,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
newVal = Math.sqrt(velocity.getX() * velocity.getX() + velocity.getZ() * velocity.getZ()); newVal = Math.sqrt(velocity.getX() * velocity.getX() + velocity.getZ() * velocity.getZ());
if (newVal > 0D) { if (newVal > 0D) {
data.horizontalFreedom += newVal; data.horizontalFreedom += newVal;
data.horizontalVelocityCounter = 50; // Math.min(100, (int) Math.round(newVal * 8.0)); // 30; data.horizontalVelocityCounter = 50; // Math.min(100, (int) Math.round(newVal * 10.0)); // 30;
} }
// Set dirty flag here. // Set dirty flag here.

View File

@ -241,13 +241,16 @@ public class SurvivalFly extends Check {
// vDistanceAboveLimit = Math.abs(yDistance) - vAllowedDistance; // vDistanceAboveLimit = Math.abs(yDistance) - vAllowedDistance;
// if (vDistanceAboveLimit > 0) tags.add("vclimb"); // if (vDistanceAboveLimit > 0) tags.add("vclimb");
final double jumpHeight = 1.45 + (data.jumpAmplifier > 0 ? (0.5 + data.jumpAmplifier - 1.0) : 0.0); final double jumpHeight = 1.45 + (data.jumpAmplifier > 0 ? (0.5 + data.jumpAmplifier - 1.0) : 0.0);
if (yDistance > climbSpeed && !from.isOnGround(jumpHeight)){ // TODO: ladders are ground !
if (yDistance > climbSpeed && !from.isOnGround(jumpHeight, 0D, 0D, BlockProperties.F_CLIMBABLE)){
// Ignore ladders. TODO: Check for false positives...
tags.add("climbspeed"); tags.add("climbspeed");
vDistanceAboveLimit = Math.max(vDistanceAboveLimit, yDistance - climbSpeed); vDistanceAboveLimit = Math.max(vDistanceAboveLimit, yDistance - climbSpeed);
} }
if (yDistance > 0){ if (yDistance > 0){
if (!fromOnGround && ! toOnGround && !data.noFallAssumeGround){ if (!fromOnGround && ! toOnGround && !data.noFallAssumeGround){
// Check if player may climb up. // Check if player may climb up.
// (This does exclude ladders.)
if (!from.canClimbUp(jumpHeight)){ if (!from.canClimbUp(jumpHeight)){
tags.add("climbup"); tags.add("climbup");
vDistanceAboveLimit = Math.max(vDistanceAboveLimit, yDistance); vDistanceAboveLimit = Math.max(vDistanceAboveLimit, yDistance);
@ -503,7 +506,7 @@ public class SurvivalFly extends Check {
final double minY = Math.min(data.toY, Math.min(data.fromY, from.getY())); final double minY = Math.min(data.toY, Math.min(data.fromY, from.getY()));
final double iY = minY; // TODO ... final double iY = minY; // TODO ...
final double r = from.getWidth() / 2.0; // TODO: check + 0.35; final double r = from.getWidth() / 2.0; // TODO: check + 0.35;
if (BlockProperties.isOnGround(from.getBlockCache(), Math.min(data.fromX, from.getX()) - r, iY - cc.yOnGround, Math.min(data.fromZ, from.getZ()) - r, Math.max(data.fromX, from.getX()) + r, iY + 0.25, Math.max(data.fromZ, from.getZ()) + r)) { if (BlockProperties.isOnGround(from.getBlockCache(), Math.min(data.fromX, from.getX()) - r, iY - cc.yOnGround, Math.min(data.fromZ, from.getZ()) - r, Math.max(data.fromX, from.getX()) + r, iY + 0.25, Math.max(data.fromZ, from.getZ()) + r, 0L)) {
useWorkaround = true; useWorkaround = true;
setBackSafe = true; setBackSafe = true;
} }