From 2f54bf0e14b50d4887566dcb30e17629e0f0ec4d Mon Sep 17 00:00:00 2001 From: Tim203 Date: Sat, 23 Apr 2022 20:57:32 +0200 Subject: [PATCH] Rotation fixes (#2396) * Should fix some rotation issues * Some more changes * Small changes * Fixed merge conflicts and updated other classes that changed * Added translation for the LookAt packet --- .../entity/type/AbstractArrowEntity.java | 6 +- .../geyser/entity/type/BoatEntity.java | 4 +- .../geysermc/geyser/entity/type/Entity.java | 15 ++-- .../geyser/entity/type/FireballEntity.java | 2 +- .../geyser/entity/type/FishingHookEntity.java | 4 +- .../geyser/entity/type/ItemEntity.java | 8 +-- .../geyser/entity/type/MinecartEntity.java | 2 +- .../geyser/entity/type/ThrowableEntity.java | 14 ++-- .../entity/type/living/ArmorStandEntity.java | 31 ++++----- .../entity/type/living/SquidEntity.java | 2 +- .../living/monster/EnderDragonEntity.java | 10 +-- .../entity/type/player/PlayerEntity.java | 17 +++-- .../player/BedrockMovePlayerTranslator.java | 10 +-- .../player/JavaPlayerLookAtTranslator.java | 68 +++++++++++++++++++ .../player/JavaPlayerPositionTranslator.java | 10 ++- .../org/geysermc/geyser/util/MathUtils.java | 19 +++++- 16 files changed, 154 insertions(+), 68 deletions(-) create mode 100644 core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerLookAtTranslator.java diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/AbstractArrowEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/AbstractArrowEntity.java index db0cfc738..963e0b70a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/AbstractArrowEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/AbstractArrowEntity.java @@ -70,8 +70,8 @@ public class AbstractArrowEntity extends Entity { super.setMotion(motion); double horizontalSpeed = Math.sqrt(motion.getX() * motion.getX() + motion.getZ() * motion.getZ()); - this.yaw = (float) Math.toDegrees(Math.atan2(motion.getX(), motion.getZ())); - this.pitch = (float) Math.toDegrees(Math.atan2(motion.getY(), horizontalSpeed)); - this.headYaw = yaw; + setYaw((float) Math.toDegrees(Math.atan2(motion.getX(), motion.getZ()))); + setPitch((float) Math.toDegrees(Math.atan2(motion.getY(), horizontalSpeed))); + setHeadYaw(getYaw()); } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java index 6ce490bc2..9fd96f46b 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/BoatEntity.java @@ -81,8 +81,8 @@ public class BoatEntity extends Entity { public void moveAbsolute(Vector3f position, float yaw, float pitch, float headYaw, boolean isOnGround, boolean teleported) { // We don't include the rotation (y) as it causes the boat to appear sideways setPosition(position.add(0d, this.definition.offset(), 0d)); - this.yaw = yaw + 90; - this.headYaw = yaw + 90; + setYaw(yaw + 90); + setHeadYaw(yaw + 90); setOnGround(isOnGround); MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket(); diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java index 270f69ee0..4dc3a437a 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/Entity.java @@ -204,7 +204,7 @@ public class Entity { } public void moveRelative(double relX, double relY, double relZ, float yaw, float pitch, boolean isOnGround) { - moveRelative(relX, relY, relZ, yaw, pitch, this.headYaw, isOnGround); + moveRelative(relX, relY, relZ, yaw, pitch, getHeadYaw(), isOnGround); } public void moveRelative(double relX, double relY, double relZ, float yaw, float pitch, float headYaw, boolean isOnGround) { @@ -225,7 +225,7 @@ public class Entity { } public void moveAbsolute(Vector3f position, float yaw, float pitch, boolean isOnGround, boolean teleported) { - moveAbsolute(position, yaw, pitch, this.headYaw, isOnGround, teleported); + moveAbsolute(position, yaw, pitch, getHeadYaw(), isOnGround, teleported); } public void moveAbsolute(Vector3f position, float yaw, float pitch, float headYaw, boolean isOnGround, boolean teleported) { @@ -254,7 +254,8 @@ public class Entity { * @param isOnGround Whether the entity is currently on the ground. */ public void teleport(Vector3f position, float yaw, float pitch, boolean isOnGround) { - moveAbsolute(position, yaw, pitch, isOnGround, false); + // teleport will always set the headYaw to yaw + moveAbsolute(position, yaw, pitch, yaw, isOnGround, false); } /** @@ -262,7 +263,7 @@ public class Entity { * @param headYaw The new head rotation of the entity. */ public void updateHeadLookRotation(float headYaw) { - moveRelative(0, 0, 0, headYaw, pitch, this.headYaw, onGround); + moveRelative(0, 0, 0, getYaw(), getPitch(), headYaw, isOnGround()); } /** @@ -275,7 +276,7 @@ public class Entity { * @param isOnGround Whether the entity is currently on the ground. */ public void updatePositionAndRotation(double moveX, double moveY, double moveZ, float yaw, float pitch, boolean isOnGround) { - moveRelative(moveX, moveY, moveZ, this.yaw, pitch, yaw, isOnGround); + moveRelative(moveX, moveY, moveZ, yaw, pitch, getHeadYaw(), isOnGround); } /** @@ -436,12 +437,12 @@ public class Entity { } /** - * x = Pitch, y = HeadYaw, z = Yaw + * x = Pitch, y = Yaw, z = HeadYaw * * @return the bedrock rotation */ public Vector3f getBedrockRotation() { - return Vector3f.from(pitch, headYaw, yaw); + return Vector3f.from(getPitch(), getYaw(), getHeadYaw()); } /** diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FireballEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FireballEntity.java index 744ddf4a6..135f58906 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/FireballEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/FireballEntity.java @@ -72,6 +72,6 @@ public class FireballEntity extends ThrowableEntity { @Override public void tick() { - moveAbsoluteImmediate(tickMovement(position), yaw, pitch, headYaw, false, false); + moveAbsoluteImmediate(tickMovement(position), getYaw(), getPitch(), getHeadYaw(), false, false); } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java index 2f5590c37..52ad82370 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/FishingHookEntity.java @@ -152,7 +152,7 @@ public class FishingHookEntity extends ThrowableEntity { float gravity = getGravity(); motion = motion.down(gravity); - moveAbsoluteImmediate(position.add(motion), yaw, pitch, headYaw, onGround, false); + moveAbsoluteImmediate(position.add(motion), getYaw(), getPitch(), getHeadYaw(), isOnGround(), false); float drag = getDrag(); motion = motion.mul(drag); @@ -160,7 +160,7 @@ public class FishingHookEntity extends ThrowableEntity { @Override protected float getGravity() { - if (!isInWater() && !onGround) { + if (!isInWater() && !isOnGround()) { return 0.03f; } return 0; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java index 79ffe68ef..f36a7c732 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ItemEntity.java @@ -76,10 +76,10 @@ public class ItemEntity extends ThrowableEntity { if (isInWater()) { return; } - if (!onGround || (motion.getX() * motion.getX() + motion.getZ() * motion.getZ()) > 0.00001) { + if (!isOnGround() || (motion.getX() * motion.getX() + motion.getZ() * motion.getZ()) > 0.00001) { float gravity = getGravity(); motion = motion.down(gravity); - moveAbsoluteImmediate(position.add(motion), yaw, pitch, headYaw, onGround, false); + moveAbsoluteImmediate(position.add(motion), getYaw(), getPitch(), getHeadYaw(), isOnGround(), false); float drag = getDrag(); motion = motion.mul(drag, 0.98f, drag); } @@ -124,7 +124,7 @@ public class ItemEntity extends ThrowableEntity { @Override protected float getGravity() { - if (getFlag(EntityFlag.HAS_GRAVITY) && !onGround && !isInWater()) { + if (getFlag(EntityFlag.HAS_GRAVITY) && !isOnGround() && !isInWater()) { // Gravity can change if the item is in water/lava, but // the server calculates the motion & position for us return 0.04f; @@ -134,7 +134,7 @@ public class ItemEntity extends ThrowableEntity { @Override protected float getDrag() { - if (onGround) { + if (isOnGround()) { Vector3i groundBlockPos = position.toInt().down(1); int blockState = session.getGeyser().getWorldManager().getBlockAt(session, groundBlockPos); return BlockStateValues.getSlipperiness(blockState) * 0.98f; diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/MinecartEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/MinecartEntity.java index a427d6a43..6f722864b 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/MinecartEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/MinecartEntity.java @@ -66,7 +66,7 @@ public class MinecartEntity extends Entity { @Override public Vector3f getBedrockRotation() { // Note: minecart rotation on rails does not care about the actual rotation value - return Vector3f.from(0, yaw, 0); + return Vector3f.from(0, getYaw(), 0); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java index 87e3be405..ad8b60bdb 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/ThrowableEntity.java @@ -56,7 +56,7 @@ public class ThrowableEntity extends Entity implements Tickable { */ @Override public void tick() { - moveAbsoluteImmediate(position.add(motion), yaw, pitch, headYaw, onGround, false); + moveAbsoluteImmediate(position.add(motion), getYaw(), getPitch(), getHeadYaw(), isOnGround(), false); float drag = getDrag(); float gravity = getGravity(); motion = motion.mul(drag).down(gravity); @@ -89,20 +89,20 @@ public class ThrowableEntity extends Entity implements Tickable { } setPosition(position); - if (this.yaw != yaw) { + if (getYaw() != yaw) { moveEntityDeltaPacket.getFlags().add(MoveEntityDeltaPacket.Flag.HAS_YAW); moveEntityDeltaPacket.setYaw(yaw); - this.yaw = yaw; + setYaw(yaw); } - if (this.pitch != pitch) { + if (getPitch() != pitch) { moveEntityDeltaPacket.getFlags().add(MoveEntityDeltaPacket.Flag.HAS_PITCH); moveEntityDeltaPacket.setPitch(pitch); - this.pitch = pitch; + setPitch(pitch); } - if (this.headYaw != headYaw) { + if (getHeadYaw() != headYaw) { moveEntityDeltaPacket.getFlags().add(MoveEntityDeltaPacket.Flag.HAS_HEAD_YAW); moveEntityDeltaPacket.setHeadYaw(headYaw); - this.headYaw = headYaw; + setHeadYaw(headYaw); } if (!moveEntityDeltaPacket.getFlags().isEmpty()) { diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java index 9c7e6d107..18076763e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/ArmorStandEntity.java @@ -42,6 +42,7 @@ import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.type.LivingEntity; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.util.InteractionResult; +import org.geysermc.geyser.util.MathUtils; import java.util.Optional; import java.util.UUID; @@ -87,8 +88,6 @@ public class ArmorStandEntity extends LivingEntity { @Override public void spawnEntity() { - this.pitch = yaw; - this.headYaw = yaw; super.spawnEntity(); } @@ -205,9 +204,9 @@ public class ArmorStandEntity extends LivingEntity { // Indicate that rotation should be checked setFlag(EntityFlag.BRIBED, true); - int rotationX = getRotation(rotation.getPitch()); - int rotationY = getRotation(rotation.getYaw()); - int rotationZ = getRotation(rotation.getRoll()); + int rotationX = MathUtils.wrapDegreesToInt(rotation.getPitch()); + int rotationY = MathUtils.wrapDegreesToInt(rotation.getYaw()); + int rotationZ = MathUtils.wrapDegreesToInt(rotation.getRoll()); // The top bit acts like binary and determines if each rotation goes above 100 // We don't do this for the negative values out of concerns of the number being too big int topBit = (Math.abs(rotationX) >= 100 ? 4 : 0) + (Math.abs(rotationY) >= 100 ? 2 : 0) + (Math.abs(rotationZ) >= 100 ? 1 : 0); @@ -319,7 +318,7 @@ public class ArmorStandEntity extends LivingEntity { // Create the second entity. It doesn't need to worry about the items, but it does need to worry about // the metadata as it will hold the name tag. secondEntity = new ArmorStandEntity(session, 0, session.getEntityCache().getNextEntityId().incrementAndGet(), null, - EntityDefinitions.ARMOR_STAND, position, motion, yaw, pitch, headYaw); + EntityDefinitions.ARMOR_STAND, position, motion, getYaw(), getPitch(), getHeadYaw()); secondEntity.primaryEntity = false; if (!this.positionRequiresOffset) { // Ensure the offset is applied for the 0 scale @@ -375,17 +374,6 @@ public class ArmorStandEntity extends LivingEntity { } } - private int getRotation(float rotation) { - rotation = rotation % 360f; - if (rotation < -180f) { - rotation += 360f; - } else if (rotation >= 180f) { - // 181 -> -179 - rotation = -(180 - (rotation - 180)); - } - return (int) rotation; - } - /** * If this armor stand is not a marker, set its bounding box size and scale. */ @@ -439,9 +427,14 @@ public class ArmorStandEntity extends LivingEntity { MoveEntityAbsolutePacket moveEntityPacket = new MoveEntityAbsolutePacket(); moveEntityPacket.setRuntimeEntityId(geyserId); moveEntityPacket.setPosition(position); - moveEntityPacket.setRotation(Vector3f.from(yaw, yaw, yaw)); - moveEntityPacket.setOnGround(onGround); + moveEntityPacket.setRotation(getBedrockRotation()); + moveEntityPacket.setOnGround(isOnGround()); moveEntityPacket.setTeleported(false); session.sendUpstreamPacket(moveEntityPacket); } + + @Override + public Vector3f getBedrockRotation() { + return Vector3f.from(getYaw(), getYaw(), getYaw()); + } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/SquidEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/SquidEntity.java index c81cf68de..552f6a46c 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/SquidEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/SquidEntity.java @@ -117,7 +117,7 @@ public class SquidEntity extends WaterEntity implements Tickable { @Override public Vector3f getBedrockRotation() { - return Vector3f.from(pitch, yaw, yaw); + return Vector3f.from(getPitch(), getYaw(), getYaw()); } @Override diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java index 0069bfb5b..99ab1a55c 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/monster/EnderDragonEntity.java @@ -130,7 +130,7 @@ public class EnderDragonEntity extends MobEntity implements Tickable { for (int i = 0; i < segmentHistory.length; i++) { segmentHistory[i] = new Segment(); - segmentHistory[i].yaw = headYaw; + segmentHistory[i].yaw = getHeadYaw(); segmentHistory[i].y = position.getY(); } } @@ -168,7 +168,7 @@ public class EnderDragonEntity extends MobEntity implements Tickable { * Updates the positions of the Ender Dragon's multiple bounding boxes */ private void updateBoundingBoxes() { - Vector3f facingDir = Vector3f.createDirectionDeg(0, headYaw); + Vector3f facingDir = Vector3f.createDirectionDeg(0, getHeadYaw()); Segment baseSegment = getSegment(5); // Used to angle the head, neck, and tail when the dragon flies up/down float pitch = (float) Math.toRadians(10 * (baseSegment.getY() - getSegment(10).getY())); @@ -187,7 +187,7 @@ public class EnderDragonEntity extends MobEntity implements Tickable { neck.setPosition(facingDir.up(pitchY).mul(pitchXZ, 1, -pitchXZ).mul(5.5f).up(headDuck)); body.setPosition(facingDir.mul(0.5f, 0f, -0.5f)); - Vector3f wingPos = Vector3f.createDirectionDeg(0, 90f - headYaw).mul(4.5f).up(2f); + Vector3f wingPos = Vector3f.createDirectionDeg(0, 90f - getHeadYaw()).mul(4.5f).up(2f); rightWing.setPosition(wingPos); leftWing.setPosition(wingPos.mul(-1, 1, -1)); // Mirror horizontally @@ -196,7 +196,7 @@ public class EnderDragonEntity extends MobEntity implements Tickable { float distance = (i + 1) * 2f; // Curls the tail when the dragon turns Segment targetSegment = getSegment(12 + 2 * i); - float angle = headYaw + targetSegment.yaw - baseSegment.yaw; + float angle = getHeadYaw() + targetSegment.yaw - baseSegment.yaw; float tailYOffset = targetSegment.y - baseSegment.y - (distance + 1.5f) * pitchY + 1.5f; tail[i].setPosition(Vector3f.createDirectionDeg(0, angle).mul(distance).add(tailBase).mul(-pitchXZ, 1, pitchXZ).up(tailYOffset)); @@ -306,7 +306,7 @@ public class EnderDragonEntity extends MobEntity implements Tickable { */ private void pushSegment() { latestSegment = (latestSegment + 1) % segmentHistory.length; - segmentHistory[latestSegment].yaw = headYaw; + segmentHistory[latestSegment].yaw = getHeadYaw(); segmentHistory[latestSegment].y = position.getY(); } diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java index 0d6c0dac1..5c0b18838 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/player/PlayerEntity.java @@ -213,7 +213,7 @@ public class PlayerEntity extends LivingEntity { @Override public void updateHeadLookRotation(float headYaw) { - moveRelative(0, 0, 0, yaw, pitch, headYaw, onGround); + moveRelative(0, 0, 0, getYaw(), getPitch(), headYaw, isOnGround()); MovePlayerPacket movePlayerPacket = new MovePlayerPacket(); movePlayerPacket.setRuntimeEntityId(geyserId); movePlayerPacket.setPosition(position); @@ -233,9 +233,11 @@ public class PlayerEntity extends LivingEntity { } } - @Override - public void updateRotation(float yaw, float pitch, boolean isOnGround) { - super.updateRotation(yaw, pitch, isOnGround); + public void updateRotation(float yaw, float pitch, float headYaw, boolean isOnGround) { + // the method below is called by super.updateRotation(yaw, pitch, isOnGround). + // but we have to be able to set the headYaw, so we call the method below directly. + super.moveRelative(0, 0, 0, yaw, pitch, headYaw, isOnGround); + // Both packets need to be sent or else player head rotation isn't correctly updated MovePlayerPacket movePlayerPacket = new MovePlayerPacket(); movePlayerPacket.setRuntimeEntityId(geyserId); @@ -252,6 +254,11 @@ public class PlayerEntity extends LivingEntity { } } + @Override + public void updateRotation(float yaw, float pitch, boolean isOnGround) { + updateRotation(yaw, pitch, getHeadYaw(), isOnGround); + } + @Override public void setPosition(Vector3f position) { super.setPosition(position.add(0, definition.offset(), 0)); @@ -300,7 +307,7 @@ public class PlayerEntity extends LivingEntity { } // The parrot is a separate entity in Bedrock, but part of the player entity in Java //TODO is a UUID provided in NBT? ParrotEntity parrot = new ParrotEntity(session, 0, session.getEntityCache().getNextEntityId().incrementAndGet(), - null, EntityDefinitions.PARROT, position, motion, yaw, pitch, headYaw); + null, EntityDefinitions.PARROT, position, motion, getYaw(), getPitch(), getHeadYaw()); parrot.spawnEntity(); parrot.getDirtyMetadata().put(EntityData.VARIANT, tag.get("Variant").getValue()); // Different position whether the parrot is left or right diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockMovePlayerTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockMovePlayerTranslator.java index a63c0f334..8732b7909 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockMovePlayerTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/bedrock/entity/player/BedrockMovePlayerTranslator.java @@ -81,8 +81,7 @@ public class BedrockMovePlayerTranslator extends PacketTranslator { + @Override + public void translate(GeyserSession session, ClientboundPlayerLookAtPacket packet) { + var targetPosition = targetPosition(session, packet); + var selfPosition = session.getPlayerEntity().getPosition(); + + var xDelta = targetPosition.getX() - selfPosition.getX(); + var yDelta = targetPosition.getY() - selfPosition.getY(); + var zDelta = targetPosition.getZ() - selfPosition.getZ(); + var sqrt = Math.sqrt(xDelta * xDelta + zDelta * zDelta); + + var yaw = MathUtils.wrapDegrees(-Math.toDegrees(Math.atan2(yDelta, sqrt))); + var pitch = MathUtils.wrapDegrees(Math.toDegrees(Math.atan2(zDelta, xDelta)) - 90.0); + + var self = session.getPlayerEntity(); + // headYaw is also set to yaw in this packet + self.updateRotation(yaw, pitch, yaw, self.isOnGround()); + } + + public Vector3f targetPosition(GeyserSession session, ClientboundPlayerLookAtPacket packet) { + if (packet.getTargetEntityOrigin() != null) { + var entityId = packet.getTargetEntityId(); + var target = session.getEntityCache().getEntityByJavaId(entityId); + if (target != null) { + return switch (packet.getTargetEntityOrigin()) { + case FEET -> target.getPosition(); + case EYES -> target.getPosition().add(0, target.getBoundingBoxHeight(), 0); + }; + } + } + return Vector3f.from(packet.getX(), packet.getY(), packet.getZ()); + } +} diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerPositionTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerPositionTranslator.java index 97487ea6a..f5d21ecc9 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerPositionTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/player/JavaPlayerPositionTranslator.java @@ -74,7 +74,7 @@ public class JavaPlayerPositionTranslator extends PacketTranslator= 180.0f) { + degrees -= 360.0f; + } + return degrees; + } + + public static float wrapDegrees(double degrees) { + return wrapDegrees((float) degrees); + } + + public static int wrapDegreesToInt(float degrees) { + return (int) wrapDegrees(degrees); + } + /** * Round the given float to the next whole number *