mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-04 23:47:59 +01:00
Merge pull request #421 from Bloepiloepi/velocity-changes
Accurate player velocity
This commit is contained in:
commit
baf9df0662
@ -67,6 +67,7 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler
|
|||||||
protected Instance instance;
|
protected Instance instance;
|
||||||
protected Chunk currentChunk;
|
protected Chunk currentChunk;
|
||||||
protected Pos position;
|
protected Pos position;
|
||||||
|
protected Pos previousPosition;
|
||||||
protected Pos lastSyncedPosition;
|
protected Pos lastSyncedPosition;
|
||||||
protected boolean onGround;
|
protected boolean onGround;
|
||||||
|
|
||||||
@ -137,6 +138,7 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler
|
|||||||
this.entityType = entityType;
|
this.entityType = entityType;
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
this.position = Pos.ZERO;
|
this.position = Pos.ZERO;
|
||||||
|
this.previousPosition = Pos.ZERO;
|
||||||
this.lastSyncedPosition = Pos.ZERO;
|
this.lastSyncedPosition = Pos.ZERO;
|
||||||
|
|
||||||
setBoundingBox(entityType.width(), entityType.height(), entityType.width());
|
setBoundingBox(entityType.width(), entityType.height(), entityType.width());
|
||||||
@ -244,6 +246,7 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler
|
|||||||
Check.stateCondition(instance == null, "You need to use Entity#setInstance before teleporting an entity!");
|
Check.stateCondition(instance == null, "You need to use Entity#setInstance before teleporting an entity!");
|
||||||
final Runnable endCallback = () -> {
|
final Runnable endCallback = () -> {
|
||||||
refreshPosition(position);
|
refreshPosition(position);
|
||||||
|
previousPosition = position;
|
||||||
synchronizePosition(true);
|
synchronizePosition(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -497,14 +500,16 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler
|
|||||||
|
|
||||||
private void velocityTick() {
|
private void velocityTick() {
|
||||||
final boolean isSocketClient = PlayerUtils.isSocketClient(this);
|
final boolean isSocketClient = PlayerUtils.isSocketClient(this);
|
||||||
|
if (isSocketClient) {
|
||||||
|
// Calculate velocity from client
|
||||||
|
velocity = position.sub(previousPosition).asVec().mul(MinecraftServer.TICK_PER_SECOND);
|
||||||
|
previousPosition = position;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final boolean noGravity = hasNoGravity();
|
final boolean noGravity = hasNoGravity();
|
||||||
final boolean hasVelocity = hasVelocity();
|
final boolean hasVelocity = hasVelocity();
|
||||||
boolean applyVelocity;
|
if (!hasVelocity && noGravity) {
|
||||||
// Non-player entities with either velocity or gravity enabled
|
|
||||||
applyVelocity = !isSocketClient && (hasVelocity || !noGravity);
|
|
||||||
// Players with a velocity applied (client is responsible for gravity)
|
|
||||||
applyVelocity |= isSocketClient && hasVelocity;
|
|
||||||
if (!applyVelocity) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final float tps = MinecraftServer.TICK_PER_SECOND;
|
final float tps = MinecraftServer.TICK_PER_SECOND;
|
||||||
@ -531,7 +536,7 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler
|
|||||||
final var finalVelocityPosition = CollisionUtils.applyWorldBorder(instance, position, newPosition);
|
final var finalVelocityPosition = CollisionUtils.applyWorldBorder(instance, position, newPosition);
|
||||||
if (finalVelocityPosition.samePoint(position)) {
|
if (finalVelocityPosition.samePoint(position)) {
|
||||||
this.velocity = Vec.ZERO;
|
this.velocity = Vec.ZERO;
|
||||||
if (hasVelocity && !isSocketClient) {
|
if (hasVelocity) {
|
||||||
sendPacketToViewers(getVelocityPacket());
|
sendPacketToViewers(getVelocityPacket());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -552,28 +557,23 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler
|
|||||||
|
|
||||||
// Update velocity
|
// Update velocity
|
||||||
if (hasVelocity || !newVelocity.isZero()) {
|
if (hasVelocity || !newVelocity.isZero()) {
|
||||||
if (onGround && isSocketClient) {
|
final double airDrag = this instanceof LivingEntity ? 0.91 : 0.98;
|
||||||
// Stop player velocity
|
final double drag = this.onGround ?
|
||||||
this.velocity = Vec.ZERO;
|
finalChunk.getBlock(position).registry().friction() : airDrag;
|
||||||
} else {
|
this.velocity = newVelocity
|
||||||
final double airDrag = this instanceof LivingEntity ? 0.91 : 0.98;
|
// Convert from block/tick to block/sec
|
||||||
final double drag = this.onGround ?
|
.mul(tps)
|
||||||
finalChunk.getBlock(position).registry().friction() : airDrag;
|
// Apply drag
|
||||||
this.velocity = newVelocity
|
.apply((x, y, z) -> new Vec(
|
||||||
// Convert from block/tick to block/sec
|
x * drag,
|
||||||
.mul(tps)
|
!noGravity ? y * (1 - gravityDragPerTick) : y,
|
||||||
// Apply drag
|
z * drag
|
||||||
.apply((x, y, z) -> new Vec(
|
))
|
||||||
x * drag,
|
// Prevent infinitely decreasing velocity
|
||||||
!noGravity ? y * (1 - gravityDragPerTick) : y,
|
.apply(Vec.Operator.EPSILON);
|
||||||
z * drag
|
|
||||||
))
|
|
||||||
// Prevent infinitely decreasing velocity
|
|
||||||
.apply(Vec.Operator.EPSILON);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Verify if velocity packet has to be sent
|
// Verify if velocity packet has to be sent
|
||||||
if ((hasVelocity || gravityTickCount > 0) && !isSocketClient) {
|
if (hasVelocity || gravityTickCount > 0) {
|
||||||
sendPacketToViewers(getVelocityPacket());
|
sendPacketToViewers(getVelocityPacket());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -724,6 +724,7 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler
|
|||||||
previousInstance.UNSAFE_removeEntity(this);
|
previousInstance.UNSAFE_removeEntity(this);
|
||||||
}
|
}
|
||||||
this.position = spawnPosition;
|
this.position = spawnPosition;
|
||||||
|
this.previousPosition = spawnPosition;
|
||||||
this.isActive = true;
|
this.isActive = true;
|
||||||
this.instance = instance;
|
this.instance = instance;
|
||||||
return instance.loadOptionalChunk(position).thenAccept(chunk -> {
|
return instance.loadOptionalChunk(position).thenAccept(chunk -> {
|
||||||
@ -1180,6 +1181,7 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler
|
|||||||
if (hasPassenger()) {
|
if (hasPassenger()) {
|
||||||
for (Entity passenger : getPassengers()) {
|
for (Entity passenger : getPassengers()) {
|
||||||
passenger.position = passenger.position.withCoord(newPosition);
|
passenger.position = passenger.position.withCoord(newPosition);
|
||||||
|
passenger.previousPosition = passenger.position;
|
||||||
passenger.refreshCoordinate(newPosition);
|
passenger.refreshCoordinate(newPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user