Code/net/minecraft/world/entity/vehicle/DismountHelper.java

108 lines
4.8 KiB
Java
Raw Permalink Normal View History

2025-07-01 06:20:03 +00:00
package net.minecraft.world.entity.vehicle;
import java.util.function.Function;
import javax.annotation.Nullable;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.tags.BlockTags;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Pose;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.CollisionGetter;
import net.minecraft.world.level.block.TrapDoorBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
public class DismountHelper {
public static int[][] offsetsForDirection(Direction p_38468_) {
Direction direction = p_38468_.getClockWise();
Direction direction1 = direction.getOpposite();
Direction direction2 = p_38468_.getOpposite();
return new int[][]{
{direction.getStepX(), direction.getStepZ()},
{direction1.getStepX(), direction1.getStepZ()},
{direction2.getStepX() + direction.getStepX(), direction2.getStepZ() + direction.getStepZ()},
{direction2.getStepX() + direction1.getStepX(), direction2.getStepZ() + direction1.getStepZ()},
{p_38468_.getStepX() + direction.getStepX(), p_38468_.getStepZ() + direction.getStepZ()},
{p_38468_.getStepX() + direction1.getStepX(), p_38468_.getStepZ() + direction1.getStepZ()},
{direction2.getStepX(), direction2.getStepZ()},
{p_38468_.getStepX(), p_38468_.getStepZ()}
};
}
public static boolean isBlockFloorValid(double p_38440_) {
return !Double.isInfinite(p_38440_) && p_38440_ < 1.0;
}
public static boolean canDismountTo(CollisionGetter p_38457_, LivingEntity p_38458_, AABB p_38459_) {
for (VoxelShape voxelshape : p_38457_.getBlockCollisions(p_38458_, p_38459_)) {
if (!voxelshape.isEmpty()) {
return false;
}
}
return p_38457_.getWorldBorder().isWithinBounds(p_38459_);
}
public static boolean canDismountTo(CollisionGetter p_150280_, Vec3 p_150281_, LivingEntity p_150282_, Pose p_150283_) {
return canDismountTo(p_150280_, p_150282_, p_150282_.getLocalBoundsForPose(p_150283_).move(p_150281_));
}
public static VoxelShape nonClimbableShape(BlockGetter p_38447_, BlockPos p_38448_) {
BlockState blockstate = p_38447_.getBlockState(p_38448_);
return !blockstate.is(BlockTags.CLIMBABLE) && (!(blockstate.getBlock() instanceof TrapDoorBlock) || !blockstate.getValue(TrapDoorBlock.OPEN))
? blockstate.getCollisionShape(p_38447_, p_38448_)
: Shapes.empty();
}
public static double findCeilingFrom(BlockPos p_38464_, int p_38465_, Function<BlockPos, VoxelShape> p_38466_) {
BlockPos.MutableBlockPos blockpos$mutableblockpos = p_38464_.mutable();
int i = 0;
while (i < p_38465_) {
VoxelShape voxelshape = p_38466_.apply(blockpos$mutableblockpos);
if (!voxelshape.isEmpty()) {
return p_38464_.getY() + i + voxelshape.min(Direction.Axis.Y);
}
i++;
blockpos$mutableblockpos.move(Direction.UP);
}
return Double.POSITIVE_INFINITY;
}
@Nullable
public static Vec3 findSafeDismountLocation(EntityType<?> p_38442_, CollisionGetter p_38443_, BlockPos p_38444_, boolean p_38445_) {
if (p_38445_ && p_38442_.isBlockDangerous(p_38443_.getBlockState(p_38444_))) {
return null;
} else {
double d0 = p_38443_.getBlockFloorHeight(nonClimbableShape(p_38443_, p_38444_), () -> nonClimbableShape(p_38443_, p_38444_.below()));
if (!isBlockFloorValid(d0)) {
return null;
} else if (p_38445_ && d0 <= 0.0 && p_38442_.isBlockDangerous(p_38443_.getBlockState(p_38444_.below()))) {
return null;
} else {
Vec3 vec3 = Vec3.upFromBottomCenterOf(p_38444_, d0);
AABB aabb = p_38442_.getDimensions().makeBoundingBox(vec3);
for (VoxelShape voxelshape : p_38443_.getBlockCollisions(null, aabb)) {
if (!voxelshape.isEmpty()) {
return null;
}
}
if (p_38442_ != EntityType.PLAYER
|| !p_38443_.getBlockState(p_38444_).is(BlockTags.INVALID_SPAWN_INSIDE) && !p_38443_.getBlockState(p_38444_.above()).is(BlockTags.INVALID_SPAWN_INSIDE)) {
return !p_38443_.getWorldBorder().isWithinBounds(aabb) ? null : vec3;
} else {
return null;
}
}
}
}
}