mirror of https://github.com/Minestom/Minestom.git
Account for flying in velocity calculation (#1111)
This commit is contained in:
parent
f80f653ee0
commit
3cd73310cd
|
@ -581,8 +581,13 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev
|
|||
// World border collision
|
||||
final Pos finalVelocityPosition = CollisionUtils.applyWorldBorder(instance, position, newPosition);
|
||||
final boolean positionChanged = !finalVelocityPosition.samePoint(position);
|
||||
final boolean flying = this instanceof Player player && player.isFlying();
|
||||
if (!positionChanged) {
|
||||
if (hasVelocity || newVelocity.isZero()) {
|
||||
if (flying) {
|
||||
this.velocity = Vec.ZERO;
|
||||
sendPacketToViewers(getVelocityPacket());
|
||||
return;
|
||||
} else if (hasVelocity || newVelocity.isZero()) {
|
||||
this.velocity = noGravity ? Vec.ZERO : new Vec(
|
||||
0,
|
||||
-gravityAcceleration * tps * (1 - gravityDragPerTick),
|
||||
|
@ -612,7 +617,7 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev
|
|||
|
||||
// Update velocity
|
||||
if (hasVelocity || !newVelocity.isZero()) {
|
||||
updateVelocity(wasOnGround, positionBeforeMove, newVelocity);
|
||||
updateVelocity(wasOnGround, flying, positionBeforeMove, newVelocity);
|
||||
}
|
||||
// Verify if velocity packet has to be sent
|
||||
if (!(this instanceof Player) && (hasVelocity || gravityTickCount > 0)) {
|
||||
|
@ -620,7 +625,7 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev
|
|||
}
|
||||
}
|
||||
|
||||
protected void updateVelocity(boolean wasOnGround, Pos positionBeforeMove, Vec newVelocity) {
|
||||
protected void updateVelocity(boolean wasOnGround, boolean flying, Pos positionBeforeMove, Vec newVelocity) {
|
||||
EntitySpawnType type = entityType.registry().spawnType();
|
||||
final double airDrag = type == EntitySpawnType.LIVING || type == EntitySpawnType.PLAYER ? 0.91 : 0.98;
|
||||
final double drag;
|
||||
|
@ -631,11 +636,14 @@ public class Entity implements Viewable, Tickable, Schedulable, Snapshotable, Ev
|
|||
}
|
||||
} else drag = airDrag;
|
||||
|
||||
double gravity = flying ? 0 : gravityAcceleration;
|
||||
double gravityDrag = flying ? 0.6 : (1 - gravityDragPerTick);
|
||||
|
||||
this.velocity = newVelocity
|
||||
// Apply drag
|
||||
// Apply gravity and drag
|
||||
.apply((x, y, z) -> new Vec(
|
||||
x * drag,
|
||||
!hasNoGravity() ? (y - gravityAcceleration) * (1 - gravityDragPerTick) : y,
|
||||
!hasNoGravity() ? (y - gravity) * gravityDrag : y,
|
||||
z * drag
|
||||
))
|
||||
// Convert from block/tick to block/sec
|
||||
|
|
|
@ -8,8 +8,6 @@ import net.minestom.server.instance.Instance;
|
|||
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@EnvTest
|
||||
|
@ -105,6 +103,31 @@ public class EntityVelocityIntegrationTest {
|
|||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void flyingVelocity(Env env) {
|
||||
var instance = env.createFlatInstance();
|
||||
loadChunks(instance);
|
||||
|
||||
var player = env.createPlayer(instance, new Pos(0, 42, 0));
|
||||
env.tick();
|
||||
|
||||
final double epsilon = 0.0000001;
|
||||
|
||||
assertEquals(player.getVelocity().y(), -1.568, epsilon);
|
||||
double previousVelocity = player.getVelocity().y();
|
||||
|
||||
player.setFlying(true);
|
||||
env.tick();
|
||||
|
||||
// Every tick, the y velocity is multiplied by 0.6, and after 27 ticks it should be 0
|
||||
for (int i = 0; i < 27; i++) {
|
||||
assertEquals(player.getVelocity().y(), previousVelocity * 0.6, epsilon);
|
||||
previousVelocity = player.getVelocity().y();
|
||||
env.tick();
|
||||
}
|
||||
assertEquals(player.getVelocity().y(), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasVelocity(Env env) {
|
||||
var instance = env.createFlatInstance();
|
||||
|
|
Loading…
Reference in New Issue