diff --git a/connector/src/main/java/org/geysermc/connector/entity/BoatEntity.java b/connector/src/main/java/org/geysermc/connector/entity/BoatEntity.java index ed5272b89..d07ecc965 100644 --- a/connector/src/main/java/org/geysermc/connector/entity/BoatEntity.java +++ b/connector/src/main/java/org/geysermc/connector/entity/BoatEntity.java @@ -28,6 +28,7 @@ package org.geysermc.connector.entity; import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata; import com.nukkitx.math.vector.Vector3f; import com.nukkitx.protocol.bedrock.data.entity.EntityData; +import com.nukkitx.protocol.bedrock.packet.AnimatePacket; import org.geysermc.connector.entity.type.EntityType; import org.geysermc.connector.network.session.GeyserSession; @@ -105,27 +106,38 @@ public class BoatEntity extends Entity { metadata.put(EntityData.VARIANT, entityMetadata.getValue()); } else if (entityMetadata.getId() == 11) { isPaddlingLeft = (boolean) entityMetadata.getValue(); - if (!isPaddlingLeft) { - metadata.put(EntityData.ROW_TIME_LEFT, 0f); - } - else { + if (isPaddlingLeft) { // Java sends simply "true" and "false" (is_paddling_left), Bedrock keeps sending packets as you're rowing // This is an asynchronous method that emulates Bedrock rowing until "false" is sent. paddleTimeLeft = 0f; - session.getConnector().getGeneralThreadPool().execute(() -> - updateLeftPaddle(session, entityMetadata) - ); + if (!this.passengers.isEmpty()) { + // Get the entity by the first stored passenger and convey motion in this manner + Entity entity = session.getEntityCache().getEntityByJavaId(this.passengers.iterator().nextLong()); + if (entity != null) { + session.getConnector().getGeneralThreadPool().execute(() -> + updateLeftPaddle(session, entity) + ); + } + } + } else { + // Indicate that the row position should be reset + metadata.put(EntityData.ROW_TIME_LEFT, 0.0f); } } else if (entityMetadata.getId() == 12) { isPaddlingRight = (boolean) entityMetadata.getValue(); - if (!isPaddlingRight) { - metadata.put(EntityData.ROW_TIME_RIGHT, 0f); - } else { + if (isPaddlingRight) { paddleTimeRight = 0f; - session.getConnector().getGeneralThreadPool().execute(() -> - updateRightPaddle(session, entityMetadata) - ); + if (!this.passengers.isEmpty()) { + Entity entity = session.getEntityCache().getEntityByJavaId(this.passengers.iterator().nextLong()); + if (entity != null) { + session.getConnector().getGeneralThreadPool().execute(() -> + updateRightPaddle(session, entity) + ); + } + } + } else { + metadata.put(EntityData.ROW_TIME_RIGHT, 0.0f); } } else if (entityMetadata.getId() == 13) { // Possibly - I don't think this does anything? @@ -135,27 +147,46 @@ public class BoatEntity extends Entity { super.updateBedrockMetadata(entityMetadata, session); } - public void updateLeftPaddle(GeyserSession session, EntityMetadata entityMetadata) { + @Override + public void updateBedrockMetadata(GeyserSession session) { + super.updateBedrockMetadata(session); + + // As these indicate to reset rowing, remove them until it is time to send them out again. + metadata.remove(EntityData.ROW_TIME_LEFT); + metadata.remove(EntityData.ROW_TIME_RIGHT); + } + + private void updateLeftPaddle(GeyserSession session, Entity rower) { if (isPaddlingLeft) { paddleTimeLeft += ROWING_SPEED; - metadata.put(EntityData.ROW_TIME_LEFT, paddleTimeLeft); - super.updateBedrockMetadata(entityMetadata, session); + sendAnimationPacket(session, rower, AnimatePacket.Action.ROW_LEFT, paddleTimeLeft); + session.getConnector().getGeneralThreadPool().schedule(() -> - updateLeftPaddle(session, entityMetadata), + updateLeftPaddle(session, rower), 100, TimeUnit.MILLISECONDS ); - }} + } + } - public void updateRightPaddle(GeyserSession session, EntityMetadata entityMetadata) { + private void updateRightPaddle(GeyserSession session, Entity rower) { if (isPaddlingRight) { paddleTimeRight += ROWING_SPEED; - metadata.put(EntityData.ROW_TIME_RIGHT, paddleTimeRight); - super.updateBedrockMetadata(entityMetadata, session); + sendAnimationPacket(session, rower, AnimatePacket.Action.ROW_RIGHT, paddleTimeRight); + session.getConnector().getGeneralThreadPool().schedule(() -> - updateRightPaddle(session, entityMetadata), + updateRightPaddle(session, rower), 100, TimeUnit.MILLISECONDS ); - }} + } + } + + private void sendAnimationPacket(GeyserSession session, Entity rower, AnimatePacket.Action action, float rowTime) { + AnimatePacket packet = new AnimatePacket(); + packet.setRuntimeEntityId(rower.getGeyserId()); + packet.setAction(action); + packet.setRowingTime(rowTime); + session.sendUpstreamPacket(packet); + } }