From 04e174fa37df54126ba43d93bcae19a0a2e329a6 Mon Sep 17 00:00:00 2001 From: Milkev Date: Sat, 25 Apr 2026 15:45:27 -0600 Subject: [PATCH] Little Tiles Partial Compatability When VoxelShapeMixin.sable$allBoxes is called in a context relevant to little tiles, it will always be null. I added some null checks for this, and just skip over the relevant code if it is null. This results in little tile blocks being placeable and visible on physics objects, however little tile blocks are completely ignored for physics object collision checks --- .../VoxelShapeMixin.java | 6 + .../SubLevelEntityCollision.java | 104 ++++++++++-------- .../resources/META-INF/neoforge.mods.toml | 4 - 3 files changed, 62 insertions(+), 52 deletions(-) diff --git a/common/src/main/java/dev/ryanhcode/sable/mixin/voxel_shape_iteration/VoxelShapeMixin.java b/common/src/main/java/dev/ryanhcode/sable/mixin/voxel_shape_iteration/VoxelShapeMixin.java index ac6b9d06..d882f1c7 100644 --- a/common/src/main/java/dev/ryanhcode/sable/mixin/voxel_shape_iteration/VoxelShapeMixin.java +++ b/common/src/main/java/dev/ryanhcode/sable/mixin/voxel_shape_iteration/VoxelShapeMixin.java @@ -31,6 +31,12 @@ public abstract class VoxelShapeMixin implements FastVoxelShapeIterable { @Override public Iterator sable$allBoxes() { synchronized (this) { + + if(sable$boxIterator == null) { + return null; + //This is null when this mixin is relevant to little tiles + } + final long id = Thread.currentThread().threadId(); FastVoxelShapeIterator iterator = this.sable$boxIterator.get(id); diff --git a/common/src/main/java/dev/ryanhcode/sable/sublevel/entity_collision/SubLevelEntityCollision.java b/common/src/main/java/dev/ryanhcode/sable/sublevel/entity_collision/SubLevelEntityCollision.java index fdd62eab..61e2f9dd 100644 --- a/common/src/main/java/dev/ryanhcode/sable/sublevel/entity_collision/SubLevelEntityCollision.java +++ b/common/src/main/java/dev/ryanhcode/sable/sublevel/entity_collision/SubLevelEntityCollision.java @@ -275,26 +275,29 @@ public static CollisionInfo collide(final Entity entity, final Vec3 collisionMot } final Iterator iterator = ((FastVoxelShapeIterable) voxelShape).sable$allBoxes(); - while (iterator.hasNext()) { - final BoundingBox3dc box = iterator.next(); - box.center(center); - cubeOBB.getPosition().set(block.getX() + center.x, - block.getY() + center.y, - block.getZ() + center.z); - subLevelPose.transformPosition(cubeOBB.getPosition()); - box.size(cubeOBB.getDimensions()); - - OrientedBoundingBox3d.sat(entityBoundsOBB, cubeOBB, mtv); - - if (mtv.lengthSquared() > 0.0 && mtv.x != Double.MAX_VALUE && mtv.y != Double.MAX_VALUE && mtv.z != Double.MAX_VALUE) { - final double lengthMtv = mtv.lengthSquared(); - if (lengthMtv > maxMTVLength) { - maxMTVLength = lengthMtv; - maxMTV.set(mtv); - - box.move(block.getX(), block.getY(), block.getZ(), maxAABB); - maxBlockPos.set(block); - maxBlockState = state; + //This is null when this is relevant to little tiles + if(iterator != null) { + while (iterator.hasNext()) { + final BoundingBox3dc box = iterator.next(); + box.center(center); + cubeOBB.getPosition().set(block.getX() + center.x, + block.getY() + center.y, + block.getZ() + center.z); + subLevelPose.transformPosition(cubeOBB.getPosition()); + box.size(cubeOBB.getDimensions()); + + OrientedBoundingBox3d.sat(entityBoundsOBB, cubeOBB, mtv); + + if (mtv.lengthSquared() > 0.0 && mtv.x != Double.MAX_VALUE && mtv.y != Double.MAX_VALUE && mtv.z != Double.MAX_VALUE) { + final double lengthMtv = mtv.lengthSquared(); + if (lengthMtv > maxMTVLength) { + maxMTVLength = lengthMtv; + maxMTV.set(mtv); + + box.move(block.getX(), block.getY(), block.getZ(), maxAABB); + maxBlockPos.set(block); + maxBlockState = state; + } } } } @@ -325,35 +328,38 @@ public static CollisionInfo collide(final Entity entity, final Vec3 collisionMot boolean discard = false; final Iterator iterator = ((FastVoxelShapeIterable) offsetShape).sable$allBoxes(); - while (iterator.hasNext()) { - final BoundingBox3dc box = iterator.next(); - box.move(newPos.getX(), newPos.getY(), newPos.getZ(), offsetAABB).expand(0.001); - if (!maxAABB.intersects(offsetAABB)) { - continue; - } + //This is null when this is relevant to little tiles + if(iterator != null) { + while (iterator.hasNext()) { + final BoundingBox3dc box = iterator.next(); + box.move(newPos.getX(), newPos.getY(), newPos.getZ(), offsetAABB).expand(0.001); + if (!maxAABB.intersects(offsetAABB)) { + continue; + } - compressedMinAABB.set( - maxAABB.minX * (1.0 - direction.getStepX()), - maxAABB.minY * (1.0 - direction.getStepY()), - maxAABB.minZ * (1.0 - direction.getStepZ()), - maxAABB.maxX * (1.0 - direction.getStepX()) + direction.getStepX(), - maxAABB.maxY * (1.0 - direction.getStepY()) + direction.getStepY(), - maxAABB.maxZ * (1.0 - direction.getStepZ()) + direction.getStepZ() - ); - - compressedOffsetAABB.set( - offsetAABB.minX * (1.0 - direction.getStepX()), - offsetAABB.minY * (1.0 - direction.getStepY()), - offsetAABB.minZ * (1.0 - direction.getStepZ()), - offsetAABB.maxX * (1.0 - direction.getStepX()) + direction.getStepX(), - offsetAABB.maxY * (1.0 - direction.getStepY()) + direction.getStepY(), - offsetAABB.maxZ * (1.0 - direction.getStepZ()) + direction.getStepZ() - ); - - compressedMinAABB.intersect(compressedOffsetAABB, intersection); - if (Math.abs(intersection.volume() - compressedMinAABB.volume()) < 0.01) { - discard = true; - break; + compressedMinAABB.set( + maxAABB.minX * (1.0 - direction.getStepX()), + maxAABB.minY * (1.0 - direction.getStepY()), + maxAABB.minZ * (1.0 - direction.getStepZ()), + maxAABB.maxX * (1.0 - direction.getStepX()) + direction.getStepX(), + maxAABB.maxY * (1.0 - direction.getStepY()) + direction.getStepY(), + maxAABB.maxZ * (1.0 - direction.getStepZ()) + direction.getStepZ() + ); + + compressedOffsetAABB.set( + offsetAABB.minX * (1.0 - direction.getStepX()), + offsetAABB.minY * (1.0 - direction.getStepY()), + offsetAABB.minZ * (1.0 - direction.getStepZ()), + offsetAABB.maxX * (1.0 - direction.getStepX()) + direction.getStepX(), + offsetAABB.maxY * (1.0 - direction.getStepY()) + direction.getStepY(), + offsetAABB.maxZ * (1.0 - direction.getStepZ()) + direction.getStepZ() + ); + + compressedMinAABB.intersect(compressedOffsetAABB, intersection); + if (Math.abs(intersection.volume() - compressedMinAABB.volume()) < 0.01) { + discard = true; + break; + } } } @@ -570,6 +576,8 @@ private static boolean hasCollision(final LevelAccelerator accel, final LevelReu } final Iterator iterator = ((FastVoxelShapeIterable) voxelShape).sable$allBoxes(); + //This is null when this is relevant to little tiles + if(iterator == null) return false; final Vector3d center = sink.center; final Vector3d mtv = sink.mtv; diff --git a/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/neoforge/src/main/resources/META-INF/neoforge.mods.toml index c44ee1a6..2035dc0f 100644 --- a/neoforge/src/main/resources/META-INF/neoforge.mods.toml +++ b/neoforge/src/main/resources/META-INF/neoforge.mods.toml @@ -61,7 +61,3 @@ reason = "Sable is out of date" [[dependencies.sable]] modId = "scalablelux" type = "incompatible" - -[[dependencies.sable]] -modId = "littletiles" -type = "incompatible"