Better world border collision check + WorldBorder#getCollisionAxis

This commit is contained in:
Felix Cravic 2020-05-27 01:15:21 +02:00
parent ef261c1792
commit f5f5a6bb4e
2 changed files with 50 additions and 15 deletions

View File

@ -312,13 +312,28 @@ public abstract class Entity implements Viewable, EventHandler, DataContainer {
); );
onGround = CollisionUtils.handlePhysics(this, deltaPos, newPosition, newVelocityOut); onGround = CollisionUtils.handlePhysics(this, deltaPos, newPosition, newVelocityOut);
WorldBorder worldBorder = instance.getWorldBorder(); // World border collision
if (worldBorder.isInside(newPosition)) { {
// Apply velocity + gravity WorldBorder worldBorder = instance.getWorldBorder();
refreshPosition(newPosition); WorldBorder.CollisionAxis collisionAxis = worldBorder.getCollisionAxis(newPosition);
} else { switch (collisionAxis) {
// Only apply Y velocity/gravity case NONE:
refreshPosition(position.getX(), newPosition.getY(), position.getZ()); // Apply velocity + gravity
refreshPosition(newPosition);
break;
case BOTH:
// Apply Y velocity/gravity
refreshPosition(position.getX(), newPosition.getY(), position.getZ());
break;
case X:
// Apply Y/Z velocity/gravity
refreshPosition(position.getX(), newPosition.getY(), newPosition.getZ());
break;
case Z:
// Apply X/Y velocity/gravity
refreshPosition(newPosition.getX(), newPosition.getY(), position.getZ());
break;
}
} }
velocity.copy(newVelocityOut); velocity.copy(newVelocityOut);

View File

@ -41,7 +41,7 @@ public class WorldBorder {
refreshCenter(); refreshCenter();
} }
public double getCenterX() { public float getCenterX() {
return centerX; return centerX;
} }
@ -50,7 +50,7 @@ public class WorldBorder {
refreshCenter(); refreshCenter();
} }
public double getCenterZ() { public float getCenterZ() {
return centerZ; return centerZ;
} }
@ -136,6 +136,26 @@ public class WorldBorder {
sendPacket(worldBorderPacket); sendPacket(worldBorderPacket);
} }
/**
* Used to check at which axis does the position collides with the world border
*
* @param position the position to check
* @return the axis where the position collides with the world border
*/
public CollisionAxis getCollisionAxis(Position position) {
final double radius = getDiameter() / 2d;
final boolean checkX = position.getX() <= getCenterX() + radius && position.getX() >= getCenterX() - radius;
final boolean checkZ = position.getZ() <= getCenterZ() + radius && position.getZ() >= getCenterZ() - radius;
if (!checkX && !checkZ) {
return CollisionAxis.BOTH;
} else if (!checkX) {
return CollisionAxis.X;
} else if (!checkZ) {
return CollisionAxis.Z;
}
return CollisionAxis.NONE;
}
/** /**
* Used to know if a position is located inside the world border or not * Used to know if a position is located inside the world border or not
* *
@ -143,12 +163,7 @@ public class WorldBorder {
* @return true if {@code position} is inside the world border, false otherwise * @return true if {@code position} is inside the world border, false otherwise
*/ */
public boolean isInside(Position position) { public boolean isInside(Position position) {
final double radius = getDiameter() / 2d; return getCollisionAxis(position) == CollisionAxis.NONE;
final boolean checkX = position.getX() < getCenterX() + radius && position.getX() > getCenterX() - radius;
if (!checkX)
return false;
final boolean checkZ = position.getZ() < getCenterZ() + radius && position.getZ() > getCenterZ() - radius;
return checkZ;
} }
/** /**
@ -199,4 +214,9 @@ public class WorldBorder {
private void sendPacket(WorldBorderPacket worldBorderPacket) { private void sendPacket(WorldBorderPacket worldBorderPacket) {
instance.getPlayers().forEach(player -> player.getPlayerConnection().sendPacket(worldBorderPacket)); instance.getPlayers().forEach(player -> player.getPlayerConnection().sendPacket(worldBorderPacket));
} }
public enum CollisionAxis {
X, Z, BOTH, NONE
}
} }