mirror of
https://github.com/GeyserMC/Geyser.git
synced 2025-12-22 16:29:25 +00:00
More accurate ground status translation (#5481)
This commit is contained in:
@@ -36,9 +36,11 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.MovePlayerPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||
import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.level.BedrockDimension;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.AttributeUtils;
|
||||
import org.geysermc.geyser.util.DimensionUtils;
|
||||
@@ -88,6 +90,12 @@ public class SessionPlayerEntity extends PlayerEntity {
|
||||
|
||||
private int lastAirSupply = getMaxAir();
|
||||
|
||||
/**
|
||||
* The client last tick end velocity, used for calculating player onGround.
|
||||
*/
|
||||
@Getter @Setter
|
||||
private Vector3f lastTickEndVelocity = Vector3f.ZERO;
|
||||
|
||||
/**
|
||||
* Determines if our position is currently out-of-sync with the Java server
|
||||
* due to our workaround for the void floor
|
||||
@@ -407,4 +415,17 @@ public class SessionPlayerEntity extends PlayerEntity {
|
||||
movePlayerPacket.setTeleportationCause(MovePlayerPacket.TeleportationCause.BEHAVIOR);
|
||||
session.sendUpstreamPacketImmediately(movePlayerPacket);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to calculate player jumping velocity for ground status calculation.
|
||||
*/
|
||||
public float getJumpVelocity() {
|
||||
float velocity = 0.42F;
|
||||
|
||||
if (session.getGeyser().getWorldManager().blockAt(session, this.getPosition().sub(0, EntityDefinitions.PLAYER.offset() + 0.1F, 0).toInt()).is(Blocks.HONEY_BLOCK)) {
|
||||
velocity *= 0.6F;
|
||||
}
|
||||
|
||||
return velocity + 0.1F * session.getEffectCache().getJumpPower();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,11 +46,16 @@ public class EntityEffectCache {
|
||||
@Getter
|
||||
private int miningFatigue;
|
||||
|
||||
/* Used to calculate jumping velocity */
|
||||
@Getter
|
||||
private int jumpPower;
|
||||
|
||||
public void setEffect(Effect effect, int effectAmplifier) {
|
||||
switch (effect) {
|
||||
case CONDUIT_POWER -> conduitPower = effectAmplifier + 1;
|
||||
case HASTE -> haste = effectAmplifier + 1;
|
||||
case MINING_FATIGUE -> miningFatigue = effectAmplifier + 1;
|
||||
case JUMP_BOOST -> jumpPower = effectAmplifier + 1;
|
||||
}
|
||||
entityEffects.add(effect);
|
||||
}
|
||||
@@ -60,6 +65,7 @@ public class EntityEffectCache {
|
||||
case CONDUIT_POWER -> conduitPower = 0;
|
||||
case HASTE -> haste = 0;
|
||||
case MINING_FATIGUE -> miningFatigue = 0;
|
||||
case JUMP_BOOST -> jumpPower = 0;
|
||||
}
|
||||
entityEffects.remove(effect);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.geysermc.geyser.entity.EntityDefinitions;
|
||||
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
||||
import org.geysermc.geyser.level.physics.CollisionResult;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.BlockTag;
|
||||
import org.geysermc.geyser.text.ChatColor;
|
||||
import org.geysermc.mcprotocollib.network.packet.Packet;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket;
|
||||
@@ -86,15 +87,28 @@ final class BedrockMovePlayer {
|
||||
session.setLookBackScheduledFuture(null);
|
||||
}
|
||||
|
||||
// Simulate jumping since it happened this tick, not from the last tick end.
|
||||
if (entity.isOnGround() && packet.getInputData().contains(PlayerAuthInputData.START_JUMPING)) {
|
||||
entity.setLastTickEndVelocity(Vector3f.from(entity.getLastTickEndVelocity().getX(), Math.max(entity.getLastTickEndVelocity().getY(), entity.getJumpVelocity()), entity.getLastTickEndVelocity().getZ()));
|
||||
}
|
||||
|
||||
// Due to how ladder works on Bedrock, we won't get climbing velocity from tick end unless if you're colliding horizontally. So we account for it ourselves.
|
||||
boolean onClimbableBlock = session.getTagCache().is(BlockTag.CLIMBABLE, session.getGeyser().getWorldManager().blockAt(session, entity.getPosition().sub(0, EntityDefinitions.PLAYER.offset(), 0).toInt()).block());
|
||||
if (onClimbableBlock && packet.getInputData().contains(PlayerAuthInputData.JUMPING)) {
|
||||
entity.setLastTickEndVelocity(Vector3f.from(entity.getLastTickEndVelocity().getX(), 0.2F, entity.getLastTickEndVelocity().getZ()));
|
||||
}
|
||||
|
||||
// Client is telling us it wants to move down, but something is blocking it from doing so.
|
||||
boolean isOnGround;
|
||||
if (hasVehicle) {
|
||||
// VERTICAL_COLLISION is not accurate while in a vehicle (as of 1.21.62)
|
||||
isOnGround = Math.abs(packet.getDelta().getY()) < 0.1;
|
||||
isOnGround = Math.abs(entity.getLastTickEndVelocity().getY()) < 0.1;
|
||||
} else {
|
||||
isOnGround = packet.getInputData().contains(PlayerAuthInputData.VERTICAL_COLLISION) && packet.getDelta().getY() < 0;
|
||||
isOnGround = packet.getInputData().contains(PlayerAuthInputData.VERTICAL_COLLISION) && entity.getLastTickEndVelocity().getY() < 0;
|
||||
}
|
||||
|
||||
entity.setLastTickEndVelocity(packet.getDelta());
|
||||
|
||||
// This takes into account no movement sent from the client, but the player is trying to move anyway.
|
||||
// (Press into a wall in a corner - you're trying to move but nothing actually happens)
|
||||
// This isn't sent when a player is riding a vehicle (as of 1.21.62)
|
||||
|
||||
Reference in New Issue
Block a user