Let doors and trapdoors occlude in hulls

Doors and trapdoors do not occlude for the client, so they had no full face
in the hull and rays passed through closed trapdoors, revealing blocks behind
them along diagonals. Their face masks now come from their shape, so the face
their panel covers is full.
This commit is contained in:
2026-10-31 21:37:08 +01:00
parent baa4cf34e5
commit d7d452ebe6
+14 -3
View File
@@ -34,6 +34,9 @@ import net.minecraft.core.SectionPos;
import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket;
import net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.EmptyBlockGetter;
import net.minecraft.world.level.block.DoorBlock;
import net.minecraft.world.level.block.TrapDoorBlock;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.bukkit.Bukkit;
@@ -129,13 +132,21 @@ public class Hull {
return fullFacesByState[id];
}
// The faces that hide what is behind them, as the client culls them
// The faces that hide what is behind them, mostly as the client culls them
private int computeFullFaces(BlockState state) {
// Hidden blocks are replaced by an occluding block, the same decision as the techhider's
if (obfuscation.hidesBlock(state.getBlock()) || obfuscation.hidesBlockState(state)) return ALL_FACES;
if (!state.canOcclude()) return 0;
VoxelShape shape = state.getOcclusionShape();
VoxelShape shape;
if (state.canOcclude()) {
shape = state.getOcclusionShape();
} else if (state.getBlock() instanceof DoorBlock || state.getBlock() instanceof TrapDoorBlock) {
// Their panel covers a face, although the client does not cull the faces behind them
shape = state.getShape(EmptyBlockGetter.INSTANCE, BlockPos.ZERO);
} else {
return 0;
}
int faces = 0;
for (Direction direction : Direction.values()) {
if (net.minecraft.world.level.block.Block.isFaceFull(shape, direction)) {