mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-04 23:47:59 +01:00
Merge pull request #359 from Kebab11noel/fix/npe-collision
Fix collision
This commit is contained in:
commit
a2dbdbf32a
@ -69,16 +69,12 @@ public class CollisionUtils {
|
|||||||
// used to determine if 'remainingLength' should be used
|
// used to determine if 'remainingLength' should be used
|
||||||
boolean collisionFound = false;
|
boolean collisionFound = false;
|
||||||
for (int i = 0; i < Math.abs(blockLength); i++) {
|
for (int i = 0; i < Math.abs(blockLength); i++) {
|
||||||
final OneStepResult oneStepResult = stepOnce(instance, originChunk, axis, sign, corners);
|
if (collisionFound = stepOnce(instance, originChunk, axis, sign, corners)) break;
|
||||||
corners = oneStepResult.newCorners;
|
|
||||||
if (collisionFound = oneStepResult.foundCollision) break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add remainingLength
|
// add remainingLength
|
||||||
if (!collisionFound) {
|
if (!collisionFound) {
|
||||||
final OneStepResult oneStepResult = stepOnce(instance, originChunk, axis, remainingLength, corners);
|
collisionFound = stepOnce(instance, originChunk, axis, remainingLength, corners);
|
||||||
corners = oneStepResult.newCorners;
|
|
||||||
collisionFound = oneStepResult.foundCollision;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the corner which moved the least
|
// find the corner which moved the least
|
||||||
@ -99,38 +95,37 @@ public class CollisionUtils {
|
|||||||
* @param instance instance to get blocks from
|
* @param instance instance to get blocks from
|
||||||
* @param axis the axis to move along
|
* @param axis the axis to move along
|
||||||
* @param corners the corners of the bounding box to consider
|
* @param corners the corners of the bounding box to consider
|
||||||
* @return the result of one step
|
* @return true if found collision
|
||||||
*/
|
*/
|
||||||
private static OneStepResult stepOnce(Instance instance, Chunk originChunk, Vec axis, double amount, Vec[] corners) {
|
private static boolean stepOnce(Instance instance, Chunk originChunk, Vec axis, double amount, Vec[] corners) {
|
||||||
final double sign = Math.signum(amount);
|
final double sign = Math.signum(amount);
|
||||||
Vec[] newCorners = new Vec[corners.length];
|
|
||||||
for (int cornerIndex = 0; cornerIndex < corners.length; cornerIndex++) {
|
for (int cornerIndex = 0; cornerIndex < corners.length; cornerIndex++) {
|
||||||
final Vec originalCorner = corners[cornerIndex];
|
final Vec originalCorner = corners[cornerIndex];
|
||||||
final Vec corner = originalCorner.add(axis.mul(amount));
|
final Vec newCorner = originalCorner.add(axis.mul(amount));
|
||||||
|
|
||||||
Chunk chunk = ChunkUtils.retrieve(instance, originChunk, corner);
|
Chunk chunk = ChunkUtils.retrieve(instance, originChunk, newCorner);
|
||||||
if (!ChunkUtils.isLoaded(chunk)) {
|
if (!ChunkUtils.isLoaded(chunk)) {
|
||||||
// Collision at chunk border
|
// Collision at chunk border
|
||||||
return new OneStepResult(corners, true);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Block block = chunk.getBlock(corner);
|
final Block block = chunk.getBlock(newCorner);
|
||||||
|
|
||||||
// TODO: block collision boxes
|
// TODO: block collision boxes
|
||||||
// TODO: for the moment, always consider a full block
|
// TODO: for the moment, always consider a full block
|
||||||
if (block.isSolid()) {
|
if (block.isSolid()) {
|
||||||
newCorners[cornerIndex] = originalCorner.with(((x, y, z) -> new Vec(
|
corners[cornerIndex] = originalCorner.with(((x, y, z) -> new Vec(
|
||||||
Math.abs(axis.x()) > 10e-16 ? originalCorner.blockX() - axis.x() * sign : x,
|
Math.abs(axis.x()) > 10e-16 ? newCorner.blockX() - axis.x() * sign : x,
|
||||||
Math.abs(axis.y()) > 10e-16 ? originalCorner.blockY() - axis.y() * sign : y,
|
Math.abs(axis.y()) > 10e-16 ? newCorner.blockY() - axis.y() * sign : y,
|
||||||
Math.abs(axis.z()) > 10e-16 ? originalCorner.blockZ() - axis.z() * sign : z
|
Math.abs(axis.z()) > 10e-16 ? newCorner.blockZ() - axis.z() * sign : z
|
||||||
)));
|
)));
|
||||||
|
|
||||||
return new OneStepResult(newCorners, true);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
newCorners[cornerIndex] = corner;
|
corners[cornerIndex] = newCorner;
|
||||||
}
|
}
|
||||||
return new OneStepResult(newCorners, false);
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -196,14 +191,4 @@ public class CollisionUtils {
|
|||||||
this.foundCollision = foundCollision;
|
this.foundCollision = foundCollision;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class OneStepResult {
|
|
||||||
private final Vec[] newCorners;
|
|
||||||
private final boolean foundCollision;
|
|
||||||
|
|
||||||
public OneStepResult(Vec[] newCorners, boolean foundCollision) {
|
|
||||||
this.newCorners = newCorners;
|
|
||||||
this.foundCollision = foundCollision;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -531,28 +531,31 @@ public class Entity implements Viewable, Tickable, EventHandler<EntityEvent>, Da
|
|||||||
|
|
||||||
// Apply the position if changed
|
// Apply the position if changed
|
||||||
if (!finalVelocityPosition.samePoint(position)) {
|
if (!finalVelocityPosition.samePoint(position)) {
|
||||||
refreshCoordinate(finalVelocityPosition);
|
refreshPosition((Pos) finalVelocityPosition, true);
|
||||||
sendPositionUpdate(true);
|
sendPositionUpdate(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update velocity
|
// Update velocity
|
||||||
if (hasVelocity() || !newVelocity.equals(Vec.ZERO)) {
|
if (hasVelocity() || !newVelocity.equals(Vec.ZERO)) {
|
||||||
velocity = newVelocity.mul(tps); // Convert from blocks/tick to blocks/sec
|
if (onGround && isNettyClient) {
|
||||||
|
|
||||||
final Block block = finalChunk.getBlock(position);
|
|
||||||
final double drag = block.registry().friction();
|
|
||||||
if (onGround) {
|
|
||||||
// Stop player velocity
|
// Stop player velocity
|
||||||
if (isNettyClient) {
|
velocity = Vec.ZERO;
|
||||||
velocity = Vec.ZERO;
|
} else {
|
||||||
}
|
final Block block = finalChunk.getBlock(position);
|
||||||
}
|
final double drag = block.registry().friction();
|
||||||
|
|
||||||
velocity = velocity.with((x, y, z) -> new Vec(
|
velocity = newVelocity
|
||||||
x * drag,
|
// Convert from blocks/tick to blocks/sec
|
||||||
!hasNoGravity() ? y * (1 - gravityDragPerTick) : y,
|
.mul(tps)
|
||||||
z * drag
|
// Apply drag
|
||||||
)).with(Vec.Operator.EPSILON);
|
.with((x, y, z) -> new Vec(
|
||||||
|
x * drag,
|
||||||
|
!hasNoGravity() ? y * (1 - gravityDragPerTick) : y,
|
||||||
|
z * drag
|
||||||
|
))
|
||||||
|
// Prevent infinitely decreasing velocity
|
||||||
|
.with(Vec.Operator.EPSILON);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Synchronization and packets...
|
// Synchronization and packets...
|
||||||
|
Loading…
Reference in New Issue
Block a user