Skip to content

Commit 8fc840a

Browse files
committed
Simplify angle adjustment logic
Reuse existing logic from the motion translation
1 parent aa623a8 commit 8fc840a

File tree

1 file changed

+18
-82
lines changed

1 file changed

+18
-82
lines changed

src/main/java/com/direwolf20/justdirethings/common/entities/PortalEntity.java

Lines changed: 18 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818
import net.minecraft.world.level.ChunkPos;
1919
import net.minecraft.world.level.Level;
2020
import net.minecraft.world.phys.AABB;
21+
import net.minecraft.world.phys.Vec2;
2122
import net.minecraft.world.phys.Vec3;
2223
import net.minecraft.world.phys.shapes.Shapes;
2324
import net.neoforged.neoforge.common.Tags;
2425
import net.neoforged.neoforge.entity.PartEntity;
2526
import org.joml.Quaternionf;
26-
import org.joml.Vector2f;
2727
import org.joml.Vector3f;
2828

2929
import javax.annotation.Nullable;
@@ -426,13 +426,13 @@ public void teleport(Entity entity) {
426426
if (getLinkedPortal() != null) {
427427
Vec3 teleportTo = getTeleportTo(entity, linkedPortal);
428428
// Adjust the entity's rotation to match the exit portal's direction
429-
Vector2f newLookAngle = transformLookAngle(entity, linkedPortal);
429+
Vec2 newLookAngle = transformLookAngle(entity, linkedPortal);
430430
entity.resetFallDistance();
431431

432432
Vec3 newMotion = calculateVelocity(entity);
433433

434434
// Teleport the entity to the new location and set its rotation
435-
boolean success = entity.teleportTo((ServerLevel) linkedPortal.level(), teleportTo.x(), teleportTo.y(), teleportTo.z(), new HashSet<>(), newLookAngle.y(), newLookAngle.x());
435+
boolean success = entity.teleportTo((ServerLevel) linkedPortal.level(), teleportTo.x(), teleportTo.y(), teleportTo.z(), new HashSet<>(), newLookAngle.y, newLookAngle.x);
436436

437437
if (success) {
438438
entity.resetFallDistance();
@@ -491,86 +491,22 @@ public static Vec3 transformMotion(Vec3 motion, Direction from, Direction to) {
491491
/**
492492
* Adjust the entity's look angle (pitch and yaw) for seamless transitions between portals.
493493
*
494-
* <p>Transitioning between two 'vertical' portals will keep the vertical look, but transform the horizontal
495-
* look. For example, if you enter a portal looking at the portal and 10 degrees to the right, you will
496-
* leave the exit portal looking away from the portal and 10 degrees to the right. And if you walk in
497-
* backwards, you will walk out looking at the exit portal.</p>
498-
*
499-
* <p>Transitioning between two 'horizontal' (ceiling/floor) portals, the horizontal look is kept,
500-
* but the vertical look is flipped such that if you enter a floor portal looking down at it, you will exit a
501-
* ceiling portal looking down out of it, or another floor portal looking up out of it.</p>
502-
*
503-
* <p>Transitions between vertical and horizontal portals currently leave the look angle untouched.
504-
* Similar ideas could be applied to enhance this (albeit with a more complex implementation), but these use cases
505-
* are less common, and the lack of seamless angle adjustment is less jarring than with axis aligned pairs.</p>
506-
*
507-
* @param entity entity
494+
* @param entity entity
508495
* @param destination destination portal
509-
* @return adjusted (pitch, yaw)
510-
*/
511-
private Vector2f transformLookAngle(Entity entity, PortalEntity destination) {
512-
final Direction myDirection = this.getDirection();
513-
final boolean verticalEntry = myDirection.getAxis() != Direction.Axis.Y;
514-
final Direction destDirection = destination.getDirection();
515-
final boolean verticalExit = destDirection.getAxis() != Direction.Axis.Y;
516-
final float entityYaw = entity.getYRot();
517-
final float entityPitch = entity.getXRot();
518-
519-
float newYaw = entityYaw;
520-
float newPitch = entityPitch;
521-
522-
if (verticalEntry && verticalExit) { // Handle vertical-to-vertical portal transitions (N/E/S/W)
523-
final float entryFacingYaw = getDirectFacingYaw(myDirection);
524-
final float exitAwayYaw = getDirectFacingAwayYaw(destDirection);
525-
526-
// Calculate deviation from facing the entry portal
527-
final float yawDeviation = Mth.wrapDegrees(entityYaw - entryFacingYaw);
528-
529-
// Apply deviation to the direction facing AWAY from the exit portal
530-
newYaw = Mth.wrapDegrees(exitAwayYaw + yawDeviation);
531-
} else if (!verticalEntry && !verticalExit) { // Both portals are horizontal (U/D to U/D)
532-
// Keep horizontal look
533-
newYaw = entityYaw;
534-
// If we enter looking at the portal, we should exit looking away (and vice versa)
535-
newPitch = myDirection == destDirection ? -entityPitch : entityPitch;
536-
}
537-
538-
// Normalize angles to valid ranges
539-
newYaw = Mth.wrapDegrees(newYaw);
540-
newPitch = Math.max(-90, Math.min(90, newPitch));
541-
542-
return new Vector2f(newPitch, newYaw);
543-
}
544-
545-
/**
546-
* Returns the yaw for looking directly away from the front of the portal.
547-
*
548-
* @param direction direction
549-
* @return yaw
550-
*/
551-
private static float getDirectFacingAwayYaw(Direction direction) {
552-
return switch (direction) {
553-
case NORTH -> 180;
554-
case SOUTH -> 0;
555-
case EAST -> -90;
556-
case WEST -> 90;
557-
default -> 0;
558-
};
559-
}
560-
561-
/**
562-
* Returns the yaw for looking directly at the front of the portal.
563-
*
564-
* @param direction direction
565-
* @return yaw
496+
* @return adjusted (xrot, yrot)
566497
*/
567-
private static float getDirectFacingYaw(Direction direction) {
568-
return switch (direction) {
569-
case NORTH -> 0;
570-
case SOUTH -> 180;
571-
case EAST -> 90;
572-
case WEST -> -90;
573-
default -> 0;
574-
};
498+
private Vec2 transformLookAngle(Entity entity, PortalEntity destination) {
499+
final Vec3 newLook = transformMotion(entity.getLookAngle(), getDirection(), destination.getDirection().getOpposite());
500+
return toDegrees(newLook);
501+
}
502+
503+
private static Vec2 toDegrees(Vec3 vector) {
504+
double x = vector.x;
505+
double y = vector.y;
506+
double z = vector.z;
507+
double hyp = Math.sqrt(x * x + z * z);
508+
float xrot = Mth.wrapDegrees((float)(-(Mth.atan2(y, hyp) * 180.0F / (float)Math.PI)));
509+
float yrot = Mth.wrapDegrees((float)(Mth.atan2(z, x) * 180.0F / (float)Math.PI) - 90.0F);
510+
return new Vec2(xrot, yrot);
575511
}
576512
}

0 commit comments

Comments
 (0)