Only expose velocity relative tp flags to API (#11532)

Since 1.21.2, vanilla split relative teleportation flags into position
and delta/velocity flags into separate enum entries.
This highlighted a design flaw in the paper api addition for teleport
flags, which just simply mirrored internals while also only being able
to apply the delta/velocity part of a flag, given the teleport target is
always absolute in the API.

This patch proposes to simply no longer expose the non-velocity related
flags to the API, instead marking the entire Relative enum as being
purely velocity related, as non-velocity related flags are not useful to
callers. This was done over simply exposing all internal flags, as
another vanilla change to the internal enum would result in the same
breakage.

The newly proposed API *only* promises that the passed flags prevent the
loss of velocity in the specific axis/context, which should be
independent enough of vanillas specific implementation of this feature.
This commit is contained in:
Bjarne Koll 2024-10-31 17:25:52 +01:00
parent d9fcd64770
commit c18eaf9bee
2 changed files with 63 additions and 30 deletions

View File

@ -57,35 +57,69 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ /**
+ * Note: These flags only work on {@link org.bukkit.entity.Player} entities.
+ * <p>
+ * Represents coordinates in a teleportation that should be handled relatively.
+ * <p>
+ * Coordinates of the location that the client should handle as relative teleportation
+ * Relative teleportation flags are only used client side, and cause the player to not lose velocity in that
+ * specific coordinate. The location of the teleportation will not change.
+ * Relative flags enable a player to not loose their velocity in the flag-specific axis/context when teleporting.
+ *
+ * @apiNote The relative flags exposed in the API do *not* mirror all flags known to vanilla, as relative flags concerning
+ * the position are non-applicable given teleports always expect an absolute location.
+ * @see org.bukkit.entity.Player#teleport(Location, PlayerTeleportEvent.TeleportCause, TeleportFlag...)
+ */
+ enum Relative implements TeleportFlag {
+ /**
+ * Represents the player's X coordinate
+ * Configures the player to not loose velocity in their x axis during the teleport.
+ */
+ X,
+ VELOCITY_X,
+ /**
+ * Represents the player's Y coordinate
+ * Configures the player to not loose velocity in their y axis during the teleport.
+ */
+ Y,
+ VELOCITY_Y,
+ /**
+ * Represents the player's Z coordinate
+ * Configures the player to not loose velocity in their z axis during the teleport.
+ */
+ Z,
+ VELOCITY_Z,
+ /**
+ * Configures the player to not loose velocity in their current rotation during the teleport.
+ */
+ VELOCITY_ROTATION;
+ /**
+ * Configures the player to not loose velocity in their x axis during the teleport.
+ * @deprecated Since 1.21.3, vanilla split up the relative teleport flags into velocity and position related
+ * ones. As the API does not deal with position relative flags, this name is no longer applicable.
+ * Use {@link #VELOCITY_X} instead.
+ */
+ @Deprecated(since = "1.21.3", forRemoval = true)
+ public static final Relative X = VELOCITY_X;
+ /**
+ * Configures the player to not loose velocity in their y axis during the teleport.
+ * @deprecated Since 1.21.3, vanilla split up the relative teleport flags into velocity and position related
+ * ones. As the API does not deal with position relative flags, this name is no longer applicable.
+ * Use {@link #VELOCITY_Y} instead.
+ */
+ @Deprecated(since = "1.21.3", forRemoval = true)
+ public static final Relative Y = VELOCITY_Y;
+ /**
+ * Configures the player to not loose velocity in their z axis during the teleport.
+ * @deprecated Since 1.21.3, vanilla split up the relative teleport flags into velocity and position related
+ * ones. As the API does not deal with position relative flags, this name is no longer applicable.
+ * Use {@link #VELOCITY_Z} instead.
+ */
+ @Deprecated(since = "1.21.3", forRemoval = true)
+ public static final Relative Z = VELOCITY_Z;
+ /**
+ * Represents the player's yaw
+ *
+ * @deprecated relative velocity flags now allow for the whole rotation to be relative, instead of the yaw and
+ * pitch having individual options. Use {@link #VELOCITY_ROTATION} instead.
+ */
+ YAW,
+ @Deprecated(since = "1.21.3", forRemoval = true)
+ public static final Relative YAW = VELOCITY_ROTATION;
+ /**
+ * Represents the player's pitch
+ *
+ * @deprecated relative velocity flags now allow for the whole rotation to be relative, instead of the yaw and
+ * pitch having individual options. Use {@link #VELOCITY_ROTATION} instead.
+ */
+ PITCH;
+ @Deprecated(since = "1.21.3", forRemoval = true)
+ public static final Relative PITCH = VELOCITY_ROTATION;
+ }
+
+ /**

View File

@ -14,9 +14,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
- PlayerTeleportEvent event = new PlayerTeleportEvent(player, from.clone(), to.clone(), cause);
+ // Paper start - Teleport API
+ Set<io.papermc.paper.entity.TeleportFlag.Relative> relativeFlags = java.util.EnumSet.noneOf(io.papermc.paper.entity.TeleportFlag.Relative.class);
+ for (Relative relativeArgument : set) {
+ relativeFlags.add(org.bukkit.craftbukkit.entity.CraftPlayer.toApiRelativeFlag(relativeArgument));
+ final Set<io.papermc.paper.entity.TeleportFlag.Relative> relativeFlags = java.util.EnumSet.noneOf(io.papermc.paper.entity.TeleportFlag.Relative.class);
+ for (final Relative relativeArgument : set) {
+ final io.papermc.paper.entity.TeleportFlag.Relative flag = org.bukkit.craftbukkit.entity.CraftPlayer.deltaRelativeToAPI(relativeArgument);
+ if (flag != null) relativeFlags.add(flag);
+ }
+ PlayerTeleportEvent event = new PlayerTeleportEvent(player, from.clone(), to.clone(), cause, java.util.Set.copyOf(relativeFlags));
+ // Paper end - Teleport API
@ -156,24 +157,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ };
+ }
+
+ public static net.minecraft.world.entity.Relative toNmsRelativeFlag(io.papermc.paper.entity.TeleportFlag.Relative apiFlag) {
+ public static net.minecraft.world.entity.Relative deltaRelativeToNMS(io.papermc.paper.entity.TeleportFlag.Relative apiFlag) {
+ return switch (apiFlag) {
+ case X -> net.minecraft.world.entity.Relative.X;
+ case Y -> net.minecraft.world.entity.Relative.Y;
+ case Z -> net.minecraft.world.entity.Relative.Z;
+ case PITCH -> net.minecraft.world.entity.Relative.X_ROT;
+ case YAW -> net.minecraft.world.entity.Relative.Y_ROT;
+ case VELOCITY_X -> net.minecraft.world.entity.Relative.DELTA_X;
+ case VELOCITY_Y -> net.minecraft.world.entity.Relative.DELTA_Y;
+ case VELOCITY_Z -> net.minecraft.world.entity.Relative.DELTA_Z;
+ case VELOCITY_ROTATION -> net.minecraft.world.entity.Relative.ROTATE_DELTA;
+ };
+ }
+
+ public static io.papermc.paper.entity.TeleportFlag.Relative toApiRelativeFlag(net.minecraft.world.entity.Relative nmsFlag) {
+ public static @org.jetbrains.annotations.Nullable io.papermc.paper.entity.TeleportFlag.Relative deltaRelativeToAPI(net.minecraft.world.entity.Relative nmsFlag) {
+ return switch (nmsFlag) {
+ case X -> io.papermc.paper.entity.TeleportFlag.Relative.X;
+ case Y -> io.papermc.paper.entity.TeleportFlag.Relative.Y;
+ case Z -> io.papermc.paper.entity.TeleportFlag.Relative.Z;
+ case X_ROT -> io.papermc.paper.entity.TeleportFlag.Relative.PITCH;
+ case Y_ROT -> io.papermc.paper.entity.TeleportFlag.Relative.YAW;
+ default -> throw new RuntimeException("not yet"); // TODO figure out what to do with new flags
+ case DELTA_X -> io.papermc.paper.entity.TeleportFlag.Relative.VELOCITY_X;
+ case DELTA_Y -> io.papermc.paper.entity.TeleportFlag.Relative.VELOCITY_Y;
+ case DELTA_Z -> io.papermc.paper.entity.TeleportFlag.Relative.VELOCITY_Z;
+ case ROTATE_DELTA -> io.papermc.paper.entity.TeleportFlag.Relative.VELOCITY_ROTATION;
+ default -> null;
+ };
+ }
+
@ -255,7 +254,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ // Paper start - Teleport API
+ final Set<net.minecraft.world.entity.Relative> nms = java.util.EnumSet.noneOf(net.minecraft.world.entity.Relative.class);
+ for (final io.papermc.paper.entity.TeleportFlag.Relative bukkit : relativeArguments) {
+ nms.add(toNmsRelativeFlag(bukkit));
+ nms.add(deltaRelativeToNMS(bukkit));
+ }
+ entity.connection.internalTeleport(new net.minecraft.world.entity.PositionMoveRotation(
+ io.papermc.paper.util.MCUtil.toVec3(to), net.minecraft.world.phys.Vec3.ZERO, to.getYaw(), to.getPitch()