[SPIGOT-7451] PlayerMoveEvent.setTo will clear momentum of player Created: 06/Aug/23 Updated: 25/Dec/24 |
|
| Status: | Open |
| Project: | Spigot |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Minor |
| Reporter: | Silenter | Assignee: | Unassigned |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | None | ||
| Version: | 1.20.1 |
| Guidelines Read: | Yes |
| Description |
|
But execute as @a at @s run tp @s ~ ~ ~ wont |
| Comments |
| Comment by Silenter [ 06/Aug/23 ] |
|
Maybe i should make a feature request about relative teleport because there are some difference between absolute and relative |
| Comment by Silenter [ 06/Aug/23 ] |
|
confirmed,By modifying teleport packet(from absolute to relative) i can keep momentum after teleport
private Map<UUID, Vector> lastLocation = new HashMap<>(); public enum PlayerTeleportFlag { X, Y, Z, Y_ROT, X_ROT, } @Override public void onEnable() { // Plugin startup logic getServer().getPluginManager().registerEvents(this, this); // Register events ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(this, PacketType.Play.Client.POSITION,PacketType.Play.Client.POSITION_LOOK) { @Override public void onPacketReceiving(PacketEvent event) { lastLocation.put(event.getPlayer().getUniqueId(),new Vector(event.getPacket().getDoubles().read(0),event.getPacket().getDoubles().read(1),event.getPacket().getDoubles().read(2))); } }); ProtocolLibrary.getProtocolManager().addPacketListener(new PacketAdapter(this, PacketType.Play.Server.POSITION) { @Override public void onPacketSending(PacketEvent event) { Set<PlayerTeleportFlag> set = event.getPacket().getSets(EnumWrappers.getGenericConverter(MinecraftReflection.getMinecraftClass("world.entity.RelativeMovement"),PlayerTeleportFlag.class)).read(0); if (!set.contains(PlayerTeleportFlag.X)) { event.getPacket().getDoubles().writeSafely(0, event.getPacket().getDoubles().read(0) - lastLocation.getOrDefault(event.getPlayer().getUniqueId(),event.getPlayer().getLocation().toVector()).getX()); set.add(PlayerTeleportFlag.X); } if (!set.contains(PlayerTeleportFlag.Y)) { event.getPacket().getDoubles().writeSafely(1, event.getPacket().getDoubles().read(1) - lastLocation.getOrDefault(event.getPlayer().getUniqueId(),event.getPlayer().getLocation().toVector()).getY()); set.add(PlayerTeleportFlag.Y); } if (!set.contains(PlayerTeleportFlag.Z)) { event.getPacket().getDoubles().writeSafely(2, event.getPacket().getDoubles().read(2) - lastLocation.getOrDefault(event.getPlayer().getUniqueId(),event.getPlayer().getLocation().toVector()).getZ()); set.add(PlayerTeleportFlag.Z); } event.getPacket().getSets(EnumWrappers.getGenericConverter(MinecraftReflection.getMinecraftClass("world.entity.RelativeMovement"),PlayerTeleportFlag.class)).writeSafely(0, set); } }); } |
| Comment by Silenter [ 06/Aug/23 ] |
+ // If a Plugin has changed the To destination then we teleport the Player + // there to avoid any 'Moved wrongly' or 'Moved too quickly' errors. + // We only do this if the Event was not cancelled. + if (!oldTo.equals(event.getTo()) && !event.isCancelled()) { + this.player.getBukkitEntity().teleport(event.getTo(), PlayerTeleportEvent.TeleportCause.UNKNOWN); + return; + }
Okay...(relative?)teleport in vanilla Minecraft wont clear momentum but Bukkit teleport will |
| Comment by Silenter [ 06/Aug/23 ] |
|
AFAIK,move wont trigger PlayerVelocityEvent,Velocity isnt stand for "momentum" or "speed" of player but for "propulsive force" to player
edited:i checked the code and it seems will only trigger when repelled |
| Comment by Doc [ 06/Aug/23 ] |
|
For that exists the Velocity methods, the event handle the location, the momentum are part of Velocity in teory handled too in PlayerVelocityEvent |