minecraft-source/src/net/minecraft/world/level/CollisionGetter.java

128 lines
5.9 KiB
Java

package net.minecraft.world.level;
import java.util.Spliterator;
import java.util.stream.StreamSupport;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.phys.shapes.BooleanOp;
import java.util.function.Consumer;
import java.util.Spliterators;
import net.minecraft.core.Cursor3D;
import net.minecraft.util.Mth;
import com.google.common.collect.Streams;
import java.util.stream.Stream;
import java.util.Set;
import java.util.Collections;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraft.world.entity.Entity;
import javax.annotation.Nullable;
import net.minecraft.world.level.border.WorldBorder;
public interface CollisionGetter extends BlockGetter {
WorldBorder getWorldBorder();
@Nullable
BlockGetter getChunkForCollisions(final int integer1, final int integer2);
default boolean isUnobstructed(@Nullable final Entity akn, final VoxelShape cwc) {
return true;
}
default boolean isUnobstructed(final BlockState byg, final BlockPos fk, final CollisionContext cvn) {
final VoxelShape cwc5 = byg.getCollisionShape(this, fk, cvn);
return cwc5.isEmpty() || this.isUnobstructed(null, cwc5.move(fk.getX(), fk.getY(), fk.getZ()));
}
default boolean isUnobstructed(final Entity akn) {
return this.isUnobstructed(akn, Shapes.create(akn.getBoundingBox()));
}
default boolean noCollision(final AABB cvc) {
return this.noCollision(null, cvc, Collections.<Entity>emptySet());
}
default boolean noCollision(final Entity akn) {
return this.noCollision(akn, akn.getBoundingBox(), Collections.<Entity>emptySet());
}
default boolean noCollision(final Entity akn, final AABB cvc) {
return this.noCollision(akn, cvc, Collections.<Entity>emptySet());
}
default boolean noCollision(@Nullable final Entity akn, final AABB cvc, final Set<Entity> set) {
return this.getCollisions(akn, cvc, set).allMatch(VoxelShape::isEmpty);
}
default Stream<VoxelShape> getEntityCollisions(@Nullable final Entity akn, final AABB cvc, final Set<Entity> set) {
return Stream.<VoxelShape>empty();
}
default Stream<VoxelShape> getCollisions(@Nullable final Entity akn, final AABB cvc, final Set<Entity> set) {
return Streams.<VoxelShape>concat(new Stream[] { this.getBlockCollisions(akn, cvc), this.getEntityCollisions(akn, cvc, set) });
}
default Stream<VoxelShape> getBlockCollisions(@Nullable final Entity akn, final AABB cvc) {
final int integer4 = Mth.floor(cvc.minX - 1.0E-7) - 1;
final int integer5 = Mth.floor(cvc.maxX + 1.0E-7) + 1;
final int integer6 = Mth.floor(cvc.minY - 1.0E-7) - 1;
final int integer7 = Mth.floor(cvc.maxY + 1.0E-7) + 1;
final int integer8 = Mth.floor(cvc.minZ - 1.0E-7) - 1;
final int integer9 = Mth.floor(cvc.maxZ + 1.0E-7) + 1;
final CollisionContext cvn10 = (akn == null) ? CollisionContext.empty() : CollisionContext.of(akn);
final Cursor3D fn11 = new Cursor3D(integer4, integer6, integer8, integer5, integer7, integer9);
final BlockPos.MutableBlockPos a12 = new BlockPos.MutableBlockPos();
final VoxelShape cwc13 = Shapes.create(cvc);
return StreamSupport.<VoxelShape>stream((Spliterator<VoxelShape>)new Spliterators.AbstractSpliterator<VoxelShape>(Long.MAX_VALUE, 1280) {
boolean checkedBorder = akn == null;
@Override
public boolean tryAdvance(final Consumer<? super VoxelShape> consumer) {
if (!this.checkedBorder) {
this.checkedBorder = true;
final VoxelShape cwc3 = CollisionGetter.this.getWorldBorder().getCollisionShape();
final boolean boolean4 = Shapes.joinIsNotEmpty(cwc3, Shapes.create(akn.getBoundingBox().deflate(1.0E-7)), BooleanOp.AND);
final boolean boolean5 = Shapes.joinIsNotEmpty(cwc3, Shapes.create(akn.getBoundingBox().inflate(1.0E-7)), BooleanOp.AND);
if (!boolean4 && boolean5) {
consumer.accept(cwc3);
return true;
}
}
while (fn11.advance()) {
final int integer3 = fn11.nextX();
final int integer4 = fn11.nextY();
final int integer5 = fn11.nextZ();
final int integer6 = fn11.getNextType();
if (integer6 == 3) {
continue;
}
final int integer7 = integer3 >> 4;
final int integer8 = integer5 >> 4;
final BlockGetter bjd9 = CollisionGetter.this.getChunkForCollisions(integer7, integer8);
if (bjd9 == null) {
continue;
}
a12.set(integer3, integer4, integer5);
final BlockState byg10 = bjd9.getBlockState(a12);
if (integer6 == 1 && !byg10.hasLargeCollisionShape()) {
continue;
}
if (integer6 == 2 && byg10.getBlock() != Blocks.MOVING_PISTON) {
continue;
}
final VoxelShape cwc4 = byg10.getCollisionShape(CollisionGetter.this, a12, cvn10);
final VoxelShape cwc5 = cwc4.move(integer3, integer4, integer5);
if (Shapes.joinIsNotEmpty(cwc13, cwc5, BooleanOp.AND)) {
consumer.accept(cwc5);
return true;
}
}
return false;
}
}, false);
}
}