Fix incorrect Entity#isInWall() mixin

The VoxelShapes retrieved need to be offset for the
intersection checks.
This commit is contained in:
Spottedleaf
2023-09-12 07:12:37 -07:00
parent b8935d1dd1
commit fcc3b02a54
7 changed files with 30 additions and 22 deletions

View File

@@ -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;

View File

@@ -153,7 +153,7 @@ public abstract class DirectionMixin implements CollisionDirection {
}
@Override
public int uniqueId() {
public final int uniqueId() {
return this.id;
}
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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