From 6911379669057f6691272f52dc983b770fd5dc97 Mon Sep 17 00:00:00 2001 From: EZForever <34133756+EZForever@users.noreply.github.com> Date: Sun, 17 May 2026 21:08:00 +0800 Subject: [PATCH] Change explosion calculation to be ray-based --- .../sable/mixin/explosion/ExplosionMixin.java | 68 +++++++------------ 1 file changed, 25 insertions(+), 43 deletions(-) diff --git a/common/src/main/java/dev/ryanhcode/sable/mixin/explosion/ExplosionMixin.java b/common/src/main/java/dev/ryanhcode/sable/mixin/explosion/ExplosionMixin.java index fb39b261..43e8f8b2 100644 --- a/common/src/main/java/dev/ryanhcode/sable/mixin/explosion/ExplosionMixin.java +++ b/common/src/main/java/dev/ryanhcode/sable/mixin/explosion/ExplosionMixin.java @@ -102,53 +102,35 @@ public class ExplosionMixin { for (final SubLevel subLevel : subLevels) { final Pose3d pose = subLevel.logicalPose(); + final Vec3 localRayPosition = pose.transformPositionInverse(new Vec3(d4, d6, d8)); + final Vec3 localExplosionPosition = pose.transformPositionInverse(new Vec3(this.x, this.y, this.z)); - final BoundingBox3d localBounds = new BoundingBox3d(); - globalBounds.transformInverse(pose, localBounds); + blockpos = BlockPos.containing(localRayPosition); + blockstate = this.level.getBlockState(blockpos); + fluidstate = this.level.getFluidState(blockpos); - final BoundingBox3i blockBounds = new BoundingBox3i( - Mth.floor(localBounds.minX()), - Mth.floor(localBounds.minY()), - Mth.floor(localBounds.minZ()), - Mth.floor(localBounds.maxX()), - Mth.floor(localBounds.maxY()), - Mth.floor(localBounds.maxZ()) - ); + final boolean canExplodeBefore = f > 0.0; - final Vec3 localExplosionPosition = pose.transformPositionInverse(new Vec3(this.x, this.y, this.z)); + final Optional optional = this.damageCalculator.getBlockExplosionResistance(self, this.level, blockpos, blockstate, fluidstate); + if (optional.isPresent()) { + f -= (optional.get() + 0.3F) * 0.3F; + } + + if (f > 0.0F && this.damageCalculator.shouldBlockExplode(self, this.level, blockpos, blockstate, f)) { + set.add(blockpos); + } + + final boolean wind = this.source instanceof AbstractWindCharge && !blockstate.isAir(); + if (canExplodeBefore && (f < 0.0f || wind) && explodedSet.get().add(blockpos)) { + explodedSet.get().add(blockpos); + + if (subLevel instanceof final ServerSubLevel serverSubLevel) { + final SubLevelPhysicsSystem physicsSystem = ((ServerSubLevelContainer) container).physicsSystem(); + final RigidBodyHandle handle = physicsSystem.getPhysicsHandle(serverSubLevel); - for (int x = blockBounds.minX(); x <= blockBounds.maxX(); x++) { - for (int z = blockBounds.minZ(); z <= blockBounds.maxZ(); z++) { - for (int y = blockBounds.minY(); y <= blockBounds.maxY(); y++) { - blockpos = new BlockPos(x, y, z); - blockstate = this.level.getBlockState(blockpos); - fluidstate = this.level.getFluidState(blockpos); - - final boolean canExplodeBefore = f > 0.0; - - final Optional optional = this.damageCalculator.getBlockExplosionResistance(self, this.level, blockpos, blockstate, fluidstate); - if (optional.isPresent()) { - f -= (optional.get() + 0.3F) * 0.3F; - } - - if (f > 0.0F && this.damageCalculator.shouldBlockExplode(self, this.level, blockpos, blockstate, f)) { - set.add(blockpos); - } - - final boolean wind = this.source instanceof AbstractWindCharge && !blockstate.isAir(); - if (canExplodeBefore && (f < 0.0f || wind) && explodedSet.get().add(blockpos)) { - explodedSet.get().add(blockpos); - - if (subLevel instanceof final ServerSubLevel serverSubLevel) { - final SubLevelPhysicsSystem physicsSystem = ((ServerSubLevelContainer) container).physicsSystem(); - final RigidBodyHandle handle = physicsSystem.getPhysicsHandle(serverSubLevel); - - final Vec3 pos = blockpos.getCenter(); - final Vec3 force = pos.subtract(localExplosionPosition).normalize().scale(5.0); - handle.applyImpulseAtPoint(pos, force); - } - } - } + final Vec3 pos = blockpos.getCenter(); + final Vec3 force = pos.subtract(localExplosionPosition).normalize().scale(5.0); + handle.applyImpulseAtPoint(pos, force); } } }