Skip to content

Commit

Permalink
Fix stepping onto boats.
Browse files Browse the repository at this point in the history
  • Loading branch information
asofold committed Jan 26, 2016
1 parent 8985b67 commit c20d593
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 12 deletions.
Expand Up @@ -859,7 +859,12 @@ private double[] vDistAir(final long now, final Player player, final PlayerLocat
else if (resetFrom || data.thisMove.touchedGroundWorkaround) {
// TODO: More concise conditions? Some workaround may allow more.
if (toOnGround) {
vAllowedDistance = Math.max(cc.sfStepHeight, maxJumpGain + jumpGainMargin);
// Hack for boats (coarse: allows minecarts too).
if (yDistance > cc.sfStepHeight && yDistance - cc.sfStepHeight < 0.00000003 && to.isOnGroundDueToStandingOnAnEntity()) {
vAllowedDistance = yDistance;
} else {
vAllowedDistance = Math.max(cc.sfStepHeight, maxJumpGain + jumpGainMargin);
}
}
else {
// Code duplication with the absolute limit below.
Expand Down
Expand Up @@ -50,6 +50,12 @@ public class PlayerLocation {
/** Maximal yOnGround for which the player is not on ground. No extra xz/y margin.*/
private double notOnGroundMaxY = Double.MIN_VALUE;

/**
* Player is on ground, due to standing on an entity. (Might not get
* evaluated if the player is on ground anyway.)
*/
private boolean standsOnEntity = false;

// "Light" object members (reset to null) //

// TODO: The following should be changed to primitive types, add one long for "checked"-flags. Booleans can be compressed into a long.
Expand Down Expand Up @@ -495,8 +501,12 @@ public boolean isOnGround() {
return onGround;
}
// Check cached values and simplifications.
if (notOnGroundMaxY >= yOnGround) onGround = false;
else if (onGroundMinY <= yOnGround) onGround = true;
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) {
Expand Down Expand Up @@ -525,15 +535,17 @@ public boolean isOnGround() {
onGround = BlockProperties.isOnGround(blockCache, minX, minY - yOnGround, minZ, maxX, minY, maxZ, 0L);
}
}
else onGround = false;
else {
onGround = false;
}
}
if (onGround) {
onGroundMinY = Math.min(onGroundMinY, yOnGround);
}
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);
final double d1 = 0.25;
onGround = standsOnEntity = blockCache.standsOnEntity(player, minX - d1, minY - yOnGround - d1, minZ - d1, maxX + d1, minY + 0.25 + d1, maxZ + d1);
}
return onGround;
}
Expand Down Expand Up @@ -627,16 +639,29 @@ public boolean standsOnBlock(final int id) {
}

/**
* Simple check with custom margins (Boat, Minecart).
* @param yOnGround Margin below the player.
* Simple check with custom margins (Boat, Minecart). Does not update the
* internally stored standsOnEntity field.
*
* @param yOnGround
* Margin below the player.
* @param xzMargin
* @param yMargin Extra margin added below and above.
* @param yMargin
* Extra margin added below and above.
* @return
*/
public boolean standsOnEntity(final double yOnGround, final double xzMargin, final double yMargin) {
return blockCache.standsOnEntity(player, minX - xzMargin, minY - yOnGround - yMargin, minZ - xzMargin, maxX + xzMargin, minY + yMargin, maxZ + xzMargin);
}

/**
* Test if the player is just on ground due to standing on an entity.
*
* @return True, if the player is not standing on blocks, but on an entity.
*/
public boolean isOnGroundDueToStandingOnAnEntity() {
return isOnGround() && standsOnEntity; // Just ensure it is initialized.
}

/**
* Check if solid blocks hit the box.
* @param xzMargin
Expand Down Expand Up @@ -866,6 +891,7 @@ public void set(final Location location, final Player player, final double yOnGr
// Reset cached values.
typeId = typeIdBelow = data = null;
aboveStairs = inLava = inWater = inWeb = onGround = onIce = onClimbable = passable = null;
standsOnEntity = false;
onGroundMinY = Double.MAX_VALUE;
notOnGroundMaxY = Double.MIN_VALUE;
blockFlags = null;
Expand Down Expand Up @@ -1061,6 +1087,7 @@ private boolean coversDistance(final int x, final int y, final int z, final Dire
*/
public void prepare(final PlayerLocation other) {
this.onGround = other.isOnGround();
this.standsOnEntity = other.standsOnEntity;
this.inWater = other.isInWater();
this.inLava = other.isInLava();
this.inWeb = other.isInWeb();
Expand Down

0 comments on commit c20d593

Please sign in to comment.