Properly check empty context-sensitive collision shape

The emptyCollisionShape() function only checks whether the
cached collision shape (not the context-sensitive collision shape)
is empty. In places where we use the context-sensitive
collision, we need to check the context-sensitive shape instead.
This commit is contained in:
Spottedleaf
2024-08-29 07:47:08 -07:00
parent 92e5f2c81e
commit 007551903b
6 changed files with 23 additions and 26 deletions

View File

@@ -59,10 +59,10 @@ abstract class BlockStateBaseMixin extends StateHolder<Block, BlockState> implem
private boolean emptyCollisionShape;
@Unique
private VoxelShape constantCollisionShape;
private boolean emptyConstantCollisionShape;
@Unique
private AABB constantAABBCollision;
private VoxelShape constantCollisionShape;
@Unique
private static void initCaches(final VoxelShape shape, final boolean neighbours) {
@@ -95,14 +95,13 @@ abstract class BlockStateBaseMixin extends StateHolder<Block, BlockState> implem
final VoxelShape collisionShape = this.cache.collisionShape;
try {
this.constantCollisionShape = this.getCollisionShape(null, null, null);
this.constantAABBCollision = this.constantCollisionShape == null ? null : ((CollisionVoxelShape)this.constantCollisionShape).moonrise$getSingleAABBRepresentation();
} catch (final Throwable throwable) {
// :(
this.constantCollisionShape = null;
this.constantAABBCollision = null;
}
this.occludesFullBlock = ((CollisionVoxelShape)collisionShape).moonrise$occludesFullBlock();
this.emptyCollisionShape = collisionShape.isEmpty();
this.emptyConstantCollisionShape = this.constantCollisionShape != null && this.constantCollisionShape.isEmpty();
// init caches
initCaches(collisionShape, true);
if (this.constantCollisionShape != null) {
@@ -116,8 +115,8 @@ abstract class BlockStateBaseMixin extends StateHolder<Block, BlockState> implem
} else {
this.occludesFullBlock = false;
this.emptyCollisionShape = false;
this.emptyConstantCollisionShape = false;
this.constantCollisionShape = null;
this.constantAABBCollision = null;
}
}
@@ -136,6 +135,11 @@ abstract class BlockStateBaseMixin extends StateHolder<Block, BlockState> implem
return this.emptyCollisionShape;
}
@Override
public final boolean moonrise$emptyContextCollisionShape() {
return this.emptyConstantCollisionShape;
}
@Override
public final int moonrise$uniqueId1() {
return this.id1;
@@ -147,12 +151,7 @@ abstract class BlockStateBaseMixin extends StateHolder<Block, BlockState> implem
}
@Override
public final VoxelShape moonrise$getConstantCollisionShape() {
public final VoxelShape moonrise$getConstantContextCollisionShape() {
return this.constantCollisionShape;
}
@Override
public final AABB moonrise$getConstantCollisionAABB() {
return this.constantAABBCollision;
}
}

View File

@@ -246,10 +246,10 @@ abstract class ExplosionMixin {
}
final BlockState blockState = cachedBlock.blockState;
if (blockState != null && !((CollisionBlockState)blockState).moonrise$emptyCollisionShape()) {
if (blockState != null && !((CollisionBlockState)blockState).moonrise$emptyContextCollisionShape()) {
VoxelShape collision = cachedBlock.cachedCollisionShape;
if (collision == null) {
collision = ((CollisionBlockState)blockState).moonrise$getConstantCollisionShape();
collision = ((CollisionBlockState)blockState).moonrise$getConstantContextCollisionShape();
if (collision == null) {
collision = blockState.getCollisionShape(this.level, currPos, context);
if (!context.isDelegated()) {

View File

@@ -9,7 +9,6 @@ import ca.spottedleaf.moonrise.patches.collisions.world.CollisionLevel;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.level.Level;
@@ -425,11 +424,11 @@ abstract class LevelMixin implements CollisionLevel, LevelAccessor, AutoCloseabl
}
final BlockState state = ((GetBlockChunk)lastChunk).moonrise$getBlock(currX, currY, currZ);
if (((CollisionBlockState)state).moonrise$emptyCollisionShape()) {
if (((CollisionBlockState)state).moonrise$emptyContextCollisionShape()) {
continue;
}
VoxelShape blockCollision = ((CollisionBlockState)state).moonrise$getConstantCollisionShape();
VoxelShape blockCollision = ((CollisionBlockState)state).moonrise$getConstantContextCollisionShape();
if ((edgeCount != 1 || state.hasLargeCollisionShape()) && (edgeCount != 2 || state.getBlock() == Blocks.MOVING_PISTON)) {
if (collisionContext == null) {

View File

@@ -69,8 +69,7 @@ abstract class ThreadedLevelLightEngineMixin extends LevelLightEngine implements
final ChunkAccess center = this.starlight$getLightEngine().getAnyChunkNow(chunkX, chunkZ);
if (center == null || !center.getPersistedStatus().isOrAfter(ChunkStatus.LIGHT)) {
// do not accept updates in unlit chunks, unless we might be generating a chunk. thanks to the amazing
// chunk scheduling, we could be lighting and generating a chunk at the same time
// do not accept updates in unlit chunks, unless we might be generating a chunk
return;
}

View File

@@ -2023,11 +2023,11 @@ public final class CollisionUtil {
final BlockState blockData = blocks.get(localBlockIndex);
if (((CollisionBlockState)blockData).moonrise$emptyCollisionShape()) {
if (((CollisionBlockState)blockData).moonrise$emptyContextCollisionShape()) {
continue;
}
VoxelShape blockCollision = ((CollisionBlockState)blockData).moonrise$getConstantCollisionShape();
VoxelShape blockCollision = ((CollisionBlockState)blockData).moonrise$getConstantContextCollisionShape();
if (edgeCount == 0 || ((edgeCount != 1 || blockData.hasLargeCollisionShape()) && (edgeCount != 2 || blockData.getBlock() == Blocks.MOVING_PISTON))) {
if (blockCollision == null) {

View File

@@ -1,6 +1,5 @@
package ca.spottedleaf.moonrise.patches.collisions.block;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.shapes.VoxelShape;
public interface CollisionBlockState {
@@ -12,6 +11,9 @@ public interface CollisionBlockState {
// whether the cached collision shape exists and is empty
public boolean moonrise$emptyCollisionShape();
// whether the context-sensitive shape is constant and is empty
public boolean moonrise$emptyContextCollisionShape();
// indicates that occludesFullBlock is cached for the collision shape
public boolean moonrise$hasCache();
@@ -23,7 +25,5 @@ public interface CollisionBlockState {
// value is still unique
public int moonrise$uniqueId2();
public VoxelShape moonrise$getConstantCollisionShape();
public AABB moonrise$getConstantCollisionAABB();
public VoxelShape moonrise$getConstantContextCollisionShape();
}