forked from GeyserMC/Geyser
Fix boat movement on land (#1668)
* Fix boat movement on land 1.16.100 appears to now take advantage of two newer entity metadata properties, IS_BUOYANT and BUOYANCY_DATA. Without the former, moving on land will not work properly. With the former and without the latter, moving in water no longer works. * Use offset kind of
This commit is contained in:
parent
aed1eef6e1
commit
988fd66a85
5 changed files with 47 additions and 15 deletions
|
@ -35,6 +35,16 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
public class BoatEntity extends Entity {
|
||||
|
||||
/**
|
||||
* Required when IS_BUOYANT is sent in order for boats to work in the water. <br>
|
||||
*
|
||||
* Taken from BDS 1.16.200, with the modification of <code>simulate_waves</code> since Java doesn't bob the boat up and down
|
||||
* like Bedrock.
|
||||
*/
|
||||
private static final String BUOYANCY_DATA = "{\"apply_gravity\":true,\"base_buoyancy\":1.0,\"big_wave_probability\":0.02999999932944775," +
|
||||
"\"big_wave_speed\":10.0,\"drag_down_on_buoyancy_removed\":0.0,\"liquid_blocks\":[\"minecraft:water\"," +
|
||||
"\"minecraft:flowing_water\"],\"simulate_waves\":false}}";
|
||||
|
||||
private boolean isPaddlingLeft;
|
||||
private float paddleTimeLeft;
|
||||
private boolean isPaddlingRight;
|
||||
|
@ -45,6 +55,10 @@ public class BoatEntity extends Entity {
|
|||
|
||||
public BoatEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
||||
super(entityId, geyserId, entityType, position.add(0d, entityType.getOffset(), 0d), motion, rotation.add(90, 0, 90));
|
||||
|
||||
// Required to be able to move on land 1.16.200+ or apply gravity not in the water 1.16.100+
|
||||
metadata.put(EntityData.IS_BUOYANT, (byte) 1);
|
||||
metadata.put(EntityData.BUOYANCY_DATA, BUOYANCY_DATA);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -219,6 +219,17 @@ public class GeyserSession implements CommandSender {
|
|||
@Setter
|
||||
private long lastHitTime;
|
||||
|
||||
/**
|
||||
* Saves if the client is steering left on a boat.
|
||||
*/
|
||||
@Setter
|
||||
private boolean steeringLeft;
|
||||
/**
|
||||
* Saves if the client is steering right on a boat.
|
||||
*/
|
||||
@Setter
|
||||
private boolean steeringRight;
|
||||
|
||||
/**
|
||||
* Store the last time the player interacted. Used to fix a right-click spam bug.
|
||||
* See https://github.com/GeyserMC/Geyser/issues/503 for context.
|
||||
|
|
|
@ -25,23 +25,19 @@
|
|||
|
||||
package org.geysermc.connector.network.translators.bedrock;
|
||||
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.network.translators.Translator;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerSwingArmPacket;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.client.world.ClientSteerBoatPacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.AnimatePacket;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.network.translators.Translator;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Translator(packet = AnimatePacket.class)
|
||||
public class BedrockAnimateTranslator extends PacketTranslator<AnimatePacket> {
|
||||
|
||||
private boolean isSteeringLeft;
|
||||
private boolean isSteeringRight;
|
||||
|
||||
@Override
|
||||
public void translate(AnimatePacket packet, GeyserSession session) {
|
||||
// Stop the player sending animations before they have fully spawned into the server
|
||||
|
@ -61,13 +57,13 @@ public class BedrockAnimateTranslator extends PacketTranslator<AnimatePacket> {
|
|||
// These two might need to be flipped, but my recommendation is getting moving working first
|
||||
case ROW_LEFT:
|
||||
// Packet value is a float of how long one has been rowing, so we convert that into a boolean
|
||||
isSteeringLeft = packet.getRowingTime() > 0.0;
|
||||
ClientSteerBoatPacket steerLeftPacket = new ClientSteerBoatPacket(isSteeringRight, isSteeringLeft);
|
||||
session.setSteeringLeft(packet.getRowingTime() > 0.0);
|
||||
ClientSteerBoatPacket steerLeftPacket = new ClientSteerBoatPacket(session.isSteeringLeft(), session.isSteeringRight());
|
||||
session.sendDownstreamPacket(steerLeftPacket);
|
||||
break;
|
||||
case ROW_RIGHT:
|
||||
isSteeringRight = packet.getRowingTime() > 0.0;
|
||||
ClientSteerBoatPacket steerRightPacket = new ClientSteerBoatPacket(isSteeringRight, isSteeringLeft);
|
||||
session.setSteeringRight(packet.getRowingTime() > 0.0);
|
||||
ClientSteerBoatPacket steerRightPacket = new ClientSteerBoatPacket(session.isSteeringLeft(), session.isSteeringRight());
|
||||
session.sendDownstreamPacket(steerRightPacket);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ package org.geysermc.connector.network.translators.bedrock;
|
|||
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.client.world.ClientVehicleMovePacket;
|
||||
import com.nukkitx.protocol.bedrock.packet.MoveEntityAbsolutePacket;
|
||||
import org.geysermc.connector.entity.BoatEntity;
|
||||
import org.geysermc.connector.entity.type.EntityType;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.PacketTranslator;
|
||||
import org.geysermc.connector.network.translators.Translator;
|
||||
|
@ -39,8 +41,14 @@ public class BedrockMoveEntityAbsoluteTranslator extends PacketTranslator<MoveEn
|
|||
|
||||
@Override
|
||||
public void translate(MoveEntityAbsolutePacket packet, GeyserSession session) {
|
||||
float y = packet.getPosition().getY();
|
||||
if (session.getRidingVehicleEntity() instanceof BoatEntity) {
|
||||
// Remove some Y position to prevents boats from looking like they're floating in water
|
||||
// Not by the full boat offset because 1.16.100 complains and that's probably not good for the future
|
||||
y -= (EntityType.BOAT.getOffset() - 0.5f);
|
||||
}
|
||||
ClientVehicleMovePacket clientVehicleMovePacket = new ClientVehicleMovePacket(
|
||||
packet.getPosition().getX(), packet.getPosition().getY(), packet.getPosition().getZ(),
|
||||
packet.getPosition().getX(), y, packet.getPosition().getZ(),
|
||||
packet.getRotation().getY() - 90, packet.getRotation().getX()
|
||||
);
|
||||
session.sendDownstreamPacket(clientVehicleMovePacket);
|
||||
|
|
|
@ -86,9 +86,9 @@ public class JavaEntitySetPassengersTranslator extends PacketTranslator<ServerEn
|
|||
passenger.getMetadata().put(EntityData.RIDER_MAX_ROTATION, 90f);
|
||||
passenger.getMetadata().put(EntityData.RIDER_MIN_ROTATION, !passengers.isEmpty() ? -90f : 0f);
|
||||
} else {
|
||||
passenger.getMetadata().remove(EntityData.RIDER_ROTATION_LOCKED);
|
||||
passenger.getMetadata().remove(EntityData.RIDER_MAX_ROTATION);
|
||||
passenger.getMetadata().remove(EntityData.RIDER_MIN_ROTATION);
|
||||
passenger.getMetadata().put(EntityData.RIDER_ROTATION_LOCKED, (byte) 0);
|
||||
passenger.getMetadata().put(EntityData.RIDER_MAX_ROTATION, 0f);
|
||||
passenger.getMetadata().put(EntityData.RIDER_MIN_ROTATION, 0f);
|
||||
}
|
||||
|
||||
passenger.updateBedrockMetadata(session);
|
||||
|
@ -110,6 +110,9 @@ public class JavaEntitySetPassengersTranslator extends PacketTranslator<ServerEn
|
|||
linkPacket.setEntityLink(new EntityLinkData(entity.getGeyserId(), passenger.getGeyserId(), EntityLinkData.Type.REMOVE, false));
|
||||
session.sendUpstreamPacket(linkPacket);
|
||||
passengers.remove(passenger.getEntityId());
|
||||
passenger.getMetadata().put(EntityData.RIDER_ROTATION_LOCKED, (byte) 0);
|
||||
passenger.getMetadata().put(EntityData.RIDER_MAX_ROTATION, 0f);
|
||||
passenger.getMetadata().put(EntityData.RIDER_MIN_ROTATION, 0f);
|
||||
|
||||
this.updateOffset(passenger, entity, session, false, false, (packet.getPassengerIds().length > 1));
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue