From b178a6adaccccd6ca0b3f4791d89851d58bf4df6 Mon Sep 17 00:00:00 2001 From: TheMode Date: Fri, 30 Jul 2021 18:10:35 +0200 Subject: [PATCH] Create velocityTick method --- .../net/minestom/server/entity/Entity.java | 163 +++++++++--------- 1 file changed, 80 insertions(+), 83 deletions(-) diff --git a/src/main/java/net/minestom/server/entity/Entity.java b/src/main/java/net/minestom/server/entity/Entity.java index 5eac446ac..2e1ab97ed 100644 --- a/src/main/java/net/minestom/server/entity/Entity.java +++ b/src/main/java/net/minestom/server/entity/Entity.java @@ -422,90 +422,11 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler } } - final boolean isNettyClient = PlayerUtils.isNettyClient(this); // Entity tick { - // Cache the number of "gravity tick" - if (!onGround) { - gravityTickCount++; - } else { - gravityTickCount = 0; - } - - // Velocity - final boolean noGravity = hasNoGravity(); - boolean applyVelocity; - // Non-player entities with either velocity or gravity enabled - applyVelocity = !isNettyClient && (hasVelocity() || !noGravity); - // Players with a velocity applied (client is responsible for gravity) - applyVelocity |= isNettyClient && hasVelocity(); - - if (applyVelocity) { - final float tps = MinecraftServer.TICK_PER_SECOND; - final Pos newPosition; - final Vec newVelocity; - - final Vec currentVelocity = getVelocity(); - final Vec deltaPos = new Vec( - currentVelocity.x() / tps, - currentVelocity.y() / tps - (noGravity ? 0 : gravityAcceleration), - currentVelocity.z() / tps - ); - - if (this.hasPhysics) { - final var physicsResult = CollisionUtils.handlePhysics(this, deltaPos); - this.onGround = physicsResult.isOnGround(); - newPosition = physicsResult.newPosition(); - newVelocity = physicsResult.newVelocity(); - } else { - newVelocity = deltaPos; - newPosition = position.add(currentVelocity.div(20)); - } - - // World border collision - final var finalVelocityPosition = CollisionUtils.applyWorldBorder(instance, position, newPosition); - final Chunk finalChunk = ChunkUtils.retrieve(instance, currentChunk, finalVelocityPosition); - if (!ChunkUtils.isLoaded(finalChunk)) { - // Entity shouldn't be updated when moving in an unloaded chunk - return; - } - - // Apply the position if changed - if (!finalVelocityPosition.samePoint(position)) { - refreshPosition(finalVelocityPosition, true); - if (!isNettyClient) { - synchronizePosition(true); - } - } - - // Update velocity - if (hasVelocity() || !newVelocity.isZero()) { - if (onGround && isNettyClient) { - // Stop player velocity - this.velocity = Vec.ZERO; - } else { - final double drag = this.onGround ? - finalChunk.getBlock(position).registry().friction() : 0.91; - this.velocity = newVelocity - // Convert from block/tick to block/sec - .mul(tps) - // Apply drag - .apply((x, y, z) -> new Vec( - x * drag, - !noGravity ? y * (1 - gravityDragPerTick) : y, - z * drag - )) - // Prevent infinitely decreasing velocity - .apply(Vec.Operator.EPSILON); - } - } - - // Verify if velocity packet has to be sent - if (hasVelocity() || (!isNettyClient && gravityTickCount > 0)) { - sendPacketToViewersAndSelf(getVelocityPacket()); - } - } + this.gravityTickCount = onGround ? 0 : gravityTickCount + 1; + velocityTick(); // handle block contacts // TODO do not call every tick (it is pretty expensive) @@ -559,17 +480,93 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler }); } } - // Scheduled synchronization if (!Cooldown.hasCooldown(time, lastAbsoluteSynchronizationTime, getSynchronizationCooldown())) { synchronizePosition(false); } - if (shouldRemove() && !MinecraftServer.isStopping()) { remove(); } } + private void velocityTick() { + final boolean isNettyClient = PlayerUtils.isNettyClient(this); + final boolean noGravity = hasNoGravity(); + final boolean hasVelocity = hasVelocity(); + boolean applyVelocity; + // Non-player entities with either velocity or gravity enabled + applyVelocity = !isNettyClient && (hasVelocity || !noGravity); + // Players with a velocity applied (client is responsible for gravity) + applyVelocity |= isNettyClient && hasVelocity; + if (!applyVelocity) { + return; + } + final float tps = MinecraftServer.TICK_PER_SECOND; + final Vec currentVelocity = getVelocity(); + final Vec deltaPos = new Vec( + currentVelocity.x() / tps, + currentVelocity.y() / tps - (noGravity ? 0 : gravityAcceleration), + currentVelocity.z() / tps + ); + + final Pos newPosition; + final Vec newVelocity; + if (this.hasPhysics) { + final var physicsResult = CollisionUtils.handlePhysics(this, deltaPos); + this.onGround = physicsResult.isOnGround(); + newPosition = physicsResult.newPosition(); + newVelocity = physicsResult.newVelocity(); + } else { + newVelocity = deltaPos; + newPosition = position.add(currentVelocity.div(20)); + } + + // World border collision + final var finalVelocityPosition = CollisionUtils.applyWorldBorder(instance, position, newPosition); + if (finalVelocityPosition.samePoint(position)) { + this.velocity = Vec.ZERO; + if (hasVelocity) { + sendPacketToViewersAndSelf(getVelocityPacket()); + } + return; + } + final Chunk finalChunk = ChunkUtils.retrieve(instance, currentChunk, finalVelocityPosition); + if (!ChunkUtils.isLoaded(finalChunk)) { + // Entity shouldn't be updated when moving in an unloaded chunk + return; + } + refreshPosition(finalVelocityPosition, true); + if (!isNettyClient) { + synchronizePosition(true); + } + + // Update velocity + if (hasVelocity || !newVelocity.isZero()) { + if (onGround && isNettyClient) { + // Stop player velocity + this.velocity = Vec.ZERO; + } else { + final double drag = this.onGround ? + finalChunk.getBlock(position).registry().friction() : 0.91; + this.velocity = newVelocity + // Convert from block/tick to block/sec + .mul(tps) + // Apply drag + .apply((x, y, z) -> new Vec( + x * drag, + !noGravity ? y * (1 - gravityDragPerTick) : y, + z * drag + )) + // Prevent infinitely decreasing velocity + .apply(Vec.Operator.EPSILON); + } + } + // Verify if velocity packet has to be sent + if (hasVelocity || gravityTickCount > 0) { + sendPacketToViewersAndSelf(getVelocityPacket()); + } + } + /** * Gets the number of ticks this entity has been active for. *