mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
Piston support
This commit is contained in:
parent
e1aebca67c
commit
1a6c70feed
4 changed files with 139 additions and 57 deletions
|
|
@ -35,7 +35,6 @@ import org.cloudburstmc.math.vector.Vector3i;
|
|||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.MoveEntityDeltaPacket;
|
||||
import org.geysermc.erosion.util.BlockPositionIterator;
|
||||
import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
|
||||
import org.geysermc.geyser.entity.type.LivingEntity;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
|
|
@ -81,8 +80,8 @@ public class VehicleComponent<T extends LivingEntity & ClientVehicle> {
|
|||
this.moveSpeed = (float) AttributeType.Builtin.GENERIC_MOVEMENT_SPEED.getDef();
|
||||
this.gravity = AttributeType.Builtin.GENERIC_GRAVITY.getDef();
|
||||
|
||||
double width = Double.parseDouble(Float.toString(vehicle.getBoundingBoxWidth()));
|
||||
double height = Double.parseDouble(Float.toString(vehicle.getBoundingBoxHeight()));
|
||||
double width = vehicle.getBoundingBoxWidth();
|
||||
double height = vehicle.getBoundingBoxHeight();
|
||||
this.boundingBox = new BoundingBox(
|
||||
vehicle.getPosition().getX(),
|
||||
vehicle.getPosition().getY() + height / 2,
|
||||
|
|
@ -92,15 +91,13 @@ public class VehicleComponent<T extends LivingEntity & ClientVehicle> {
|
|||
}
|
||||
|
||||
public void setWidth(float width) {
|
||||
double doubleWidth = Double.parseDouble(Float.toString(width));
|
||||
boundingBox.setSizeX(doubleWidth);
|
||||
boundingBox.setSizeZ(doubleWidth);
|
||||
boundingBox.setSizeX(width);
|
||||
boundingBox.setSizeZ(width);
|
||||
}
|
||||
|
||||
public void setHeight(float height) {
|
||||
double doubleHeight = Double.parseDouble(Float.toString(height));
|
||||
boundingBox.translate(0, (doubleHeight - boundingBox.getSizeY()) / 2, 0);
|
||||
boundingBox.setSizeY(doubleHeight);
|
||||
boundingBox.translate(0, (height - boundingBox.getSizeY()) / 2, 0);
|
||||
boundingBox.setSizeY(height);
|
||||
}
|
||||
|
||||
public void moveAbsolute(double x, double y, double z) {
|
||||
|
|
@ -113,6 +110,14 @@ public class VehicleComponent<T extends LivingEntity & ClientVehicle> {
|
|||
boundingBox.translate(x, y, z);
|
||||
}
|
||||
|
||||
public void moveRelative(Vector3d vec) {
|
||||
boundingBox.translate(vec);
|
||||
}
|
||||
|
||||
public BoundingBox getBoundingBox() {
|
||||
return this.boundingBox;
|
||||
}
|
||||
|
||||
public void setEffect(Effect effect, int effectAmplifier) {
|
||||
switch (effect) {
|
||||
case LEVITATION -> effectLevitation = effectAmplifier + 1;
|
||||
|
|
@ -129,6 +134,12 @@ public class VehicleComponent<T extends LivingEntity & ClientVehicle> {
|
|||
}
|
||||
}
|
||||
|
||||
public Vector3d correctMovement(Vector3d movement) {
|
||||
return vehicle.getSession().getCollisionManager().correctMovement(
|
||||
movement, boundingBox, vehicle.isOnGround(), this.stepHeight, true, vehicle.canWalkOnLava()
|
||||
);
|
||||
}
|
||||
|
||||
public void setMoveSpeed(float moveSpeed) {
|
||||
this.moveSpeed = moveSpeed;
|
||||
}
|
||||
|
|
@ -382,7 +393,7 @@ public class VehicleComponent<T extends LivingEntity & ClientVehicle> {
|
|||
|
||||
protected void landMovement(VehicleContext ctx) {
|
||||
double gravity = getGravity();
|
||||
float slipperiness = BlockStateValues.getSlipperiness(ctx.velocityAffectingBlock());
|
||||
float slipperiness = BlockStateValues.getSlipperiness(getVelocityBlock(ctx));
|
||||
float drag = vehicle.isOnGround() ? 0.91f * slipperiness : 0.91f;
|
||||
float speed = vehicle.getVehicleSpeed() * (vehicle.isOnGround() ? BASE_SLIPPERINESS_CUBED / (slipperiness * slipperiness * slipperiness) : 0.1f);
|
||||
|
||||
|
|
@ -556,13 +567,12 @@ public class VehicleComponent<T extends LivingEntity & ClientVehicle> {
|
|||
// Non-zero values indicate a collision on that axis
|
||||
Vector3d moveDiff = motion.toDouble().sub(correctedMovement);
|
||||
|
||||
boolean onGround = moveDiff.getY() != 0 && motion.getY() < 0;
|
||||
vehicle.setOnGround(moveDiff.getY() != 0 && motion.getY() < 0);
|
||||
boolean horizontalCollision = moveDiff.getX() != 0 || moveDiff.getZ() != 0;
|
||||
|
||||
boolean bounced = false;
|
||||
if (onGround) {
|
||||
Vector3i landingPos = ctx.centerPos().sub(0, 0.2f, 0).toInt();
|
||||
Block landingBlock = ctx.getBlock(landingPos).block();
|
||||
if (vehicle.isOnGround()) {
|
||||
Block landingBlock = getLandingBlock(ctx).block();
|
||||
|
||||
if (landingBlock == Blocks.SLIME_BLOCK) {
|
||||
motion = Vector3f.from(motion.getX(), -motion.getY(), motion.getZ());
|
||||
|
|
@ -592,7 +602,7 @@ public class VehicleComponent<T extends LivingEntity & ClientVehicle> {
|
|||
}
|
||||
|
||||
// Send the new position to the bedrock client and java server
|
||||
moveVehicle(ctx.centerPos(), onGround);
|
||||
moveVehicle(ctx.centerPos());
|
||||
vehicle.setMotion(motion);
|
||||
|
||||
applyBlockCollisionEffects(ctx);
|
||||
|
|
@ -651,17 +661,16 @@ public class VehicleComponent<T extends LivingEntity & ClientVehicle> {
|
|||
return Vector2f.from(player.getYaw(), player.getPitch() * 0.5f);
|
||||
}
|
||||
|
||||
protected void moveVehicle(Vector3d javaPos, boolean isOnGround) {
|
||||
protected void moveVehicle(Vector3d javaPos) {
|
||||
Vector3f bedrockPos = javaPos.toFloat();
|
||||
Vector2f rotation = getVehicleRotation();
|
||||
|
||||
MoveEntityDeltaPacket moveEntityDeltaPacket = new MoveEntityDeltaPacket();
|
||||
moveEntityDeltaPacket.setRuntimeEntityId(vehicle.getGeyserId());
|
||||
|
||||
if (isOnGround) {
|
||||
if (vehicle.isOnGround()) {
|
||||
moveEntityDeltaPacket.getFlags().add(MoveEntityDeltaPacket.Flag.ON_GROUND);
|
||||
}
|
||||
vehicle.setOnGround(isOnGround);
|
||||
|
||||
if (vehicle.getPosition().getX() != bedrockPos.getX()) {
|
||||
moveEntityDeltaPacket.getFlags().add(MoveEntityDeltaPacket.Flag.HAS_X);
|
||||
|
|
@ -714,7 +723,16 @@ public class VehicleComponent<T extends LivingEntity & ClientVehicle> {
|
|||
return this.gravity;
|
||||
}
|
||||
|
||||
protected @Nullable Vector3i getSupportingBlockPos(VehicleContext ctx) {
|
||||
/**
|
||||
* Finds the position of the main block supporting the vehicle.
|
||||
* Used when determining slipperiness, speed, etc.
|
||||
* <p>
|
||||
* Should use {@link VehicleContext#supportingBlockPos()}, instead of calling this directly.
|
||||
*
|
||||
* @param ctx context
|
||||
* @return position of the main block supporting this entity
|
||||
*/
|
||||
private @Nullable Vector3i getSupportingBlockPos(VehicleContext ctx) {
|
||||
Vector3i result = null;
|
||||
|
||||
if (vehicle.isOnGround()) {
|
||||
|
|
@ -752,13 +770,25 @@ public class VehicleComponent<T extends LivingEntity & ClientVehicle> {
|
|||
return result;
|
||||
}
|
||||
|
||||
protected Vector3i getVelocityAffectingPos(VehicleContext ctx) {
|
||||
Vector3i blockPos = getSupportingBlockPos(ctx);
|
||||
if (blockPos != null) {
|
||||
return Vector3i.from(blockPos.getX(), Math.floor(ctx.centerPos().getY() - 0.500001f), blockPos.getZ());
|
||||
protected BlockState getBlockUnder(VehicleContext ctx, float dist) {
|
||||
Vector3i supportingBlockPos = ctx.supportingBlockPos();
|
||||
|
||||
Vector3i blockPos;
|
||||
if (supportingBlockPos != null) {
|
||||
blockPos = Vector3i.from(supportingBlockPos.getX(), Math.floor(ctx.centerPos().getY() - dist), supportingBlockPos.getZ());
|
||||
} else {
|
||||
return ctx.centerPos().sub(0, 0.500001f, 0).toInt();
|
||||
blockPos = ctx.centerPos().sub(0, dist, 0).toInt();
|
||||
}
|
||||
|
||||
return ctx.getBlock(blockPos);
|
||||
}
|
||||
|
||||
protected BlockState getLandingBlock(VehicleContext ctx) {
|
||||
return getBlockUnder(ctx, 0.2f);
|
||||
}
|
||||
|
||||
protected BlockState getVelocityBlock(VehicleContext ctx) {
|
||||
return getBlockUnder(ctx, 0.500001f);
|
||||
}
|
||||
|
||||
protected float getVelocityMultiplier(VehicleContext ctx) {
|
||||
|
|
@ -771,7 +801,7 @@ public class VehicleComponent<T extends LivingEntity & ClientVehicle> {
|
|||
return 0.4f;
|
||||
}
|
||||
|
||||
block = ctx.velocityAffectingBlock().block();
|
||||
block = getVelocityBlock(ctx).block();
|
||||
if (block == Blocks.SOUL_SAND || block == Blocks.HONEY_BLOCK) {
|
||||
return 0.4f;
|
||||
}
|
||||
|
|
@ -785,7 +815,7 @@ public class VehicleComponent<T extends LivingEntity & ClientVehicle> {
|
|||
return 0.5f;
|
||||
}
|
||||
|
||||
block = ctx.velocityAffectingBlock().block();
|
||||
block = getVelocityBlock(ctx).block();
|
||||
if (block == Blocks.HONEY_BLOCK) {
|
||||
return 0.5f;
|
||||
}
|
||||
|
|
@ -796,7 +826,7 @@ public class VehicleComponent<T extends LivingEntity & ClientVehicle> {
|
|||
protected class VehicleContext {
|
||||
private Vector3d centerPos;
|
||||
private BlockState centerBlock;
|
||||
private BlockState velocityAffectingBlock;
|
||||
private Vector3i supportingBlockPos;
|
||||
private BlockPositionIterator blockIter;
|
||||
private int[] blocks;
|
||||
|
||||
|
|
@ -811,7 +841,7 @@ public class VehicleComponent<T extends LivingEntity & ClientVehicle> {
|
|||
|
||||
this.centerPos = boundingBox.getBottomCenter();
|
||||
this.centerBlock = getBlock(this.centerPos.toInt());
|
||||
this.velocityAffectingBlock = null;
|
||||
this.supportingBlockPos = null;
|
||||
}
|
||||
|
||||
protected Vector3d centerPos() {
|
||||
|
|
@ -822,12 +852,12 @@ public class VehicleComponent<T extends LivingEntity & ClientVehicle> {
|
|||
return this.centerBlock;
|
||||
}
|
||||
|
||||
protected BlockState velocityAffectingBlock() {
|
||||
if (this.velocityAffectingBlock == null) {
|
||||
this.velocityAffectingBlock = getBlock(getVelocityAffectingPos(this));
|
||||
protected Vector3i supportingBlockPos() {
|
||||
if (this.supportingBlockPos == null) {
|
||||
this.supportingBlockPos = getSupportingBlockPos(this);
|
||||
}
|
||||
|
||||
return this.velocityAffectingBlock;
|
||||
return this.supportingBlockPos;
|
||||
}
|
||||
|
||||
protected int getBlockId(int x, int y, int z) {
|
||||
|
|
|
|||
|
|
@ -177,7 +177,8 @@ public class CollisionManager {
|
|||
// Send corrected position to Bedrock if they differ by too much to prevent de-syncs
|
||||
if (onGround != newOnGround || movement.distanceSquared(adjustedMovement) > INCORRECT_MOVEMENT_THRESHOLD) {
|
||||
PlayerEntity playerEntity = session.getPlayerEntity();
|
||||
if (pistonCache.getPlayerMotion().equals(Vector3f.ZERO) && !pistonCache.isPlayerSlimeCollision()) {
|
||||
// Client will dismount if on a vehicle
|
||||
if (playerEntity.getVehicle() == null && pistonCache.getPlayerMotion().equals(Vector3f.ZERO) && !pistonCache.isPlayerSlimeCollision()) {
|
||||
playerEntity.moveAbsolute(position.toFloat(), playerEntity.getYaw(), playerEntity.getPitch(), playerEntity.getHeadYaw(), newOnGround, true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,9 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
|||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
||||
import org.geysermc.geyser.entity.vehicle.ClientVehicle;
|
||||
import org.geysermc.geyser.level.physics.Axis;
|
||||
import org.geysermc.geyser.level.physics.BoundingBox;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
|
|
@ -119,6 +121,12 @@ public class PistonCache {
|
|||
private void sendPlayerMovement() {
|
||||
if (!playerDisplacement.equals(Vector3d.ZERO) && playerMotion.equals(Vector3f.ZERO)) {
|
||||
SessionPlayerEntity playerEntity = session.getPlayerEntity();
|
||||
|
||||
Entity vehicle = playerEntity.getVehicle();
|
||||
if (vehicle instanceof ClientVehicle clientVehicle && clientVehicle.isClientControlled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isOnGround = playerDisplacement.getY() > 0 || playerEntity.isOnGround();
|
||||
Vector3d position = session.getCollisionManager().getPlayerBoundingBox().getBottomCenter();
|
||||
playerEntity.moveAbsolute(position.toFloat(), playerEntity.getYaw(), playerEntity.getPitch(), playerEntity.getHeadYaw(), isOnGround, true);
|
||||
|
|
@ -128,6 +136,13 @@ public class PistonCache {
|
|||
private void sendPlayerMotion() {
|
||||
if (!playerMotion.equals(Vector3f.ZERO)) {
|
||||
SessionPlayerEntity playerEntity = session.getPlayerEntity();
|
||||
|
||||
Entity vehicle = playerEntity.getVehicle();
|
||||
if (vehicle instanceof ClientVehicle clientVehicle && clientVehicle.isClientControlled()) {
|
||||
vehicle.setMotion(playerMotion);
|
||||
return;
|
||||
}
|
||||
|
||||
playerEntity.setMotion(playerMotion);
|
||||
|
||||
SetEntityMotionPacket setEntityMotionPacket = new SetEntityMotionPacket();
|
||||
|
|
@ -149,10 +164,15 @@ public class PistonCache {
|
|||
totalDisplacement = totalDisplacement.max(-0.51d, -0.51d, -0.51d).min(0.51d, 0.51d, 0.51d);
|
||||
|
||||
Vector3d delta = totalDisplacement.sub(playerDisplacement);
|
||||
// Check if the piston is pushing a player into collision
|
||||
delta = session.getCollisionManager().correctPlayerMovement(delta, true, false);
|
||||
|
||||
session.getCollisionManager().getPlayerBoundingBox().translate(delta.getX(), delta.getY(), delta.getZ());
|
||||
// Check if the piston is pushing a player into collision
|
||||
if (session.getPlayerEntity().getVehicle() instanceof ClientVehicle clientVehicle && clientVehicle.isClientControlled()) {
|
||||
delta = clientVehicle.getVehicleComponent().correctMovement(delta);
|
||||
clientVehicle.getVehicleComponent().moveRelative(delta);
|
||||
} else {
|
||||
delta = session.getCollisionManager().correctPlayerMovement(delta, true, false);
|
||||
session.getCollisionManager().getPlayerBoundingBox().translate(delta.getX(), delta.getY(), delta.getZ());
|
||||
}
|
||||
|
||||
playerDisplacement = totalDisplacement;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import org.cloudburstmc.nbt.NbtMap;
|
|||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
||||
import org.geysermc.geyser.api.util.PlatformType;
|
||||
import org.geysermc.geyser.entity.vehicle.ClientVehicle;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.level.block.property.Properties;
|
||||
|
|
@ -348,18 +349,31 @@ public class PistonBlockEntity {
|
|||
blockMovement = 1f - lastProgress;
|
||||
}
|
||||
|
||||
BoundingBox playerBoundingBox = session.getCollisionManager().getPlayerBoundingBox();
|
||||
boolean onGround;
|
||||
BoundingBox playerBoundingBox;
|
||||
if (session.getPlayerEntity().getVehicle() instanceof ClientVehicle clientVehicle && clientVehicle.isClientControlled()) {
|
||||
onGround = session.getPlayerEntity().getVehicle().isOnGround();
|
||||
playerBoundingBox = clientVehicle.getVehicleComponent().getBoundingBox();
|
||||
} else {
|
||||
onGround = session.getPlayerEntity().isOnGround();
|
||||
playerBoundingBox = session.getCollisionManager().getPlayerBoundingBox();
|
||||
}
|
||||
|
||||
// Shrink the collision in the other axes slightly, to avoid false positives when pressed up against the side of blocks
|
||||
Vector3d shrink = Vector3i.ONE.sub(direction.abs()).toDouble().mul(CollisionManager.COLLISION_TOLERANCE * 2);
|
||||
playerBoundingBox.setSizeX(playerBoundingBox.getSizeX() - shrink.getX());
|
||||
playerBoundingBox.setSizeY(playerBoundingBox.getSizeY() - shrink.getY());
|
||||
playerBoundingBox.setSizeZ(playerBoundingBox.getSizeZ() - shrink.getZ());
|
||||
double sizeX = playerBoundingBox.getSizeX();
|
||||
double sizeY = playerBoundingBox.getSizeY();
|
||||
double sizeZ = playerBoundingBox.getSizeZ();
|
||||
|
||||
playerBoundingBox.setSizeX(sizeX - shrink.getX());
|
||||
playerBoundingBox.setSizeY(sizeY - shrink.getY());
|
||||
playerBoundingBox.setSizeZ(sizeZ - shrink.getZ());
|
||||
|
||||
// Resolve collision with the piston head
|
||||
BlockState pistonHeadId = Blocks.PISTON_HEAD.defaultBlockState()
|
||||
.withValue(Properties.SHORT, false)
|
||||
.withValue(Properties.FACING, orientation);
|
||||
pushPlayerBlock(pistonHeadId, getPistonHeadPos().toDouble(), blockMovement, playerBoundingBox);
|
||||
pushPlayerBlock(pistonHeadId, getPistonHeadPos().toDouble(), blockMovement, playerBoundingBox, onGround);
|
||||
|
||||
// Resolve collision with any attached moving blocks, but skip slime blocks
|
||||
// This prevents players from being launched by slime blocks covered by other blocks
|
||||
|
|
@ -367,7 +381,7 @@ public class PistonBlockEntity {
|
|||
BlockState state = entry.getValue();
|
||||
if (!state.is(Blocks.SLIME_BLOCK)) {
|
||||
Vector3d blockPos = entry.getKey().toDouble();
|
||||
pushPlayerBlock(state, blockPos, blockMovement, playerBoundingBox);
|
||||
pushPlayerBlock(state, blockPos, blockMovement, playerBoundingBox, onGround);
|
||||
}
|
||||
}
|
||||
// Resolve collision with slime blocks
|
||||
|
|
@ -375,14 +389,14 @@ public class PistonBlockEntity {
|
|||
BlockState state = entry.getValue();
|
||||
if (state.is(Blocks.SLIME_BLOCK)) {
|
||||
Vector3d blockPos = entry.getKey().toDouble();
|
||||
pushPlayerBlock(state, blockPos, blockMovement, playerBoundingBox);
|
||||
pushPlayerBlock(state, blockPos, blockMovement, playerBoundingBox, onGround);
|
||||
}
|
||||
}
|
||||
|
||||
// Undo shrink
|
||||
playerBoundingBox.setSizeX(playerBoundingBox.getSizeX() + shrink.getX());
|
||||
playerBoundingBox.setSizeY(playerBoundingBox.getSizeY() + shrink.getY());
|
||||
playerBoundingBox.setSizeZ(playerBoundingBox.getSizeZ() + shrink.getZ());
|
||||
playerBoundingBox.setSizeX(sizeX);
|
||||
playerBoundingBox.setSizeY(sizeY);
|
||||
playerBoundingBox.setSizeZ(sizeZ);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -392,20 +406,22 @@ public class PistonBlockEntity {
|
|||
* @param playerBoundingBox The player's bounding box
|
||||
* @return True if the player attached, otherwise false
|
||||
*/
|
||||
private boolean isPlayerAttached(Vector3d blockPos, BoundingBox playerBoundingBox) {
|
||||
private boolean isPlayerAttached(Vector3d blockPos, BoundingBox playerBoundingBox, boolean onGround) {
|
||||
if (orientation.isVertical()) {
|
||||
return false;
|
||||
}
|
||||
return session.getPlayerEntity().isOnGround() && HONEY_BOUNDING_BOX.checkIntersection(blockPos, playerBoundingBox);
|
||||
return onGround && HONEY_BOUNDING_BOX.checkIntersection(blockPos, playerBoundingBox);
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches a player if the player is on the pushing side of the slime block
|
||||
*
|
||||
* @param blockPos The position of the slime block
|
||||
* @param playerPos The player's position
|
||||
* @param playerBoundingBox The player's bounding box
|
||||
*/
|
||||
private void applySlimeBlockMotion(Vector3d blockPos, Vector3d playerPos) {
|
||||
private void applySlimeBlockMotion(Vector3d blockPos, BoundingBox playerBoundingBox) {
|
||||
Vector3d playerPos = Vector3d.from(playerBoundingBox.getMiddleX(), playerBoundingBox.getMiddleY(), playerBoundingBox.getMiddleZ());
|
||||
|
||||
Direction movementDirection = orientation;
|
||||
// Invert direction when pulling
|
||||
if (action == PistonValueType.PULLING) {
|
||||
|
|
@ -471,7 +487,7 @@ public class PistonBlockEntity {
|
|||
return maxIntersection;
|
||||
}
|
||||
|
||||
private void pushPlayerBlock(BlockState state, Vector3d startingPos, double blockMovement, BoundingBox playerBoundingBox) {
|
||||
private void pushPlayerBlock(BlockState state, Vector3d startingPos, double blockMovement, BoundingBox playerBoundingBox, boolean onGround) {
|
||||
PistonCache pistonCache = session.getPistonCache();
|
||||
Vector3d movement = getMovement().toDouble();
|
||||
// Check if the player collides with the movingBlock block entity
|
||||
|
|
@ -481,12 +497,12 @@ public class PistonBlockEntity {
|
|||
|
||||
if (state.is(Blocks.SLIME_BLOCK)) {
|
||||
pistonCache.setPlayerSlimeCollision(true);
|
||||
applySlimeBlockMotion(finalBlockPos, Vector3d.from(playerBoundingBox.getMiddleX(), playerBoundingBox.getMiddleY(), playerBoundingBox.getMiddleZ()));
|
||||
applySlimeBlockMotion(finalBlockPos, playerBoundingBox);
|
||||
}
|
||||
}
|
||||
|
||||
Vector3d blockPos = startingPos.add(movement.mul(blockMovement));
|
||||
if (state.is(Blocks.HONEY_BLOCK) && isPlayerAttached(blockPos, playerBoundingBox)) {
|
||||
if (state.is(Blocks.HONEY_BLOCK) && isPlayerAttached(blockPos, playerBoundingBox, onGround)) {
|
||||
pistonCache.setPlayerCollided(true);
|
||||
pistonCache.setPlayerAttachedToHoney(true);
|
||||
|
||||
|
|
@ -509,7 +525,7 @@ public class PistonBlockEntity {
|
|||
|
||||
if (state.is(Blocks.SLIME_BLOCK)) {
|
||||
pistonCache.setPlayerSlimeCollision(true);
|
||||
applySlimeBlockMotion(blockPos, Vector3d.from(playerBoundingBox.getMiddleX(), playerBoundingBox.getMiddleY(), playerBoundingBox.getMiddleZ()));
|
||||
applySlimeBlockMotion(blockPos, playerBoundingBox);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -585,7 +601,14 @@ public class PistonBlockEntity {
|
|||
movingBlockMap.put(getPistonHeadPos(), this);
|
||||
|
||||
Vector3i movement = getMovement();
|
||||
BoundingBox playerBoundingBox = session.getCollisionManager().getPlayerBoundingBox().clone();
|
||||
|
||||
BoundingBox playerBoundingBox;
|
||||
if (session.getPlayerEntity().getVehicle() instanceof ClientVehicle clientVehicle && clientVehicle.isClientControlled()) {
|
||||
playerBoundingBox = clientVehicle.getVehicleComponent().getBoundingBox().clone();
|
||||
} else {
|
||||
playerBoundingBox = session.getCollisionManager().getPlayerBoundingBox().clone();
|
||||
}
|
||||
|
||||
if (orientation == Direction.UP) {
|
||||
// Extend the bounding box down, to catch collisions when the player is falling down
|
||||
playerBoundingBox.extend(0, -256, 0);
|
||||
|
|
@ -629,17 +652,25 @@ public class PistonBlockEntity {
|
|||
return;
|
||||
}
|
||||
placedFinalBlocks = true;
|
||||
|
||||
BoundingBox playerBoundingBox;
|
||||
if (session.getPlayerEntity().getVehicle() instanceof ClientVehicle clientVehicle && clientVehicle.isClientControlled()) {
|
||||
playerBoundingBox = clientVehicle.getVehicleComponent().getBoundingBox().clone();
|
||||
} else {
|
||||
playerBoundingBox = session.getCollisionManager().getPlayerBoundingBox().clone();
|
||||
}
|
||||
|
||||
Vector3i movement = getMovement();
|
||||
attachedBlocks.forEach((blockPos, state) -> {
|
||||
blockPos = blockPos.add(movement);
|
||||
// Don't place blocks that collide with the player
|
||||
if (!SOLID_BOUNDING_BOX.checkIntersection(blockPos.toDouble(), session.getCollisionManager().getPlayerBoundingBox())) {
|
||||
if (!SOLID_BOUNDING_BOX.checkIntersection(blockPos.toDouble(), playerBoundingBox)) {
|
||||
ChunkUtils.updateBlock(session, state, blockPos);
|
||||
}
|
||||
});
|
||||
if (action == PistonValueType.PUSHING) {
|
||||
Vector3i pistonHeadPos = getPistonHeadPos().add(movement);
|
||||
if (!SOLID_BOUNDING_BOX.checkIntersection(pistonHeadPos.toDouble(), session.getCollisionManager().getPlayerBoundingBox())) {
|
||||
if (!SOLID_BOUNDING_BOX.checkIntersection(pistonHeadPos.toDouble(), playerBoundingBox)) {
|
||||
ChunkUtils.updateBlock(session, Blocks.PISTON_HEAD.defaultBlockState()
|
||||
.withValue(Properties.SHORT, false)
|
||||
.withValue(Properties.FACING, orientation), pistonHeadPos);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue