diff --git a/src/main/java/dev/isxander/debugify/mixins/basic/mc168573/BlocksAttacksMixin.java b/src/main/java/dev/isxander/debugify/mixins/basic/mc168573/BlocksAttacksMixin.java index 9033b3c4..299d2135 100644 --- a/src/main/java/dev/isxander/debugify/mixins/basic/mc168573/BlocksAttacksMixin.java +++ b/src/main/java/dev/isxander/debugify/mixins/basic/mc168573/BlocksAttacksMixin.java @@ -1,22 +1,28 @@ package dev.isxander.debugify.mixins.basic.mc168573; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.llamalad7.mixinextras.sugar.Local; import dev.isxander.debugify.fixes.BugFix; import dev.isxander.debugify.fixes.FixCategory; -import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.component.BlocksAttacks; -import net.minecraft.world.level.Level; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @BugFix(id = "MC-168573", category = FixCategory.BASIC, env = BugFix.Env.SERVER, description = "After breaking a shield, the player's off-hand can't finish using some items") @Mixin(BlocksAttacks.class) public class BlocksAttacksMixin { - @Inject(method = "hurtBlockingItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;hurtAndBreak(ILnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/world/entity/EquipmentSlot;)V")) - private void fixShieldBreakItemUse(Level level, ItemStack itemStack, LivingEntity livingEntity, InteractionHand interactionHand, float f, CallbackInfo ci) { - livingEntity.stopUsingItem(); + /** + * We need to check if the shield is going to break and only stop using the item after it is broken. + * We can't use isBroken here, so instead we check if the next damage will break the blockable, then do the damage call after. + */ + @WrapOperation(method = "hurtBlockingItem", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;hurtAndBreak(ILnet/minecraft/world/entity/LivingEntity;Lnet/minecraft/world/entity/EquipmentSlot;)V")) + private void fixShieldBreakItemUse(ItemStack instance, int amount, LivingEntity entity, EquipmentSlot slot, Operation original, @Local(argsOnly = true) ItemStack stack) { + boolean isBroken = stack.nextDamageWillBreak(); + original.call(instance, amount, entity, slot); + if (isBroken) entity.stopUsingItem(); } }