diff --git a/src/main/java/de/hysky/skyblocker/mixins/AbstractContainerMenuMixin.java b/src/main/java/de/hysky/skyblocker/mixins/AbstractContainerMenuMixin.java index e307c8dc7ef..c274e934315 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/AbstractContainerMenuMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/AbstractContainerMenuMixin.java @@ -1,21 +1,64 @@ package de.hysky.skyblocker.mixins; +import de.hysky.skyblocker.skyblock.item.ItemStackUpdateDurability; import de.hysky.skyblocker.skyblock.InventorySearch; import de.hysky.skyblocker.skyblock.ItemPickupWidget; +import net.minecraft.core.NonNullList; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.ClickType; +import net.minecraft.world.inventory.Slot; import net.minecraft.world.item.ItemStack; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import java.util.List; + @Mixin(AbstractContainerMenu.class) -public class AbstractContainerMenuMixin { +public abstract class AbstractContainerMenuMixin { + @Shadow + @Final + public NonNullList slots; + + @Shadow + private ItemStack carried; + + /// When the server creates or updates the entire menu + @Inject(method = "initializeContents", at = @At("TAIL")) + private void skyblocker$initializeContents(int stateId, List list, ItemStack itemStack, CallbackInfo ci) { + for (int j = 0; j < list.size(); j++) { + ((ItemStackUpdateDurability) (Object) this.slots.get(j).getItem()).skyblocker$getAndCacheDurability(); + if (InventorySearch.isSearching()) { + InventorySearch.refreshSlot(j); + } + } + ((ItemStackUpdateDurability) (Object) this.carried).skyblocker$getAndCacheDurability(); + } + + /// When the player clicks + @Inject(method = "doClick", at = @At("TAIL")) + private void skyblocker$doClick(int i, int j, ClickType clickType, Player player, CallbackInfo ci) { + // I'm way too lazy to figure how to only update the slots that were moved, soo... + for (int k = 0; k < this.slots.size(); k++) { + ((ItemStackUpdateDurability) (Object) this.slots.get(k).getItem()).skyblocker$getAndCacheDurability(); + if (InventorySearch.isSearching()) { + InventorySearch.refreshSlot(k); + } + } + ((ItemStackUpdateDurability) (Object) this.carried).skyblocker$getAndCacheDurability(); + } + + /// When the server updates a single item @Inject(method = "setItem", at = @At("HEAD")) private void onSetStackInSlot(int slot, int revision, ItemStack stack, CallbackInfo ci) { if (InventorySearch.isSearching()) { InventorySearch.refreshSlot(slot); } ItemPickupWidget.getInstance().onItemPickup(slot, stack); + ((ItemStackUpdateDurability) (Object) stack).skyblocker$getAndCacheDurability(); } } diff --git a/src/main/java/de/hysky/skyblocker/mixins/ItemStackMixin.java b/src/main/java/de/hysky/skyblocker/mixins/ItemStackMixin.java index 0295d954efd..85051393067 100644 --- a/src/main/java/de/hysky/skyblocker/mixins/ItemStackMixin.java +++ b/src/main/java/de/hysky/skyblocker/mixins/ItemStackMixin.java @@ -4,6 +4,7 @@ import com.llamalad7.mixinextras.injector.ModifyReturnValue; import com.llamalad7.mixinextras.sugar.Local; import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.skyblock.item.ItemStackUpdateDurability; import de.hysky.skyblocker.injected.SkyblockerStack; import de.hysky.skyblocker.skyblock.item.PetInfo; import de.hysky.skyblocker.skyblock.item.SkyblockItemRarity; @@ -35,7 +36,7 @@ import net.minecraft.world.item.enchantment.ItemEnchantments; @Mixin(ItemStack.class) -public abstract class ItemStackMixin implements DataComponentHolder, SkyblockerStack { +public abstract class ItemStackMixin implements DataComponentHolder, SkyblockerStack, ItemStackUpdateDurability { @Unique private float durabilityBarFill = -1; @@ -88,14 +89,6 @@ public abstract class ItemStackMixin implements DataComponentHolder, SkyblockerS } } - /** - * Updates the durability of this item stack every tick when in the inventory. - */ - @Inject(method = "inventoryTick", at = @At("TAIL")) - private void skyblocker$updateDamage(CallbackInfo ci) { - skyblocker$getAndCacheDurability(); - } - @ModifyReturnValue(method = "isBarVisible", at = @At("RETURN")) private boolean modifyItemBarVisible(boolean original) { return original || durabilityBarFill >= 0f; @@ -111,11 +104,6 @@ private int modifyItemBarColor(int original) { return durabilityBarFill >= 0 ? OkLabColor.interpolate(CommonColors.RED, CommonColors.GREEN, durabilityBarFill) : original; } - @Inject(method = "(Lnet/minecraft/world/level/ItemLike;ILnet/minecraft/core/component/PatchedDataComponentMap;)V", at = @At("TAIL")) - private void onInit(CallbackInfo ci) { - skyblocker$getAndCacheDurability(); - } - @Inject(method = "set*", at = @At("TAIL")) private void skyblocker$resetFields(DataComponentType type, @Nullable T value, CallbackInfoReturnable cir) { if (type == DataComponents.CUSTOM_DATA) { @@ -137,7 +125,8 @@ private void onInit(CallbackInfo ci) { } @Unique - private void skyblocker$getAndCacheDurability() { + @Override + public void skyblocker$getAndCacheDurability() { if (!skyblocker$shouldProcess()) { durabilityBarFill = -1; return; diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/ItemStackUpdateDurability.java b/src/main/java/de/hysky/skyblocker/skyblock/item/ItemStackUpdateDurability.java new file mode 100644 index 00000000000..5cf9cb0128f --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/item/ItemStackUpdateDurability.java @@ -0,0 +1,5 @@ +package de.hysky.skyblocker.skyblock.item; + +public interface ItemStackUpdateDurability { + void skyblocker$getAndCacheDurability(); +}