Mirror von
https://github.com/GeyserMC/Geyser.git
synchronisiert 2024-12-26 16:12:46 +01:00
Horses are still weird, but boats are mostly working
Dieser Commit ist enthalten in:
Ursprung
2025a2dc3a
Commit
774d3670c5
@ -701,9 +701,4 @@ public class Entity implements GeyserEntity {
|
|||||||
packet.setData(data);
|
packet.setData(data);
|
||||||
session.sendUpstreamPacket(packet);
|
session.sendUpstreamPacket(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public <I extends Entity> @Nullable I as(Class<I> entityClass) {
|
|
||||||
return entityClass.isInstance(this) ? (I) this : null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -758,7 +758,6 @@ public class VehicleComponent<T extends LivingEntity & ClientVehicle> {
|
|||||||
|
|
||||||
ServerboundMoveVehiclePacket moveVehiclePacket = new ServerboundMoveVehiclePacket(javaPos.getX(), javaPos.getY(), javaPos.getZ(), rotation.getX(), rotation.getY());
|
ServerboundMoveVehiclePacket moveVehiclePacket = new ServerboundMoveVehiclePacket(javaPos.getX(), javaPos.getY(), javaPos.getZ(), rotation.getX(), rotation.getY());
|
||||||
vehicle.getSession().sendDownstreamPacket(moveVehiclePacket);
|
vehicle.getSession().sendDownstreamPacket(moveVehiclePacket);
|
||||||
vehicle.getSession().setLastVehicleMoveTimestamp(System.currentTimeMillis());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected double getGravity() {
|
protected double getGravity() {
|
||||||
|
@ -524,12 +524,6 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
|
|||||||
@Setter
|
@Setter
|
||||||
private boolean placedBucket;
|
private boolean placedBucket;
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to send a ServerboundMoveVehiclePacket for every PlayerInputPacket after idling on a boat/horse for more than 100ms
|
|
||||||
*/
|
|
||||||
@Setter
|
|
||||||
private long lastVehicleMoveTimestamp = System.currentTimeMillis();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Counts how many ticks have occurred since an arm animation started.
|
* Counts how many ticks have occurred since an arm animation started.
|
||||||
* -1 means there is no active arm swing; -2 means an arm swing will start in a tick.
|
* -1 means there is no active arm swing; -2 means an arm swing will start in a tick.
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.session.cache;
|
package org.geysermc.geyser.session.cache;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.PlayerAuthInputData;
|
import org.cloudburstmc.protocol.bedrock.data.PlayerAuthInputData;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.PlayerAuthInputPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.PlayerAuthInputPacket;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
@ -37,6 +39,10 @@ public final class InputCache {
|
|||||||
private ServerboundPlayerInputPacket inputPacket = new ServerboundPlayerInputPacket(false, false, false, false, false, false, false);
|
private ServerboundPlayerInputPacket inputPacket = new ServerboundPlayerInputPacket(false, false, false, false, false, false, false);
|
||||||
private boolean lastHorizontalCollision;
|
private boolean lastHorizontalCollision;
|
||||||
private int ticksSinceLastMovePacket;
|
private int ticksSinceLastMovePacket;
|
||||||
|
@Getter @Setter
|
||||||
|
private int jumpingTicks;
|
||||||
|
@Getter @Setter
|
||||||
|
private float jumpScale;
|
||||||
|
|
||||||
public InputCache(GeyserSession session) {
|
public InputCache(GeyserSession session) {
|
||||||
this.session = session;
|
this.session = session;
|
||||||
@ -61,6 +67,10 @@ public final class InputCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean wasJumping() {
|
||||||
|
return this.inputPacket.isJump();
|
||||||
|
}
|
||||||
|
|
||||||
public void markPositionPacketSent() {
|
public void markPositionPacketSent() {
|
||||||
this.ticksSinceLastMovePacket = 0;
|
this.ticksSinceLastMovePacket = 0;
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ public class TeleportCache {
|
|||||||
/**
|
/**
|
||||||
* How many move packets the teleport can be unconfirmed for before it gets resent to the client
|
* How many move packets the teleport can be unconfirmed for before it gets resent to the client
|
||||||
*/
|
*/
|
||||||
private static final int RESEND_THRESHOLD = 5;
|
private static final int RESEND_THRESHOLD = 20; // Make it one full second with auth input
|
||||||
|
|
||||||
private final double x, y, z;
|
private final double x, y, z;
|
||||||
private final float pitch, yaw;
|
private final float pitch, yaw;
|
||||||
|
@ -42,17 +42,15 @@ public class BedrockMoveEntityAbsoluteTranslator extends PacketTranslator<MoveEn
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translate(GeyserSession session, MoveEntityAbsolutePacket packet) {
|
public void translate(GeyserSession session, MoveEntityAbsolutePacket packet) {
|
||||||
session.setLastVehicleMoveTimestamp(System.currentTimeMillis());
|
|
||||||
|
|
||||||
Entity ridingEntity = session.getPlayerEntity().getVehicle();
|
Entity ridingEntity = session.getPlayerEntity().getVehicle();
|
||||||
if (ridingEntity != null && session.getWorldBorder().isPassingIntoBorderBoundaries(packet.getPosition(), false)) {
|
if (ridingEntity != null && session.getWorldBorder().isPassingIntoBorderBoundaries(packet.getPosition(), false)) {
|
||||||
Vector3f position = Vector3f.from(ridingEntity.getPosition().getX(), packet.getPosition().getY(),
|
Vector3f position = Vector3f.from(ridingEntity.getPosition().getX(), packet.getPosition().getY(),
|
||||||
ridingEntity.getPosition().getZ());
|
ridingEntity.getPosition().getZ());
|
||||||
if (ridingEntity instanceof BoatEntity) {
|
if (ridingEntity instanceof BoatEntity) {
|
||||||
// Undo the changes usually applied to the boat
|
// Undo the changes usually applied to the boat
|
||||||
ridingEntity.as(BoatEntity.class)
|
// ridingEntity.as(BoatEntity.class)
|
||||||
.moveAbsoluteWithoutAdjustments(position, ridingEntity.getYaw(),
|
// .moveAbsoluteWithoutAdjustments(position, ridingEntity.getYaw(),
|
||||||
ridingEntity.isOnGround(), true);
|
// ridingEntity.isOnGround(), true);
|
||||||
} else {
|
} else {
|
||||||
// This doesn't work if teleported is false
|
// This doesn't work if teleported is false
|
||||||
ridingEntity.moveAbsolute(position,
|
ridingEntity.moveAbsolute(position,
|
||||||
|
@ -44,47 +44,6 @@ public class BedrockPlayerInputTranslator extends PacketTranslator<PlayerInputPa
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translate(GeyserSession session, PlayerInputPacket packet) {
|
public void translate(GeyserSession session, PlayerInputPacket packet) {
|
||||||
// ServerboundPlayerInputPacket playerInputPacket = new ServerboundPlayerInputPacket(
|
|
||||||
// packet.getInputMotion().getX(), packet.getInputMotion().getY(), packet.isJumping(), packet.isSneaking()
|
|
||||||
// );
|
|
||||||
//
|
|
||||||
// session.sendDownstreamGamePacket(playerInputPacket);
|
|
||||||
|
|
||||||
session.getPlayerEntity().setVehicleInput(packet.getInputMotion());
|
|
||||||
|
|
||||||
// Bedrock only sends movement vehicle packets while moving
|
|
||||||
// This allows horses to take damage while standing on magma
|
|
||||||
Entity vehicle = session.getPlayerEntity().getVehicle();
|
|
||||||
boolean sendMovement = false;
|
|
||||||
if (vehicle instanceof AbstractHorseEntity && !(vehicle instanceof LlamaEntity)) {
|
|
||||||
sendMovement = vehicle.isOnGround();
|
|
||||||
} else if (vehicle instanceof BoatEntity) {
|
|
||||||
if (vehicle.getPassengers().size() == 1) {
|
|
||||||
// The player is the only rider
|
|
||||||
sendMovement = true;
|
|
||||||
} else {
|
|
||||||
// Check if the player is the front rider
|
|
||||||
if (session.getPlayerEntity().isRidingInFront()) {
|
|
||||||
sendMovement = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sendMovement) {
|
|
||||||
long timeSinceVehicleMove = System.currentTimeMillis() - session.getLastVehicleMoveTimestamp();
|
|
||||||
if (timeSinceVehicleMove >= 100) {
|
|
||||||
Vector3f vehiclePosition = vehicle.getPosition();
|
|
||||||
|
|
||||||
if (vehicle instanceof BoatEntity && !vehicle.isOnGround()) {
|
|
||||||
// Remove some Y position to prevents boats flying up
|
|
||||||
vehiclePosition = vehiclePosition.down(vehicle.getDefinition().offset());
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerboundMoveVehiclePacket moveVehiclePacket = new ServerboundMoveVehiclePacket(
|
|
||||||
vehiclePosition.getX(), vehiclePosition.getY(), vehiclePosition.getZ(),
|
|
||||||
vehicle.getYaw() - 90, vehicle.getPitch()
|
|
||||||
);
|
|
||||||
session.sendDownstreamGamePacket(moveVehiclePacket);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,6 @@ import org.cloudburstmc.protocol.bedrock.data.PlayerAuthInputData;
|
|||||||
import org.cloudburstmc.protocol.bedrock.packet.PlayerAuthInputPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.PlayerAuthInputPacket;
|
||||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||||
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
||||||
import org.geysermc.geyser.entity.vehicle.ClientVehicle;
|
|
||||||
import org.geysermc.geyser.level.physics.CollisionResult;
|
import org.geysermc.geyser.level.physics.CollisionResult;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.text.ChatColor;
|
import org.geysermc.geyser.text.ChatColor;
|
||||||
@ -48,17 +47,17 @@ public final class BedrockMovePlayerTranslator {
|
|||||||
SessionPlayerEntity entity = session.getPlayerEntity();
|
SessionPlayerEntity entity = session.getPlayerEntity();
|
||||||
if (!session.isSpawned()) return;
|
if (!session.isSpawned()) return;
|
||||||
|
|
||||||
|
// Ignore movement packets until Bedrock's position matches the teleported position
|
||||||
|
if (session.getUnconfirmedTeleport() != null) {
|
||||||
|
session.confirmTeleport(packet.getPosition().toDouble().sub(0, EntityDefinitions.PLAYER.offset(), 0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
boolean actualPositionChanged = !entity.getPosition().equals(packet.getPosition());
|
boolean actualPositionChanged = !entity.getPosition().equals(packet.getPosition());
|
||||||
|
|
||||||
if (actualPositionChanged) {
|
if (actualPositionChanged) {
|
||||||
// Send book update before the player moves
|
// Send book update before the player moves
|
||||||
session.getBookEditCache().checkForSend();
|
session.getBookEditCache().checkForSend();
|
||||||
|
|
||||||
// Ignore movement packets until Bedrock's position matches the teleported position
|
|
||||||
if (session.getUnconfirmedTeleport() != null) {
|
|
||||||
session.confirmTeleport(packet.getPosition().toDouble().sub(0, EntityDefinitions.PLAYER.offset(), 0));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity.getBedPosition() != null) {
|
if (entity.getBedPosition() != null) {
|
||||||
@ -72,9 +71,11 @@ public final class BedrockMovePlayerTranslator {
|
|||||||
float pitch = packet.getRotation().getX();
|
float pitch = packet.getRotation().getX();
|
||||||
float headYaw = packet.getRotation().getY();
|
float headYaw = packet.getRotation().getY();
|
||||||
|
|
||||||
// shouldSendPositionReminder also increments a tick counter, so make sure it's always called.
|
boolean hasVehicle = entity.getVehicle() != null;
|
||||||
boolean positionChanged = session.getInputCache().shouldSendPositionReminder() || actualPositionChanged;
|
|
||||||
boolean rotationChanged = entity.getYaw() != yaw || entity.getPitch() != pitch || entity.getHeadYaw() != headYaw;
|
// shouldSendPositionReminder also increments a tick counter, so make sure it's always called unless the player is on a vehicle.
|
||||||
|
boolean positionChanged = !hasVehicle && session.getInputCache().shouldSendPositionReminder() || actualPositionChanged;
|
||||||
|
boolean rotationChanged = hasVehicle || (entity.getYaw() != yaw || entity.getPitch() != pitch || entity.getHeadYaw() != headYaw);
|
||||||
|
|
||||||
if (session.getLookBackScheduledFuture() != null) {
|
if (session.getLookBackScheduledFuture() != null) {
|
||||||
// Resend the rotation if it was changed by Geyser
|
// Resend the rotation if it was changed by Geyser
|
||||||
@ -99,12 +100,6 @@ public final class BedrockMovePlayerTranslator {
|
|||||||
|
|
||||||
session.sendDownstreamGamePacket(playerRotationPacket);
|
session.sendDownstreamGamePacket(playerRotationPacket);
|
||||||
} else if (positionChanged) {
|
} else if (positionChanged) {
|
||||||
// World border collision will be handled by client vehicle
|
|
||||||
if (!(entity.getVehicle() instanceof ClientVehicle clientVehicle && clientVehicle.isClientControlled())
|
|
||||||
&& session.getWorldBorder().isPassingIntoBorderBoundaries(packet.getPosition(), true)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isValidMove(session, entity.getPosition(), packet.getPosition())) {
|
if (isValidMove(session, entity.getPosition(), packet.getPosition())) {
|
||||||
CollisionResult result = session.getCollisionManager().adjustBedrockPosition(packet.getPosition(), packet.getInputData().contains(PlayerAuthInputData.HANDLE_TELEPORT));
|
CollisionResult result = session.getCollisionManager().adjustBedrockPosition(packet.getPosition(), packet.getInputData().contains(PlayerAuthInputData.HANDLE_TELEPORT));
|
||||||
if (result != null) { // A null return value cancels the packet
|
if (result != null) { // A null return value cancels the packet
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
package org.geysermc.geyser.translator.protocol.bedrock.entity.player;
|
package org.geysermc.geyser.translator.protocol.bedrock.entity.player;
|
||||||
|
|
||||||
|
import org.cloudburstmc.math.vector.Vector2f;
|
||||||
import org.cloudburstmc.math.vector.Vector3f;
|
import org.cloudburstmc.math.vector.Vector3f;
|
||||||
import org.cloudburstmc.math.vector.Vector3i;
|
import org.cloudburstmc.math.vector.Vector3i;
|
||||||
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
|
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
|
||||||
@ -36,19 +37,25 @@ import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
|
|||||||
import org.cloudburstmc.protocol.bedrock.packet.PlayerActionPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.PlayerActionPacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.PlayerAuthInputPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.PlayerAuthInputPacket;
|
||||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||||
|
import org.geysermc.geyser.entity.type.BoatEntity;
|
||||||
import org.geysermc.geyser.entity.type.Entity;
|
import org.geysermc.geyser.entity.type.Entity;
|
||||||
import org.geysermc.geyser.entity.type.ItemFrameEntity;
|
import org.geysermc.geyser.entity.type.ItemFrameEntity;
|
||||||
|
import org.geysermc.geyser.entity.type.living.animal.horse.AbstractHorseEntity;
|
||||||
|
import org.geysermc.geyser.entity.type.living.animal.horse.LlamaEntity;
|
||||||
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
||||||
|
import org.geysermc.geyser.entity.vehicle.ClientVehicle;
|
||||||
import org.geysermc.geyser.level.block.type.Block;
|
import org.geysermc.geyser.level.block.type.Block;
|
||||||
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;
|
||||||
import org.geysermc.geyser.translator.protocol.bedrock.BedrockInventoryTransactionTranslator;
|
import org.geysermc.geyser.translator.protocol.bedrock.BedrockInventoryTransactionTranslator;
|
||||||
|
import org.geysermc.geyser.util.MathUtils;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction;
|
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
|
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.InteractAction;
|
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.InteractAction;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerAction;
|
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerAction;
|
||||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerState;
|
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.PlayerState;
|
||||||
|
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.level.ServerboundMoveVehiclePacket;
|
||||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket;
|
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket;
|
||||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket;
|
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundPlayerAbilitiesPacket;
|
||||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket;
|
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundPlayerActionPacket;
|
||||||
@ -57,13 +64,17 @@ import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.Serv
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@Translator(packet = PlayerAuthInputPacket.class)
|
@Translator(packet = PlayerAuthInputPacket.class)
|
||||||
public class BedrockPlayerAuthInputTranslator extends PacketTranslator<PlayerAuthInputPacket> {
|
public final class BedrockPlayerAuthInputTranslator extends PacketTranslator<PlayerAuthInputPacket> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void translate(GeyserSession session, PlayerAuthInputPacket packet) {
|
public void translate(GeyserSession session, PlayerAuthInputPacket packet) {
|
||||||
SessionPlayerEntity entity = session.getPlayerEntity();
|
SessionPlayerEntity entity = session.getPlayerEntity();
|
||||||
|
|
||||||
|
boolean wasJumping = session.getInputCache().wasJumping();
|
||||||
session.getInputCache().processInputs(packet);
|
session.getInputCache().processInputs(packet);
|
||||||
|
|
||||||
|
processVehicleInput(session, packet, wasJumping);
|
||||||
|
|
||||||
BedrockMovePlayerTranslator.translate(session, packet);
|
BedrockMovePlayerTranslator.translate(session, packet);
|
||||||
|
|
||||||
Set<PlayerAuthInputData> inputData = packet.getInputData();
|
Set<PlayerAuthInputData> inputData = packet.getInputData();
|
||||||
@ -202,4 +213,94 @@ public class BedrockPlayerAuthInputTranslator extends PacketTranslator<PlayerAut
|
|||||||
session.getGeyser().getLogger().error("Unhandled item use transaction type!");
|
session.getGeyser().getLogger().error("Unhandled item use transaction type!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void processVehicleInput(GeyserSession session, PlayerAuthInputPacket packet, boolean wasJumping) {
|
||||||
|
Entity vehicle = session.getPlayerEntity().getVehicle();
|
||||||
|
if (vehicle == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (vehicle instanceof ClientVehicle) {
|
||||||
|
session.getPlayerEntity().setVehicleInput(packet.getAnalogMoveVector());
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean sendMovement = false;
|
||||||
|
if (vehicle instanceof AbstractHorseEntity && !(vehicle instanceof LlamaEntity)) {
|
||||||
|
sendMovement = vehicle.isOnGround();
|
||||||
|
} else if (vehicle instanceof BoatEntity) {
|
||||||
|
if (vehicle.getPassengers().size() == 1) {
|
||||||
|
// The player is the only rider
|
||||||
|
sendMovement = true;
|
||||||
|
} else {
|
||||||
|
// Check if the player is the front rider
|
||||||
|
if (session.getPlayerEntity().isRidingInFront()) {
|
||||||
|
sendMovement = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vehicle instanceof AbstractHorseEntity) {
|
||||||
|
// Behavior verified as of Java Edition 1.21.3
|
||||||
|
int currentJumpingTicks = session.getInputCache().getJumpingTicks();
|
||||||
|
if (currentJumpingTicks < 0) {
|
||||||
|
session.getInputCache().setJumpingTicks(++currentJumpingTicks);
|
||||||
|
if (currentJumpingTicks == 0) {
|
||||||
|
session.getPlayerEntity().setVehicleJumpStrength(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean holdingJump = packet.getInputData().contains(PlayerAuthInputData.JUMPING);
|
||||||
|
if (wasJumping && !holdingJump) {
|
||||||
|
// Jump released
|
||||||
|
// Yes, I'm fairly certain that entity ID is correct.
|
||||||
|
session.sendDownstreamGamePacket(new ServerboundPlayerCommandPacket(session.getPlayerEntity().getEntityId(),
|
||||||
|
PlayerState.START_HORSE_JUMP, MathUtils.floor(session.getInputCache().getJumpScale() * 100f)));
|
||||||
|
session.getInputCache().setJumpingTicks(-10);
|
||||||
|
} else if (!wasJumping && holdingJump) {
|
||||||
|
session.getInputCache().setJumpingTicks(0);
|
||||||
|
session.getInputCache().setJumpScale(0);
|
||||||
|
} else if (holdingJump) {
|
||||||
|
session.getInputCache().setJumpingTicks(++currentJumpingTicks);
|
||||||
|
if (currentJumpingTicks < 10) {
|
||||||
|
session.getInputCache().setJumpScale(session.getInputCache().getJumpScale() * 0.1F);
|
||||||
|
} else {
|
||||||
|
session.getInputCache().setJumpScale(0.8f + 2.0f / (currentJumpingTicks - 9) * 0.1f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
session.getInputCache().setJumpScale(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sendMovement) {
|
||||||
|
Vector3f vehiclePosition = packet.getPosition();
|
||||||
|
Vector2f vehicleRotation = packet.getVehicleRotation();
|
||||||
|
if (vehicleRotation == null) {
|
||||||
|
return; // If the client just got in or out of a vehicle for example.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session.getWorldBorder().isPassingIntoBorderBoundaries(vehiclePosition, false)) {
|
||||||
|
Vector3f position = vehicle.getPosition();
|
||||||
|
if (vehicle instanceof BoatEntity boat) {
|
||||||
|
// Undo the changes usually applied to the boat
|
||||||
|
boat.moveAbsoluteWithoutAdjustments(position, vehicle.getYaw(), vehicle.isOnGround(), true);
|
||||||
|
} else {
|
||||||
|
// This doesn't work if teleported is false
|
||||||
|
vehicle.moveAbsolute(position,
|
||||||
|
vehicle.getYaw(), vehicle.getPitch(), vehicle.getHeadYaw(),
|
||||||
|
vehicle.isOnGround(), true);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vehicle instanceof BoatEntity && !vehicle.isOnGround()) {
|
||||||
|
// Remove some Y position to prevents boats flying up
|
||||||
|
vehiclePosition = vehiclePosition.down(vehicle.getDefinition().offset());
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerboundMoveVehiclePacket moveVehiclePacket = new ServerboundMoveVehiclePacket(
|
||||||
|
vehiclePosition.getX(), vehiclePosition.getY(), vehiclePosition.getZ(),
|
||||||
|
vehicleRotation.getY() - 90, vehiclePosition.getX() // TODO I wonder if this is related to the horse spinning bugs...
|
||||||
|
);
|
||||||
|
session.sendDownstreamGamePacket(moveVehiclePacket);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,6 +105,17 @@ public class MathUtils {
|
|||||||
return floatNumber > truncated ? truncated + 1 : truncated;
|
return floatNumber > truncated ? truncated + 1 : truncated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Round the given float to the previous whole number
|
||||||
|
*
|
||||||
|
* @param floatNumber Float to round
|
||||||
|
* @return Rounded number
|
||||||
|
*/
|
||||||
|
public static int floor(float floatNumber) {
|
||||||
|
int truncated = (int) floatNumber;
|
||||||
|
return floatNumber < truncated ? truncated - 1 : truncated;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If number is greater than the max, set it to max, and if number is lower than low, set it to low.
|
* If number is greater than the max, set it to max, and if number is lower than low, set it to low.
|
||||||
*
|
*
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren