From 1dd88d2b5d92f4ae3bbd0b235fb36f9d98d2bef6 Mon Sep 17 00:00:00 2001 From: WenXin2 Date: Wed, 1 Jan 2025 14:33:12 -0600 Subject: [PATCH] Fix suffocation with small hitbox --- .../wenxin2/marioverse/mixin/EntityMixin.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/main/java/com/wenxin2/marioverse/mixin/EntityMixin.java b/src/main/java/com/wenxin2/marioverse/mixin/EntityMixin.java index 6143b2b1..e30cf33b 100644 --- a/src/main/java/com/wenxin2/marioverse/mixin/EntityMixin.java +++ b/src/main/java/com/wenxin2/marioverse/mixin/EntityMixin.java @@ -24,6 +24,8 @@ import net.minecraft.world.level.block.state.properties.DoubleBlockHalf; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; +import net.minecraft.world.phys.shapes.BooleanOp; +import net.minecraft.world.phys.shapes.Shapes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; @@ -176,6 +178,42 @@ private void getBbWidth(CallbackInfoReturnable cir) { } } + @Inject(method = "isInWall", at = @At("HEAD"), cancellable = true) + public void modifyIsInWall(CallbackInfoReturnable cir) { + Entity entity = (Entity) (Object) this; + if (entity.noPhysics) { + cir.setReturnValue(false); + return; + } + + if (entity instanceof LivingEntity livingEntity) { + AttributeMap attributeMap = livingEntity.getAttributes(); + if (attributeMap != null) { + float widthScale = (float) attributeMap.getValue(AttributesRegistry.WIDTH_SCALE); + + if (widthScale != 1.0F) { + float scaledWidth = entity.getDimensions(entity.getPose()).width() * 0.8F * widthScale; + AABB aabb = AABB.ofSize(entity.getEyePosition(), scaledWidth, 1.0E-6, scaledWidth); + + boolean isInWall = BlockPos.betweenClosedStream(aabb) + .anyMatch( + pos -> { + BlockState blockState = entity.level().getBlockState(pos); + return !blockState.isAir() + && blockState.isSuffocating(entity.level(), pos) + && Shapes.joinIsNotEmpty( + blockState.getCollisionShape(entity.level(), pos) + .move(pos.getX(), pos.getY(), pos.getZ()), + Shapes.create(aabb), BooleanOp.AND + ); + } + ); + cir.setReturnValue(isInWall); + } else cir.setReturnValue(cir.getReturnValue()); + } + } + } + @Unique public int marioverse$getWarpCooldown() { return marioverse$warpCooldown;