Fix incorrect Entity#isInWall() mixin
The VoxelShapes retrieved need to be offset for the intersection checks.
This commit is contained in:
@@ -28,6 +28,17 @@ import java.util.concurrent.atomic.AtomicInteger;
|
||||
@Mixin(BlockBehaviour.BlockStateBase.class)
|
||||
public abstract class BlockStateBaseMixin extends StateHolder<Block, BlockState> implements CollisionBlockState {
|
||||
|
||||
@Shadow
|
||||
protected BlockBehaviour.BlockStateBase.Cache cache;
|
||||
|
||||
@Shadow
|
||||
public abstract VoxelShape getCollisionShape(BlockGetter blockGetter, BlockPos blockPos, CollisionContext collisionContext);
|
||||
|
||||
protected BlockStateBaseMixin(Block object, ImmutableMap<Property<?>, Comparable<?>> immutableMap, MapCodec<BlockState> mapCodec) {
|
||||
super(object, immutableMap, mapCodec);
|
||||
}
|
||||
|
||||
|
||||
@Unique
|
||||
private static final int RANDOM_OFFSET = 704237939;
|
||||
|
||||
@@ -40,19 +51,6 @@ public abstract class BlockStateBaseMixin extends StateHolder<Block, BlockState>
|
||||
@Unique
|
||||
private int id1, id2;
|
||||
|
||||
@Shadow
|
||||
protected BlockBehaviour.BlockStateBase.Cache cache;
|
||||
|
||||
@Shadow
|
||||
public abstract VoxelShape getCollisionShape(BlockGetter blockGetter, BlockPos blockPos, CollisionContext collisionContext);
|
||||
|
||||
|
||||
|
||||
protected BlockStateBaseMixin(Block object, ImmutableMap<Property<?>, Comparable<?>> immutableMap, MapCodec<BlockState> mapCodec) {
|
||||
super(object, immutableMap, mapCodec);
|
||||
}
|
||||
|
||||
|
||||
@Unique
|
||||
private boolean occludesFullBlock;
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ public abstract class DirectionMixin implements CollisionDirection {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int uniqueId() {
|
||||
public final int uniqueId() {
|
||||
return this.id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package ca.spottedleaf.moonrise.mixin.collisions;
|
||||
|
||||
import ca.spottedleaf.moonrise.common.util.CoordinateUtils;
|
||||
import ca.spottedleaf.moonrise.patches.collisions.CollisionUtil;
|
||||
import ca.spottedleaf.moonrise.patches.collisions.block.CollisionBlockState;
|
||||
import ca.spottedleaf.moonrise.patches.collisions.entity.CollisionEntity;
|
||||
import ca.spottedleaf.moonrise.patches.collisions.shape.CollisionVoxelShape;
|
||||
import ca.spottedleaf.moonrise.patches.collisions.util.EmptyStreamForMoveCall;
|
||||
@@ -18,6 +19,7 @@ import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.ChunkSource;
|
||||
import net.minecraft.world.level.chunk.ChunkStatus;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
@@ -331,6 +333,8 @@ public abstract class EntityMixin implements CollisionEntity {
|
||||
final int maxY = Mth.floor(box.maxY);
|
||||
final int maxZ = Mth.floor(box.maxZ);
|
||||
|
||||
final ChunkSource chunkProvider = this.level.getChunkSource();
|
||||
|
||||
long lastChunkKey = ChunkPos.INVALID_CHUNK_POS;
|
||||
LevelChunk lastChunk = null;
|
||||
for (int fz = minZ; fz <= maxZ; ++fz) {
|
||||
@@ -339,14 +343,14 @@ public abstract class EntityMixin implements CollisionEntity {
|
||||
final int newChunkX = fx >> 4;
|
||||
final int newChunkZ = fz >> 4;
|
||||
final LevelChunk chunk = lastChunkKey == (lastChunkKey = CoordinateUtils.getChunkKey(newChunkX, newChunkZ)) ?
|
||||
lastChunk : (lastChunk = this.level.getChunk(fx >> 4, fz >> 4));
|
||||
lastChunk : (lastChunk = (LevelChunk)chunkProvider.getChunk(fx >> 4, fz >> 4, ChunkStatus.FULL, true));
|
||||
tempPos.setX(fx);
|
||||
for (int fy = minY; fy <= maxY; ++fy) {
|
||||
tempPos.setY(fy);
|
||||
|
||||
final BlockState state = chunk.getBlockState(tempPos);
|
||||
|
||||
if (state.isAir() || !state.isSuffocating(this.level, tempPos)) {
|
||||
if (((CollisionBlockState)state).emptyCollisionShape() || !state.isSuffocating(this.level, tempPos)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -357,15 +361,17 @@ public abstract class EntityMixin implements CollisionEntity {
|
||||
continue;
|
||||
}
|
||||
|
||||
final AABB toCollide = box.move(-(double)fx, -(double)fy, -(double)fz);
|
||||
|
||||
final AABB singleAABB = ((CollisionVoxelShape)collisionShape).getSingleAABBRepresentation();
|
||||
if (singleAABB != null) {
|
||||
if (CollisionUtil.voxelShapeIntersect(box, singleAABB)) {
|
||||
if (CollisionUtil.voxelShapeIntersect(singleAABB, toCollide)) {
|
||||
return true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (CollisionUtil.voxelShapeIntersectNoEmpty(collisionShape, box)) {
|
||||
if (CollisionUtil.voxelShapeIntersectNoEmpty(collisionShape, toCollide)) {
|
||||
return true;
|
||||
}
|
||||
continue;
|
||||
|
||||
@@ -298,7 +298,7 @@ public abstract class LevelMixin implements CollisionLevel, CollisionEntityGette
|
||||
int lastChunkY = Integer.MIN_VALUE;
|
||||
int lastChunkZ = Integer.MIN_VALUE;
|
||||
|
||||
final int minSection = WorldUtil.getMinSection(level);
|
||||
final int minSection = ((CollisionLevel)level).getMinSectionMoonrise();
|
||||
|
||||
for (;;) {
|
||||
currPos.set(currX, currY, currZ);
|
||||
|
||||
@@ -259,7 +259,8 @@ public abstract class VoxelShapeMixin implements CollisionVoxelShape {
|
||||
final AABB singleAABB = this.singleAABBRepresentation;
|
||||
if (singleAABB != null) {
|
||||
// check if the bounding box encloses the full cube
|
||||
final boolean ret = (singleAABB.minY <= CollisionUtil.COLLISION_EPSILON && singleAABB.maxY >= (1 - CollisionUtil.COLLISION_EPSILON)) &&
|
||||
final boolean ret =
|
||||
(singleAABB.minY <= CollisionUtil.COLLISION_EPSILON && singleAABB.maxY >= (1 - CollisionUtil.COLLISION_EPSILON)) &&
|
||||
(singleAABB.minX <= CollisionUtil.COLLISION_EPSILON && singleAABB.maxX >= (1 - CollisionUtil.COLLISION_EPSILON)) &&
|
||||
(singleAABB.minZ <= CollisionUtil.COLLISION_EPSILON && singleAABB.maxZ >= (1 - CollisionUtil.COLLISION_EPSILON));
|
||||
this.occludesFullBlock = Boolean.valueOf(ret);
|
||||
|
||||
@@ -133,7 +133,7 @@ public abstract class ExplosionMixin {
|
||||
private static final Float ZERO_RESISTANCE = Float.valueOf(-0.3f);
|
||||
|
||||
@Unique
|
||||
private Long2ObjectOpenHashMap<ExplosionBlockCache> blockCache = new Long2ObjectOpenHashMap<>();
|
||||
private Long2ObjectOpenHashMap<ExplosionBlockCache> blockCache = null;
|
||||
|
||||
@Unique
|
||||
private long[] chunkPosCache = null;
|
||||
@@ -350,12 +350,14 @@ public abstract class ExplosionMixin {
|
||||
public void explode() {
|
||||
this.level.gameEvent(this.source, GameEvent.EXPLODE, new Vec3(this.x, this.y, this.z));
|
||||
|
||||
this.blockCache = new it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap<>();
|
||||
|
||||
this.chunkPosCache = new long[CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH];
|
||||
Arrays.fill(this.chunkPosCache, ChunkPos.INVALID_CHUNK_POS);
|
||||
|
||||
this.chunkCache = new LevelChunk[CHUNK_CACHE_WIDTH * CHUNK_CACHE_WIDTH];
|
||||
|
||||
ExplosionBlockCache[] blockCache = new ExplosionBlockCache[BLOCK_EXPLOSION_CACHE_WIDTH * BLOCK_EXPLOSION_CACHE_WIDTH * BLOCK_EXPLOSION_CACHE_WIDTH];
|
||||
final ExplosionBlockCache[] blockCache = new ExplosionBlockCache[BLOCK_EXPLOSION_CACHE_WIDTH * BLOCK_EXPLOSION_CACHE_WIDTH * BLOCK_EXPLOSION_CACHE_WIDTH];
|
||||
|
||||
// use initial cache value that is most likely to be used: the source position
|
||||
final ExplosionBlockCache initialCache;
|
||||
|
||||
@@ -96,6 +96,7 @@ accessible method net/minecraft/world/phys/shapes/BitSetDiscreteVoxelShape isZSt
|
||||
accessible method net/minecraft/world/phys/shapes/BitSetDiscreteVoxelShape isXZRectangleFull (IIIII)Z
|
||||
accessible method net/minecraft/world/phys/shapes/BitSetDiscreteVoxelShape clearZStrip (IIII)V
|
||||
|
||||
|
||||
# IndexMerger
|
||||
accessible class net/minecraft/world/phys/shapes/IndexMerger
|
||||
|
||||
|
||||
Reference in New Issue
Block a user