From 8d72970db9a5779ab8f4222548a62849ecc879a2 Mon Sep 17 00:00:00 2001 From: AJ Ferguson Date: Fri, 17 May 2024 03:12:52 -0400 Subject: [PATCH] Fixes for Camel dash and pose transition --- .../geyser/entity/EntityDefinitions.java | 2 +- .../type/living/animal/horse/CamelEntity.java | 12 +++ .../entity/vehicle/CamelVehicleComponent.java | 96 ++++++++++++++----- .../entity/vehicle/VehicleComponent.java | 13 +-- .../entity/JavaSetPassengersTranslator.java | 5 + 5 files changed, 95 insertions(+), 33 deletions(-) diff --git a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java index 19b8c9cdb..44d3c00d6 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java +++ b/core/src/main/java/org/geysermc/geyser/entity/EntityDefinitions.java @@ -926,7 +926,7 @@ public final class EntityDefinitions { .type(EntityType.CAMEL) .height(2.375f).width(1.7f) .addTranslator(MetadataType.BOOLEAN, CamelEntity::setDashing) - .addTranslator(null) // Last pose change tick + .addTranslator(MetadataType.LONG, CamelEntity::setLastPoseTick) .build(); HORSE = EntityDefinition.inherited(HorseEntity::new, abstractHorseEntityBase) .type(EntityType.HORSE) diff --git a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/CamelEntity.java b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/CamelEntity.java index b48569381..4bd6e8481 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/CamelEntity.java +++ b/core/src/main/java/org/geysermc/geyser/entity/type/living/animal/horse/CamelEntity.java @@ -46,6 +46,7 @@ import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.AttributeT import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata; import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata; +import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.LongEntityMetadata; import java.util.UUID; @@ -120,12 +121,23 @@ public class CamelEntity extends AbstractHorseEntity implements ClientVehicle { } public void setDashing(BooleanEntityMetadata entityMetadata) { + // Java sends true to show dash animation and start the dash cooldown, + // false ends the dash animation, not the cooldown. + // Bedrock shows dash animation if HAS_DASH_COOLDOWN is set and the camel is above ground if (entityMetadata.getPrimitiveValue()) { setFlag(EntityFlag.HAS_DASH_COOLDOWN, true); vehicleComponent.startDashCooldown(); + } else if (!isClientControlled()) { // Don't remove dash cooldown prematurely if client is controlling + setFlag(EntityFlag.HAS_DASH_COOLDOWN, false); } } + public void setLastPoseTick(LongEntityMetadata entityMetadata) { + // Tick is based on world time. If negative, the camel is sitting. + // Must be compared to world time to know if the camel is fully standing/sitting or transitioning. + vehicleComponent.setLastPoseTick(entityMetadata.getPrimitiveValue()); + } + @Override protected AttributeData calculateAttribute(Attribute javaAttribute, GeyserAttributeType type) { AttributeData attributeData = super.calculateAttribute(javaAttribute, type); diff --git a/core/src/main/java/org/geysermc/geyser/entity/vehicle/CamelVehicleComponent.java b/core/src/main/java/org/geysermc/geyser/entity/vehicle/CamelVehicleComponent.java index c5b91fcc3..bf06d130c 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/vehicle/CamelVehicleComponent.java +++ b/core/src/main/java/org/geysermc/geyser/entity/vehicle/CamelVehicleComponent.java @@ -25,6 +25,7 @@ package org.geysermc.geyser.entity.vehicle; +import lombok.Setter; import org.cloudburstmc.math.vector.Vector3f; import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag; import org.geysermc.geyser.entity.type.living.animal.horse.CamelEntity; @@ -32,7 +33,15 @@ import org.geysermc.geyser.entity.type.player.SessionPlayerEntity; import org.geysermc.mcprotocollib.protocol.data.game.entity.Effect; public class CamelVehicleComponent extends VehicleComponent { - private float horseJumpStrength = 0.42f; // This is the default for Camels. Not sent by vanilla Java server when spawned + private static final int STANDING_TICKS = 52; + private static final int DASH_TICKS = 55; + + @Setter + private float horseJumpStrength = 0.42f; // Not sent by vanilla Java server when spawned + + @Setter + private long lastPoseTick; + private int dashTick; private int jumpBoost; @@ -40,26 +49,78 @@ public class CamelVehicleComponent extends VehicleComponent { super(vehicle); } - public void setHorseJumpStrength(float horseJumpStrength) { - this.horseJumpStrength = horseJumpStrength; - } - public void startDashCooldown() { - this.dashTick = vehicle.getSession().getTicks() + 55; + this.dashTick = vehicle.getSession().getTicks() + DASH_TICKS; } @Override public void tickVehicle() { - if (vehicle.getFlag(EntityFlag.HAS_DASH_COOLDOWN)) { - if (vehicle.getSession().getTicks() > dashTick) { + if (this.dashTick != 0) { + if (vehicle.getSession().getTicks() > this.dashTick) { vehicle.setFlag(EntityFlag.HAS_DASH_COOLDOWN, false); - vehicle.updateBedrockMetadata(); + this.dashTick = 0; + } else { + vehicle.setFlag(EntityFlag.HAS_DASH_COOLDOWN, true); } } + vehicle.setFlag(EntityFlag.CAN_DASH, vehicle.getFlag(EntityFlag.SADDLED) && !isStationary()); + vehicle.updateBedrockMetadata(); + super.tickVehicle(); } + @Override + public void onDismount() { + vehicle.setFlag(EntityFlag.HAS_DASH_COOLDOWN, false); + vehicle.updateBedrockMetadata(); + } + + @Override + protected boolean travel(CamelEntity vehicle, float speed) { + if (vehicle.isOnGround() && isStationary()) { + vehicle.setMotion(vehicle.getMotion().mul(0, 1, 0)); + } + + return super.travel(vehicle, speed); + } + + @Override + protected Vector3f getInputVelocity(CamelEntity vehicle, float speed) { + if (isStationary()) { + return Vector3f.ZERO; + } + + SessionPlayerEntity player = vehicle.getSession().getPlayerEntity(); + Vector3f inputVelocity = super.getInputVelocity(vehicle, speed); + float jumpStrength = player.getVehicleJumpStrength(); + + if (jumpStrength > 0) { + player.setVehicleJumpStrength(0); + + if (jumpStrength >= 90) { + jumpStrength = 1.0f; + } else { + jumpStrength = 0.4f + 0.4f * jumpStrength / 90.0f; + } + + return inputVelocity.add(Vector3f.createDirectionDeg(0, -player.getYaw()) + .mul(22.2222f * jumpStrength * this.moveSpeed * getVelocityMultiplier(vehicle)) + .up(1.4285f * jumpStrength * (this.horseJumpStrength * getJumpVelocityMultiplier(vehicle) + (this.jumpBoost * 0.1f)))); + } + + return inputVelocity; + } + + /** + * Checks if the camel is sitting + * or transitioning to standing pose. + */ + private boolean isStationary() { + // Java checks if sitting using lastPoseTick + return this.lastPoseTick < 0 || vehicle.getSession().getWorldTicks() < this.lastPoseTick + STANDING_TICKS; + } + @Override public void setEffect(Effect effect, int effectAmplifier) { if (effect == Effect.JUMP_BOOST) { @@ -77,21 +138,4 @@ public class CamelVehicleComponent extends VehicleComponent { super.removeEffect(effect); } } - - @Override - protected Vector3f getJumpVelocity(CamelEntity vehicle) { - SessionPlayerEntity player = vehicle.getSession().getPlayerEntity(); - float jumpStrength = player.getVehicleJumpStrength(); - - if (jumpStrength > 0) { - player.setVehicleJumpStrength(0); - - jumpStrength = jumpStrength >= 90 ? 1.0f : 0.4f + 0.4f * jumpStrength / 90.0f; - return Vector3f.createDirectionDeg(0, -player.getYaw()) - .mul(22.2222f * jumpStrength * moveSpeed * getVelocityMultiplier(vehicle)) - .up(1.4285f * jumpStrength * (horseJumpStrength * getJumpVelocityMultiplier(vehicle) + (jumpBoost * 0.1f))); - } - - return Vector3f.ZERO; - } } diff --git a/core/src/main/java/org/geysermc/geyser/entity/vehicle/VehicleComponent.java b/core/src/main/java/org/geysermc/geyser/entity/vehicle/VehicleComponent.java index 26f998674..70be16f3e 100644 --- a/core/src/main/java/org/geysermc/geyser/entity/vehicle/VehicleComponent.java +++ b/core/src/main/java/org/geysermc/geyser/entity/vehicle/VehicleComponent.java @@ -96,7 +96,9 @@ public class VehicleComponent { } public void setHeight(float height) { - boundingBox.setSizeY(Double.parseDouble(Float.toString(height))); + double doubleHeight = Double.parseDouble(Float.toString(height)); + boundingBox.translate(0, (doubleHeight - boundingBox.getSizeY()) / 2, 0); + boundingBox.setSizeY(doubleHeight); } public void moveAbsolute(double x, double y, double z) { @@ -131,6 +133,10 @@ public class VehicleComponent { return moveSpeed; } + public void onDismount() { + // + } + public void tickVehicle() { if (!vehicle.isClientControlled()) { return; @@ -489,10 +495,6 @@ public class VehicleComponent { )); } - protected Vector3f getJumpVelocity(T vehicle) { - return Vector3f.ZERO; - } - /** * @return True if there was a horizontal collision */ @@ -511,7 +513,6 @@ public class VehicleComponent { // TODO: isImmobile? set input to 0 and jump to false motion = motion.add(getInputVelocity(vehicle, speed)); - motion = motion.add(getJumpVelocity(vehicle)); Vector3f movementMultiplier = getBlockMovementMultiplier(vehicle); if (movementMultiplier != null) { diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetPassengersTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetPassengersTranslator.java index 9895a248c..c35c2b756 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetPassengersTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/entity/JavaSetPassengersTranslator.java @@ -30,6 +30,7 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData; import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket; import org.geysermc.geyser.entity.EntityDefinitions; import org.geysermc.geyser.entity.type.Entity; +import org.geysermc.geyser.entity.vehicle.ClientVehicle; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; @@ -100,6 +101,10 @@ public class JavaSetPassengersTranslator extends PacketTranslator