|
| 1 | +package dev.isxander.debugify.mixins.basic.mc263999; |
| 2 | + |
| 3 | +import com.llamalad7.mixinextras.expression.Definition; |
| 4 | +import com.llamalad7.mixinextras.expression.Expression; |
| 5 | +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; |
| 6 | +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; |
| 7 | +import com.llamalad7.mixinextras.sugar.Share; |
| 8 | +import com.llamalad7.mixinextras.sugar.ref.LocalRef; |
| 9 | +import dev.isxander.debugify.fixes.BugFix; |
| 10 | +import dev.isxander.debugify.fixes.FixCategory; |
| 11 | +import net.minecraft.core.BlockPos; |
| 12 | +import net.minecraft.world.entity.Mob; |
| 13 | +import net.minecraft.world.entity.ai.goal.BreakDoorGoal; |
| 14 | +import net.minecraft.world.entity.ai.goal.DoorInteractGoal; |
| 15 | +import net.minecraft.world.level.Level; |
| 16 | +import net.minecraft.world.level.block.state.BlockState; |
| 17 | +import org.spongepowered.asm.mixin.Mixin; |
| 18 | +import org.spongepowered.asm.mixin.injection.At; |
| 19 | +import org.spongepowered.asm.mixin.injection.Inject; |
| 20 | +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; |
| 21 | + |
| 22 | +/** |
| 23 | + * removeBlock is called before querying the block state of the door, |
| 24 | + * which breaks the level event that causes particles |
| 25 | + */ |
| 26 | +@BugFix(id = "MC-263999", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "Zombies breaking doors do not show break particles") |
| 27 | +@Mixin(BreakDoorGoal.class) |
| 28 | +public class BreakDoorGoalMixin extends DoorInteractGoal { |
| 29 | + public BreakDoorGoalMixin(Mob mob) { |
| 30 | + super(mob); |
| 31 | + } |
| 32 | + |
| 33 | + // Store the block state before removal |
| 34 | + @Inject(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/Level;removeBlock(Lnet/minecraft/core/BlockPos;Z)Z")) |
| 35 | + private void storeBlockStatePreRemoval(CallbackInfo ci, @Share("blockState") LocalRef<BlockState> blockStateRef) { |
| 36 | + blockStateRef.set(this.mob.level().getBlockState(this.doorPos)); |
| 37 | + } |
| 38 | + |
| 39 | + // Use the stored block state for the level event |
| 40 | + @Definition(id = "levelEvent", method = "Lnet/minecraft/world/level/Level;levelEvent(ILnet/minecraft/core/BlockPos;I)V") |
| 41 | + @Definition(id = "getId", method = "Lnet/minecraft/world/level/block/Block;getId(Lnet/minecraft/world/level/block/state/BlockState;)I") |
| 42 | + @Definition(id = "getBlockState", method = "Lnet/minecraft/world/level/Level;getBlockState(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/level/block/state/BlockState;") |
| 43 | + @Definition(id = "doorPos", field = "Lnet/minecraft/world/entity/ai/goal/BreakDoorGoal;doorPos:Lnet/minecraft/core/BlockPos;") |
| 44 | + @Expression("?.levelEvent(2001, ?, getId(@(?.getBlockState(?.doorPos))))") |
| 45 | + @WrapOperation(method = "tick", at = @At("MIXINEXTRAS:EXPRESSION")) |
| 46 | + private BlockState injectCorrectBlockState(Level instance, BlockPos pos, Operation<BlockState> original, @Share("blockState") LocalRef<BlockState> blockStateRef) { |
| 47 | + return blockStateRef.get(); |
| 48 | + } |
| 49 | +} |
0 commit comments