|
1 | 1 | package dev.isxander.debugify.client.mixins.basic.mc176559;
|
2 | 2 |
|
3 |
| -import com.llamalad7.mixinextras.injector.ModifyReturnValue; |
| 3 | +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; |
| 4 | +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; |
4 | 5 | import dev.isxander.debugify.fixes.BugFix;
|
5 | 6 | import dev.isxander.debugify.fixes.FixCategory;
|
6 |
| -import org.spongepowered.asm.mixin.Final; |
| 7 | +import net.minecraft.core.component.PatchedDataComponentMap; |
7 | 8 | import org.spongepowered.asm.mixin.Mixin;
|
8 |
| -import org.spongepowered.asm.mixin.Shadow; |
| 9 | +import org.spongepowered.asm.mixin.Unique; |
9 | 10 | import org.spongepowered.asm.mixin.injection.At;
|
10 |
| -import org.spongepowered.asm.mixin.injection.ModifyVariable; |
11 |
| -import org.spongepowered.asm.mixin.injection.Redirect; |
12 |
| -import org.spongepowered.asm.mixin.injection.Slice; |
13 | 11 |
|
14 |
| -import java.util.HashSet; |
15 | 12 | import java.util.Objects;
|
16 |
| -import java.util.Set; |
17 |
| -import net.minecraft.client.Minecraft; |
18 | 13 | import net.minecraft.client.multiplayer.MultiPlayerGameMode;
|
19 |
| -import net.minecraft.nbt.CompoundTag; |
20 | 14 | import net.minecraft.world.item.ItemStack;
|
21 | 15 |
|
22 |
| -@BugFix(id = "MC-176559", category = FixCategory.BASIC, env = BugFix.Env.CLIENT, modConflicts = "fabric-api") |
23 |
| -@Mixin(MultiPlayerGameMode.class) |
| 16 | +@BugFix(id = "MC-176559", category = FixCategory.BASIC, env = BugFix.Env.CLIENT) |
| 17 | +@Mixin(value = MultiPlayerGameMode.class, priority = 1010) |
24 | 18 | public class MultiPlayerGameModeMixin {
|
25 |
| - @Shadow private ItemStack destroyingItem; |
26 |
| - |
27 |
| - @Shadow @Final private Minecraft minecraft; |
28 |
| - |
29 |
| - @Redirect(method = "sameDestroyTarget", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;isSameItemSameTags(Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/item/ItemStack;)Z")) |
30 |
| - private boolean isSameItem(ItemStack itemStack, ItemStack itemStack2) { |
31 |
| - return !canCauseBlockBreakReset(destroyingItem, minecraft.player.getMainHandItem()); |
| 19 | + // Fabric API also redirects here. WrapOperation is compatible |
| 20 | + @WrapOperation(method = "sameDestroyTarget", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/item/ItemStack;isSameItemSameComponents(Lnet/minecraft/world/item/ItemStack;Lnet/minecraft/world/item/ItemStack;)Z")) |
| 21 | + private boolean isSameItem(ItemStack mainHandItem, ItemStack destroyingItem, Operation<Boolean> original) { |
| 22 | + return isSameItemSameComponentsIgnoringDurability(mainHandItem, destroyingItem); |
32 | 23 | }
|
33 | 24 |
|
34 |
| - /** |
35 |
| - * Taken from <a href="https://github.com/MinecraftForge/MinecraftForge/blob/9d74a3520fa9d47db27fed74dcdd462956dd90ec/src/main/java/net/minecraftforge/common/extensions/IForgeItem.java">MinecraftForge</a> |
36 |
| - * under LGPLv2.1 license |
37 |
| - * <br> |
38 |
| - * It has been adapted into a mixin with yarn mappings for use in fabric |
39 |
| - * |
40 |
| - * @author BlueAgent |
41 |
| - */ |
42 |
| - private boolean canCauseBlockBreakReset(ItemStack oldStack, ItemStack newStack) { |
43 |
| - try { |
44 |
| - if (!newStack.is(oldStack.getItem())) |
45 |
| - return true; |
46 |
| - |
47 |
| - if (!newStack.isDamageableItem() || !oldStack.isDamageableItem()) |
48 |
| - return !ItemStack.isSameItemSameTags(newStack, oldStack); |
49 |
| - |
50 |
| - CompoundTag newTag = newStack.getTag(); |
51 |
| - CompoundTag oldTag = oldStack.getTag(); |
52 |
| - |
53 |
| - if (newTag == null || oldTag == null) |
54 |
| - return !(newTag == null && oldTag == null); |
55 |
| - |
56 |
| - Set<String> newKeys = new HashSet<>(newTag.getAllKeys()); |
57 |
| - Set<String> oldKeys = new HashSet<>(oldTag.getAllKeys()); |
58 |
| - |
59 |
| - newKeys.remove(ItemStack.TAG_DAMAGE); |
60 |
| - oldKeys.remove(ItemStack.TAG_DAMAGE); |
61 |
| - |
62 |
| - if (!newKeys.equals(oldKeys)) |
63 |
| - return true; |
64 |
| - |
65 |
| - return !newKeys.stream().allMatch(key -> Objects.equals(newTag.get(key), oldTag.get(key))); |
66 |
| - } catch (Throwable t) { |
67 |
| - t.printStackTrace(); |
| 25 | + @Unique |
| 26 | + private boolean isSameItemSameComponentsIgnoringDurability(ItemStack stack1, ItemStack stack2) { |
| 27 | + if (!stack1.is(stack2.getItem())) { |
68 | 28 | return false;
|
| 29 | + } else if (stack1.isEmpty() && stack2.isEmpty()) { |
| 30 | + return true; |
| 31 | + } else { |
| 32 | + int damage1 = stack1.getDamageValue(); |
| 33 | + int damage2 = stack2.getDamageValue(); |
| 34 | + stack1.setDamageValue(0); |
| 35 | + stack2.setDamageValue(0); |
| 36 | + |
| 37 | + PatchedDataComponentMap components1 = ((ItemStackAccessor) (Object) stack1).getComponents(); |
| 38 | + PatchedDataComponentMap components2 = ((ItemStackAccessor) (Object) stack2).getComponents(); |
| 39 | + boolean comparison = Objects.equals(components1, components2); |
| 40 | + |
| 41 | + stack1.setDamageValue(damage1); |
| 42 | + stack2.setDamageValue(damage2); |
| 43 | + |
| 44 | + return comparison; |
69 | 45 | }
|
70 |
| - |
71 | 46 | }
|
72 | 47 | }
|
0 commit comments