/* * Copyright (C) 2022 NotEnoughUpdates contributors * * This file is part of NotEnoughUpdates. * * NotEnoughUpdates is free software: you can redistribute it * and/or modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation, either * version 3 of the License, or (at your option) any later version. * * NotEnoughUpdates is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with NotEnoughUpdates. If not, see . */ package io.github.moulberry.notenoughupdates.mixins; import io.github.moulberry.notenoughupdates.NEUOverlay; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.events.DrawSlotReturnEvent; import io.github.moulberry.notenoughupdates.events.GuiContainerBackgroundDrawnEvent; import io.github.moulberry.notenoughupdates.events.IsSlotBeingHoveredEvent; import io.github.moulberry.notenoughupdates.events.SlotClickEvent; import io.github.moulberry.notenoughupdates.listener.RenderListener; import io.github.moulberry.notenoughupdates.miscfeatures.AbiphoneFavourites; import io.github.moulberry.notenoughupdates.miscfeatures.AuctionBINWarning; import io.github.moulberry.notenoughupdates.miscfeatures.AuctionSortModeWarning; import io.github.moulberry.notenoughupdates.miscfeatures.BetterContainers; import io.github.moulberry.notenoughupdates.miscfeatures.EnchantingSolvers; import io.github.moulberry.notenoughupdates.miscfeatures.PresetWarning; import io.github.moulberry.notenoughupdates.miscfeatures.SlotLocking; import io.github.moulberry.notenoughupdates.miscgui.GuiCustomEnchant; import io.github.moulberry.notenoughupdates.miscgui.StorageOverlay; import io.github.moulberry.notenoughupdates.miscgui.hex.GuiCustomHex; import io.github.moulberry.notenoughupdates.miscgui.itemcustomization.ItemCustomizeManager; import lombok.var; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Gui; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.RenderHelper; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import net.minecraftforge.common.MinecraftForge; 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.ModifyArg; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import java.util.Set; @Mixin(value = GuiContainer.class, priority = 500) public abstract class MixinGuiContainer extends GuiScreen { @Inject(method = "drawSlot", at = @At("RETURN")) public void drawSlotRet(Slot slotIn, CallbackInfo ci) { SlotLocking.getInstance().drawSlot(slotIn); new DrawSlotReturnEvent(slotIn).post(); } @Inject(method = "drawSlot", at = @At("HEAD"), cancellable = true) public void drawSlot(Slot slot, CallbackInfo ci) { if (slot == null) return; if (slot.getStack() == null && NotEnoughUpdates.INSTANCE.overlay.searchMode && RenderListener.drawingGuiScreen && NotEnoughUpdates.INSTANCE.isOnSkyblock()) { GlStateManager.pushMatrix(); GlStateManager.translate(0, 0, 100 + Minecraft.getMinecraft().getRenderItem().zLevel); GlStateManager.depthMask(false); Gui.drawRect(slot.xDisplayPosition, slot.yDisplayPosition, slot.xDisplayPosition + 16, slot.yDisplayPosition + 16, NEUOverlay.overlayColourDark ); GlStateManager.depthMask(true); GlStateManager.popMatrix(); } ItemStack stack = slot.getStack(); if (stack != null) { if (EnchantingSolvers.onStackRender( stack, slot.inventory, slot.getSlotIndex(), slot.xDisplayPosition, slot.yDisplayPosition )) { ci.cancel(); return; } if (AbiphoneFavourites.getInstance().onRenderStack(stack)) { ci.cancel(); return; } } RenderHelper.enableGUIStandardItemLighting(); if (BetterContainers.isOverriding() && !BetterContainers.shouldRenderStack(slot.slotNumber, stack)) { ci.cancel(); } } @Inject(method = "drawScreen", at = @At( value = "INVOKE", target = "Lnet/minecraft/entity/player/InventoryPlayer;getItemStack()Lnet/minecraft/item/ItemStack;", shift = At.Shift.BEFORE, ordinal = 1 ) ) public void drawScreen_after(int mouseX, int mouseY, float partialTicks, CallbackInfo ci) { AuctionSortModeWarning.getInstance().onPostGuiRender(); } @Redirect(method = "mouseReleased", at = @At(value = "INVOKE", target = "Ljava/util/Set;isEmpty()Z")) public boolean mouseReleased_isEmpty(Set set) { return set.size() <= 1; } @Inject(method = "isMouseOverSlot", at = @At("HEAD"), cancellable = true) public void isMouseOverSlot(Slot slotIn, int mouseX, int mouseY, CallbackInfoReturnable cir) { StorageOverlay.getInstance().overrideIsMouseOverSlot(slotIn, mouseX, mouseY, cir); GuiCustomEnchant.getInstance().overrideIsMouseOverSlot(slotIn, mouseX, mouseY, cir); GuiCustomHex.getInstance().overrideIsMouseOverSlot(slotIn, mouseX, mouseY, cir); AuctionBINWarning.getInstance().overrideIsMouseOverSlot(slotIn, mouseX, mouseY, cir); PresetWarning.getInstance().overrideIsMouseOverSlot(slotIn, mouseX, mouseY, cir); var event = new IsSlotBeingHoveredEvent(); MinecraftForge.EVENT_BUS.post(event); switch (event.getOverride()) { case DEFER_TO_DEFAULT: break; case IS_HOVERED: cir.setReturnValue(true); break; case IS_NOT_HOVERED: cir.setReturnValue(false); break; } } @Redirect(method = "drawScreen", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/inventory/GuiContainer;drawGradientRect(IIIIII)V")) public void drawScreen_drawGradientRect( GuiContainer container, int left, int top, int right, int bottom, int startColor, int endColor ) { if (startColor == 0x80ffffff && endColor == 0x80ffffff && theSlot != null && SlotLocking.getInstance().isSlotLocked(theSlot)) { int col = 0x80ff8080; drawGradientRect(left, top, right, bottom, col, col); } else { drawGradientRect(left, top, right, bottom, startColor, endColor); } } @Shadow private Slot theSlot; @Inject(method = "drawScreen", at = @At("RETURN")) public void drawScreen(CallbackInfo ci) { if (theSlot != null && SlotLocking.getInstance().isSlotLocked(theSlot)) { SlotLocking.getInstance().setRealSlot(theSlot); theSlot = null; } else if (theSlot == null) { SlotLocking.getInstance().setRealSlot(null); } } private static final String TARGET_GETSTACK = "Lnet/minecraft/inventory/Slot;getStack()Lnet/minecraft/item/ItemStack;"; @Redirect(method = "drawScreen", at = @At(value = "INVOKE", target = TARGET_GETSTACK)) public ItemStack drawScreen_getStack(Slot slot) { if (theSlot != null && theSlot == slot && theSlot.getStack() != null) { ItemStack newStack = EnchantingSolvers.overrideStack( theSlot.inventory, theSlot.getSlotIndex(), theSlot.getStack() ); if (newStack != null) { return newStack; } } return slot.getStack(); } @Redirect(method = "drawSlot", at = @At(value = "INVOKE", target = TARGET_GETSTACK)) public ItemStack drawSlot_getStack(Slot slot) { ItemStack stack = slot.getStack(); if (stack != null) { ItemStack newStack = EnchantingSolvers.overrideStack(slot.inventory, slot.getSlotIndex(), stack); if (newStack != null) { stack = newStack; } } return stack; } private static final String TARGET_CANBEHOVERED = "Lnet/minecraft/inventory/Slot;canBeHovered()Z"; @Redirect(method = "drawScreen", at = @At(value = "INVOKE", target = TARGET_CANBEHOVERED)) public boolean drawScreen_canBeHovered(Slot slot) { if ((NotEnoughUpdates.INSTANCE.config.improvedSBMenu.hideEmptyPanes && BetterContainers.isOverriding() && BetterContainers.isBlankStack(slot.slotNumber, slot.getStack())) || slot.getStack() != null && slot.getStack().hasTagCompound() && slot.getStack().getTagCompound().getBoolean("NEUHIDETOOLIP")) { return false; } return slot.canBeHovered(); } @Inject(method = "checkHotbarKeys", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/inventory/GuiContainer;handleMouseClick(Lnet/minecraft/inventory/Slot;III)V"), locals = LocalCapture.CAPTURE_FAILSOFT, cancellable = true) public void checkHotbarKeys_Slotlock(int keyCode, CallbackInfoReturnable cir, int i) { if (SlotLocking.getInstance().isSlotIndexLocked(i)) { cir.setReturnValue(false); } } @Inject(method = "handleMouseClick", at = @At(value = "HEAD"), cancellable = true) public void handleMouseClick(Slot slotIn, int slotId, int clickedButton, int clickType, CallbackInfo ci) { if (slotIn == null) return; GuiContainer $this = (GuiContainer) (Object) this; SlotClickEvent event = new SlotClickEvent($this, slotIn, slotId, clickedButton, clickType); event.post(); if (event.isCanceled()) { ci.cancel(); return; } if (event.usePickblockInstead) { $this.mc.playerController.windowClick( $this.inventorySlots.windowId, slotId, 2, 3, $this.mc.thePlayer ); ci.cancel(); } } @Inject(method = "drawScreen", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/GlStateManager;color(FFFF)V", ordinal = 1)) private void drawBackground(int mouseX, int mouseY, float partialTicks, CallbackInfo ci) { new GuiContainerBackgroundDrawnEvent(((GuiContainer) (Object) this), partialTicks).post(); } @ModifyArg(method = "drawSlot", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/entity/RenderItem;renderItemAndEffectIntoGUI(Lnet/minecraft/item/ItemStack;II)V", ordinal = 0)) public ItemStack drawSlot_renderItemAndEffectIntoGUI(ItemStack stack) { return ItemCustomizeManager.useCustomItem(stack); } @ModifyArg(method = "drawSlot", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/entity/RenderItem;renderItemOverlayIntoGUI(Lnet/minecraft/client/gui/FontRenderer;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V")) public ItemStack drawSlot_renderItemOverlays(ItemStack stack) { return ItemCustomizeManager.useCustomItem(stack); } }