/** * Checks if the player is on a ladder or vine. * * @return If so. */ public boolean isOnClimbable() { if (onClimbable == null) { // Climbable blocks. if (blockFlags != null && (blockFlags.longValue() & BlockProperties.F_CLIMBABLE) == 0) { onClimbable = false; return false; } onClimbable = (BlockProperties.getBlockFlags(getTypeId()) & BlockProperties.F_CLIMBABLE) != 0; // TODO: maybe use specialized bounding box. // final double d = 0.1d; // onClimbable = BlockProperties.collides(getBlockAccess(), minX - d, minY - d, minZ // - d, maxX + d, minY + 1.0, maxZ + d, BlockProperties.F_CLIMBABLE); } return onClimbable; }
/** * Checks if the player is on ground, including entities such as Minecart, Boat. * * @return true, if the player is on ground */ public boolean isOnGround() { if (onGround != null) { return onGround; } // Check cached values and simplifications. if (notOnGroundMaxY >= yOnGround) onGround = false; else if (onGroundMinY <= yOnGround) onGround = true; else { // Shortcut check (currently needed for being stuck + sf). if (blockFlags == null || (blockFlags.longValue() & BlockProperties.F_GROUND) != 0) { // TODO: Consider dropping this shortcut. final int bY = Location.locToBlock(y - yOnGround); final int id = bY == blockY ? getTypeId() : (bY == blockY - 1 ? getTypeIdBelow() : blockCache.getTypeId(blockX, bY, blockZ)); final long flags = BlockProperties.getBlockFlags(id); // TODO: Might remove check for variable ? if ((flags & BlockProperties.F_GROUND) != 0 && (flags & BlockProperties.F_VARIABLE) == 0) { final double[] bounds = blockCache.getBounds(blockX, bY, blockZ); // Check collision if not inside of the block. [Might be a problem for cauldron or similar // + something solid above.] // TODO: Might need more refinement. if (bounds != null && y - bY >= bounds[4] && BlockProperties.collidesBlock( blockCache, x, minY - yOnGround, z, x, minY, z, blockX, bY, blockZ, id, bounds, flags)) { // TODO: BlockHeight is needed for fences, use right away (above)? if (!BlockProperties.isPassableWorkaround( blockCache, blockX, bY, blockZ, minX - blockX, minY - yOnGround - bY, minZ - blockZ, id, maxX - minX, yOnGround, maxZ - minZ, 1.0) || (flags & BlockProperties.F_GROUND_HEIGHT) != 0 && BlockProperties.getGroundMinHeight( blockCache, blockX, bY, blockZ, id, bounds, flags) <= y - bY) { // // NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, "*** // onground SHORTCUT"); onGround = true; } } } if (onGround == null) { // // NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, "*** fetch // onground std"); // Full on-ground check (blocks). // Note: Might check for half-block height too (getTypeId), but that is much more seldom. onGround = BlockProperties.isOnGround( blockCache, minX, minY - yOnGround, minZ, maxX, minY, maxZ, 0L); } } else onGround = false; } if (onGround) onGroundMinY = Math.min(onGroundMinY, yOnGround); else { // NCPAPIProvider.getNoCheatPlusAPI().getLogManager().debug(Streams.TRACE_FILE, "*** // onground check entities"); // TODO: further confine this ? notOnGroundMaxY = Math.max(notOnGroundMaxY, yOnGround); final double d1 = 0.25D; onGround = blockCache.standsOnEntity( player, minX - d1, minY - yOnGround - d1, minZ - d1, maxX + d1, minY + 0.25 + d1, maxZ + d1); } return onGround; }
/** * Checks if the player is above a ladder or vine.<br> * Does not save back value to field. * * @return If so. */ public boolean isAboveLadder() { if (blockFlags != null && (blockFlags.longValue() & BlockProperties.F_CLIMBABLE) == 0) return false; // TODO: bounding box ? return (BlockProperties.getBlockFlags(getTypeIdBelow()) & BlockProperties.F_CLIMBABLE) != 0; }