Skip to content

Commit

Permalink
Fix boat movement on land (GeyserMC#1668)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
Camotoy authored Dec 15, 2020
1 parent aed1eef commit 988fd66
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@

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;
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -61,13 +57,13 @@ public void translate(AnimatePacket packet, GeyserSession session) {
// 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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

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;
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,9 @@ public void translate(ServerEntitySetPassengersPacket packet, GeyserSession sess
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);
Expand All @@ -110,6 +110,9 @@ public void translate(ServerEntitySetPassengersPacket packet, GeyserSession sess
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 {
Expand Down

0 comments on commit 988fd66

Please sign in to comment.