mirror of
https://github.com/GeyserMC/Geyser.git
synced 2025-12-23 00:39:19 +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.data.entity.EntityFlag;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.MovePlayerPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.MovePlayerPacket;
|
||||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket;
|
import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket;
|
||||||
|
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||||
import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
|
import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
|
||||||
import org.geysermc.geyser.item.Items;
|
import org.geysermc.geyser.item.Items;
|
||||||
import org.geysermc.geyser.level.BedrockDimension;
|
import org.geysermc.geyser.level.BedrockDimension;
|
||||||
|
import org.geysermc.geyser.level.block.Blocks;
|
||||||
import org.geysermc.geyser.session.GeyserSession;
|
import org.geysermc.geyser.session.GeyserSession;
|
||||||
import org.geysermc.geyser.util.AttributeUtils;
|
import org.geysermc.geyser.util.AttributeUtils;
|
||||||
import org.geysermc.geyser.util.DimensionUtils;
|
import org.geysermc.geyser.util.DimensionUtils;
|
||||||
@@ -88,6 +90,12 @@ public class SessionPlayerEntity extends PlayerEntity {
|
|||||||
|
|
||||||
private int lastAirSupply = getMaxAir();
|
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
|
* Determines if our position is currently out-of-sync with the Java server
|
||||||
* due to our workaround for the void floor
|
* due to our workaround for the void floor
|
||||||
@@ -407,4 +415,17 @@ public class SessionPlayerEntity extends PlayerEntity {
|
|||||||
movePlayerPacket.setTeleportationCause(MovePlayerPacket.TeleportationCause.BEHAVIOR);
|
movePlayerPacket.setTeleportationCause(MovePlayerPacket.TeleportationCause.BEHAVIOR);
|
||||||
session.sendUpstreamPacketImmediately(movePlayerPacket);
|
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
|
@Getter
|
||||||
private int miningFatigue;
|
private int miningFatigue;
|
||||||
|
|
||||||
|
/* Used to calculate jumping velocity */
|
||||||
|
@Getter
|
||||||
|
private int jumpPower;
|
||||||
|
|
||||||
public void setEffect(Effect effect, int effectAmplifier) {
|
public void setEffect(Effect effect, int effectAmplifier) {
|
||||||
switch (effect) {
|
switch (effect) {
|
||||||
case CONDUIT_POWER -> conduitPower = effectAmplifier + 1;
|
case CONDUIT_POWER -> conduitPower = effectAmplifier + 1;
|
||||||
case HASTE -> haste = effectAmplifier + 1;
|
case HASTE -> haste = effectAmplifier + 1;
|
||||||
case MINING_FATIGUE -> miningFatigue = effectAmplifier + 1;
|
case MINING_FATIGUE -> miningFatigue = effectAmplifier + 1;
|
||||||
|
case JUMP_BOOST -> jumpPower = effectAmplifier + 1;
|
||||||
}
|
}
|
||||||
entityEffects.add(effect);
|
entityEffects.add(effect);
|
||||||
}
|
}
|
||||||
@@ -60,6 +65,7 @@ public class EntityEffectCache {
|
|||||||
case CONDUIT_POWER -> conduitPower = 0;
|
case CONDUIT_POWER -> conduitPower = 0;
|
||||||
case HASTE -> haste = 0;
|
case HASTE -> haste = 0;
|
||||||
case MINING_FATIGUE -> miningFatigue = 0;
|
case MINING_FATIGUE -> miningFatigue = 0;
|
||||||
|
case JUMP_BOOST -> jumpPower = 0;
|
||||||
}
|
}
|
||||||
entityEffects.remove(effect);
|
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.entity.type.player.SessionPlayerEntity;
|
||||||
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.session.cache.tags.BlockTag;
|
||||||
import org.geysermc.geyser.text.ChatColor;
|
import org.geysermc.geyser.text.ChatColor;
|
||||||
import org.geysermc.mcprotocollib.network.packet.Packet;
|
import org.geysermc.mcprotocollib.network.packet.Packet;
|
||||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket;
|
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundMovePlayerPosPacket;
|
||||||
@@ -86,15 +87,28 @@ final class BedrockMovePlayer {
|
|||||||
session.setLookBackScheduledFuture(null);
|
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.
|
// Client is telling us it wants to move down, but something is blocking it from doing so.
|
||||||
boolean isOnGround;
|
boolean isOnGround;
|
||||||
if (hasVehicle) {
|
if (hasVehicle) {
|
||||||
// VERTICAL_COLLISION is not accurate while in a vehicle (as of 1.21.62)
|
// 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 {
|
} 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.
|
// 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)
|
// (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)
|
// This isn't sent when a player is riding a vehicle (as of 1.21.62)
|
||||||
|
|||||||
Reference in New Issue
Block a user