Minestom/src/main/java/net/minestom/server/collision/CollisionUtils.java

76 lines
3.2 KiB
Java

package net.minestom.server.collision;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.Entity;
import net.minestom.server.instance.Instance;
import net.minestom.server.instance.WorldBorder;
import net.minestom.server.instance.block.Block;
import net.minestom.server.item.Material;
import net.minestom.server.utils.chunk.ChunkCache;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Supplier;
@ApiStatus.Internal
@ApiStatus.Experimental
public final class CollisionUtils {
/**
* Moves an entity with physics applied (ie checking against blocks)
* <p>
* Works by getting all the full blocks that an entity could interact with.
* All bounding boxes inside the full blocks are checked for collisions with the entity.
*
* @param entity the entity to move
* @return the result of physics simulation
*/
public static PhysicsResult handlePhysics(@NotNull Entity entity, @NotNull Vec entityVelocity,
@Nullable PhysicsResult lastPhysicsResult) {
final BoundingBox boundingBox = entity.getBoundingBox();
final Pos currentPosition = entity.getPosition();
final Block.Getter getter = new ChunkCache(entity.getInstance(), entity.getChunk(), Block.STONE);
return BlockCollision.handlePhysics(boundingBox,
entityVelocity, currentPosition,
getter, lastPhysicsResult);
}
public static PhysicsResult handlePhysics(@NotNull Entity entity, @NotNull Vec entityVelocity) {
return handlePhysics(entity, entityVelocity, null);
}
/**
* Applies world border collision.
*
* @param instance the instance where the world border is
* @param currentPosition the current position
* @param newPosition the future target position
* @return the position with the world border collision applied (can be {@code newPosition} if not changed)
*/
public static @NotNull Pos applyWorldBorder(@NotNull Instance instance,
@NotNull Pos currentPosition, @NotNull Pos newPosition) {
final WorldBorder worldBorder = instance.getWorldBorder();
final WorldBorder.CollisionAxis collisionAxis = worldBorder.getCollisionAxis(newPosition);
return switch (collisionAxis) {
case NONE ->
// Apply velocity + gravity
newPosition;
case BOTH ->
// Apply Y velocity/gravity
new Pos(currentPosition.x(), newPosition.y(), currentPosition.z());
case X ->
// Apply Y/Z velocity/gravity
new Pos(currentPosition.x(), newPosition.y(), newPosition.z());
case Z ->
// Apply X/Y velocity/gravity
new Pos(newPosition.x(), newPosition.y(), currentPosition.z());
};
}
public static Shape parseBlockShape(String str, Supplier<Material> block) {
return ShapeImpl.parseBlockFromRegistry(str, block);
}
}