Support world border

This commit is contained in:
AJ Ferguson 2024-07-02 08:03:15 -04:00
parent 727604f82c
commit c86b41d198
5 changed files with 72 additions and 3 deletions

View file

@ -102,11 +102,15 @@ public class PigEntity extends AnimalEntity implements Tickable, ClientVehicle {
@Override
public void tick() {
PlayerEntity player = getPlayerPassenger();
if (player == null) {
return;
}
if (player == session.getPlayerEntity()) {
if (session.getPlayerInventory().isHolding(Items.CARROT_ON_A_STICK)) {
vehicleComponent.tickBoost();
}
} else if (player != null) { // getHand() for session player seems to always return air
} else { // getHand() for session player seems to always return air
ItemDefinition itemDefinition = session.getItemMappings().getStoredItems().carrotOnAStick().getBedrockDefinition();
if (player.getHand().getDefinition() == itemDefinition || player.getOffhand().getDefinition() == itemDefinition) {
vehicleComponent.tickBoost();

View file

@ -149,11 +149,15 @@ public class StriderEntity extends AnimalEntity implements Tickable, ClientVehic
@Override
public void tick() {
PlayerEntity player = getPlayerPassenger();
if (player == null) {
return;
}
if (player == session.getPlayerEntity()) {
if (session.getPlayerInventory().isHolding(Items.WARPED_FUNGUS_ON_A_STICK)) {
vehicleComponent.tickBoost();
}
} else if (player != null) { // getHand() for session player seems to always return air
} else { // getHand() for session player seems to always return air
ItemDefinition itemDefinition = session.getItemMappings().getStoredItems().warpedFungusOnAStick().getBedrockDefinition();
if (player.getHand().getDefinition() == itemDefinition || player.getOffhand().getDefinition() == itemDefinition) {
vehicleComponent.tickBoost();

View file

@ -559,6 +559,8 @@ public class VehicleComponent<T extends LivingEntity & ClientVehicle> {
motion.toDouble(), boundingBox, vehicle.isOnGround(), this.stepHeight, true, vehicle.canWalkOnLava()
);
correctedMovement = vehicle.getSession().getWorldBorder().correctMovement(boundingBox, correctedMovement);
boundingBox.translate(correctedMovement);
ctx.loadSurroundingBlocks();

View file

@ -28,6 +28,7 @@ package org.geysermc.geyser.session.cache;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.cloudburstmc.math.GenericMath;
import org.cloudburstmc.math.vector.Vector2d;
import org.cloudburstmc.math.vector.Vector3d;
import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
import org.cloudburstmc.protocol.bedrock.data.LevelEventType;
@ -36,8 +37,11 @@ import lombok.Getter;
import lombok.Setter;
import org.geysermc.geyser.entity.EntityDefinitions;
import org.geysermc.geyser.entity.type.player.PlayerEntity;
import org.geysermc.geyser.level.physics.BoundingBox;
import org.geysermc.geyser.session.GeyserSession;
import static org.geysermc.geyser.level.physics.CollisionManager.COLLISION_TOLERANCE;
public class WorldBorder {
private static final double DEFAULT_WORLD_BORDER_SIZE = 5.9999968E7D;
@ -190,6 +194,59 @@ public class WorldBorder {
return entityPosition.getX() > warningMinX && entityPosition.getX() < warningMaxX && entityPosition.getZ() > warningMinZ && entityPosition.getZ() < warningMaxZ;
}
/**
* Adjusts the movement of an entity so that it does not cross the world border.
*
* @param boundingBox bounding box of the entity
* @param movement movement of the entity
* @return the corrected movement
*/
public Vector3d correctMovement(BoundingBox boundingBox, Vector3d movement) {
Vector3d bbMin = boundingBox.getMin();
Vector3d bbMax = boundingBox.getMax();
// If outside border, don't adjust movement
if (bbMin.getX() + COLLISION_TOLERANCE < GenericMath.floor(minX)
|| bbMin.getZ() + COLLISION_TOLERANCE < GenericMath.floor(minZ)
|| bbMax.getX() - COLLISION_TOLERANCE > GenericMath.ceil(maxX)
|| bbMax.getZ() - COLLISION_TOLERANCE > GenericMath.ceil(maxZ)) {
return movement;
}
double diff; // Difference between edge of bounding box and world border
double correctedX = movement.getX();
diff = GenericMath.floor(minX) - (bbMin.getX() + movement.getX());
if (diff > 0) {
correctedX += diff;
} else {
diff = (bbMax.getX() + movement.getX()) - GenericMath.ceil(maxX);
if (diff > 0) {
correctedX -= diff;
}
}
if (Math.abs(correctedX) < COLLISION_TOLERANCE) {
correctedX = 0;
}
double correctedZ = movement.getZ();
diff = GenericMath.floor(minZ) - (bbMin.getZ() + movement.getZ());
if (diff > 0) {
correctedZ += diff;
} else {
diff = (bbMax.getZ() + movement.getZ()) - GenericMath.ceil(maxZ);
if (diff > 0) {
correctedZ -= diff;
}
}
if (Math.abs(correctedZ) < COLLISION_TOLERANCE) {
correctedZ = 0;
}
return Vector3d.from(correctedX, movement.getY(), correctedZ);
}
/**
* Updates the world border's minimum and maximum properties
*/

View file

@ -30,6 +30,7 @@ import org.cloudburstmc.math.vector.Vector3f;
import org.cloudburstmc.protocol.bedrock.packet.MovePlayerPacket;
import org.geysermc.geyser.entity.EntityDefinitions;
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
import org.geysermc.geyser.entity.vehicle.ClientVehicle;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.text.ChatColor;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
@ -84,7 +85,8 @@ public class BedrockMovePlayerTranslator extends PacketTranslator<MovePlayerPack
session.sendDownstreamGamePacket(playerRotationPacket);
} else {
if (session.getWorldBorder().isPassingIntoBorderBoundaries(packet.getPosition(), true)) {
if (!(entity.getVehicle() instanceof ClientVehicle clientVehicle && clientVehicle.isClientControlled())
&& session.getWorldBorder().isPassingIntoBorderBoundaries(packet.getPosition(), true)) {
return;
}