Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-11-20 06:50:09 +01:00
Fixes for Camel dash and pose transition
Dieser Commit ist enthalten in:
Ursprung
b25087448c
Commit
8d72970db9
@ -926,7 +926,7 @@ public final class EntityDefinitions {
|
|||||||
.type(EntityType.CAMEL)
|
.type(EntityType.CAMEL)
|
||||||
.height(2.375f).width(1.7f)
|
.height(2.375f).width(1.7f)
|
||||||
.addTranslator(MetadataType.BOOLEAN, CamelEntity::setDashing)
|
.addTranslator(MetadataType.BOOLEAN, CamelEntity::setDashing)
|
||||||
.addTranslator(null) // Last pose change tick
|
.addTranslator(MetadataType.LONG, CamelEntity::setLastPoseTick)
|
||||||
.build();
|
.build();
|
||||||
HORSE = EntityDefinition.inherited(HorseEntity::new, abstractHorseEntityBase)
|
HORSE = EntityDefinition.inherited(HorseEntity::new, abstractHorseEntityBase)
|
||||||
.type(EntityType.HORSE)
|
.type(EntityType.HORSE)
|
||||||
|
@ -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.Pose;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
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.ByteEntityMetadata;
|
||||||
|
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.LongEntityMetadata;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@ -120,12 +121,23 @@ public class CamelEntity extends AbstractHorseEntity implements ClientVehicle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setDashing(BooleanEntityMetadata entityMetadata) {
|
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()) {
|
if (entityMetadata.getPrimitiveValue()) {
|
||||||
setFlag(EntityFlag.HAS_DASH_COOLDOWN, true);
|
setFlag(EntityFlag.HAS_DASH_COOLDOWN, true);
|
||||||
vehicleComponent.startDashCooldown();
|
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
|
@Override
|
||||||
protected AttributeData calculateAttribute(Attribute javaAttribute, GeyserAttributeType type) {
|
protected AttributeData calculateAttribute(Attribute javaAttribute, GeyserAttributeType type) {
|
||||||
AttributeData attributeData = super.calculateAttribute(javaAttribute, type);
|
AttributeData attributeData = super.calculateAttribute(javaAttribute, type);
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.entity.vehicle;
|
package org.geysermc.geyser.entity.vehicle;
|
||||||
|
|
||||||
|
import lombok.Setter;
|
||||||
import org.cloudburstmc.math.vector.Vector3f;
|
import org.cloudburstmc.math.vector.Vector3f;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||||
import org.geysermc.geyser.entity.type.living.animal.horse.CamelEntity;
|
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;
|
import org.geysermc.mcprotocollib.protocol.data.game.entity.Effect;
|
||||||
|
|
||||||
public class CamelVehicleComponent extends VehicleComponent<CamelEntity> {
|
public class CamelVehicleComponent extends VehicleComponent<CamelEntity> {
|
||||||
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 dashTick;
|
||||||
private int jumpBoost;
|
private int jumpBoost;
|
||||||
|
|
||||||
@ -40,26 +49,78 @@ public class CamelVehicleComponent extends VehicleComponent<CamelEntity> {
|
|||||||
super(vehicle);
|
super(vehicle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHorseJumpStrength(float horseJumpStrength) {
|
|
||||||
this.horseJumpStrength = horseJumpStrength;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void startDashCooldown() {
|
public void startDashCooldown() {
|
||||||
this.dashTick = vehicle.getSession().getTicks() + 55;
|
this.dashTick = vehicle.getSession().getTicks() + DASH_TICKS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tickVehicle() {
|
public void tickVehicle() {
|
||||||
if (vehicle.getFlag(EntityFlag.HAS_DASH_COOLDOWN)) {
|
if (this.dashTick != 0) {
|
||||||
if (vehicle.getSession().getTicks() > dashTick) {
|
if (vehicle.getSession().getTicks() > this.dashTick) {
|
||||||
vehicle.setFlag(EntityFlag.HAS_DASH_COOLDOWN, false);
|
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();
|
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
|
@Override
|
||||||
public void setEffect(Effect effect, int effectAmplifier) {
|
public void setEffect(Effect effect, int effectAmplifier) {
|
||||||
if (effect == Effect.JUMP_BOOST) {
|
if (effect == Effect.JUMP_BOOST) {
|
||||||
@ -77,21 +138,4 @@ public class CamelVehicleComponent extends VehicleComponent<CamelEntity> {
|
|||||||
super.removeEffect(effect);
|
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,9 @@ public class VehicleComponent<T extends LivingEntity & ClientVehicle> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setHeight(float height) {
|
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) {
|
public void moveAbsolute(double x, double y, double z) {
|
||||||
@ -131,6 +133,10 @@ public class VehicleComponent<T extends LivingEntity & ClientVehicle> {
|
|||||||
return moveSpeed;
|
return moveSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onDismount() {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
public void tickVehicle() {
|
public void tickVehicle() {
|
||||||
if (!vehicle.isClientControlled()) {
|
if (!vehicle.isClientControlled()) {
|
||||||
return;
|
return;
|
||||||
@ -489,10 +495,6 @@ public class VehicleComponent<T extends LivingEntity & ClientVehicle> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Vector3f getJumpVelocity(T vehicle) {
|
|
||||||
return Vector3f.ZERO;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return True if there was a horizontal collision
|
* @return True if there was a horizontal collision
|
||||||
*/
|
*/
|
||||||
@ -511,7 +513,6 @@ public class VehicleComponent<T extends LivingEntity & ClientVehicle> {
|
|||||||
// TODO: isImmobile? set input to 0 and jump to false
|
// TODO: isImmobile? set input to 0 and jump to false
|
||||||
|
|
||||||
motion = motion.add(getInputVelocity(vehicle, speed));
|
motion = motion.add(getInputVelocity(vehicle, speed));
|
||||||
motion = motion.add(getJumpVelocity(vehicle));
|
|
||||||
|
|
||||||
Vector3f movementMultiplier = getBlockMovementMultiplier(vehicle);
|
Vector3f movementMultiplier = getBlockMovementMultiplier(vehicle);
|
||||||
if (movementMultiplier != null) {
|
if (movementMultiplier != null) {
|
||||||
|
@ -30,6 +30,7 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityLinkData;
|
|||||||
import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.SetEntityLinkPacket;
|
||||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||||
import org.geysermc.geyser.entity.type.Entity;
|
import org.geysermc.geyser.entity.type.Entity;
|
||||||
|
import org.geysermc.geyser.entity.vehicle.ClientVehicle;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
import org.geysermc.geyser.translator.protocol.PacketTranslator;
|
||||||
import org.geysermc.geyser.translator.protocol.Translator;
|
import org.geysermc.geyser.translator.protocol.Translator;
|
||||||
@ -100,6 +101,10 @@ public class JavaSetPassengersTranslator extends PacketTranslator<ClientboundSet
|
|||||||
// as of Java 1.19.3, but the scheduled future checks for the vehicle being null anyway.
|
// as of Java 1.19.3, but the scheduled future checks for the vehicle being null anyway.
|
||||||
session.getMountVehicleScheduledFuture().cancel(false);
|
session.getMountVehicleScheduledFuture().cancel(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (entity instanceof ClientVehicle clientVehicle) {
|
||||||
|
clientVehicle.getVehicleComponent().onDismount();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren