From 28dca16b294ba4b9b0b63bbf4884b3fbe78130f3 Mon Sep 17 00:00:00 2001 From: TheMode Date: Tue, 6 Jul 2021 20:44:24 +0200 Subject: [PATCH] Initial position api implementation --- .../adventure/AdventurePacketConvertor.java | 21 +- .../server/collision/BoundingBox.java | 12 +- .../server/collision/CollisionUtils.java | 12 +- .../net/minestom/server/entity/Entity.java | 237 +++++++----------- .../server/entity/EntityCreature.java | 14 -- .../server/entity/EntityProjectile.java | 42 ++-- .../server/entity/EntitySpawnType.java | 18 +- .../minestom/server/entity/ExperienceOrb.java | 36 +-- .../minestom/server/entity/ItemEntity.java | 19 +- .../minestom/server/entity/LivingEntity.java | 28 +-- .../net/minestom/server/entity/Player.java | 41 ++- .../entity/ai/goal/CombinedAttackGoal.java | 11 +- .../server/entity/ai/goal/EatBlockGoal.java | 95 ------- .../entity/ai/goal/FollowTargetGoal.java | 39 ++- .../entity/ai/goal/MeleeAttackGoal.java | 10 +- .../entity/ai/goal/RandomLookAroundGoal.java | 13 +- .../entity/ai/goal/RandomStrollGoal.java | 20 +- .../entity/ai/goal/RangedAttackGoal.java | 8 +- .../server/entity/hologram/Hologram.java | 47 +--- .../server/entity/pathfinding/Navigator.java | 62 +++-- .../entity/pathfinding/PFPathingEntity.java | 13 +- .../server/event/entity/EntityShootEvent.java | 7 +- .../event/entity/EntityVelocityEvent.java | 16 +- .../server/event/player/PlayerMoveEvent.java | 11 +- .../event/player/PlayerRespawnEvent.java | 10 +- .../minestom/server/instance/Instance.java | 25 +- .../server/instance/InstanceContainer.java | 5 +- .../server/instance/SharedInstance.java | 5 +- .../minestom/server/instance/WorldBorder.java | 17 +- .../rule/vanilla/StairsPlacementRule.java | 2 +- .../listener/PlayerDiggingListener.java | 8 +- .../listener/PlayerPositionListener.java | 35 +-- .../listener/PlayerVehicleListener.java | 7 +- .../play/EntityPositionAndRotationPacket.java | 17 +- .../server/play/EntityPositionPacket.java | 13 +- .../server/play/EntityTeleportPacket.java | 20 +- .../play/PlayerPositionAndLookPacket.java | 18 +- .../packet/server/play/SoundEffectPacket.java | 17 +- .../packet/server/play/SpawnEntityPacket.java | 23 +- .../server/play/SpawnExperienceOrbPacket.java | 14 +- .../server/play/SpawnLivingEntityPacket.java | 23 +- .../packet/server/play/SpawnPlayerPacket.java | 28 +-- .../server/utils/block/BlockIterator.java | 7 +- .../server/utils/chunk/ChunkUtils.java | 13 +- .../server/utils/coordinate/Point.java | 24 ++ .../minestom/server/utils/coordinate/Pos.java | 52 ++++ .../server/utils/entity/EntityFinder.java | 18 +- .../server/utils/entity/EntityUtils.java | 19 +- .../utils/location/RelativeLocation.java | 8 +- src/test/java/demo/MainDemo.java | 4 +- src/test/java/demo/PlayerInit.java | 14 +- 51 files changed, 541 insertions(+), 737 deletions(-) delete mode 100644 src/main/java/net/minestom/server/entity/ai/goal/EatBlockGoal.java diff --git a/src/main/java/net/minestom/server/adventure/AdventurePacketConvertor.java b/src/main/java/net/minestom/server/adventure/AdventurePacketConvertor.java index 7629a4430..05496344d 100644 --- a/src/main/java/net/minestom/server/adventure/AdventurePacketConvertor.java +++ b/src/main/java/net/minestom/server/adventure/AdventurePacketConvertor.java @@ -15,7 +15,6 @@ import net.minestom.server.network.packet.server.play.SoundEffectPacket; import net.minestom.server.network.packet.server.play.StopSoundPacket; import net.minestom.server.registry.Registries; import net.minestom.server.sound.SoundEvent; -import net.minestom.server.utils.Position; import org.jetbrains.annotations.NotNull; import java.util.Collection; @@ -25,6 +24,7 @@ import java.util.Collection; */ public class AdventurePacketConvertor { private static final Object2IntMap NAMED_TEXT_COLOR_ID_MAP = new Object2IntArrayMap<>(16); + static { NAMED_TEXT_COLOR_ID_MAP.put(NamedTextColor.BLACK, 0); NAMED_TEXT_COLOR_ID_MAP.put(NamedTextColor.DARK_BLUE, 1); @@ -102,9 +102,9 @@ public class AdventurePacketConvertor { * Creates a sound packet from a sound and a location. * * @param sound the sound - * @param x the x coordinate - * @param y the y coordinate - * @param z the z coordinate + * @param x the x coordinate + * @param y the y coordinate + * @param z the z coordinate * @return the sound packet */ public static @NotNull ServerPacket createSoundPacket(@NotNull Sound sound, double x, double y, double z) { @@ -136,7 +136,7 @@ public class AdventurePacketConvertor { /** * Creates a sound effect packet from a sound and an emitter. * - * @param sound the sound + * @param sound the sound * @param emitter the emitter, must be an {@link Entity} * @return the sound packet */ @@ -158,14 +158,13 @@ public class AdventurePacketConvertor { packet.pitch = sound.pitch(); return packet; } else { - final Position pos = entity.getPosition(); - + final var pos = entity.getPosition(); final NamedSoundEffectPacket packet = new NamedSoundEffectPacket(); packet.soundName = sound.name().asString(); packet.soundSource = sound.source(); - packet.x = (int) pos.getX(); - packet.y = (int) pos.getY(); - packet.z = (int) pos.getX(); + packet.x = (int) pos.x(); + packet.y = (int) pos.y(); + packet.z = (int) pos.z(); packet.volume = sound.volume(); packet.pitch = sound.pitch(); return packet; @@ -175,7 +174,7 @@ public class AdventurePacketConvertor { /** * Creates an entity sound packet from an Adventure sound. * - * @param sound the sound + * @param sound the sound * @param entity the entity the sound is coming from * @return the packet * @deprecated Use {@link #createSoundPacket(Sound, Sound.Emitter)} diff --git a/src/main/java/net/minestom/server/collision/BoundingBox.java b/src/main/java/net/minestom/server/collision/BoundingBox.java index 84abd70d4..1c946d6c5 100644 --- a/src/main/java/net/minestom/server/collision/BoundingBox.java +++ b/src/main/java/net/minestom/server/collision/BoundingBox.java @@ -150,7 +150,7 @@ public class BoundingBox { * @return the min X */ public double getMinX() { - return entity.getPosition().getX() - (x / 2); + return entity.getPosition().x() - (x / 2); } /** @@ -159,7 +159,7 @@ public class BoundingBox { * @return the max X */ public double getMaxX() { - return entity.getPosition().getX() + (x / 2); + return entity.getPosition().x() + (x / 2); } /** @@ -168,7 +168,7 @@ public class BoundingBox { * @return the min Y */ public double getMinY() { - return entity.getPosition().getY(); + return entity.getPosition().y(); } /** @@ -177,7 +177,7 @@ public class BoundingBox { * @return the max Y */ public double getMaxY() { - return entity.getPosition().getY() + y; + return entity.getPosition().y() + y; } /** @@ -186,7 +186,7 @@ public class BoundingBox { * @return the min Z */ public double getMinZ() { - return entity.getPosition().getZ() - (z / 2); + return entity.getPosition().z() - (z / 2); } /** @@ -195,7 +195,7 @@ public class BoundingBox { * @return the max Z */ public double getMaxZ() { - return entity.getPosition().getZ() + (z / 2); + return entity.getPosition().z() + (z / 2); } /** diff --git a/src/main/java/net/minestom/server/collision/CollisionUtils.java b/src/main/java/net/minestom/server/collision/CollisionUtils.java index ec86bf2c9..d87e4a4fc 100644 --- a/src/main/java/net/minestom/server/collision/CollisionUtils.java +++ b/src/main/java/net/minestom/server/collision/CollisionUtils.java @@ -9,6 +9,8 @@ import net.minestom.server.utils.BlockPosition; import net.minestom.server.utils.Position; import net.minestom.server.utils.Vector; import net.minestom.server.utils.chunk.ChunkUtils; +import net.minestom.server.utils.coordinate.Point; +import net.minestom.server.utils.coordinate.Vec; import org.jetbrains.annotations.NotNull; public class CollisionUtils { @@ -190,8 +192,8 @@ public class CollisionUtils { * @return the position with the world border collision applied (can be {@code newPosition} if not changed) */ @NotNull - public static Position applyWorldBorder(@NotNull Instance instance, - @NotNull Position currentPosition, @NotNull Position newPosition) { + public static Point applyWorldBorder(@NotNull Instance instance, + @NotNull Point currentPosition, @NotNull Point newPosition) { final WorldBorder worldBorder = instance.getWorldBorder(); final WorldBorder.CollisionAxis collisionAxis = worldBorder.getCollisionAxis(newPosition); switch (collisionAxis) { @@ -200,13 +202,13 @@ public class CollisionUtils { return newPosition; case BOTH: // Apply Y velocity/gravity - return new Position(currentPosition.getX(), newPosition.getY(), currentPosition.getZ()); + return new Vec(currentPosition.x(), newPosition.y(), currentPosition.z()); case X: // Apply Y/Z velocity/gravity - return new Position(currentPosition.getX(), newPosition.getY(), newPosition.getZ()); + return new Vec(currentPosition.x(), newPosition.y(), newPosition.z()); case Z: // Apply X/Y velocity/gravity - return new Position(newPosition.getX(), newPosition.getY(), currentPosition.getZ()); + return new Vec(newPosition.x(), newPosition.y(), currentPosition.z()); } throw new IllegalStateException("Something weird happened..."); } diff --git a/src/main/java/net/minestom/server/entity/Entity.java b/src/main/java/net/minestom/server/entity/Entity.java index af02cfb85..c716a9d8a 100644 --- a/src/main/java/net/minestom/server/entity/Entity.java +++ b/src/main/java/net/minestom/server/entity/Entity.java @@ -42,6 +42,8 @@ import net.minestom.server.utils.Vector; import net.minestom.server.utils.callback.OptionalCallback; import net.minestom.server.utils.chunk.ChunkCallback; import net.minestom.server.utils.chunk.ChunkUtils; +import net.minestom.server.utils.coordinate.Point; +import net.minestom.server.utils.coordinate.Pos; import net.minestom.server.utils.coordinate.Vec; import net.minestom.server.utils.entity.EntityUtils; import net.minestom.server.utils.player.PlayerUtils; @@ -77,16 +79,8 @@ public class Entity implements Viewable, Tickable, EventHandler, Da protected Instance instance; protected Chunk currentChunk; - protected final Position position; - /** - * Used to calculate delta movement - */ - protected final Position lastPosition; - /** - * Used to check if any change made to the {@link Entity#position} field since - * the last packets sent - */ - protected final Position lastSyncedPosition; + protected Pos position; + protected Pos lastSyncedPosition; protected boolean onGround; private BoundingBox boundingBox; @@ -94,7 +88,7 @@ public class Entity implements Viewable, Tickable, EventHandler, Da protected Entity vehicle; // Velocity - protected Vector velocity = new Vector(); // Movement in block per second + protected Vec velocity = Vec.ZERO; // Movement in block per second protected boolean hasPhysics = true; /** @@ -159,9 +153,8 @@ public class Entity implements Viewable, Tickable, EventHandler, Da this.id = generateId(); this.entityType = entityType; this.uuid = uuid; - this.position = new Position(); - this.lastPosition = new Position(); - this.lastSyncedPosition = new Position(); + this.position = Pos.ZERO; + this.lastSyncedPosition = Pos.ZERO; setBoundingBox(entityType.getWidth(), entityType.getHeight(), entityType.getWidth()); @@ -181,18 +174,6 @@ public class Entity implements Viewable, Tickable, EventHandler, Da this(entityType, UUID.randomUUID()); } - @Deprecated - public Entity(@NotNull EntityType entityType, @NotNull UUID uuid, @NotNull Position spawnPosition) { - this(entityType, uuid); - this.position.set(spawnPosition); - this.lastPosition.set(spawnPosition); - } - - @Deprecated - public Entity(@NotNull EntityType entityType, @NotNull Position spawnPosition) { - this(entityType, UUID.randomUUID(), spawnPosition); - } - /** * Schedules a task to be run during the next entity tick. * It ensures that the task will be executed in the same thread as the entity (depending of the {@link ThreadProvider}). @@ -281,31 +262,26 @@ public class Entity implements Viewable, Tickable, EventHandler, Da * @param callback the optional callback executed, even if auto chunk is not enabled * @throws IllegalStateException if you try to teleport an entity before settings its instance */ - public void teleport(@NotNull Position position, @Nullable long[] chunks, @Nullable Runnable callback) { + public void teleport(@NotNull Pos position, @Nullable long[] chunks, @Nullable Runnable callback) { Check.stateCondition(instance == null, "You need to use Entity#setInstance before teleporting an entity!"); - - final Position teleportPosition = position.clone(); // Prevent synchronization issue - final ChunkCallback endCallback = (chunk) -> { - refreshPosition(teleportPosition); - + refreshPosition(position); synchronizePosition(true); - OptionalCallback.execute(callback); }; if (chunks == null || chunks.length == 0) { - instance.loadOptionalChunk(teleportPosition, endCallback); + instance.loadOptionalChunk(position, endCallback); } else { ChunkUtils.optionalLoadAll(instance, chunks, null, endCallback); } } - public void teleport(@NotNull Position position, @Nullable Runnable callback) { + public void teleport(@NotNull Pos position, @Nullable Runnable callback) { teleport(position, null, callback); } - public void teleport(@NotNull Position position) { + public void teleport(@NotNull Pos position) { teleport(position, null); } @@ -316,7 +292,7 @@ public class Entity implements Viewable, Tickable, EventHandler, Da * @param pitch the new pitch */ public void setView(float yaw, float pitch) { - refreshView(yaw, pitch); + this.position = position.withView(yaw, pitch); EntityRotationPacket entityRotationPacket = new EntityRotationPacket(); entityRotationPacket.entityId = getEntityId(); @@ -396,7 +372,7 @@ public class Entity implements Viewable, Tickable, EventHandler, Da { EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket(); entityHeadLookPacket.entityId = getEntityId(); - entityHeadLookPacket.yaw = position.getYaw(); + entityHeadLookPacket.yaw = position.yaw(); playerConnection.sendPacket(entityHeadLookPacket); } @@ -532,9 +508,9 @@ public class Entity implements Viewable, Tickable, EventHandler, Da if (applyVelocity) { final float tps = MinecraftServer.TICK_PER_SECOND; - final double newX = position.getX() + velocity.getX() / tps; - final double newY = position.getY() + velocity.getY() / tps; - final double newZ = position.getZ() + velocity.getZ() / tps; + final double newX = position.x() + velocity.x() / tps; + final double newY = position.y() + velocity.y() / tps; + final double newZ = position.z() + velocity.z() / tps; Position newPosition = new Position(newX, newY, newZ); Vector newVelocityOut = new Vector(); @@ -555,7 +531,7 @@ public class Entity implements Viewable, Tickable, EventHandler, Da } // World border collision - final Position finalVelocityPosition = CollisionUtils.applyWorldBorder(instance, position, newPosition); + final Point 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 @@ -563,20 +539,17 @@ public class Entity implements Viewable, Tickable, EventHandler, Da } // Apply the position if changed - if (!finalVelocityPosition.isSimilar(position)) { - refreshPosition(finalVelocityPosition.getX(), - finalVelocityPosition.getY(), - finalVelocityPosition.getZ()); + if (!finalVelocityPosition.samePoint(position)) { + refreshCoordinate(finalVelocityPosition); sendPositionUpdate(true); } - // Update velocity if (hasVelocity() || !newVelocityOut.isZero()) { this.velocity.copy(newVelocityOut); this.velocity.multiply(tps); - final Block block = finalChunk.getBlock(position.toBlockPosition()); + final Block block = finalChunk.getBlock(position); final double drag = block.registry().friction(); if (onGround) { // Stop player velocity @@ -686,10 +659,10 @@ public class Entity implements Viewable, Tickable, EventHandler, Da * @param clientSide {@code true} if the client triggered this action */ protected void sendPositionUpdate(final boolean clientSide) { - final boolean viewChange = !position.hasSimilarView(lastSyncedPosition); - final double distanceX = Math.abs(position.getX() - lastSyncedPosition.getX()); - final double distanceY = Math.abs(position.getY() - lastSyncedPosition.getY()); - final double distanceZ = Math.abs(position.getZ() - lastSyncedPosition.getZ()); + final boolean viewChange = !position.sameView(lastSyncedPosition); + final double distanceX = Math.abs(position.x() - lastSyncedPosition.x()); + final double distanceY = Math.abs(position.y() - lastSyncedPosition.y()); + final double distanceZ = Math.abs(position.z() - lastSyncedPosition.z()); final boolean positionChange = (distanceX + distanceY + distanceZ) > 0; if (distanceX > 8 || distanceY > 8 || distanceZ > 8) { @@ -704,7 +677,7 @@ public class Entity implements Viewable, Tickable, EventHandler, Da // Fix head rotation final EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket(); entityHeadLookPacket.entityId = getEntityId(); - entityHeadLookPacket.yaw = position.getYaw(); + entityHeadLookPacket.yaw = position.yaw(); sendPacketToViewersAndSelf(entityHeadLookPacket); } else if (positionChange) { final EntityPositionPacket entityPositionPacket = EntityPositionPacket @@ -713,13 +686,13 @@ public class Entity implements Viewable, Tickable, EventHandler, Da } else if (viewChange) { final EntityRotationPacket entityRotationPacket = new EntityRotationPacket(); entityRotationPacket.entityId = getEntityId(); - entityRotationPacket.yaw = position.getYaw(); - entityRotationPacket.pitch = position.getPitch(); + entityRotationPacket.yaw = position.yaw(); + entityRotationPacket.pitch = position.pitch(); entityRotationPacket.onGround = onGround; final EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket(); entityHeadLookPacket.entityId = getEntityId(); - entityHeadLookPacket.yaw = position.getYaw(); + entityHeadLookPacket.yaw = position.yaw(); if (clientSide) { sendPacketToViewers(entityHeadLookPacket); @@ -736,12 +709,12 @@ public class Entity implements Viewable, Tickable, EventHandler, Da if (PlayerUtils.isNettyClient(this) && !clientSide) { final PlayerPositionAndLookPacket playerPositionAndLookPacket = new PlayerPositionAndLookPacket(); playerPositionAndLookPacket.flags = 0b111; - playerPositionAndLookPacket.position = position.clone().subtract(lastSyncedPosition.getX(), lastSyncedPosition.getY(), lastSyncedPosition.getZ()); + playerPositionAndLookPacket.position = position.sub(lastSyncedPosition); playerPositionAndLookPacket.teleportId = ((Player) this).getNextTeleportId(); ((Player) this).getPlayerConnection().sendPacket(playerPositionAndLookPacket); } - lastSyncedPosition.set(position); + this.lastSyncedPosition = position; } /** @@ -893,25 +866,25 @@ public class Entity implements Viewable, Tickable, EventHandler, Da * @param spawnPosition the spawn position for the entity. * @throws IllegalStateException if {@code instance} has not been registered in {@link InstanceManager} */ - public void setInstance(@NotNull Instance instance, @NotNull Position spawnPosition) { + public void setInstance(@NotNull Instance instance, @NotNull Pos spawnPosition) { Check.stateCondition(!instance.isRegistered(), "Instances need to be registered, please use InstanceManager#registerInstance or InstanceManager#registerSharedInstance"); - if (this.instance != null) { this.instance.UNSAFE_removeEntity(this); } - - this.position.set(spawnPosition); - this.lastPosition.set(position); - + this.position = spawnPosition; this.isActive = true; this.instance = instance; - refreshCurrentChunk(instance.getChunkAt(position.getX(), position.getZ())); + refreshCurrentChunk(instance.getChunkAt(position)); instance.UNSAFE_addEntity(this); spawn(); EventDispatcher.call(new EntitySpawnEvent(this, instance)); } + public void setInstance(@NotNull Instance instance, @NotNull Position spawnPosition) { + setInstance(instance, Pos.fromPosition(spawnPosition)); + } + /** * Changes the entity instance. * @@ -928,8 +901,7 @@ public class Entity implements Viewable, Tickable, EventHandler, Da * * @return the entity current velocity */ - @NotNull - public Vector getVelocity() { + public @NotNull Vec getVelocity() { return velocity; } @@ -940,10 +912,10 @@ public class Entity implements Viewable, Tickable, EventHandler, Da * * @param velocity the new entity velocity */ - public void setVelocity(@NotNull Vector velocity) { + public void setVelocity(@NotNull Vec velocity) { EntityVelocityEvent entityVelocityEvent = new EntityVelocityEvent(this, velocity); EventDispatcher.callCancellable(entityVelocityEvent, () -> { - this.velocity.copy(entityVelocityEvent.getVelocity()); + this.velocity = entityVelocityEvent.getVelocity(); sendPacketToViewersAndSelf(getVelocityPacket()); }); } @@ -954,7 +926,7 @@ public class Entity implements Viewable, Tickable, EventHandler, Da * @return true if velocity is not set to 0 */ public boolean hasVelocity() { - return !velocity.isZero(); + return !velocity.samePoint(Vec.ZERO); } /** @@ -1003,7 +975,7 @@ public class Entity implements Viewable, Tickable, EventHandler, Da * @return the distance between this and {@code entity} */ public double getDistance(@NotNull Entity entity) { - return getPosition().getDistance(entity.getPosition()); + return getPosition().distance(entity.getPosition()); } /** @@ -1013,7 +985,7 @@ public class Entity implements Viewable, Tickable, EventHandler, Da * @return the distance squared between this and {@code entity} */ public double getDistanceSquared(@NotNull Entity entity) { - return getPosition().getDistanceSquared(entity.getPosition()); + return getPosition().distanceSquared(entity.getPosition()); } /** @@ -1321,42 +1293,57 @@ public class Entity implements Viewable, Tickable, EventHandler, Da this.entityMeta.setHasNoGravity(noGravity); } + /** + * Updates internal fields and sends updates + * + * @param position the new position + * @see #refreshCoordinate(Pos) + * @see #sendPositionUpdate(boolean) + */ + @ApiStatus.Internal + public void refreshPosition(@NotNull final Pos position, boolean ignoreView) { + if (!ignoreView) { + this.position = position; + } else { + this.position = this.position.withCoord(position); + } + if (!position.samePoint(this.position)) { + refreshCoordinate(position); + } + sendPositionUpdate(true); + } + + @ApiStatus.Internal + public void refreshPosition(@NotNull final Pos position) { + refreshPosition(position, false); + } + /** * Used to refresh the entity and its passengers position * - put the entity in the right instance chunk * - update the viewable chunks (load and unload) * - add/remove players from the viewers list if {@link #isAutoViewable()} is enabled *

- * WARNING: unsafe, should only be used internally in Minestom. Use {@link #teleport(Position)} instead. + * WARNING: unsafe, should only be used internally in Minestom. Use {@link #teleport(Pos)} instead. * - * @param x new position X - * @param y new position Y - * @param z new position Z + * @param newPosition the new position */ - private void refreshPosition(double x, double y, double z) { - position.setX(x); - position.setY(y); - position.setZ(z); - + private void refreshCoordinate(Point newPosition) { if (hasPassenger()) { for (Entity passenger : getPassengers()) { - passenger.refreshPosition(x, y, z); + passenger.refreshCoordinate(newPosition); } } - final Instance instance = getInstance(); if (instance != null) { final int lastChunkX = currentChunk.getChunkX(); final int lastChunkZ = currentChunk.getChunkZ(); - - final int newChunkX = ChunkUtils.getChunkCoordinate(x); - final int newChunkZ = ChunkUtils.getChunkCoordinate(z); - + final int newChunkX = ChunkUtils.getChunkCoordinate(newPosition.x()); + final int newChunkZ = ChunkUtils.getChunkCoordinate(newPosition.z()); if (lastChunkX != newChunkX || lastChunkZ != newChunkZ) { // Entity moved in a new chunk final Chunk newChunk = instance.getChunk(newChunkX, newChunkZ); - Check.notNull(newChunk, "The entity {0} tried to move in an unloaded chunk at {1};{2}", getEntityId(), x, z); - + Check.notNull(newChunk, "The entity {0} tried to move in an unloaded chunk at {1}", getEntityId(), newPosition); instance.UNSAFE_switchEntityChunk(this, currentChunk, newChunk); if (this instanceof Player) { // Refresh player view @@ -1364,45 +1351,10 @@ public class Entity implements Viewable, Tickable, EventHandler, Da player.refreshVisibleChunks(newChunk); player.refreshVisibleEntities(newChunk); } - refreshCurrentChunk(newChunk); } } - - this.lastPosition.setX(position.getX()); - this.lastPosition.setY(position.getY()); - this.lastPosition.setZ(position.getZ()); - } - - /** - * Updates internal fields and sends updates - * - * @param position the new position - * @see #refreshPosition(double, double, double) - * @see #refreshView(float, float) - * @see #sendPositionUpdate(boolean) - */ - @ApiStatus.Internal - public void refreshPosition(@NotNull final Position position) { - if (!position.isSimilar(this.position)) - refreshPosition(position.getX(), position.getY(), position.getZ()); - refreshView(position.getYaw(), position.getPitch()); - sendPositionUpdate(true); - } - - /** - * Updates the entity view internally. - *

- * Warning: you probably want to use {@link #setView(float, float)}. - * - * @param yaw the yaw - * @param pitch the pitch - */ - private void refreshView(final float yaw, final float pitch) { - lastPosition.setYaw(position.getYaw()); - lastPosition.setPitch(position.getPitch()); - position.setYaw(yaw); - position.setPitch(pitch); + this.lastPosition = position; } /** @@ -1410,8 +1362,7 @@ public class Entity implements Viewable, Tickable, EventHandler, Da * * @return the current position of the entity */ - @NotNull - public Position getPosition() { + public @NotNull Pos getPosition() { return position; } @@ -1536,19 +1487,17 @@ public class Entity implements Viewable, Tickable, EventHandler, Da return scheduledRemoveTime != 0; } - @NotNull - protected Vector getVelocityForPacket() { - return this.velocity.clone().multiply(8000f / MinecraftServer.TICK_PER_SECOND); + protected @NotNull Vec getVelocityForPacket() { + return this.velocity.mul(8000f / MinecraftServer.TICK_PER_SECOND); } - @NotNull - protected EntityVelocityPacket getVelocityPacket() { + protected @NotNull EntityVelocityPacket getVelocityPacket() { EntityVelocityPacket velocityPacket = new EntityVelocityPacket(); velocityPacket.entityId = getEntityId(); - Vector velocity = getVelocityForPacket(); - velocityPacket.velocityX = (short) velocity.getX(); - velocityPacket.velocityY = (short) velocity.getY(); - velocityPacket.velocityZ = (short) velocity.getZ(); + Vec velocity = getVelocityForPacket(); + velocityPacket.velocityX = (short) velocity.x(); + velocityPacket.velocityY = (short) velocity.y(); + velocityPacket.velocityZ = (short) velocity.z(); return velocityPacket; } @@ -1576,15 +1525,14 @@ public class Entity implements Viewable, Tickable, EventHandler, Da */ @ApiStatus.Internal protected void synchronizePosition(boolean includeSelf) { - final Position pos = position.clone(); final EntityTeleportPacket entityTeleportPacket = new EntityTeleportPacket(); entityTeleportPacket.entityId = getEntityId(); - entityTeleportPacket.position = pos; + entityTeleportPacket.position = position; entityTeleportPacket.onGround = isOnGround(); sendPacketToViewers(entityTeleportPacket); this.lastAbsoluteSynchronizationTime = System.currentTimeMillis(); - this.lastSyncedPosition.set(pos); + this.lastSyncedPosition = position; } /** @@ -1738,10 +1686,13 @@ public class Entity implements Viewable, Tickable, EventHandler, Da public void takeKnockback(final float strength, final double x, final double z) { if (strength > 0) { //TODO check possible side effects of unnatural TPS (other than 20TPS) - final Vector velocityModifier = new Vector(x, 0d, z).normalize().multiply(strength * MinecraftServer.TICK_PER_SECOND / 2); - this.velocity.setX(velocity.getX() / 2d - velocityModifier.getX()); - this.velocity.setY(onGround ? Math.min(.4d, velocity.getY() / 2d + strength) * MinecraftServer.TICK_PER_SECOND : velocity.getY()); - this.velocity.setZ(velocity.getZ() / 2d - velocityModifier.getZ()); + final Vec velocityModifier = new Vec(x, z) + .normalize() + .mul(strength * MinecraftServer.TICK_PER_SECOND / 2); + setVelocity(new Vec(velocity.x() / 2d - velocityModifier.x(), + onGround ? Math.min(.4d, velocity.y() / 2d + strength) * MinecraftServer.TICK_PER_SECOND : velocity.y(), + velocity.z() / 2d - velocityModifier.z() + )); } } diff --git a/src/main/java/net/minestom/server/entity/EntityCreature.java b/src/main/java/net/minestom/server/entity/EntityCreature.java index c8166c737..8e776d447 100644 --- a/src/main/java/net/minestom/server/entity/EntityCreature.java +++ b/src/main/java/net/minestom/server/entity/EntityCreature.java @@ -42,20 +42,6 @@ public class EntityCreature extends LivingEntity implements NavigableEntity, Ent this(entityType, UUID.randomUUID()); } - @Deprecated - public EntityCreature(@NotNull EntityType entityType, @NotNull Position spawnPosition) { - super(entityType, spawnPosition); - heal(); - } - - @Deprecated - public EntityCreature(@NotNull EntityType entityType, @NotNull Position spawnPosition, @Nullable Instance instance) { - this(entityType, spawnPosition); - if (instance != null) { - setInstance(instance); - } - } - @Override public void update(long time) { // AI diff --git a/src/main/java/net/minestom/server/entity/EntityProjectile.java b/src/main/java/net/minestom/server/entity/EntityProjectile.java index f00fd5576..f6415b270 100644 --- a/src/main/java/net/minestom/server/entity/EntityProjectile.java +++ b/src/main/java/net/minestom/server/entity/EntityProjectile.java @@ -1,8 +1,5 @@ package net.minestom.server.entity; -import net.minestom.server.entity.Entity; -import net.minestom.server.entity.EntityType; -import net.minestom.server.entity.LivingEntity; import net.minestom.server.entity.metadata.ProjectileMeta; import net.minestom.server.event.EventDispatcher; import net.minestom.server.event.entity.EntityAttackEvent; @@ -13,6 +10,8 @@ import net.minestom.server.instance.block.Block; import net.minestom.server.utils.BlockPosition; import net.minestom.server.utils.Position; import net.minestom.server.utils.Vector; +import net.minestom.server.utils.coordinate.Point; +import net.minestom.server.utils.coordinate.Vec; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -35,13 +34,6 @@ public class EntityProjectile extends Entity { setup(); } - @Deprecated - public EntityProjectile(@Nullable Entity shooter, @NotNull EntityType entityType, @NotNull Position spawnPosition) { - super(entityType, spawnPosition); - this.shooter = shooter; - setup(); - } - private void setup() { super.hasPhysics = false; if (getEntityMeta() instanceof ProjectileMeta) { @@ -70,21 +62,21 @@ public class EntityProjectile extends Entity { } - public void shoot(Position to, double power, double spread) { + public void shoot(Point to, double power, double spread) { EntityShootEvent shootEvent = new EntityShootEvent(this.shooter, this, to, power, spread); EventDispatcher.call(shootEvent); if (shootEvent.isCancelled()) { remove(); return; } - Position from = this.shooter.getPosition().clone().add(0D, this.shooter.getEyeHeight(), 0D); + final var from = this.shooter.getPosition().add(0D, this.shooter.getEyeHeight(), 0D); shoot(from, to, shootEvent.getPower(), shootEvent.getSpread()); } - private void shoot(@NotNull Position from, @NotNull Position to, double power, double spread) { - double dx = to.getX() - from.getX(); - double dy = to.getY() - from.getY(); - double dz = to.getZ() - from.getZ(); + private void shoot(@NotNull Point from, @NotNull Point to, double power, double spread) { + double dx = to.x() - from.x(); + double dy = to.y() - from.y(); + double dz = to.z() - from.z(); double xzLength = Math.sqrt(dx * dx + dz * dz); dy += xzLength * 0.20000000298023224D; @@ -97,10 +89,9 @@ public class EntityProjectile extends Entity { dx += random.nextGaussian() * spread; dy += random.nextGaussian() * spread; dz += random.nextGaussian() * spread; - super.velocity.setX(dx); - super.velocity.setY(dy); - super.velocity.setZ(dz); - super.velocity.multiply(20 * power); + + final double mul = 20 * power; + this.velocity = new Vec(dx * mul, dy * mul, dz * mul); setView( (float) Math.toDegrees(Math.atan2(dx, dz)), (float) Math.toDegrees(Math.atan2(dy, Math.sqrt(dx * dx + dz * dz))) @@ -109,15 +100,15 @@ public class EntityProjectile extends Entity { @Override public void tick(long time) { - Position posBefore = getPosition().clone(); + final var posBefore = getPosition(); super.tick(time); - Position posNow = getPosition().clone(); + final var posNow = getPosition(); if (isStuck(posBefore, posNow)) { if (super.onGround) { return; } super.onGround = true; - getVelocity().zero(); + this.velocity = Vec.ZERO; sendPacketToViewersAndSelf(getVelocityPacket()); setNoGravity(true); onStuck(); @@ -139,8 +130,8 @@ public class EntityProjectile extends Entity { * @return if an arrow is stuck in block / hit an entity. */ @SuppressWarnings("ConstantConditions") - private boolean isStuck(Position pos, Position posNow) { - if (pos.isSimilar(posNow)) { + private boolean isStuck(Point pos, Point posNow) { + if (pos.samePoint(posNow)) { return true; } @@ -200,5 +191,4 @@ public class EntityProjectile extends Entity { } return false; } - } diff --git a/src/main/java/net/minestom/server/entity/EntitySpawnType.java b/src/main/java/net/minestom/server/entity/EntitySpawnType.java index 9ebd261a5..5d249a1d6 100644 --- a/src/main/java/net/minestom/server/entity/EntitySpawnType.java +++ b/src/main/java/net/minestom/server/entity/EntitySpawnType.java @@ -21,10 +21,10 @@ public enum EntitySpawnType { ObjectDataProvider objectDataProvider = (ObjectDataProvider) entity.getEntityMeta(); packet.data = objectDataProvider.getObjectData(); if (objectDataProvider.requiresVelocityPacketAtSpawn()) { - Vector velocity = entity.getVelocityForPacket(); - packet.velocityX = (short) velocity.getX(); - packet.velocityY = (short) velocity.getY(); - packet.velocityZ = (short) velocity.getZ(); + final var velocity = entity.getVelocityForPacket(); + packet.velocityX = (short) velocity.x(); + packet.velocityY = (short) velocity.y(); + packet.velocityZ = (short) velocity.z(); } } return packet; @@ -38,11 +38,11 @@ public enum EntitySpawnType { packet.entityUuid = entity.getUuid(); packet.entityType = entity.getEntityType().ordinal(); packet.position = entity.getPosition(); - packet.headPitch = entity.getPosition().getPitch(); - Vector velocity = entity.getVelocityForPacket(); - packet.velocityX = (short) velocity.getX(); - packet.velocityY = (short) velocity.getY(); - packet.velocityZ = (short) velocity.getZ(); + packet.headPitch = entity.getPosition().pitch(); + final var velocity = entity.getVelocityForPacket(); + packet.velocityX = (short) velocity.x(); + packet.velocityY = (short) velocity.y(); + packet.velocityZ = (short) velocity.z(); return packet; } }, diff --git a/src/main/java/net/minestom/server/entity/ExperienceOrb.java b/src/main/java/net/minestom/server/entity/ExperienceOrb.java index 4566bf8c9..acf99ab98 100644 --- a/src/main/java/net/minestom/server/entity/ExperienceOrb.java +++ b/src/main/java/net/minestom/server/entity/ExperienceOrb.java @@ -1,10 +1,6 @@ package net.minestom.server.entity; -import net.minestom.server.instance.Instance; -import net.minestom.server.utils.Position; -import net.minestom.server.utils.Vector; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import net.minestom.server.utils.coordinate.Vec; import java.util.Comparator; @@ -14,22 +10,13 @@ public class ExperienceOrb extends Entity { private Player target; private long lastTargetUpdateTick; - - public ExperienceOrb(short experienceCount, @NotNull Position spawnPosition) { - super(EntityType.EXPERIENCE_ORB, spawnPosition); + public ExperienceOrb(short experienceCount) { + super(EntityType.EXPERIENCE_ORB); setBoundingBox(0.5f, 0.5f, 0.5f); //todo vanilla sets random velocity here? this.experienceCount = experienceCount; } - public ExperienceOrb(short experienceCount, @NotNull Position spawnPosition, @Nullable Instance instance) { - this(experienceCount, spawnPosition); - - if (instance != null) { - setInstance(instance); - } - } - @Override public void update(long time) { @@ -44,7 +31,7 @@ public class ExperienceOrb extends Entity { double d = 8.0; if (lastTargetUpdateTick < time - 20 + getEntityId() % 100) { - if (target == null || target.getPosition().getDistanceSquared(getPosition()) > 64) { + if (target == null || target.getPosition().distanceSquared(getPosition()) > 64) { this.target = getClosestPlayer(this, 8); } @@ -56,13 +43,13 @@ public class ExperienceOrb extends Entity { } if (target != null) { - Position pos = getPosition(); - Position targetPos = target.getPosition(); - Vector toTarget = new Vector(targetPos.getX() - pos.getX(), targetPos.getY() + (target.getEyeHeight() / 2) - pos.getY(), targetPos.getZ() - pos.getZ()); + final var pos = getPosition(); + final var targetPos = target.getPosition(); + final Vec toTarget = new Vec(targetPos.x() - pos.x(), targetPos.y() + (target.getEyeHeight() / 2) - pos.y(), targetPos.z() - pos.z()); double e = toTarget.length(); //could really be lengthSquared if (e < 8) { double f = 1 - (e / 8); - setVelocity(getVelocity().add(toTarget.normalize().multiply(f * f * 0.1))); + setVelocity(getVelocity().add(toTarget.normalize().mul(f * f * 0.1))); } } @@ -74,9 +61,10 @@ public class ExperienceOrb extends Entity { } // apply slipperiness - setVelocity(getVelocity().multiply(new Vector(g, 0.98f, g))); - if (isOnGround()) - setVelocity(getVelocity().multiply(new Vector(1, -0.9f, 1))); + setVelocity(getVelocity().mul(new Vec(g, 0.98f, g))); + if (isOnGround()) { + setVelocity(getVelocity().mul(new Vec(1, -0.9f, 1))); + } } @Override diff --git a/src/main/java/net/minestom/server/entity/ItemEntity.java b/src/main/java/net/minestom/server/entity/ItemEntity.java index aae2eaebb..843d10a90 100644 --- a/src/main/java/net/minestom/server/entity/ItemEntity.java +++ b/src/main/java/net/minestom/server/entity/ItemEntity.java @@ -4,10 +4,8 @@ import net.minestom.server.entity.metadata.item.ItemEntityMeta; import net.minestom.server.event.EventDispatcher; import net.minestom.server.event.entity.EntityItemMergeEvent; import net.minestom.server.instance.Chunk; -import net.minestom.server.instance.Instance; import net.minestom.server.item.ItemStack; import net.minestom.server.item.StackingRule; -import net.minestom.server.utils.Position; import net.minestom.server.utils.time.Cooldown; import net.minestom.server.utils.time.TimeUnit; import org.jetbrains.annotations.NotNull; @@ -41,20 +39,12 @@ public class ItemEntity extends Entity { private long spawnTime; private long pickupDelay; - public ItemEntity(@NotNull ItemStack itemStack, @NotNull Position spawnPosition) { - super(EntityType.ITEM, spawnPosition); + public ItemEntity(@NotNull ItemStack itemStack) { + super(EntityType.ITEM); setItemStack(itemStack); setBoundingBox(0.25f, 0.25f, 0.25f); } - public ItemEntity(@NotNull ItemStack itemStack, @NotNull Position spawnPosition, @Nullable Instance instance) { - this(itemStack, spawnPosition); - - if (instance != null) { - setInstance(instance); - } - } - /** * Gets the update option for the merging feature. * @@ -70,7 +60,6 @@ public class ItemEntity extends Entity { * Can be set to null to entirely remove the delay. * * @param mergeUpdateOption the new merge update option - * * @deprecated Replaced by {@link #setMergeDelay(Duration)} */ @SuppressWarnings("removal") @@ -239,7 +228,7 @@ public class ItemEntity extends Entity { /** * Sets the pickup delay of the ItemEntity. * - * @param delay the pickup delay + * @param delay the pickup delay * @param temporalUnit the unit of the delay */ public void setPickupDelay(long delay, @NotNull TemporalUnit temporalUnit) { @@ -249,7 +238,7 @@ public class ItemEntity extends Entity { /** * Sets the pickup delay of the ItemEntity. * - * @param delay the pickup delay + * @param delay the pickup delay */ public void setPickupDelay(Duration delay) { this.pickupDelay = delay.toMillis(); diff --git a/src/main/java/net/minestom/server/entity/LivingEntity.java b/src/main/java/net/minestom/server/entity/LivingEntity.java index 4de8f37f7..894f1e56d 100644 --- a/src/main/java/net/minestom/server/entity/LivingEntity.java +++ b/src/main/java/net/minestom/server/entity/LivingEntity.java @@ -26,9 +26,9 @@ import net.minestom.server.network.player.PlayerConnection; import net.minestom.server.scoreboard.Team; import net.minestom.server.sound.SoundEvent; import net.minestom.server.utils.BlockPosition; -import net.minestom.server.utils.Position; import net.minestom.server.utils.Vector; import net.minestom.server.utils.block.BlockIterator; +import net.minestom.server.utils.coordinate.Vec; import net.minestom.server.utils.time.Cooldown; import net.minestom.server.utils.time.TimeUnit; import org.jetbrains.annotations.NotNull; @@ -90,7 +90,7 @@ public class LivingEntity extends Entity implements EquipmentHandler { * Constructor which allows to specify an UUID. Only use if you know what you are doing! */ public LivingEntity(@NotNull EntityType entityType, @NotNull UUID uuid) { - this(entityType, uuid, new Position()); + super(entityType, uuid); initEquipments(); } @@ -98,20 +98,6 @@ public class LivingEntity extends Entity implements EquipmentHandler { this(entityType, UUID.randomUUID()); } - /** - * Constructor which allows to specify an UUID. Only use if you know what you are doing! - */ - @Deprecated - public LivingEntity(@NotNull EntityType entityType, @NotNull UUID uuid, @NotNull Position spawnPosition) { - super(entityType, uuid, spawnPosition); - initEquipments(); - } - - @Deprecated - public LivingEntity(@NotNull EntityType entityType, @NotNull Position spawnPosition) { - this(entityType, UUID.randomUUID(), spawnPosition); - } - private void initEquipments() { this.mainHandItem = ItemStack.AIR; this.offHandItem = ItemStack.AIR; @@ -300,7 +286,7 @@ public class LivingEntity extends Entity implements EquipmentHandler { setHealth(0); // Reset velocity - velocity.zero(); + this.velocity = Vec.ZERO; // Remove passengers if any if (hasPassenger()) { @@ -323,8 +309,8 @@ public class LivingEntity extends Entity implements EquipmentHandler { /** * Sets fire to this entity for a given duration. * - * @param duration duration of the effect - * @param temporalUnit unit used to express the duration + * @param duration duration of the effect + * @param temporalUnit unit used to express the duration * @see #setOnFire(boolean) if you want it to be permanent without any event callback */ public void setFireForDuration(int duration, TemporalUnit temporalUnit) { @@ -804,8 +790,8 @@ public class LivingEntity extends Entity implements EquipmentHandler { * Note: The strength is reduced based on knockback resistance * * @param strength the strength of the knockback, 0.4 is the vanilla value for a bare hand hit - * @param x knockback on x axle, for default knockback use the following formula

sin(attacker.yaw * (pi/180))
- * @param z knockback on z axle, for default knockback use the following formula
-cos(attacker.yaw * (pi/180))
+ * @param x knockback on x axle, for default knockback use the following formula
sin(attacker.yaw * (pi/180))
+ * @param z knockback on z axle, for default knockback use the following formula
-cos(attacker.yaw * (pi/180))
*/ @Override public void takeKnockback(float strength, final double x, final double z) { diff --git a/src/main/java/net/minestom/server/entity/Player.java b/src/main/java/net/minestom/server/entity/Player.java index eb1442910..941cd4dcd 100644 --- a/src/main/java/net/minestom/server/entity/Player.java +++ b/src/main/java/net/minestom/server/entity/Player.java @@ -68,6 +68,8 @@ import net.minestom.server.stat.PlayerStatistic; import net.minestom.server.utils.*; import net.minestom.server.utils.chunk.ChunkCallback; import net.minestom.server.utils.chunk.ChunkUtils; +import net.minestom.server.utils.coordinate.Point; +import net.minestom.server.utils.coordinate.Pos; import net.minestom.server.utils.entity.EntityUtils; import net.minestom.server.utils.identity.NamedAndIdentified; import net.minestom.server.utils.instance.InstanceUtils; @@ -130,7 +132,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable, private byte heldSlot; - private Position respawnPoint; + private Pos respawnPoint; private int food; private float foodSaturation; @@ -179,7 +181,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable, setBoundingBox(0.6f, 1.8f, 0.6f); - setRespawnPoint(new Position(0, 0, 0)); + setRespawnPoint(Pos.ZERO); this.settings = new PlayerSettings(); this.inventory = new PlayerInventory(this); @@ -520,9 +522,8 @@ public class Player extends LivingEntity implements CommandSender, Localizable, * @param spawnPosition the new position of the player */ @Override - public void setInstance(@NotNull Instance instance, @NotNull Position spawnPosition) { + public void setInstance(@NotNull Instance instance, @NotNull Pos spawnPosition) { Check.argCondition(this.instance == instance, "Instance should be different than the current one"); - // true if the chunks need to be sent to the client, can be false if the instances share the same chunks (eg SharedInstance) final boolean needWorldRefresh = !InstanceUtils.areLinked(this.instance, instance) || !spawnPosition.inSameChunk(this.position); @@ -557,7 +558,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable, * if the player is not in any instance). * * @param instance the new player instance - * @see #setInstance(Instance, Position) + * @see #setInstance(Instance, Pos) */ @Override public void setInstance(@NotNull Instance instance) { @@ -569,14 +570,14 @@ public class Player extends LivingEntity implements CommandSender, Localizable, *

* Does add the player to {@code instance}, remove all viewable entities and call {@link PlayerSpawnEvent}. *

- * UNSAFE: only called with {@link #setInstance(Instance, Position)}. + * UNSAFE: only called with {@link #setInstance(Instance, Pos)}. * * @param spawnPosition the position to teleport the player * @param firstSpawn true if this is the player first spawn * @param updateChunks true if chunks should be refreshed, false if the new instance shares the same * chunks */ - private void spawnPlayer(@NotNull Instance instance, @NotNull Position spawnPosition, + private void spawnPlayer(@NotNull Instance instance, @NotNull Pos spawnPosition, boolean firstSpawn, boolean dimensionChange, boolean updateChunks) { if (!firstSpawn) { // Player instance changed, clear current viewable collections @@ -768,7 +769,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable, @Override public void playSound(@NotNull Sound sound) { - this.playSound(sound, this.position.getX(), this.position.getY(), this.position.getZ()); + this.playSound(sound, this.position.x(), this.position.y(), this.position.z()); } @Override @@ -1294,14 +1295,14 @@ public class Player extends LivingEntity implements CommandSender, Localizable, facePosition(facePoint, entity.getPosition(), entity, targetPoint); } - private void facePosition(@NotNull FacePoint facePoint, @NotNull Position targetPosition, + private void facePosition(@NotNull FacePoint facePoint, @NotNull Point targetPosition, @Nullable Entity entity, @Nullable FacePoint targetPoint) { FacePlayerPacket facePlayerPacket = new FacePlayerPacket(); facePlayerPacket.entityFacePosition = facePoint == FacePoint.EYE ? FacePlayerPacket.FacePosition.EYES : FacePlayerPacket.FacePosition.FEET; - facePlayerPacket.targetX = targetPosition.getX(); - facePlayerPacket.targetY = targetPosition.getY(); - facePlayerPacket.targetZ = targetPosition.getZ(); + facePlayerPacket.targetX = targetPosition.x(); + facePlayerPacket.targetY = targetPosition.y(); + facePlayerPacket.targetZ = targetPosition.z(); if (entity != null) { facePlayerPacket.entityId = entity.getEntityId(); facePlayerPacket.entityFacePosition = targetPoint == FacePoint.EYE ? @@ -1329,13 +1330,12 @@ public class Player extends LivingEntity implements CommandSender, Localizable, /** * Used to retrieve the default spawn point. *

- * Can be altered by the {@link PlayerRespawnEvent#setRespawnPosition(Position)}. + * Can be altered by the {@link PlayerRespawnEvent#setRespawnPosition(Pos)}. * * @return a copy of the default respawn point */ - @NotNull - public Position getRespawnPoint() { - return respawnPoint.clone(); + public @NotNull Pos getRespawnPoint() { + return respawnPoint; } /** @@ -1343,7 +1343,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable, * * @param respawnPoint the player respawn point */ - public void setRespawnPoint(@NotNull Position respawnPoint) { + public void setRespawnPoint(@NotNull Pos respawnPoint) { this.respawnPoint = respawnPoint; } @@ -1365,8 +1365,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable, { // Send new chunks - final BlockPosition pos = position.toBlockPosition(); - final Chunk chunk = instance.getChunk(pos.getX() >> 4, pos.getZ() >> 4); + final Chunk chunk = instance.getChunkAt(position); Check.notNull(chunk, "Tried to interact with an unloaded chunk."); refreshVisibleChunks(chunk); } @@ -1903,7 +1902,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable, protected void synchronizePosition(boolean includeSelf) { if (includeSelf) { final PlayerPositionAndLookPacket positionAndLookPacket = new PlayerPositionAndLookPacket(); - positionAndLookPacket.position = position.clone(); + positionAndLookPacket.position = position; positionAndLookPacket.flags = 0x00; positionAndLookPacket.teleportId = teleportId.incrementAndGet(); playerConnection.sendPacket(positionAndLookPacket); @@ -2324,7 +2323,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable, EntityHeadLookPacket entityHeadLookPacket = new EntityHeadLookPacket(); entityHeadLookPacket.entityId = getEntityId(); - entityHeadLookPacket.yaw = position.getYaw(); + entityHeadLookPacket.yaw = position.yaw(); connection.sendPacket(entityHeadLookPacket); } diff --git a/src/main/java/net/minestom/server/entity/ai/goal/CombinedAttackGoal.java b/src/main/java/net/minestom/server/entity/ai/goal/CombinedAttackGoal.java index df309307d..5cfa0f406 100644 --- a/src/main/java/net/minestom/server/entity/ai/goal/CombinedAttackGoal.java +++ b/src/main/java/net/minestom/server/entity/ai/goal/CombinedAttackGoal.java @@ -2,11 +2,10 @@ package net.minestom.server.entity.ai.goal; import net.minestom.server.entity.Entity; import net.minestom.server.entity.EntityCreature; +import net.minestom.server.entity.EntityProjectile; import net.minestom.server.entity.EntityType; import net.minestom.server.entity.ai.GoalSelector; import net.minestom.server.entity.pathfinding.Navigator; -import net.minestom.server.entity.EntityProjectile; -import net.minestom.server.utils.Position; import net.minestom.server.utils.time.Cooldown; import net.minestom.server.utils.time.TimeUnit; import net.minestom.server.utils.validate.Check; @@ -175,7 +174,7 @@ public class CombinedAttackGoal extends GoalSelector { if (!Cooldown.hasCooldown(time, this.lastAttack, this.rangedDelay)) { if (this.entityCreature.hasLineOfSight(target)) { // If target is on line of entity sight, ranged attack can be performed - Position to = target.getPosition().clone().add(0D, target.getEyeHeight(), 0D); + final var to = target.getPosition().add(0D, target.getEyeHeight(), 0D); Function projectileGenerator = this.projectileGenerator; if (projectileGenerator == null) { @@ -193,7 +192,7 @@ public class CombinedAttackGoal extends GoalSelector { } } Navigator navigator = this.entityCreature.getNavigator(); - Position pathPosition = navigator.getPathPosition(); + final var pathPosition = navigator.getPathPosition(); // If we don't want to come close and we're already within desirable range, no movement is needed. if (!comeClose && distanceSquared <= this.desirableRangeSquared) { if (pathPosition != null) { @@ -202,8 +201,8 @@ public class CombinedAttackGoal extends GoalSelector { return; } // Otherwise going to the target. - Position targetPosition = target.getPosition(); - if (pathPosition == null || !pathPosition.isSimilar(targetPosition)) { + final var targetPosition = target.getPosition(); + if (pathPosition == null || !pathPosition.samePoint(targetPosition)) { if (this.cooldown.isReady(time)) { this.cooldown.refreshLastUpdate(time); navigator.setPathTo(targetPosition); diff --git a/src/main/java/net/minestom/server/entity/ai/goal/EatBlockGoal.java b/src/main/java/net/minestom/server/entity/ai/goal/EatBlockGoal.java deleted file mode 100644 index 927d01ff9..000000000 --- a/src/main/java/net/minestom/server/entity/ai/goal/EatBlockGoal.java +++ /dev/null @@ -1,95 +0,0 @@ -package net.minestom.server.entity.ai.goal; - -import it.unimi.dsi.fastutil.shorts.Short2ShortArrayMap; -import net.minestom.server.entity.EntityCreature; -import net.minestom.server.entity.ai.GoalSelector; -import net.minestom.server.instance.Instance; -import net.minestom.server.instance.block.Block; -import net.minestom.server.utils.BlockPosition; -import org.jetbrains.annotations.NotNull; - -import java.util.Random; - -public class EatBlockGoal extends GoalSelector { - private static final Random RANDOM = new Random(); - private final Short2ShortArrayMap eatBelowMap; - private final Short2ShortArrayMap eatInMap; - private final int chancePerTick; - private int eatAnimationTick; - - /** - * @param entityCreature Creature that should eat a block. - * @param eatInMap Map containing the block IDs that the entity can eat (when inside the block) and the block ID of the replacement block. - * @param eatBelowMap Map containing block IDs that the entity can eat (when above the block) and the block ID of the replacement block. - * @param chancePerTick The chance (per tick) that the entity eats. Settings this to N would mean there is a 1 in N chance. - */ - public EatBlockGoal( - @NotNull EntityCreature entityCreature, - @NotNull Short2ShortArrayMap eatInMap, - @NotNull Short2ShortArrayMap eatBelowMap, - int chancePerTick) { - super(entityCreature); - this.eatInMap = eatInMap; - this.eatBelowMap = eatBelowMap; - this.chancePerTick = chancePerTick; - } - - @Override - public boolean shouldStart() { - // TODO: is Baby - if (RANDOM.nextInt(chancePerTick) != 0) { - return false; - } - - final Instance instance = entityCreature.getInstance(); - - // An entity shouldn't be eating blocks on null instances. - if (instance == null) { - return false; - } - - final BlockPosition blockPosition = entityCreature.getPosition().toBlockPosition(); - final short blockStateIdIn = instance.getBlock(blockPosition.clone().subtract(0, 1, 0)).stateId(); - final short blockStateIdBelow = instance.getBlock(blockPosition.clone().subtract(0, 2, 0)).stateId(); - - return eatInMap.containsKey(blockStateIdIn) || eatBelowMap.containsKey(blockStateIdBelow); - } - - @Override - public void start() { - this.eatAnimationTick = 40; - // TODO: EatBlockEvent call here. - // Stop moving - entityCreature.getNavigator().setPathTo(null); - } - - @Override - public void tick(long time) { - this.eatAnimationTick = Math.max(0, this.eatAnimationTick - 1); - if (this.eatAnimationTick != 4) { - return; - } - Instance instance = entityCreature.getInstance(); - final BlockPosition currentPosition = entityCreature.getPosition().toBlockPosition().clone().subtract(0, 1, 0); - final BlockPosition belowPosition = currentPosition.clone().subtract(0, 1, 0); - - final short blockStateIdIn = instance.getBlock(currentPosition).stateId(); - final short blockStateIdBelow = instance.getBlock(belowPosition).stateId(); - if (eatInMap.containsKey(blockStateIdIn)) { - instance.setBlock(currentPosition, Block.fromStateId(eatInMap.get(blockStateIdIn))); - } else if (eatBelowMap.containsKey(blockStateIdBelow)) { - instance.setBlock(belowPosition, Block.fromStateId(eatBelowMap.get(blockStateIdBelow))); - } - // TODO: Call Entity Eat Animation - } - - @Override - public boolean shouldEnd() { - return eatAnimationTick <= 0; - } - - @Override - public void end() { - this.eatAnimationTick = 0; - } -} diff --git a/src/main/java/net/minestom/server/entity/ai/goal/FollowTargetGoal.java b/src/main/java/net/minestom/server/entity/ai/goal/FollowTargetGoal.java index 47a895279..589a71074 100644 --- a/src/main/java/net/minestom/server/entity/ai/goal/FollowTargetGoal.java +++ b/src/main/java/net/minestom/server/entity/ai/goal/FollowTargetGoal.java @@ -4,8 +4,7 @@ import net.minestom.server.entity.Entity; import net.minestom.server.entity.EntityCreature; import net.minestom.server.entity.ai.GoalSelector; import net.minestom.server.entity.pathfinding.Navigator; -import net.minestom.server.utils.MathUtils; -import net.minestom.server.utils.Position; +import net.minestom.server.utils.coordinate.Point; import org.jetbrains.annotations.NotNull; import java.time.Duration; @@ -15,14 +14,13 @@ public class FollowTargetGoal extends GoalSelector { private final Duration pathDuration; private long lastUpdateTime = 0; private boolean forceEnd = false; - private Position lastTargetPos; + private Point lastTargetPos; /** * Creates a follow target goal object. * * @param entityCreature the entity * @param pathUpdateOption the time between each path update (to check if the target moved) - * * @deprecated Replaced by {@link #FollowTargetGoal(EntityCreature, Duration)} */ @SuppressWarnings("removal") @@ -34,8 +32,8 @@ public class FollowTargetGoal extends GoalSelector { /** * Creates a follow target goal object. * - * @param entityCreature the entity - * @param pathDuration the time between each path update (to check if the target moved) + * @param entityCreature the entity + * @param pathDuration the time between each path update (to check if the target moved) */ public FollowTargetGoal(@NotNull EntityCreature entityCreature, @NotNull Duration pathDuration) { super(entityCreature); @@ -45,7 +43,7 @@ public class FollowTargetGoal extends GoalSelector { @Override public boolean shouldStart() { return entityCreature.getTarget() != null && - getDistance(entityCreature.getTarget().getPosition(), entityCreature.getPosition()) >= 2; + entityCreature.getTarget().getPosition().distance(entityCreature.getPosition()) >= 2; } @Override @@ -54,19 +52,18 @@ public class FollowTargetGoal extends GoalSelector { forceEnd = false; lastTargetPos = null; final Entity target = entityCreature.getTarget(); - if (target != null) { Navigator navigator = entityCreature.getNavigator(); - lastTargetPos = target.getPosition().clone(); - if (getDistance(lastTargetPos, entityCreature.getPosition()) < 2) { + lastTargetPos = target.getPosition(); + if (lastTargetPos.distance(entityCreature.getPosition()) < 2) { forceEnd = true; navigator.setPathTo(null); return; } if (navigator.getPathPosition() == null || - (!navigator.getPathPosition().isSimilar(lastTargetPos))) { + (!navigator.getPathPosition().samePoint(lastTargetPos))) { navigator.setPathTo(lastTargetPos); } else { forceEnd = true; @@ -83,28 +80,24 @@ public class FollowTargetGoal extends GoalSelector { pathDuration.toMillis() + lastUpdateTime > time) { return; } - Position targetPos = entityCreature.getTarget() != null ? entityCreature.getTarget().getPosition() : null; - if (targetPos != null && !targetPos.equals(lastTargetPos)) { - lastUpdateTime = time; - lastTargetPos.copy(lastTargetPos); - entityCreature.getNavigator().setPathTo(targetPos); + final var targetPos = entityCreature.getTarget() != null ? entityCreature.getTarget().getPosition() : null; + if (targetPos != null && !targetPos.samePoint(lastTargetPos)) { + this.lastUpdateTime = time; + this.lastTargetPos = targetPos; + this.entityCreature.getNavigator().setPathTo(targetPos); } } @Override public boolean shouldEnd() { + final Entity target = entityCreature.getTarget(); return forceEnd || - entityCreature.getTarget() == null || - getDistance(entityCreature.getTarget().getPosition(), entityCreature.getPosition()) < 2; + target == null || + target.getPosition().distance(entityCreature.getPosition()) < 2; } @Override public void end() { entityCreature.getNavigator().setPathTo(null); } - - private double getDistance(@NotNull Position a, @NotNull Position b) { - return MathUtils.square(a.getX() - b.getX()) + - MathUtils.square(a.getZ() - b.getZ()); - } } diff --git a/src/main/java/net/minestom/server/entity/ai/goal/MeleeAttackGoal.java b/src/main/java/net/minestom/server/entity/ai/goal/MeleeAttackGoal.java index 761d8ecb1..12f357b20 100644 --- a/src/main/java/net/minestom/server/entity/ai/goal/MeleeAttackGoal.java +++ b/src/main/java/net/minestom/server/entity/ai/goal/MeleeAttackGoal.java @@ -5,7 +5,7 @@ import net.minestom.server.entity.EntityCreature; import net.minestom.server.entity.ai.GoalSelector; import net.minestom.server.entity.ai.TargetSelector; import net.minestom.server.entity.pathfinding.Navigator; -import net.minestom.server.utils.Position; +import net.minestom.server.utils.coordinate.Point; import net.minestom.server.utils.time.Cooldown; import net.minestom.server.utils.time.TimeUnit; import org.jetbrains.annotations.NotNull; @@ -61,7 +61,7 @@ public class MeleeAttackGoal extends GoalSelector { @Override public void start() { - final Position targetPosition = this.cachedTarget.getPosition(); + final Point targetPosition = this.cachedTarget.getPosition(); entityCreature.getNavigator().setPathTo(targetPosition); } @@ -90,9 +90,9 @@ public class MeleeAttackGoal extends GoalSelector { // Move toward the target entity Navigator navigator = entityCreature.getNavigator(); - final Position pathPosition = navigator.getPathPosition(); - final Position targetPosition = target.getPosition(); - if (pathPosition == null || !pathPosition.isSimilar(targetPosition)) { + final var pathPosition = navigator.getPathPosition(); + final var targetPosition = target.getPosition(); + if (pathPosition == null || !pathPosition.samePoint(targetPosition)) { if (this.cooldown.isReady(time)) { this.cooldown.refreshLastUpdate(time); navigator.setPathTo(targetPosition); diff --git a/src/main/java/net/minestom/server/entity/ai/goal/RandomLookAroundGoal.java b/src/main/java/net/minestom/server/entity/ai/goal/RandomLookAroundGoal.java index 27e530dfe..af0e39ba5 100644 --- a/src/main/java/net/minestom/server/entity/ai/goal/RandomLookAroundGoal.java +++ b/src/main/java/net/minestom/server/entity/ai/goal/RandomLookAroundGoal.java @@ -3,6 +3,7 @@ package net.minestom.server.entity.ai.goal; import net.minestom.server.entity.EntityCreature; import net.minestom.server.entity.ai.GoalSelector; import net.minestom.server.utils.Vector; +import net.minestom.server.utils.coordinate.Vec; import org.jetbrains.annotations.NotNull; import java.util.Random; @@ -13,20 +14,20 @@ public class RandomLookAroundGoal extends GoalSelector { private static final Random RANDOM = new Random(); private final int chancePerTick; private final Supplier minimalLookTimeSupplier; - private final Function randomDirectionFunction; - private Vector lookDirection; + private final Function randomDirectionFunction; + private Vec lookDirection; private int lookTime = 0; public RandomLookAroundGoal(EntityCreature entityCreature, int chancePerTick) { this(entityCreature, chancePerTick, - // These two functions act similarily enough to how MC randomly looks around. + // These two functions act similarly enough to how MC randomly looks around. // Look in one direction for at most 40 ticks and at minimum 20 ticks. () -> 20 + RANDOM.nextInt(20), // Look at a random block (creature) -> { final double n = Math.PI * 2 * RANDOM.nextDouble(); - return new Vector( + return new Vec( (float) Math.cos(n), 0, (float) Math.sin(n) @@ -44,8 +45,7 @@ public class RandomLookAroundGoal extends GoalSelector { EntityCreature entityCreature, int chancePerTick, @NotNull Supplier minimalLookTimeSupplier, - @NotNull Function randomDirectionFunction - ) { + @NotNull Function randomDirectionFunction) { super(entityCreature); this.chancePerTick = chancePerTick; this.minimalLookTimeSupplier = minimalLookTimeSupplier; @@ -79,6 +79,5 @@ public class RandomLookAroundGoal extends GoalSelector { @Override public void end() { - } } diff --git a/src/main/java/net/minestom/server/entity/ai/goal/RandomStrollGoal.java b/src/main/java/net/minestom/server/entity/ai/goal/RandomStrollGoal.java index 9f1cd1385..5e5c068d2 100644 --- a/src/main/java/net/minestom/server/entity/ai/goal/RandomStrollGoal.java +++ b/src/main/java/net/minestom/server/entity/ai/goal/RandomStrollGoal.java @@ -2,7 +2,7 @@ package net.minestom.server.entity.ai.goal; import net.minestom.server.entity.EntityCreature; import net.minestom.server.entity.ai.GoalSelector; -import net.minestom.server.utils.Position; +import net.minestom.server.utils.coordinate.Vec; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -14,14 +14,13 @@ public class RandomStrollGoal extends GoalSelector { private static final long DELAY = 2500; private final int radius; - private final List closePositions; + private final List closePositions; private long lastStroll; public RandomStrollGoal(@NotNull EntityCreature entityCreature, int radius) { super(entityCreature); this.radius = radius; - this.closePositions = getNearbyBlocks(radius); } @@ -33,20 +32,17 @@ public class RandomStrollGoal extends GoalSelector { @Override public void start() { Collections.shuffle(closePositions); - - for (Position position : closePositions) { - final Position target = position.clone().add(entityCreature.getPosition()); + for (var position : closePositions) { + final var target = entityCreature.getPosition().add(position); final boolean result = entityCreature.getNavigator().setPathTo(target); if (result) { break; } } - } @Override public void tick(long time) { - } @Override @@ -64,17 +60,15 @@ public class RandomStrollGoal extends GoalSelector { } @NotNull - private List getNearbyBlocks(int radius) { - List blocks = new ArrayList<>(); + private List getNearbyBlocks(int radius) { + List blocks = new ArrayList<>(); for (int x = -radius; x <= radius; x++) { for (int y = -radius; y <= radius; y++) { for (int z = -radius; z <= radius; z++) { - final Position position = new Position(x, y, z); - blocks.add(position); + blocks.add(new Vec(x, y, z)); } } } return blocks; } - } diff --git a/src/main/java/net/minestom/server/entity/ai/goal/RangedAttackGoal.java b/src/main/java/net/minestom/server/entity/ai/goal/RangedAttackGoal.java index e0af845e8..d4da300e7 100644 --- a/src/main/java/net/minestom/server/entity/ai/goal/RangedAttackGoal.java +++ b/src/main/java/net/minestom/server/entity/ai/goal/RangedAttackGoal.java @@ -104,7 +104,7 @@ public class RangedAttackGoal extends GoalSelector { if (distanceSquared <= this.attackRangeSquared) { if (!Cooldown.hasCooldown(time, this.lastShot, this.delay)) { if (this.entityCreature.hasLineOfSight(target)) { - Position to = target.getPosition().clone().add(0D, target.getEyeHeight(), 0D); + final var to = target.getPosition().add(0D, target.getEyeHeight(), 0D); Function projectileGenerator = this.projectileGenerator; if (projectileGenerator == null) { @@ -121,15 +121,15 @@ public class RangedAttackGoal extends GoalSelector { } } Navigator navigator = this.entityCreature.getNavigator(); - Position pathPosition = navigator.getPathPosition(); + final var pathPosition = navigator.getPathPosition(); if (!comeClose && distanceSquared <= this.desirableRangeSquared) { if (pathPosition != null) { navigator.setPathTo(null); } return; } - Position targetPosition = target.getPosition(); - if (pathPosition == null || !pathPosition.isSimilar(targetPosition)) { + final var targetPosition = target.getPosition(); + if (pathPosition == null || !pathPosition.samePoint(targetPosition)) { if (this.cooldown.isReady(time)) { this.cooldown.refreshLastUpdate(time); navigator.setPathTo(targetPosition); diff --git a/src/main/java/net/minestom/server/entity/hologram/Hologram.java b/src/main/java/net/minestom/server/entity/hologram/Hologram.java index 0c680ff95..476fdc108 100644 --- a/src/main/java/net/minestom/server/entity/hologram/Hologram.java +++ b/src/main/java/net/minestom/server/entity/hologram/Hologram.java @@ -9,6 +9,7 @@ import net.minestom.server.entity.Player; import net.minestom.server.entity.metadata.other.ArmorStandMeta; import net.minestom.server.instance.Instance; import net.minestom.server.utils.Position; +import net.minestom.server.utils.coordinate.Pos; import net.minestom.server.utils.validate.Check; import org.jetbrains.annotations.NotNull; @@ -25,7 +26,7 @@ public class Hologram implements Viewable { private final Entity entity; private final float yOffset; - private Position position; + private Pos position; private Component text; private boolean removed; @@ -36,35 +37,8 @@ public class Hologram implements Viewable { * @param instance The instance where the hologram should be spawned. * @param spawnPosition The spawn position of this hologram. * @param text The text of this hologram. - * @param autoViewable {@code true}if the hologram should be visible automatically, otherwise {@code false}. - * @deprecated Use {@link #Hologram(Instance, Position, Component, boolean)} */ - @Deprecated - public Hologram(Instance instance, Position spawnPosition, JsonMessage text, boolean autoViewable) { - this(instance, spawnPosition, text.asComponent(), autoViewable); - } - - /** - * Constructs a new {@link Hologram} with the given parameters. - * - * @param instance The instance where the hologram should be spawned. - * @param spawnPosition The spawn position of this hologram. - * @param text The text of this hologram. - * @deprecated Use {@link #Hologram(Instance, Position, Component)} - */ - @Deprecated - public Hologram(Instance instance, Position spawnPosition, JsonMessage text) { - this(instance, spawnPosition, text, true); - } - - /** - * Constructs a new {@link Hologram} with the given parameters. - * - * @param instance The instance where the hologram should be spawned. - * @param spawnPosition The spawn position of this hologram. - * @param text The text of this hologram. - */ - public Hologram(Instance instance, Position spawnPosition, Component text) { + public Hologram(Instance instance, Pos spawnPosition, Component text) { this(instance, spawnPosition, text, true); } @@ -76,7 +50,7 @@ public class Hologram implements Viewable { * @param text The text of this hologram. * @param autoViewable {@code true}if the hologram should be visible automatically, otherwise {@code false}. */ - public Hologram(Instance instance, Position spawnPosition, Component text, boolean autoViewable) { + public Hologram(Instance instance, Pos spawnPosition, Component text, boolean autoViewable) { this(instance, spawnPosition, text, autoViewable, false); } @@ -88,7 +62,7 @@ public class Hologram implements Viewable { * @param text The text of this hologram. * @param autoViewable {@code true}if the hologram should be visible automatically, otherwise {@code false}. */ - public Hologram(Instance instance, Position spawnPosition, Component text, boolean autoViewable, boolean marker) { + public Hologram(Instance instance, Pos spawnPosition, Component text, boolean autoViewable, boolean marker) { this.entity = new Entity(EntityType.ARMOR_STAND); ArmorStandMeta armorStandMeta = (ArmorStandMeta) entity.getEntityMeta(); @@ -109,7 +83,7 @@ public class Hologram implements Viewable { armorStandMeta.setNotifyAboutChanges(true); - this.entity.setInstance(instance, spawnPosition.clone().add(0, this.yOffset, 0)); + this.entity.setInstance(instance, spawnPosition.add(0, this.yOffset, 0)); this.entity.setAutoViewable(autoViewable); this.position = spawnPosition; @@ -121,7 +95,7 @@ public class Hologram implements Viewable { * * @return the hologram's position */ - public Position getPosition() { + public Pos getPosition() { return position; } @@ -130,11 +104,10 @@ public class Hologram implements Viewable { * * @param position the new hologram's position */ - public void setPosition(Position position) { + public void setPosition(Pos position) { checkRemoved(); - position.add(0, this.yOffset, 0); - this.position = position; - this.entity.teleport(position); + this.position = position.add(0, this.yOffset, 0); + this.entity.teleport(this.position); } /** diff --git a/src/main/java/net/minestom/server/entity/pathfinding/Navigator.java b/src/main/java/net/minestom/server/entity/pathfinding/Navigator.java index ff2b5d7e6..9150ddfc3 100644 --- a/src/main/java/net/minestom/server/entity/pathfinding/Navigator.java +++ b/src/main/java/net/minestom/server/entity/pathfinding/Navigator.java @@ -12,6 +12,9 @@ import net.minestom.server.instance.WorldBorder; import net.minestom.server.utils.Position; import net.minestom.server.utils.Vector; import net.minestom.server.utils.chunk.ChunkUtils; +import net.minestom.server.utils.coordinate.Point; +import net.minestom.server.utils.coordinate.Pos; +import net.minestom.server.utils.coordinate.Vec; import net.minestom.server.utils.position.PositionUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -26,7 +29,7 @@ public class Navigator { private final PFPathingEntity pathingEntity; private HydrazinePathFinder pathFinder; private IPath path; - private Position pathPosition; + private Point pathPosition; private final Entity entity; @@ -43,17 +46,16 @@ public class Navigator { * @param direction the targeted position * @param speed define how far the entity will move */ - public void moveTowards(@NotNull Position direction, double speed) { + public void moveTowards(@NotNull Point direction, double speed) { + final Pos position = entity.getPosition(); - final Position position = entity.getPosition(); + final double currentX = position.x(); + final double currentY = position.y(); + final double currentZ = position.z(); - final double currentX = position.getX(); - final double currentY = position.getY(); - final double currentZ = position.getZ(); - - final double targetX = direction.getX(); - final double targetY = direction.getY(); - final double targetZ = direction.getZ(); + final double targetX = direction.x(); + final double targetY = direction.y(); + final double targetZ = direction.z(); final double dx = targetX - currentX; final double dy = targetY - currentY; @@ -71,7 +73,7 @@ public class Navigator { final double speedZ = Math.sin(radians) * speed; // Update 'position' view - PositionUtils.lookAlong(position, dx, direction.getY(), dz); + PositionUtils.lookAlong(position, dx, direction.y(), dz); Position newPosition = new Position(); Vector newVelocityOut = new Vector(); @@ -87,8 +89,7 @@ public class Navigator { public void jump(float height) { // FIXME magic value - final Vector velocity = new Vector(0, height * 2.5f, 0); - this.entity.setVelocity(velocity); + this.entity.setVelocity(new Vec(0, height * 2.5f, 0)); } /** @@ -99,13 +100,13 @@ public class Navigator { * The position is cloned, if you want the entity to continually follow this position object * you need to call this when you want the path to update. * - * @param position the position to find the path to, null to reset the pathfinder + * @param point the position to find the path to, null to reset the pathfinder * @param bestEffort whether to use the best-effort algorithm to the destination, * if false then this method is more likely to return immediately * @return true if a path has been found */ - public synchronized boolean setPathTo(@Nullable Position position, boolean bestEffort) { - if (position != null && pathPosition != null && position.isSimilar(pathPosition)) { + public synchronized boolean setPathTo(@Nullable Point point, boolean bestEffort) { + if (point != null && pathPosition != null && point.samePoint(pathPosition)) { // Tried to set path to the same target position return false; } @@ -118,7 +119,7 @@ public class Navigator { } pathFinder.reset(); - if (position == null) { + if (point == null) { return false; } @@ -129,38 +130,36 @@ public class Navigator { // Can't path outside of the world border final WorldBorder worldBorder = instance.getWorldBorder(); - if (!worldBorder.isInside(position)) { + if (!worldBorder.isInside(point)) { return false; } // Can't path in an unloaded chunk - final Chunk chunk = instance.getChunkAt(position); + final Chunk chunk = instance.getChunkAt(point); if (!ChunkUtils.isLoaded(chunk)) { return false; } - final Position targetPosition = position.clone(); - final PathOptions pathOptions = new PathOptions() .targetingStrategy(bestEffort ? PathOptions.TargetingStrategy.gravitySnap : PathOptions.TargetingStrategy.none); final IPath path = pathFinder.initiatePathTo( - targetPosition.getX(), - targetPosition.getY(), - targetPosition.getZ(), + point.x(), + point.y(), + point.z(), pathOptions); this.path = path; final boolean success = path != null; - this.pathPosition = success ? targetPosition : null; + this.pathPosition = success ? point : null; return success; } /** - * @see #setPathTo(Position, boolean) with {@code bestEffort} sets to {@code true}. + * @see #setPathTo(Point, boolean) with {@code bestEffort} sets to {@code true}. */ - public boolean setPathTo(@Nullable Position position) { + public boolean setPathTo(@Nullable Point position) { return setPathTo(position, true); } @@ -174,7 +173,7 @@ public class Navigator { this.path = path; if (path != null) { - final Position targetPosition = pathingEntity.getTargetPosition(); + final Point targetPosition = pathingEntity.getTargetPosition(); if (targetPosition != null) { moveTowards(targetPosition, speed); } @@ -220,8 +219,7 @@ public class Navigator { * * @return the target pathfinder position, null if there is no one */ - @Nullable - public Position getPathPosition() { + public @Nullable Point getPathPosition() { return pathPosition; } @@ -229,10 +227,10 @@ public class Navigator { * Changes the position this element is trying to reach. * * @param pathPosition the new current path position - * @deprecated Please use {@link #setPathTo(Position)} + * @deprecated Please use {@link #setPathTo(Point)} */ @Deprecated - public void setPathPosition(@Nullable Position pathPosition) { + public void setPathPosition(@Nullable Point pathPosition) { this.pathPosition = pathPosition; } diff --git a/src/main/java/net/minestom/server/entity/pathfinding/PFPathingEntity.java b/src/main/java/net/minestom/server/entity/pathfinding/PFPathingEntity.java index bac0578af..5227797d3 100644 --- a/src/main/java/net/minestom/server/entity/pathfinding/PFPathingEntity.java +++ b/src/main/java/net/minestom/server/entity/pathfinding/PFPathingEntity.java @@ -8,6 +8,7 @@ import net.minestom.server.attribute.Attribute; import net.minestom.server.entity.Entity; import net.minestom.server.entity.LivingEntity; import net.minestom.server.utils.Position; +import net.minestom.server.utils.coordinate.Point; import org.jetbrains.annotations.NotNull; public class PFPathingEntity implements IPathingEntity { @@ -16,7 +17,7 @@ public class PFPathingEntity implements IPathingEntity { private final Entity entity; private float searchRange; - private Position targetPosition; + private Point targetPosition; // Capacities private boolean fireResistant; @@ -36,7 +37,7 @@ public class PFPathingEntity implements IPathingEntity { this.searchRange = getAttributeValue(Attribute.FOLLOW_RANGE); } - public Position getTargetPosition() { + public Point getTargetPosition() { return targetPosition; } @@ -195,16 +196,16 @@ public class PFPathingEntity implements IPathingEntity { public void moveTo(Vec3d position, Passibility passibility, Gravitation gravitation) { this.targetPosition = new Position(position.x, position.y, position.z); - final double entityY = entity.getPosition().getY(); - if (entityY < targetPosition.getY()) { + final double entityY = entity.getPosition().y(); + if (entityY < targetPosition.y()) { this.navigator.jump(1); } } @Override public Vec3d coordinates() { - final Position position = entity.getPosition(); - return new Vec3d(position.getX(), position.getY(), position.getZ()); + final var position = entity.getPosition(); + return new Vec3d(position.x(), position.y(), position.z()); } @Override diff --git a/src/main/java/net/minestom/server/event/entity/EntityShootEvent.java b/src/main/java/net/minestom/server/event/entity/EntityShootEvent.java index 88c02f14e..bffae8387 100644 --- a/src/main/java/net/minestom/server/event/entity/EntityShootEvent.java +++ b/src/main/java/net/minestom/server/event/entity/EntityShootEvent.java @@ -5,6 +5,7 @@ import net.minestom.server.entity.EntityProjectile; import net.minestom.server.event.trait.CancellableEvent; import net.minestom.server.event.trait.EntityEvent; import net.minestom.server.utils.Position; +import net.minestom.server.utils.coordinate.Point; import org.jetbrains.annotations.NotNull; /** @@ -14,13 +15,13 @@ public class EntityShootEvent implements EntityEvent, CancellableEvent { private final Entity entity; private final Entity projectile; - private final Position to; + private final Point to; private double power; private double spread; private boolean cancelled; - public EntityShootEvent(@NotNull Entity entity, @NotNull Entity projectile, @NotNull Position to, double power, double spread) { + public EntityShootEvent(@NotNull Entity entity, @NotNull Entity projectile, @NotNull Point to, double power, double spread) { this.entity = entity; this.projectile = projectile; this.to = to; @@ -42,7 +43,7 @@ public class EntityShootEvent implements EntityEvent, CancellableEvent { * * @return the position projectile was shot to. */ - public Position getTo() { + public Point getTo() { return this.to; } diff --git a/src/main/java/net/minestom/server/event/entity/EntityVelocityEvent.java b/src/main/java/net/minestom/server/event/entity/EntityVelocityEvent.java index 9ccdf6377..91a181b04 100644 --- a/src/main/java/net/minestom/server/event/entity/EntityVelocityEvent.java +++ b/src/main/java/net/minestom/server/event/entity/EntityVelocityEvent.java @@ -3,20 +3,20 @@ package net.minestom.server.event.entity; import net.minestom.server.entity.Entity; import net.minestom.server.event.trait.CancellableEvent; import net.minestom.server.event.trait.EntityEvent; -import net.minestom.server.utils.Vector; +import net.minestom.server.utils.coordinate.Vec; import org.jetbrains.annotations.NotNull; /** - * Called when a velocity is applied to an entity using {@link Entity#setVelocity(Vector)}. + * Called when a velocity is applied to an entity using {@link Entity#setVelocity(Vec)}. */ public class EntityVelocityEvent implements EntityEvent, CancellableEvent { private final Entity entity; - private Vector velocity; + private Vec velocity; private boolean cancelled; - public EntityVelocityEvent(@NotNull Entity entity, @NotNull Vector velocity) { + public EntityVelocityEvent(@NotNull Entity entity, @NotNull Vec velocity) { this.entity = entity; this.velocity = velocity; } @@ -26,9 +26,8 @@ public class EntityVelocityEvent implements EntityEvent, CancellableEvent { * * @return the entity */ - @NotNull @Override - public Entity getEntity() { + public @NotNull Entity getEntity() { return entity; } @@ -37,8 +36,7 @@ public class EntityVelocityEvent implements EntityEvent, CancellableEvent { * * @return the velocity */ - @NotNull - public Vector getVelocity() { + public @NotNull Vec getVelocity() { return velocity; } @@ -47,7 +45,7 @@ public class EntityVelocityEvent implements EntityEvent, CancellableEvent { * * @param velocity the new velocity */ - public void setVelocity(@NotNull Vector velocity) { + public void setVelocity(@NotNull Vec velocity) { this.velocity = velocity; } diff --git a/src/main/java/net/minestom/server/event/player/PlayerMoveEvent.java b/src/main/java/net/minestom/server/event/player/PlayerMoveEvent.java index 2d7bf046d..bf20d28b0 100644 --- a/src/main/java/net/minestom/server/event/player/PlayerMoveEvent.java +++ b/src/main/java/net/minestom/server/event/player/PlayerMoveEvent.java @@ -3,7 +3,7 @@ package net.minestom.server.event.player; import net.minestom.server.entity.Player; import net.minestom.server.event.trait.CancellableEvent; import net.minestom.server.event.trait.PlayerEvent; -import net.minestom.server.utils.Position; +import net.minestom.server.utils.coordinate.Pos; import org.jetbrains.annotations.NotNull; /** @@ -12,11 +12,11 @@ import org.jetbrains.annotations.NotNull; public class PlayerMoveEvent implements PlayerEvent, CancellableEvent { private final Player player; - private Position newPosition; + private Pos newPosition; private boolean cancelled; - public PlayerMoveEvent(@NotNull Player player, @NotNull Position newPosition) { + public PlayerMoveEvent(@NotNull Player player, @NotNull Pos newPosition) { this.player = player; this.newPosition = newPosition; } @@ -26,8 +26,7 @@ public class PlayerMoveEvent implements PlayerEvent, CancellableEvent { * * @return the new position */ - @NotNull - public Position getNewPosition() { + public @NotNull Pos getNewPosition() { return newPosition; } @@ -36,7 +35,7 @@ public class PlayerMoveEvent implements PlayerEvent, CancellableEvent { * * @param newPosition the new target position */ - public void setNewPosition(@NotNull Position newPosition) { + public void setNewPosition(@NotNull Pos newPosition) { this.newPosition = newPosition; } diff --git a/src/main/java/net/minestom/server/event/player/PlayerRespawnEvent.java b/src/main/java/net/minestom/server/event/player/PlayerRespawnEvent.java index a064e0efb..8bcd19d4c 100644 --- a/src/main/java/net/minestom/server/event/player/PlayerRespawnEvent.java +++ b/src/main/java/net/minestom/server/event/player/PlayerRespawnEvent.java @@ -1,9 +1,8 @@ package net.minestom.server.event.player; import net.minestom.server.entity.Player; -import net.minestom.server.event.Event; import net.minestom.server.event.trait.PlayerEvent; -import net.minestom.server.utils.Position; +import net.minestom.server.utils.coordinate.Pos; import org.jetbrains.annotations.NotNull; /** @@ -13,7 +12,7 @@ import org.jetbrains.annotations.NotNull; public class PlayerRespawnEvent implements PlayerEvent { private final Player player; - private Position respawnPosition; + private Pos respawnPosition; public PlayerRespawnEvent(@NotNull Player player) { this.player = player; @@ -27,8 +26,7 @@ public class PlayerRespawnEvent implements PlayerEvent { * * @return the respawn position */ - @NotNull - public Position getRespawnPosition() { + public @NotNull Pos getRespawnPosition() { return respawnPosition; } @@ -37,7 +35,7 @@ public class PlayerRespawnEvent implements PlayerEvent { * * @param respawnPosition the new respawn position */ - public void setRespawnPosition(@NotNull Position respawnPosition) { + public void setRespawnPosition(@NotNull Pos respawnPosition) { this.respawnPosition = respawnPosition; } diff --git a/src/main/java/net/minestom/server/instance/Instance.java b/src/main/java/net/minestom/server/instance/Instance.java index 13be7960b..55a6f1c5b 100644 --- a/src/main/java/net/minestom/server/instance/Instance.java +++ b/src/main/java/net/minestom/server/instance/Instance.java @@ -35,6 +35,7 @@ import net.minestom.server.utils.Position; import net.minestom.server.utils.chunk.ChunkCallback; import net.minestom.server.utils.chunk.ChunkUtils; import net.minestom.server.utils.coordinate.Point; +import net.minestom.server.utils.coordinate.Pos; import net.minestom.server.utils.entity.EntityUtils; import net.minestom.server.utils.time.Cooldown; import net.minestom.server.utils.time.TimeUnit; @@ -309,10 +310,10 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta *

* Always returning false allow entities to survive in the void. * - * @param position the position in the world - * @return true iif position is inside the void + * @param point the point in the world + * @return true if the point is inside the void */ - public abstract boolean isInVoid(@NotNull Position position); + public abstract boolean isInVoid(@NotNull Point point); /** * Gets if the instance has been registered in {@link InstanceManager}. @@ -535,12 +536,12 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta /** * Loads the chunk at the given {@link Position} with a callback. * - * @param position the chunk position + * @param point the chunk position * @param callback the optional callback to run when the chunk is loaded */ - public void loadChunk(@NotNull Position position, @Nullable ChunkCallback callback) { - final int chunkX = ChunkUtils.getChunkCoordinate(position.getX()); - final int chunkZ = ChunkUtils.getChunkCoordinate(position.getZ()); + public void loadChunk(@NotNull Point point, @Nullable ChunkCallback callback) { + final int chunkX = ChunkUtils.getChunkCoordinate(point.x()); + final int chunkZ = ChunkUtils.getChunkCoordinate(point.z()); loadChunk(chunkX, chunkZ, callback); } @@ -548,12 +549,12 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta * Loads a {@link Chunk} (if {@link #hasEnabledAutoChunkLoad()} returns true) * at the given {@link Position} with a callback. * - * @param position the chunk position + * @param point the chunk position * @param callback the optional callback executed when the chunk is loaded (or with a null chunk if not) */ - public void loadOptionalChunk(@NotNull Position position, @Nullable ChunkCallback callback) { - final int chunkX = ChunkUtils.getChunkCoordinate(position.getX()); - final int chunkZ = ChunkUtils.getChunkCoordinate(position.getZ()); + public void loadOptionalChunk(@NotNull Point point, @Nullable ChunkCallback callback) { + final int chunkX = ChunkUtils.getChunkCoordinate(point.x()); + final int chunkZ = ChunkUtils.getChunkCoordinate(point.z()); loadOptionalChunk(chunkX, chunkZ, callback); } @@ -703,7 +704,7 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta } AddEntityToInstanceEvent event = new AddEntityToInstanceEvent(this, entity); EventDispatcher.callCancellable(event, () -> { - final Position entityPosition = entity.getPosition(); + final Pos entityPosition = entity.getPosition(); final boolean isPlayer = entity instanceof Player; if (isPlayer) { diff --git a/src/main/java/net/minestom/server/instance/InstanceContainer.java b/src/main/java/net/minestom/server/instance/InstanceContainer.java index 4a3d0f2fe..1bb1395aa 100644 --- a/src/main/java/net/minestom/server/instance/InstanceContainer.java +++ b/src/main/java/net/minestom/server/instance/InstanceContainer.java @@ -19,7 +19,6 @@ import net.minestom.server.network.packet.server.play.UnloadChunkPacket; import net.minestom.server.storage.StorageLocation; import net.minestom.server.utils.BlockPosition; import net.minestom.server.utils.PacketUtils; -import net.minestom.server.utils.Position; import net.minestom.server.utils.callback.OptionalCallback; import net.minestom.server.utils.chunk.ChunkCallback; import net.minestom.server.utils.chunk.ChunkSupplier; @@ -385,9 +384,9 @@ public class InstanceContainer extends Instance { } @Override - public boolean isInVoid(@NotNull Position position) { + public boolean isInVoid(@NotNull Point point) { // TODO: customizable - return position.getY() < -64; + return point.y() < -64; } /** diff --git a/src/main/java/net/minestom/server/instance/SharedInstance.java b/src/main/java/net/minestom/server/instance/SharedInstance.java index 604b78d56..cd210ec89 100644 --- a/src/main/java/net/minestom/server/instance/SharedInstance.java +++ b/src/main/java/net/minestom/server/instance/SharedInstance.java @@ -4,7 +4,6 @@ import net.minestom.server.entity.Player; import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.BlockFace; import net.minestom.server.storage.StorageLocation; -import net.minestom.server.utils.Position; import net.minestom.server.utils.chunk.ChunkCallback; import net.minestom.server.utils.coordinate.Point; import org.jetbrains.annotations.NotNull; @@ -119,8 +118,8 @@ public class SharedInstance extends Instance { } @Override - public boolean isInVoid(@NotNull Position position) { - return instanceContainer.isInVoid(position); + public boolean isInVoid(@NotNull Point point) { + return instanceContainer.isInVoid(point); } /** diff --git a/src/main/java/net/minestom/server/instance/WorldBorder.java b/src/main/java/net/minestom/server/instance/WorldBorder.java index ea5474bc8..f8167fe2b 100644 --- a/src/main/java/net/minestom/server/instance/WorldBorder.java +++ b/src/main/java/net/minestom/server/instance/WorldBorder.java @@ -5,7 +5,7 @@ import net.minestom.server.entity.Player; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.play.*; import net.minestom.server.utils.PacketUtils; -import net.minestom.server.utils.Position; +import net.minestom.server.utils.coordinate.Point; import org.jetbrains.annotations.NotNull; /** @@ -159,14 +159,13 @@ public class WorldBorder { /** * Used to check at which axis does the position collides with the world border. * - * @param position the position to check + * @param point the point to check * @return the axis where the position collides with the world border */ - @NotNull - public CollisionAxis getCollisionAxis(@NotNull Position position) { + public @NotNull CollisionAxis getCollisionAxis(@NotNull Point point) { 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; + final boolean checkX = point.x() <= getCenterX() + radius && point.x() >= getCenterX() - radius; + final boolean checkZ = point.z() <= getCenterZ() + radius && point.z() >= getCenterZ() - radius; if (!checkX && !checkZ) { return CollisionAxis.BOTH; } else if (!checkX) { @@ -180,11 +179,11 @@ public class WorldBorder { /** * Used to know if a position is located inside the world border or not. * - * @param position the position to check + * @param point the point to check * @return true if {@code position} is inside the world border, false otherwise */ - public boolean isInside(@NotNull Position position) { - return getCollisionAxis(position) == CollisionAxis.NONE; + public boolean isInside(@NotNull Point point) { + return getCollisionAxis(point) == CollisionAxis.NONE; } /** diff --git a/src/main/java/net/minestom/server/instance/block/rule/vanilla/StairsPlacementRule.java b/src/main/java/net/minestom/server/instance/block/rule/vanilla/StairsPlacementRule.java index 66e255ac3..5f010cc86 100644 --- a/src/main/java/net/minestom/server/instance/block/rule/vanilla/StairsPlacementRule.java +++ b/src/main/java/net/minestom/server/instance/block/rule/vanilla/StairsPlacementRule.java @@ -155,7 +155,7 @@ public class StairsPlacementRule extends BlockPlacementRule { @NotNull private Facing getFacing(@NotNull Player player) { - float degrees = (player.getPosition().getYaw() - 90) % 360; + float degrees = (player.getPosition().yaw() - 90) % 360; if (degrees < 0) { degrees += 360; } diff --git a/src/main/java/net/minestom/server/listener/PlayerDiggingListener.java b/src/main/java/net/minestom/server/listener/PlayerDiggingListener.java index b6eb02da1..dbefb981c 100644 --- a/src/main/java/net/minestom/server/listener/PlayerDiggingListener.java +++ b/src/main/java/net/minestom/server/listener/PlayerDiggingListener.java @@ -13,7 +13,6 @@ import net.minestom.server.item.ItemStack; import net.minestom.server.item.StackingRule; import net.minestom.server.network.packet.client.play.ClientPlayerDiggingPacket; import net.minestom.server.network.packet.server.play.AcknowledgePlayerDiggingPacket; -import net.minestom.server.utils.BlockPosition; import net.minestom.server.utils.coordinate.Point; import org.jetbrains.annotations.NotNull; @@ -150,11 +149,10 @@ public class PlayerDiggingListener { if (!result) { if (block.isSolid()) { - final BlockPosition playerBlockPosition = player.getPosition().toBlockPosition(); - + final var playerPosition = player.getPosition(); // Teleport the player back if he broke a solid block just below him - if (playerBlockPosition.subtract(0, 1, 0).equals(blockPosition)) - player.teleport(player.getPosition()); + if (playerPosition.sub(0, 1, 0).samePoint(blockPosition)) + player.teleport(playerPosition); } } } diff --git a/src/main/java/net/minestom/server/listener/PlayerPositionListener.java b/src/main/java/net/minestom/server/listener/PlayerPositionListener.java index aadbe5a17..d7c31e29a 100644 --- a/src/main/java/net/minestom/server/listener/PlayerPositionListener.java +++ b/src/main/java/net/minestom/server/listener/PlayerPositionListener.java @@ -5,8 +5,8 @@ import net.minestom.server.event.EventDispatcher; import net.minestom.server.event.player.PlayerMoveEvent; import net.minestom.server.instance.Instance; import net.minestom.server.network.packet.client.play.*; -import net.minestom.server.utils.Position; import net.minestom.server.utils.chunk.ChunkUtils; +import net.minestom.server.utils.coordinate.Pos; import org.jetbrains.annotations.NotNull; public class PlayerPositionListener { @@ -16,10 +16,10 @@ public class PlayerPositionListener { } public static void playerLookListener(ClientPlayerRotationPacket packet, Player player) { - final Position playerPosition = player.getPosition(); - final double x = playerPosition.getX(); - final double y = playerPosition.getY(); - final double z = playerPosition.getZ(); + final var playerPosition = player.getPosition(); + final double x = playerPosition.x(); + final double y = playerPosition.y(); + final double z = playerPosition.z(); final float yaw = packet.yaw; final float pitch = packet.pitch; final boolean onGround = packet.onGround; @@ -27,9 +27,9 @@ public class PlayerPositionListener { } public static void playerPositionListener(ClientPlayerPositionPacket packet, Player player) { - final Position playerPosition = player.getPosition(); - final float yaw = playerPosition.getYaw(); - final float pitch = playerPosition.getPitch(); + final var playerPosition = player.getPosition(); + final float yaw = playerPosition.yaw(); + final float pitch = playerPosition.pitch(); final boolean onGround = packet.onGround; processMovement(player, packet.x, packet.y, packet.z, @@ -53,46 +53,35 @@ public class PlayerPositionListener { private static void processMovement(@NotNull Player player, double x, double y, double z, float yaw, float pitch, boolean onGround) { final Instance instance = player.getInstance(); - // Prevent moving before the player spawned, probably a modified client (or high latency?) if (instance == null) { return; } - // Prevent the player from moving during a teleport if (player.getLastSentTeleportId() != player.getLastReceivedTeleportId()) { return; } - // Try to move in an unloaded chunk, prevent it if (!ChunkUtils.isLoaded(instance, x, z)) { player.teleport(player.getPosition()); return; } - final Position currentPosition = player.getPosition().clone(); - Position newPosition = new Position(x, y, z, yaw, pitch); - final Position cachedPosition = newPosition.clone(); + final var currentPosition = player.getPosition(); + final var newPosition = new Pos(x, y, z, yaw, pitch); PlayerMoveEvent playerMoveEvent = new PlayerMoveEvent(player, newPosition); EventDispatcher.call(playerMoveEvent); // True if the event call changed the player position (possibly a teleport) final boolean positionChanged = !currentPosition.equals(player.getPosition()); - if (!playerMoveEvent.isCancelled() && !positionChanged) { // Move the player - newPosition = playerMoveEvent.getNewPosition(); - if (!newPosition.equals(cachedPosition)) { - // New position from the event changed, teleport the player - player.teleport(newPosition); - } - // Change the internal data - player.refreshPosition(newPosition); + player.refreshPosition(playerMoveEvent.getNewPosition()); player.refreshOnGround(onGround); } else { + // Cancelled, teleport to previous position player.teleport(player.getPosition()); } } - } diff --git a/src/main/java/net/minestom/server/listener/PlayerVehicleListener.java b/src/main/java/net/minestom/server/listener/PlayerVehicleListener.java index 28705dbbf..a816be7c0 100644 --- a/src/main/java/net/minestom/server/listener/PlayerVehicleListener.java +++ b/src/main/java/net/minestom/server/listener/PlayerVehicleListener.java @@ -6,7 +6,7 @@ import net.minestom.server.entity.metadata.other.BoatMeta; import net.minestom.server.network.packet.client.play.ClientSteerBoatPacket; import net.minestom.server.network.packet.client.play.ClientSteerVehiclePacket; import net.minestom.server.network.packet.client.play.ClientVehicleMovePacket; -import net.minestom.server.utils.Position; +import net.minestom.server.utils.coordinate.Pos; public class PlayerVehicleListener { @@ -19,11 +19,10 @@ public class PlayerVehicleListener { public static void vehicleMoveListener(ClientVehicleMovePacket packet, Player player) { final Entity vehicle = player.getVehicle(); - if (vehicle == null) return; - final Position newPosition = new Position((float) packet.x, (float) packet.y, (float) packet.z, packet.yaw, packet.pitch); + final var newPosition = new Pos(packet.x, packet.y, packet.z, packet.yaw, packet.pitch); vehicle.refreshPosition(newPosition); // This packet causes weird screen distortion @@ -39,7 +38,6 @@ public class PlayerVehicleListener { public static void boatSteerListener(ClientSteerBoatPacket packet, Player player) { final Entity vehicle = player.getVehicle(); - if (!(vehicle.getEntityMeta() instanceof BoatMeta)) return; @@ -47,5 +45,4 @@ public class PlayerVehicleListener { boat.setLeftPaddleTurning(packet.leftPaddleTurning); boat.setRightPaddleTurning(packet.rightPaddleTurning); } - } diff --git a/src/main/java/net/minestom/server/network/packet/server/play/EntityPositionAndRotationPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/EntityPositionAndRotationPacket.java index 6813ecbfd..1bab53308 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/EntityPositionAndRotationPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/EntityPositionAndRotationPacket.java @@ -2,9 +2,9 @@ package net.minestom.server.network.packet.server.play; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; -import net.minestom.server.utils.Position; import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryWriter; +import net.minestom.server.utils.coordinate.Pos; import org.jetbrains.annotations.NotNull; public class EntityPositionAndRotationPacket implements ServerPacket { @@ -14,7 +14,8 @@ public class EntityPositionAndRotationPacket implements ServerPacket { public float yaw, pitch; public boolean onGround; - public EntityPositionAndRotationPacket() {} + public EntityPositionAndRotationPacket() { + } @Override public void write(@NotNull BinaryWriter writer) { @@ -44,15 +45,15 @@ public class EntityPositionAndRotationPacket implements ServerPacket { } public static EntityPositionAndRotationPacket getPacket(int entityId, - @NotNull Position newPosition, @NotNull Position oldPosition, + @NotNull Pos newPosition, @NotNull Pos oldPosition, boolean onGround) { EntityPositionAndRotationPacket entityPositionAndRotationPacket = new EntityPositionAndRotationPacket(); entityPositionAndRotationPacket.entityId = entityId; - entityPositionAndRotationPacket.deltaX = (short) ((newPosition.getX() * 32 - oldPosition.getX() * 32) * 128); - entityPositionAndRotationPacket.deltaY = (short) ((newPosition.getY() * 32 - oldPosition.getY() * 32) * 128); - entityPositionAndRotationPacket.deltaZ = (short) ((newPosition.getZ() * 32 - oldPosition.getZ() * 32) * 128); - entityPositionAndRotationPacket.yaw = newPosition.getYaw(); - entityPositionAndRotationPacket.pitch = newPosition.getPitch(); + entityPositionAndRotationPacket.deltaX = (short) ((newPosition.x() * 32 - oldPosition.x() * 32) * 128); + entityPositionAndRotationPacket.deltaY = (short) ((newPosition.y() * 32 - oldPosition.y() * 32) * 128); + entityPositionAndRotationPacket.deltaZ = (short) ((newPosition.z() * 32 - oldPosition.z() * 32) * 128); + entityPositionAndRotationPacket.yaw = newPosition.yaw(); + entityPositionAndRotationPacket.pitch = newPosition.pitch(); entityPositionAndRotationPacket.onGround = onGround; return entityPositionAndRotationPacket; diff --git a/src/main/java/net/minestom/server/network/packet/server/play/EntityPositionPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/EntityPositionPacket.java index e69e4fb72..8df4a2c04 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/EntityPositionPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/EntityPositionPacket.java @@ -2,9 +2,9 @@ package net.minestom.server.network.packet.server.play; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; -import net.minestom.server.utils.Position; import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryWriter; +import net.minestom.server.utils.coordinate.Pos; import org.jetbrains.annotations.NotNull; public class EntityPositionPacket implements ServerPacket { @@ -13,7 +13,8 @@ public class EntityPositionPacket implements ServerPacket { public short deltaX, deltaY, deltaZ; public boolean onGround; - public EntityPositionPacket() {} + public EntityPositionPacket() { + } @Override public void write(@NotNull BinaryWriter writer) { @@ -40,13 +41,13 @@ public class EntityPositionPacket implements ServerPacket { @NotNull public static EntityPositionPacket getPacket(int entityId, - @NotNull Position newPosition, @NotNull Position oldPosition, + @NotNull Pos newPosition, @NotNull Pos oldPosition, boolean onGround) { EntityPositionPacket entityPositionPacket = new EntityPositionPacket(); entityPositionPacket.entityId = entityId; - entityPositionPacket.deltaX = (short) ((newPosition.getX() * 32 - oldPosition.getX() * 32) * 128); - entityPositionPacket.deltaY = (short) ((newPosition.getY() * 32 - oldPosition.getY() * 32) * 128); - entityPositionPacket.deltaZ = (short) ((newPosition.getZ() * 32 - oldPosition.getZ() * 32) * 128); + entityPositionPacket.deltaX = (short) ((newPosition.x() * 32 - oldPosition.x() * 32) * 128); + entityPositionPacket.deltaY = (short) ((newPosition.y() * 32 - oldPosition.y() * 32) * 128); + entityPositionPacket.deltaZ = (short) ((newPosition.z() * 32 - oldPosition.z() * 32) * 128); entityPositionPacket.onGround = onGround; return entityPositionPacket; diff --git a/src/main/java/net/minestom/server/network/packet/server/play/EntityTeleportPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/EntityTeleportPacket.java index 764f9c371..040bd2e30 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/EntityTeleportPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/EntityTeleportPacket.java @@ -2,42 +2,42 @@ package net.minestom.server.network.packet.server.play; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; -import net.minestom.server.utils.Position; import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryWriter; +import net.minestom.server.utils.coordinate.Pos; import org.jetbrains.annotations.NotNull; public class EntityTeleportPacket implements ServerPacket { public int entityId; - public Position position; + public Pos position; public boolean onGround; public EntityTeleportPacket() { - position = new Position(); + position = Pos.ZERO; } @Override public void write(@NotNull BinaryWriter writer) { writer.writeVarInt(entityId); - writer.writeDouble(position.getX()); - writer.writeDouble(position.getY()); - writer.writeDouble(position.getZ()); - writer.writeByte((byte) (position.getYaw() * 256f / 360f)); - writer.writeByte((byte) (position.getPitch() * 256f / 360f)); + writer.writeDouble(position.x()); + writer.writeDouble(position.y()); + writer.writeDouble(position.z()); + writer.writeByte((byte) (position.yaw() * 256f / 360f)); + writer.writeByte((byte) (position.pitch() * 256f / 360f)); writer.writeBoolean(onGround); } @Override public void read(@NotNull BinaryReader reader) { entityId = reader.readVarInt(); - position = new Position( + position = new Pos( reader.readDouble(), reader.readDouble(), reader.readDouble(), reader.readByte() * 360f / 256f, reader.readByte() * 360f / 256f - ); + ); onGround = reader.readBoolean(); } diff --git a/src/main/java/net/minestom/server/network/packet/server/play/PlayerPositionAndLookPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/PlayerPositionAndLookPacket.java index 4b354eec2..6e86d68fb 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/PlayerPositionAndLookPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/PlayerPositionAndLookPacket.java @@ -2,30 +2,30 @@ package net.minestom.server.network.packet.server.play; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; -import net.minestom.server.utils.Position; import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryWriter; +import net.minestom.server.utils.coordinate.Pos; import org.jetbrains.annotations.NotNull; public class PlayerPositionAndLookPacket implements ServerPacket { - public Position position; + public Pos position; public byte flags; public int teleportId; public boolean dismountVehicle; public PlayerPositionAndLookPacket() { - position = new Position(); + position = Pos.ZERO; } @Override public void write(@NotNull BinaryWriter writer) { - writer.writeDouble(position.getX()); - writer.writeDouble(position.getY()); - writer.writeDouble(position.getZ()); + writer.writeDouble(position.x()); + writer.writeDouble(position.y()); + writer.writeDouble(position.z()); - writer.writeFloat(position.getYaw()); - writer.writeFloat(position.getPitch()); + writer.writeFloat(position.yaw()); + writer.writeFloat(position.pitch()); writer.writeByte(flags); writer.writeVarInt(teleportId); @@ -34,7 +34,7 @@ public class PlayerPositionAndLookPacket implements ServerPacket { @Override public void read(@NotNull BinaryReader reader) { - position = new Position(reader.readDouble(), reader.readDouble(), reader.readDouble(), reader.readFloat(), reader.readFloat()); + position = new Pos(reader.readDouble(), reader.readDouble(), reader.readDouble(), reader.readFloat(), reader.readFloat()); flags = reader.readByte(); teleportId = reader.readVarInt(); diff --git a/src/main/java/net/minestom/server/network/packet/server/play/SoundEffectPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/SoundEffectPacket.java index 83edb0492..e3c0f433b 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/SoundEffectPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/SoundEffectPacket.java @@ -5,9 +5,9 @@ import net.minestom.server.adventure.AdventurePacketConvertor; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.sound.SoundEvent; -import net.minestom.server.utils.Position; import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryWriter; +import net.minestom.server.utils.coordinate.Pos; import org.jetbrains.annotations.NotNull; public class SoundEffectPacket implements ServerPacket { @@ -23,18 +23,19 @@ public class SoundEffectPacket implements ServerPacket { } @NotNull - public static SoundEffectPacket create(Source category, SoundEvent sound, Position position, float volume, float pitch) { + public static SoundEffectPacket create(Source category, SoundEvent sound, Pos position, float volume, float pitch) { SoundEffectPacket packet = new SoundEffectPacket(); packet.soundId = sound.getId(); packet.soundSource = category; // *8 converts to fixed-point representation with 3 bits for fractional part - packet.x = (int) position.getX(); - packet.y = (int) position.getY(); - packet.z = (int) position.getZ(); + packet.x = (int) position.x(); + packet.y = (int) position.y(); + packet.z = (int) position.z(); packet.volume = volume; packet.pitch = pitch; return packet; } + @Override public void write(@NotNull BinaryWriter writer) { writer.writeVarInt(soundId); @@ -50,9 +51,9 @@ public class SoundEffectPacket implements ServerPacket { public void read(@NotNull BinaryReader reader) { soundId = reader.readVarInt(); soundSource = Source.values()[reader.readVarInt()]; - x = reader.readInt()/8; - y = reader.readInt()/8; - z = reader.readInt()/8; + x = reader.readInt() / 8; + y = reader.readInt() / 8; + z = reader.readInt() / 8; volume = reader.readFloat(); pitch = reader.readFloat(); } diff --git a/src/main/java/net/minestom/server/network/packet/server/play/SpawnEntityPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/SpawnEntityPacket.java index 555d8d870..d345fae9d 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/SpawnEntityPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/SpawnEntityPacket.java @@ -2,9 +2,9 @@ package net.minestom.server.network.packet.server.play; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; -import net.minestom.server.utils.Position; import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryWriter; +import net.minestom.server.utils.coordinate.Pos; import org.jetbrains.annotations.NotNull; import java.util.UUID; @@ -14,13 +14,13 @@ public class SpawnEntityPacket implements ServerPacket { public int entityId; public UUID uuid; public int type; - public Position position; + public Pos position; public int data; public short velocityX, velocityY, velocityZ; public SpawnEntityPacket() { uuid = new UUID(0, 0); - position = new Position(); + position = Pos.ZERO; } @Override @@ -29,12 +29,12 @@ public class SpawnEntityPacket implements ServerPacket { writer.writeUuid(uuid); writer.writeVarInt(type); - writer.writeDouble(position.getX()); - writer.writeDouble(position.getY()); - writer.writeDouble(position.getZ()); + writer.writeDouble(position.x()); + writer.writeDouble(position.y()); + writer.writeDouble(position.z()); - writer.writeByte((byte) (position.getYaw() * 256 / 360)); - writer.writeByte((byte) (position.getPitch() * 256 / 360)); + writer.writeByte((byte) (position.yaw() * 256 / 360)); + writer.writeByte((byte) (position.pitch() * 256 / 360)); writer.writeInt(data); @@ -49,10 +49,9 @@ public class SpawnEntityPacket implements ServerPacket { uuid = reader.readUuid(); type = reader.readVarInt(); - position = new Position(reader.readDouble(), reader.readDouble(), reader.readDouble()); - - position.setYaw(reader.readByte() * 360f / 256f); - position.setPitch(reader.readByte() * 360f / 256f); + position = new Pos(reader.readDouble(), reader.readDouble(), reader.readDouble(), + reader.readByte() * 360f / 256f, + reader.readByte() * 360f / 256f); data = reader.readInt(); diff --git a/src/main/java/net/minestom/server/network/packet/server/play/SpawnExperienceOrbPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/SpawnExperienceOrbPacket.java index a0b36f4b8..b4ffa30ac 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/SpawnExperienceOrbPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/SpawnExperienceOrbPacket.java @@ -2,34 +2,34 @@ package net.minestom.server.network.packet.server.play; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; -import net.minestom.server.utils.Position; import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryWriter; +import net.minestom.server.utils.coordinate.Pos; import org.jetbrains.annotations.NotNull; public class SpawnExperienceOrbPacket implements ServerPacket { public int entityId; - public Position position; + public Pos position; public short expCount; public SpawnExperienceOrbPacket() { - position = new Position(); + position = Pos.ZERO; } @Override public void write(@NotNull BinaryWriter writer) { writer.writeVarInt(entityId); - writer.writeDouble(position.getX()); - writer.writeDouble(position.getY()); - writer.writeDouble(position.getZ()); + writer.writeDouble(position.x()); + writer.writeDouble(position.y()); + writer.writeDouble(position.z()); writer.writeShort(expCount); } @Override public void read(@NotNull BinaryReader reader) { entityId = reader.readVarInt(); - position = new Position(reader.readDouble(), reader.readDouble(), reader.readDouble()); + position = new Pos(reader.readDouble(), reader.readDouble(), reader.readDouble()); expCount = reader.readShort(); } diff --git a/src/main/java/net/minestom/server/network/packet/server/play/SpawnLivingEntityPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/SpawnLivingEntityPacket.java index 6726ddb32..3031564b9 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/SpawnLivingEntityPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/SpawnLivingEntityPacket.java @@ -2,9 +2,9 @@ package net.minestom.server.network.packet.server.play; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; -import net.minestom.server.utils.Position; import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryWriter; +import net.minestom.server.utils.coordinate.Pos; import org.jetbrains.annotations.NotNull; import java.util.UUID; @@ -14,13 +14,13 @@ public class SpawnLivingEntityPacket implements ServerPacket { public int entityId; public UUID entityUuid; public int entityType; - public Position position; + public Pos position; public float headPitch; public short velocityX, velocityY, velocityZ; public SpawnLivingEntityPacket() { entityUuid = new UUID(0, 0); - position = new Position(); + position = Pos.ZERO; } @Override @@ -29,12 +29,12 @@ public class SpawnLivingEntityPacket implements ServerPacket { writer.writeUuid(entityUuid); writer.writeVarInt(entityType); - writer.writeDouble(position.getX()); - writer.writeDouble(position.getY()); - writer.writeDouble(position.getZ()); + writer.writeDouble(position.x()); + writer.writeDouble(position.y()); + writer.writeDouble(position.z()); - writer.writeByte((byte) (position.getYaw() * 256 / 360)); - writer.writeByte((byte) (position.getPitch() * 256 / 360)); + writer.writeByte((byte) (position.yaw() * 256 / 360)); + writer.writeByte((byte) (position.pitch() * 256 / 360)); writer.writeByte((byte) (headPitch * 256 / 360)); writer.writeShort(velocityX); @@ -48,10 +48,9 @@ public class SpawnLivingEntityPacket implements ServerPacket { entityUuid = reader.readUuid(); entityType = reader.readVarInt(); - position = new Position(reader.readDouble(), reader.readDouble(), reader.readDouble()); - - position.setYaw(reader.readByte() * 360f / 256f); - position.setPitch(reader.readByte() * 360f / 256f); + position = new Pos(reader.readDouble(), reader.readDouble(), reader.readDouble(), + reader.readByte() * 360f / 256f, + reader.readByte() * 360f / 256f); headPitch = reader.readByte() * 360f / 256f; velocityX = reader.readShort(); diff --git a/src/main/java/net/minestom/server/network/packet/server/play/SpawnPlayerPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/SpawnPlayerPacket.java index f1702983a..2d3c98cee 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/SpawnPlayerPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/SpawnPlayerPacket.java @@ -2,9 +2,9 @@ package net.minestom.server.network.packet.server.play; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; -import net.minestom.server.utils.Position; import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryWriter; +import net.minestom.server.utils.coordinate.Pos; import org.jetbrains.annotations.NotNull; import java.util.UUID; @@ -13,31 +13,31 @@ public class SpawnPlayerPacket implements ServerPacket { public int entityId; public UUID playerUuid; - public Position position; + public Pos position; public SpawnPlayerPacket() { - playerUuid = new UUID(0,0); - position = new Position(); + playerUuid = new UUID(0, 0); + position = Pos.ZERO; } @Override public void write(@NotNull BinaryWriter writer) { writer.writeVarInt(entityId); writer.writeUuid(playerUuid); - writer.writeDouble(position.getX()); - writer.writeDouble(position.getY()); - writer.writeDouble(position.getZ()); - writer.writeByte((byte) (position.getYaw() * 256f / 360f)); - writer.writeByte((byte) (position.getPitch() * 256f / 360f)); + writer.writeDouble(position.x()); + writer.writeDouble(position.y()); + writer.writeDouble(position.z()); + writer.writeByte((byte) (position.yaw() * 256f / 360f)); + writer.writeByte((byte) (position.pitch() * 256f / 360f)); } @Override public void read(@NotNull BinaryReader reader) { - entityId = reader.readVarInt(); - playerUuid = reader.readUuid(); - position = new Position(reader.readDouble(), reader.readDouble(), reader.readDouble()); - position.setYaw((reader.readByte() * 360f) / 256f); - position.setPitch((reader.readByte() * 360f) / 256f); + this.entityId = reader.readVarInt(); + this.playerUuid = reader.readUuid(); + this.position = new Pos(reader.readDouble(), reader.readDouble(), reader.readDouble(), + (reader.readByte() * 360f) / 256f, + (reader.readByte() * 360f) / 256f); } @Override diff --git a/src/main/java/net/minestom/server/utils/block/BlockIterator.java b/src/main/java/net/minestom/server/utils/block/BlockIterator.java index ec24391fa..ae7d170b0 100644 --- a/src/main/java/net/minestom/server/utils/block/BlockIterator.java +++ b/src/main/java/net/minestom/server/utils/block/BlockIterator.java @@ -5,6 +5,7 @@ import net.minestom.server.instance.block.BlockFace; import net.minestom.server.utils.BlockPosition; import net.minestom.server.utils.Position; import net.minestom.server.utils.Vector; +import net.minestom.server.utils.coordinate.Pos; import org.jetbrains.annotations.NotNull; import java.util.Iterator; @@ -228,7 +229,7 @@ public class BlockIterator implements Iterator { * trace. Setting this value above 140 may lead to problems with * unloaded chunks. A value of 0 indicates no limit */ - public BlockIterator(@NotNull Position pos, double yOffset, int maxDistance) { + public BlockIterator(@NotNull Pos pos, double yOffset, int maxDistance) { this(pos.toVector(), pos.getDirection(), yOffset, maxDistance); } @@ -242,7 +243,7 @@ public class BlockIterator implements Iterator { * by this value */ - public BlockIterator(@NotNull Position pos, double yOffset) { + public BlockIterator(@NotNull Pos pos, double yOffset) { this(pos.toVector(), pos.getDirection(), yOffset, 0); } @@ -254,7 +255,7 @@ public class BlockIterator implements Iterator { * @param pos The position for the start of the ray trace */ - public BlockIterator(@NotNull Position pos) { + public BlockIterator(@NotNull Pos pos) { this(pos, 0f); } diff --git a/src/main/java/net/minestom/server/utils/chunk/ChunkUtils.java b/src/main/java/net/minestom/server/utils/chunk/ChunkUtils.java index bf70b742b..78b118f77 100644 --- a/src/main/java/net/minestom/server/utils/chunk/ChunkUtils.java +++ b/src/main/java/net/minestom/server/utils/chunk/ChunkUtils.java @@ -6,6 +6,7 @@ import net.minestom.server.utils.BlockPosition; import net.minestom.server.utils.MathUtils; import net.minestom.server.utils.Position; import net.minestom.server.utils.callback.OptionalCallback; +import net.minestom.server.utils.coordinate.Point; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -103,8 +104,8 @@ public final class ChunkUtils { return originChunk; } - public static Chunk retrieve(Instance instance, Chunk originChunk, Position position) { - return retrieve(instance, originChunk, position.getX(), position.getZ()); + public static Chunk retrieve(Instance instance, Chunk originChunk, Point position) { + return retrieve(instance, originChunk, position.x(), position.z()); } public static Chunk retrieve(Instance instance, Chunk originChunk, BlockPosition blockPosition) { @@ -170,11 +171,11 @@ public final class ChunkUtils { /** * Gets the chunks in range of a position. * - * @param position the initial position + * @param point the initial point * @param range how far should it retrieves chunk * @return an array containing chunks index */ - public static long @NotNull [] getChunksInRange(@NotNull Position position, int range) { + public static long @NotNull [] getChunksInRange(@NotNull Point point, int range) { long[] visibleChunks = new long[MathUtils.square(range * 2 + 1)]; int xDistance = 0; int xDirection = 1; @@ -184,8 +185,8 @@ public final class ChunkUtils { int corner = 0; for (int i = 0; i < visibleChunks.length; i++) { - final int chunkX = getChunkCoordinate(xDistance * Chunk.CHUNK_SIZE_X + position.getX()); - final int chunkZ = getChunkCoordinate(zDistance * Chunk.CHUNK_SIZE_Z + position.getZ()); + final int chunkX = getChunkCoordinate(xDistance * Chunk.CHUNK_SIZE_X + point.x()); + final int chunkZ = getChunkCoordinate(zDistance * Chunk.CHUNK_SIZE_Z + point.z()); visibleChunks[i] = getChunkIndex(chunkX, chunkZ); if (corner % 2 == 0) { diff --git a/src/main/java/net/minestom/server/utils/coordinate/Point.java b/src/main/java/net/minestom/server/utils/coordinate/Point.java index e527862c9..eb4a5917b 100644 --- a/src/main/java/net/minestom/server/utils/coordinate/Point.java +++ b/src/main/java/net/minestom/server/utils/coordinate/Point.java @@ -1,6 +1,7 @@ package net.minestom.server.utils.coordinate; import net.minestom.server.utils.MathUtils; +import net.minestom.server.utils.chunk.ChunkUtils; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -138,4 +139,27 @@ public interface Point { MathUtils.square(y() - point.y()) + MathUtils.square(z() - point.z()); } + + /** + * Checks it two points have similar (x/y/z). + * + * @param point the point to compare + * @return true if the two positions are similar + */ + default boolean samePoint(@NotNull Point point) { + return Double.compare(point.x(), x()) == 0 && + Double.compare(point.y(), y()) == 0 && + Double.compare(point.z(), z()) == 0; + } + + /** + * Gets if two points are in the same chunk. + * + * @param point the point to compare two + * @return true if 'this' is in the same chunk as {@code position} + */ + default boolean inSameChunk(@NotNull Point point) { + return ChunkUtils.getChunkCoordinate(x()) == ChunkUtils.getChunkCoordinate(point.x()) && + ChunkUtils.getChunkCoordinate(z()) == ChunkUtils.getChunkCoordinate(point.z()); + } } diff --git a/src/main/java/net/minestom/server/utils/coordinate/Pos.java b/src/main/java/net/minestom/server/utils/coordinate/Pos.java index 6daafe716..3cff502e5 100644 --- a/src/main/java/net/minestom/server/utils/coordinate/Pos.java +++ b/src/main/java/net/minestom/server/utils/coordinate/Pos.java @@ -1,8 +1,10 @@ package net.minestom.server.utils.coordinate; +import net.minestom.server.utils.Position; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; +import java.util.Objects; import java.util.function.DoubleUnaryOperator; /** @@ -11,6 +13,8 @@ import java.util.function.DoubleUnaryOperator; * To become record and primitive. */ public final class Pos implements Point { + public static final Pos ZERO = new Pos(0, 0, 0); + private final double x, y, z; private final float yaw, pitch; @@ -34,6 +38,10 @@ public final class Pos implements Point { this(point, 0, 0); } + public static @NotNull Pos fromPosition(@NotNull Position position) { + return new Pos(position.getX(), position.getY(), position.getZ(), position.getYaw(), position.getPitch()); + } + @Contract(pure = true) public @NotNull Pos withCoord(double x, double y, double z) { return new Pos(x, y, z, yaw, pitch); @@ -69,6 +77,33 @@ public final class Pos implements Point { return new Pos(x, y, z, yaw, (float) operator.applyAsDouble(pitch)); } + /** + * Checks if two positions have a similar view (yaw/pitch). + * + * @param position the position to compare + * @return true if the two positions have the same view + */ + public boolean sameView(@NotNull Pos position) { + return Float.compare(position.yaw, yaw) == 0 && + Float.compare(position.pitch, pitch) == 0; + } + + /** + * Gets a unit-vector pointing in the direction that this Location is + * facing. + * + * @return a vector pointing the direction of this location's {@link + * #pitch() pitch} and {@link #yaw() yaw} + */ + public @NotNull Vec direction() { + final float rotX = yaw; + final float rotY = pitch; + final double xz = Math.cos(Math.toRadians(rotY)); + return new Vec(-xz * Math.sin(Math.toRadians(rotX)), + -Math.sin(Math.toRadians(rotY)), + xz * Math.cos(Math.toRadians(rotX))); + } + @Override @Contract(pure = true) public double x() { @@ -203,6 +238,23 @@ public final class Pos implements Point { return new Vec(x, y, z); } + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Pos pos = (Pos) o; + return Double.compare(pos.x, x) == 0 && + Double.compare(pos.y, y) == 0 && + Double.compare(pos.z, z) == 0 && + Float.compare(pos.yaw, yaw) == 0 && + Float.compare(pos.pitch, pitch) == 0; + } + + @Override + public int hashCode() { + return Objects.hash(x, y, z, yaw, pitch); + } + @FunctionalInterface public interface Operator { @NotNull Pos apply(double x, double y, double z); diff --git a/src/main/java/net/minestom/server/utils/entity/EntityFinder.java b/src/main/java/net/minestom/server/utils/entity/EntityFinder.java index 8dc9daf60..301656def 100644 --- a/src/main/java/net/minestom/server/utils/entity/EntityFinder.java +++ b/src/main/java/net/minestom/server/utils/entity/EntityFinder.java @@ -156,19 +156,19 @@ public class EntityFinder { // Diff X/Y/Z if (dx != null || dy != null || dz != null) { result = result.stream().filter(entity -> { - final Position entityPosition = entity.getPosition(); + final var entityPosition = entity.getPosition(); if (dx != null && !MathUtils.isBetweenUnordered( - entityPosition.getX(), + entityPosition.x(), startPosition.getX(), dx)) return false; if (dy != null && !MathUtils.isBetweenUnordered( - entityPosition.getY(), + entityPosition.y(), startPosition.getY(), dy)) return false; if (dz != null && !MathUtils.isBetweenUnordered( - entityPosition.getZ(), + entityPosition.z(), startPosition.getZ(), dz)) return false; @@ -231,12 +231,12 @@ public class EntityFinder { // RANDOM is handled below return 1; case FURTHEST: - return startPosition.getDistance(ent1.getPosition()) > - startPosition.getDistance(ent2.getPosition()) ? + return startPosition.distance(ent1.getPosition()) > + startPosition.distance(ent2.getPosition()) ? 1 : 0; case NEAREST: - return startPosition.getDistance(ent1.getPosition()) < - startPosition.getDistance(ent2.getPosition()) ? + return startPosition.distance(ent1.getPosition()) < + startPosition.distance(ent2.getPosition()) ? 1 : 0; } return 1; @@ -346,7 +346,7 @@ public class EntityFinder { Collection instancePlayers = instance != null ? instance.getPlayers() : MinecraftServer.getConnectionManager().getOnlinePlayers(); for (Player player : instancePlayers) { - final double distance = player.getPosition().getDistance(startPosition); + final double distance = player.getPosition().distance(startPosition); if (distance < closestDistance) { entity = player; closestDistance = distance; diff --git a/src/main/java/net/minestom/server/utils/entity/EntityUtils.java b/src/main/java/net/minestom/server/utils/entity/EntityUtils.java index 7ca0f84c1..960a18a51 100644 --- a/src/main/java/net/minestom/server/utils/entity/EntityUtils.java +++ b/src/main/java/net/minestom/server/utils/entity/EntityUtils.java @@ -5,9 +5,9 @@ import net.minestom.server.entity.Entity; import net.minestom.server.instance.Chunk; import net.minestom.server.instance.Instance; import net.minestom.server.instance.block.Block; -import net.minestom.server.utils.BlockPosition; -import net.minestom.server.utils.Position; import net.minestom.server.utils.chunk.ChunkUtils; +import net.minestom.server.utils.coordinate.Point; +import net.minestom.server.utils.coordinate.Pos; import org.jetbrains.annotations.NotNull; import java.util.function.Consumer; @@ -18,11 +18,10 @@ public final class EntityUtils { } - public static void forEachRange(@NotNull Instance instance, @NotNull Position position, + public static void forEachRange(@NotNull Instance instance, @NotNull Point point, int viewDistance, @NotNull Consumer consumer) { - final long[] chunksInRange = ChunkUtils.getChunksInRange(position, viewDistance); - + final long[] chunksInRange = ChunkUtils.getChunksInRange(point, viewDistance); for (long chunkIndex : chunksInRange) { final int chunkX = ChunkUtils.getChunkCoordX(chunkIndex); final int chunkZ = ChunkUtils.getChunkCoordZ(chunkIndex); @@ -40,7 +39,6 @@ public final class EntityUtils { return false; final Chunk chunk = ent1.getInstance().getChunkAt(ent1.getPosition()); - final long[] visibleChunksEntity = ChunkUtils.getChunksInRange(ent2.getPosition(), MinecraftServer.getEntityViewDistance()); for (long visibleChunk : visibleChunksEntity) { final int chunkX = ChunkUtils.getChunkCoordX(visibleChunk); @@ -48,7 +46,6 @@ public final class EntityUtils { if (chunk.getChunkX() == chunkX && chunk.getChunkZ() == chunkZ) return true; } - return false; } @@ -56,18 +53,14 @@ public final class EntityUtils { final Chunk chunk = entity.getChunk(); if (chunk == null) return false; - - final Position entityPosition = entity.getPosition(); - + final Pos entityPosition = entity.getPosition(); // TODO: check entire bounding box - final BlockPosition blockPosition = entityPosition.toBlockPosition().subtract(0, 1, 0); try { - final Block block = chunk.getBlock(blockPosition); + final Block block = chunk.getBlock(entityPosition.sub(0, 1, 0)); return block.isSolid(); } catch (NullPointerException e) { // Probably an entity at the border of an unloaded chunk return false; } } - } diff --git a/src/main/java/net/minestom/server/utils/location/RelativeLocation.java b/src/main/java/net/minestom/server/utils/location/RelativeLocation.java index b2c2135fc..1a2843036 100644 --- a/src/main/java/net/minestom/server/utils/location/RelativeLocation.java +++ b/src/main/java/net/minestom/server/utils/location/RelativeLocation.java @@ -2,6 +2,8 @@ package net.minestom.server.utils.location; import net.minestom.server.entity.Entity; import net.minestom.server.utils.Position; +import net.minestom.server.utils.coordinate.Point; +import net.minestom.server.utils.coordinate.Pos; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -11,7 +13,7 @@ import org.jetbrains.annotations.Nullable; * * @param the location type */ -public abstract class RelativeLocation { +public abstract class RelativeLocation { protected T location; protected boolean relativeX, relativeY, relativeZ; @@ -41,13 +43,13 @@ public abstract class RelativeLocation { * @return the location */ public T from(@Nullable Entity entity) { - final Position entityPosition = entity != null ? entity.getPosition() : new Position(); + final var entityPosition = entity != null ? entity.getPosition() : Pos.ZERO; return from(entityPosition); } @ApiStatus.Experimental public T fromView(@Nullable Entity entity) { - final Position entityPosition = entity != null ? entity.getPosition() : new Position(); + final var entityPosition = entity != null ? entity.getPosition() : Pos.ZERO; return fromView(entityPosition); } diff --git a/src/test/java/demo/MainDemo.java b/src/test/java/demo/MainDemo.java index a1c381860..fe0d3054b 100644 --- a/src/test/java/demo/MainDemo.java +++ b/src/test/java/demo/MainDemo.java @@ -7,7 +7,7 @@ import net.minestom.server.event.player.PlayerLoginEvent; import net.minestom.server.instance.*; import net.minestom.server.instance.batch.ChunkBatch; import net.minestom.server.instance.block.Block; -import net.minestom.server.utils.Position; +import net.minestom.server.utils.coordinate.Pos; import net.minestom.server.world.biomes.Biome; import org.jetbrains.annotations.NotNull; @@ -31,7 +31,7 @@ public class MainDemo { globalEventHandler.addListener(PlayerLoginEvent.class, event -> { final Player player = event.getPlayer(); event.setSpawningInstance(instanceContainer); - player.setRespawnPoint(new Position(0, 42, 0)); + player.setRespawnPoint(new Pos(0, 42, 0)); }); // Start the server on port 25565 diff --git a/src/test/java/demo/PlayerInit.java b/src/test/java/demo/PlayerInit.java index 577f2bc6c..1e9273101 100644 --- a/src/test/java/demo/PlayerInit.java +++ b/src/test/java/demo/PlayerInit.java @@ -30,8 +30,8 @@ import net.minestom.server.item.Material; import net.minestom.server.monitoring.BenchmarkManager; import net.minestom.server.monitoring.TickMonitor; import net.minestom.server.utils.MathUtils; -import net.minestom.server.utils.Position; -import net.minestom.server.utils.Vector; +import net.minestom.server.utils.coordinate.Pos; +import net.minestom.server.utils.coordinate.Vec; import net.minestom.server.utils.time.TimeUnit; import net.minestom.server.world.DimensionType; @@ -75,11 +75,11 @@ public class PlayerInit { final Player player = event.getPlayer(); ItemStack droppedItem = event.getItemStack(); - Position position = player.getPosition().clone().add(0, 1.5f, 0); - ItemEntity itemEntity = new ItemEntity(droppedItem, position); + Pos playerPos = player.getPosition(); + ItemEntity itemEntity = new ItemEntity(droppedItem); itemEntity.setPickupDelay(Duration.of(500, TimeUnit.MILLISECOND)); - itemEntity.setInstance(player.getInstance()); - Vector velocity = player.getPosition().clone().getDirection().multiply(6); + itemEntity.setInstance(player.getInstance(), playerPos.withY(y -> y + 1.5)); + Vec velocity = playerPos.direction().mul(6); itemEntity.setVelocity(velocity); }) .addListener(PlayerDisconnectEvent.class, event -> System.out.println("DISCONNECTION " + event.getPlayer().getUsername())) @@ -91,7 +91,7 @@ public class PlayerInit { event.setSpawningInstance(instance); int x = Math.abs(ThreadLocalRandom.current().nextInt()) % 500 - 250; int z = Math.abs(ThreadLocalRandom.current().nextInt()) % 500 - 250; - player.setRespawnPoint(new Position(0, 42f, 0)); + player.setRespawnPoint(new Pos(0, 42f, 0)); }) .addListener(PlayerSpawnEvent.class, event -> { final Player player = event.getPlayer();