misc tweaks, forgot to commit last week
This commit is contained in:
@@ -34,11 +34,22 @@ public class Blip {
|
||||
public static final int FULL_BLOCK = PER_BLOCK;
|
||||
public static final double RATIO = 0.0625;
|
||||
public static final int HALF_BLOCK = 8;
|
||||
public static final int PLAYER_HEIGHT = 29;
|
||||
public static final int PLAYER_HEIGHT_SLIGHT_UNDERESTIMATE = 28;
|
||||
public static final int PLAYER_HEIGHT_SLIGHT_OVERESTIMATE = PLAYER_HEIGHT_SLIGHT_UNDERESTIMATE + 1;
|
||||
public static final int TWO_BLOCKS = 2 * FULL_BLOCK;
|
||||
public static final int FEET_TO_EYE_APPROX = (int) (IPlayerContext.eyeHeight(false) / RATIO);
|
||||
|
||||
public static double playerEyeFromFeetBlips(int feetBlips, boolean sneaking) {
|
||||
return feetBlips * RATIO + IPlayerContext.eyeHeight(sneaking);
|
||||
}
|
||||
|
||||
static {
|
||||
double realPlayerHeight = 1.8;
|
||||
if (PLAYER_HEIGHT_SLIGHT_OVERESTIMATE * RATIO <= realPlayerHeight || PLAYER_HEIGHT_SLIGHT_UNDERESTIMATE * RATIO >= realPlayerHeight) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
if (PER_BLOCK * RATIO != 1) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,6 +256,9 @@ public class BlockStateCachedDataBuilder {
|
||||
if (collisionHeightBlips != null && (collisionHeightBlips > Blip.FULL_BLOCK + Blip.HALF_BLOCK || collisionHeightBlips <= 0)) { // playerphysics assumes this is never true
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
if (collidesWithPlayer && collisionHeightBlips == null) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
if (fullyWalkableTop && !collidesWithPlayer) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@@ -134,6 +134,15 @@ public class BlockStatePlacementOption {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* In EnumFacing.getDirectionFromEntityLiving, it checks if the player feet is within 2 blocks of the center of the block to be placed.
|
||||
* Normally, this is a nonissue, but a problem arises because we are considering hypothetical placements where the player stands at the exact +0.5,+0.5 center of a block.
|
||||
* In that case, it's possible for our hypothetical to have the player at precisely 2 blocks away, i.e. precisely on the edge of this condition being true or false.
|
||||
* For that reason, we treat those exact cases as "ambiguous". So, if the distance is within this tolerance of 2 (so, 1.99 to 2.01), we treat it as a "could go either way",
|
||||
* because when we really get there in-game, floating point inaccuracy could indeed actually make it go either way.
|
||||
*/
|
||||
private static final double ENTITY_FACING_TOLERANCE = 0.01;
|
||||
|
||||
private boolean directionOk(Vec3d eye, Vec3d hit) {
|
||||
if (playerMustBeHorizontalFacing.isPresent()) {
|
||||
return eye.flatDirectionTo(hit) == playerMustBeHorizontalFacing.get();
|
||||
@@ -146,27 +155,25 @@ public class BlockStatePlacementOption {
|
||||
// see EnumFacing.getDirectionFromEntityLiving
|
||||
double dx = Math.abs(eye.x - 0.5);
|
||||
double dz = Math.abs(eye.z - 0.5);
|
||||
if (dx < 1.99 && dz < 1.99) {
|
||||
// both within 2 = normal
|
||||
if (eye.y < 0) {
|
||||
if (dx < 2 - ENTITY_FACING_TOLERANCE && dz < 2 - ENTITY_FACING_TOLERANCE) { // < 1.99
|
||||
if (eye.y < 0) { // eye below placement level = it will be facing down, so this is only okay if we wantthat
|
||||
return entFace == Face.DOWN;
|
||||
}
|
||||
if (eye.y > 2) {
|
||||
if (eye.y > 2) { // same for up, if y>2 then it will be facing up
|
||||
return entFace == Face.UP;
|
||||
}
|
||||
} else if (!(dx > 2.01 || dz > 2.01)) {
|
||||
// ambiguous case
|
||||
// UP/DOWN are impossible (caught by flat check), and anything that could cause up/down instead of horizontal is also not allowed sadly
|
||||
} else if (!(dx > 2 + ENTITY_FACING_TOLERANCE || dz > 2 + ENTITY_FACING_TOLERANCE)) { // > 2.01
|
||||
// this is the ambiguous case, because we are neither unambiguously both-within-2 (previous case), nor unambiguously either-above-two (this elseif condition).
|
||||
// UP/DOWN are impossible, but that's caught by flat check
|
||||
if (eye.y < 0 || eye.y > 2) {
|
||||
return false;
|
||||
return false; // anything that could cause up/down instead of horizontal is also not allowed sadly
|
||||
}
|
||||
} // else either is above 2.01, putting us in simple horizontal mode, so fallthrough to flat condition is correct, yay
|
||||
} // else we are in unambiguous either-above-two, putting us in simple horizontal mode, so fallthrough to flat condition is correct, yay
|
||||
return eye.flatDirectionTo(hit) == entFace.opposite();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static BlockStatePlacementOption get(Face against, Half half, Optional<Face> playerMustBeHorizontalFacing, Optional<Face> playerMustBeEntityFacing) {
|
||||
BlockStatePlacementOption ret = PLACEMENT_OPTION_SINGLETON_CACHE[against.index][half.ordinal()][Face.OPTS.indexOf(playerMustBeHorizontalFacing)][Face.OPTS.indexOf(playerMustBeEntityFacing)];
|
||||
if (ret == null) {
|
||||
|
||||
@@ -21,6 +21,8 @@ public class PlayerPhysics {
|
||||
|
||||
/**
|
||||
* the player Y is within within. i.e. the player Y is greater than or equal within and less than within+1
|
||||
* <p>
|
||||
* returns a negative value if impossible. returns a >=0 value if possible.
|
||||
*/
|
||||
public static int determinePlayerRealSupport(BlockStateCachedData underneath, BlockStateCachedData within) {
|
||||
if (within.collidesWithPlayer) {
|
||||
@@ -52,7 +54,6 @@ public class PlayerPhysics {
|
||||
* YB
|
||||
* XC
|
||||
* SD
|
||||
*
|
||||
*/
|
||||
public static Collision playerTravelCollides(int feet,
|
||||
BlockStateCachedData U,
|
||||
@@ -68,7 +69,7 @@ public class PlayerPhysics {
|
||||
if (Main.DEBUG && (feet != determinePlayerRealSupport(S, X))) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
boolean alreadyWithinU = feet > Blip.TWO_BLOCKS - Blip.PLAYER_HEIGHT; // > and not >= because the player height is a slight overestimate
|
||||
boolean alreadyWithinU = feet > Blip.TWO_BLOCKS - Blip.PLAYER_HEIGHT_SLIGHT_OVERESTIMATE; // > and not >= because the player height is a slight overestimate
|
||||
if (Main.DEBUG && (alreadyWithinU && U.collidesWithPlayer)) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
@@ -92,27 +93,27 @@ public class PlayerPhysics {
|
||||
}
|
||||
return Collision.VOXEL_UP; // A is already checked, so that's it!
|
||||
}
|
||||
// betweenCandB is impossible. pessimistically, this means B is colliding. optimistically, this means B and C are air.
|
||||
// stepUp is impossible. pessimistically, this means B is colliding. optimistically, this means B and C are air.
|
||||
if (B.collidesWithPlayer) { // we have ruled out stepping on top of B, so now if B is still colliding there is no way forward
|
||||
return Collision.BLOCKED;
|
||||
}
|
||||
int stayLevel = determinePlayerRealSupport(D, C);
|
||||
if (stayLevel >= 0) {
|
||||
// fundamentally staying within the same vertical voxel, X -> C
|
||||
if (stayLevel > couldStepUpTo) {
|
||||
return Collision.BLOCKED;
|
||||
}
|
||||
if (stayLevel > Blip.TWO_BLOCKS - Blip.PLAYER_HEIGHT && !alreadyWithinU) { // step up, combined with our height, protrudes into U and A, AND we didn't already
|
||||
if (stayLevel > Blip.TWO_BLOCKS - Blip.PLAYER_HEIGHT_SLIGHT_OVERESTIMATE && !alreadyWithinU) { // step up, combined with our height, protrudes into U and A, AND we didn't already
|
||||
if (U.collidesWithPlayer) { // stayLevel could even be LESS than feet
|
||||
return Collision.BLOCKED;
|
||||
}
|
||||
if (A.collidesWithPlayer) {
|
||||
if (A.collidesWithPlayer) { // already checked (alreadyWithinU && A.collidesWithPlayer) earlier
|
||||
return Collision.BLOCKED;
|
||||
}
|
||||
}
|
||||
if (B.collidesWithPlayer) {
|
||||
return Collision.BLOCKED; // obv, our head will go into B
|
||||
}
|
||||
return Collision.VOXEL_LEVEL;
|
||||
}
|
||||
if (B.collidesWithPlayer || C.collidesWithPlayer) {
|
||||
if (C.collidesWithPlayer) {
|
||||
return Collision.BLOCKED;
|
||||
}
|
||||
if (!D.collidesWithPlayer) {
|
||||
@@ -132,7 +133,7 @@ public class PlayerPhysics {
|
||||
}
|
||||
|
||||
static {
|
||||
if (Blip.PLAYER_HEIGHT > Blip.TWO_BLOCKS || Blip.PLAYER_HEIGHT + Blip.HALF_BLOCK <= Blip.TWO_BLOCKS) {
|
||||
if (Blip.PLAYER_HEIGHT_SLIGHT_OVERESTIMATE >= Blip.TWO_BLOCKS || Blip.PLAYER_HEIGHT_SLIGHT_OVERESTIMATE + Blip.HALF_BLOCK <= Blip.TWO_BLOCKS) {
|
||||
throw new IllegalStateException("Assumptions made in playerTravelCollides");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user