Making a Ravager Mountable
andythetech opened this issue ยท 0 comments
Make sure you're doing the following
- You're using the latest build for your server version
- This isn't an issue caused by another plugin
- You've checked for duplicate issues
- You didn't use
/reload
Describe the question
A clear and concise description of what your question is.
Hello,
I am developing a plugin to allow Ravagers to be ridden. I am achieving this by hooking into STEER_VEHICLE and VEHICLE_MOVE packets and moving the Ravager accordingly. Originally, I was only hooking into STEER_VEHICLE - but this presented an issue. The entity would reset to a pitch and yaw of (0,0) while in motion. Therefore, I use VEHICLE_MOVE to set the pitch and yaw. The only issue is, there is extreme rubber banding that prevents the user from moving without getting stuck. When dismounting, the player is teleported to where (I assume) the player should've traveled to while riding. I assume that this issue is because I am grabbing the values of the VEHICLE_MOVE packets using a listener, then cancelling the packet event, and resending a new packet - though obviously the event would pick up the new packet and cancel it, and so on and so on. It's an endless looping cycle and I have no idea how to fix it.
API method(s) used
List what API method(s) you're using
Cancelling packets, writing and sending packets
Expected behavior
A clear and concise description of what you expected to happen.
The Ravager should be able to turn as the player turns, while in motion or not in motion, without rubber banding that results from the packets being resent. I'm aware that rubberbanding can occur from lag, but I am running both client and server on the same machine as a test to eliminate any possibility of rubberbanding from lag.
Code
If applicable, add relevant code from your project
`
package me.relavis.avatarcreatures.listeners;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import me.relavis.avatarcreatures.AvatarCreatures;
import org.bukkit.Location;
import org.bukkit.entity.*;
import org.bukkit.event.Listener;
import org.bukkit.util.Vector;
import java.lang.reflect.InvocationTargetException;
public class MountMoveListener implements Listener {
public static void onMountEntitySteer(PacketEvent e) {
if (e.getPacketType() == PacketType.Play.Client.STEER_VEHICLE && e.getPlayer().getVehicle() instanceof Ravager) {
PacketContainer packet = e.getPacket();
Player player = e.getPlayer();
Entity entity = player.getVehicle();
Boolean jump = packet.getBooleans().read(0); // Jump packet.
Float sideways = packet.getFloat().read(0); // Left and right packet. Left is positive.
Float forward = packet.getFloat().read(1); // Forwards/backwards packet. Forwards is positive.
// Player location, direction, and eye location. Yaw is horizontal, pitch is vertical.
Location playerLocation = player.getLocation();
Vector playerDirection = playerLocation.getDirection();
Location playerEye = player.getEyeLocation();
float playerEyeYaw = playerEye.getYaw();
float playerEyePitch = playerEye.getPitch();
// Entity location, set entity's body and head rotation to match player's
entity.setRotation(playerEyeYaw, playerEyePitch); //Set body and head rotation of entity to match mounted player
entity.setFallDistance(0);
// Jumping function
if (jump && isOnGround(entity) && !AvatarCreatures.disableJump) {
Jump(entity);
}
if (forward > 0.0F) { // Forwards
if (sideways > 0.0F) { // Move forwards and to the left
playerLocation.setYaw(playerEyeYaw + 45.0F);
}
if (sideways < 0.0F) { // Move forwards and to the right
playerLocation.setYaw(playerEyeYaw - 45.0F);
}
MoveEntity(entity, AvatarCreatures.movementSpeed, playerDirection);
}
if (forward < 0.0F) { // Backwards
if (sideways > 0.0F) { // Move backwards and to the left
playerLocation.setYaw(playerLocation.getYaw() - 45.0F);
}
if (sideways < 0.0F) { // Move backwards and to the right
playerLocation.setYaw(playerLocation.getYaw() + 45.0F);
}
MoveEntity(entity, AvatarCreatures.movementSpeed * -1.0D, playerDirection);
}
if (sideways > 0.0F) { // Strafe left
playerLocation.setYaw(playerLocation.getYaw() - 90.0F);
playerDirection = playerLocation.getDirection();
MoveEntity(entity, AvatarCreatures.movementSpeed, playerDirection);
}
if (sideways < 0.0F) { // Strafe Right
playerLocation.setYaw(playerLocation.getYaw() + 90.0F);
playerDirection = playerLocation.getDirection();
MoveEntity(entity, AvatarCreatures.movementSpeed, playerDirection);
}
}
}
public static void onMountEntityMove(PacketEvent e) {
if (e.getPacketType() == PacketType.Play.Client.VEHICLE_MOVE && e.getPlayer().getVehicle() instanceof Ravager) {
PacketContainer packet = e.getPacket();
Player player = e.getPlayer();
Location playerEye = player.getEyeLocation();
Double x = packet.getDoubles().read(0);
Double y = packet.getDoubles().read(1);
Double z = packet.getDoubles().read(2);
Float yaw = playerEye.getYaw();
Float pitch = playerEye.getPitch();
PacketContainer vehicleMove = new PacketContainer(PacketType.Play.Server.VEHICLE_MOVE);
vehicleMove.getDoubles().
write(0, x).
write(1, y).
write(2, z);
vehicleMove.getFloat().
write(0, yaw).
write(1, pitch);
e.setCancelled(true);
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, vehicleMove);
} catch (InvocationTargetException exception) {
throw new RuntimeException(
"Cannot send packet " + vehicleMove, exception);
}
}
}
public static boolean isOnGround(Entity entity) {
double entityHeight = entity.getLocation().getY();
double entityRemainder = entityHeight % (1.0/16.0);
return entityRemainder == 0;
}
public static void MoveEntity(Entity entity, Double speed, Vector vector) {
entity.setVelocity(vector.normalize().multiply(speed));
}
public static void Jump(Entity entity) {
// TODO Make jump more realistic
entity.setVelocity(entity.getVelocity().add(entity.getVelocity())); // moving forward
entity.setVelocity(entity.getVelocity().setY(1));
}
}
`
Additional context
Add any other context about the problem here.
I can provide a video of the rubber banding or allow access to a test server to showcase the rubber banding issue.