package codechicken.nei.handler; import codechicken.lib.gui.GuiDraw; import codechicken.lib.math.MathHelper; import codechicken.lib.render.state.GlStateTracker; import codechicken.nei.config.KeyBindings; import codechicken.nei.guihook.IContainerDrawHandler; import codechicken.nei.guihook.IContainerObjectHandler; import codechicken.nei.guihook.IContainerTooltipHandler; import codechicken.nei.guihook.IInputHandler; import codechicken.nei.network.NEIClientPacketHandler; import codechicken.nei.util.helper.GuiHelper; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import net.minecraftforge.client.event.GuiContainerEvent; import net.minecraftforge.client.event.GuiOpenEvent; import net.minecraftforge.client.event.GuiScreenEvent; import net.minecraftforge.client.event.GuiScreenEvent.DrawScreenEvent; import net.minecraftforge.client.event.GuiScreenEvent.KeyboardInputEvent; import net.minecraftforge.client.event.GuiScreenEvent.MouseInputEvent; import net.minecraftforge.client.event.GuiScreenEvent.PotionShiftEvent; import net.minecraftforge.client.event.RenderTooltipEvent; import net.minecraftforge.event.entity.player.ItemTooltipEvent; import net.minecraftforge.fml.common.eventhandler.EventPriority; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; import net.minecraftforge.fml.common.gameevent.TickEvent.Phase; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import org.apache.commons.lang3.tuple.Triple; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; import java.awt.*; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import static codechicken.nei.NEIClientConfig.canPerformAction; /** * Created by covers1624 on 29/03/2017. */ @SideOnly (Side.CLIENT) public class NEIClientEventHandler { public static NEIClientEventHandler INSTANCE = new NEIClientEventHandler(); public static final LinkedList<IInputHandler> inputHandlers = new LinkedList<>(); public static final LinkedList<IContainerObjectHandler> objectHandlers = new LinkedList<>(); public static final LinkedList<IContainerDrawHandler> drawHandlers = new LinkedList<>(); public static final LinkedList<IContainerTooltipHandler> tooltipHandlers = new LinkedList<>(); private static List<IContainerTooltipHandler> instanceTooltipHandlers; private static GuiScreen lastGui; /** * Register a new Input handler; * * @param handler The handler to register */ public static void addInputHandler(IInputHandler handler) { inputHandlers.add(handler); } /** * Register a new Tooltip render handler; * * @param handler The handler to register */ public static void addTooltipHandler(IContainerTooltipHandler handler) { tooltipHandlers.add(handler); } /** * Register a new Drawing handler; * * @param handler The handler to register */ public static void addDrawHandler(IContainerDrawHandler handler) { drawHandlers.add(handler); } /** * Register a new Object handler; * * @param handler The handler to register */ public static void addObjectHandler(IContainerObjectHandler handler) { objectHandlers.add(handler); } private NEIClientEventHandler() { } public void init() { } @SubscribeEvent (priority = EventPriority.HIGHEST) public void onKeyTypedPre(KeyboardInputEvent.Pre event) { GuiScreen gui = event.getGui(); if (gui instanceof GuiContainer) { char c = Keyboard.getEventCharacter(); int eventKey = Keyboard.getEventKey(); if (eventKey == 0 && c >= 32 || Keyboard.getEventKeyState()) { //TODO, do we want canceled events to appear here? inputHandlers.forEach(handler -> handler.onKeyTyped(gui, c, eventKey)); for (IInputHandler handler : inputHandlers) { if (handler.keyTyped(gui, c, eventKey)) { event.setCanceled(true); return; } } } } } @SubscribeEvent public void onKeyTypedPost(KeyboardInputEvent.Post event) { GuiScreen gui = event.getGui(); if (gui instanceof GuiContainer) { char c = Keyboard.getEventCharacter(); int eventKey = Keyboard.getEventKey(); if (eventKey == 0 && c >= 32 || Keyboard.getEventKeyState()) { if (eventKey != 1) { for (IInputHandler inputhander : inputHandlers) { if (inputhander.lastKeyTyped(gui, c, eventKey)) { event.setCanceled(true); return; } } } if (KeyBindings.get("nei.options.keys.gui.enchant").isActiveAndMatches(eventKey) && canPerformAction("enchant")) { NEIClientPacketHandler.sendOpenEnchantmentWindow(); event.setCanceled(true); } if (KeyBindings.get("nei.options.keys.gui.potion").isActiveAndMatches(eventKey) && canPerformAction("potion")) { NEIClientPacketHandler.sendOpenPotionWindow(); event.setCanceled(true); } } } } @SubscribeEvent (priority = EventPriority.HIGHEST)//TODO, DragN'Drop isn't working properly. public void onMouseEventPre(MouseInputEvent.Pre event) { GuiScreen gui = event.getGui(); if (gui instanceof GuiContainer) { Point mousePos = GuiDraw.getMousePosition(); int mouseButton = Mouse.getEventButton(); if (Mouse.getEventButtonState()) { gui.lastMouseEvent = Minecraft.getSystemTime(); inputHandlers.forEach(handler -> handler.onMouseClicked(gui, mousePos.x, mousePos.y, mouseButton)); for (IInputHandler handler : inputHandlers) { if (handler.mouseClicked(gui, mousePos.x, mousePos.y, mouseButton)) { event.setCanceled(true); return; } } } else if (mouseButton != -1) { inputHandlers.forEach(handler -> handler.onMouseUp(gui, mousePos.x, mousePos.y, mouseButton)); } else if (mouseButton != -1 && gui.lastMouseEvent > 0) { long heldTime = Minecraft.getSystemTime() - gui.lastMouseEvent; inputHandlers.forEach(handler -> handler.onMouseDragged(gui, mousePos.x, mousePos.y, mouseButton, heldTime)); } } } @SubscribeEvent public void onMouseEventPost(MouseInputEvent.Post event) { GuiScreen gui = event.getGui(); if (gui instanceof GuiContainer) { Point mousePos = GuiDraw.getMousePosition(); if (Mouse.getEventButtonState()) { int mouseButton = Mouse.getEventButton(); inputHandlers.forEach(handler -> handler.onMouseClickedPost(gui, mousePos.x, mousePos.y, mouseButton)); } int i = Mouse.getDWheel(); if (i != 0) { int scrolled = i > 0 ? 1 : -1; for (IInputHandler handler : inputHandlers) { if (handler.mouseScrolled(gui, mousePos.x, mousePos.y, scrolled)) { event.setCanceled(true); return; } } } } } @SubscribeEvent public void potionShiftEvent(PotionShiftEvent event) { event.setCanceled(true); } @SubscribeEvent public void containerInitEvent(GuiScreenEvent.InitGuiEvent.Pre event) { if (event.getGui() instanceof GuiContainer) { GuiContainer container = (GuiContainer) event.getGui(); objectHandlers.forEach(handler -> handler.load(container)); } } @SubscribeEvent public void guiOpenEvent(GuiOpenEvent event) { if (event.getGui() instanceof GuiContainer) { if (lastGui != event.getGui()) { if (event.getGui() == null) { instanceTooltipHandlers = null; } else { instanceTooltipHandlers = new LinkedList<>(); if (event.getGui() instanceof IContainerTooltipHandler) { instanceTooltipHandlers.add((IContainerTooltipHandler) event.getGui()); } instanceTooltipHandlers.addAll(tooltipHandlers); } lastGui = event.getGui(); } } } @SubscribeEvent public void clientTickEvent(TickEvent.ClientTickEvent event) { if (event.phase == Phase.START) { Minecraft minecraft = Minecraft.getMinecraft(); if (minecraft.currentScreen instanceof GuiContainer) { objectHandlers.forEach(handler -> handler.guiTick((GuiContainer) minecraft.currentScreen)); } } } @SubscribeEvent public void drawScreenPost(DrawScreenEvent.Post event) { GuiScreen screen = event.getGui(); Point mousePos = GuiDraw.getMousePosition(); List<String> tooltip = new LinkedList<>(); ItemStack stack = ItemStack.EMPTY; if (instanceTooltipHandlers != null) { instanceTooltipHandlers.forEach(handler -> handler.handleTooltip(screen, mousePos.x, mousePos.y, tooltip)); } if (screen instanceof GuiContainer) { if (tooltip.isEmpty() && GuiHelper.shouldShowTooltip(screen)) { GuiContainer container = (GuiContainer) screen; stack = GuiHelper.getStackMouseOver(container, false); if (!stack.isEmpty()) { tooltip.clear(); tooltip.addAll(GuiHelper.itemDisplayNameMultiline(stack, container, false)); } } } GuiDraw.drawMultiLineTip(stack, mousePos.x + 10, mousePos.y - 12, tooltip); } @SubscribeEvent public void foregroundRenderEvent(GuiContainerEvent.DrawForeground event) { GuiContainer container = event.getGuiContainer(); GlStateTracker.pushState(); Point mousePos = GuiDraw.getMousePosition(); GlStateManager.translate(-container.getGuiLeft(), -container.getGuiTop(), 100F); drawHandlers.forEach(handler -> handler.renderObjects(container, mousePos.x, mousePos.y)); drawHandlers.forEach(handler -> handler.postRenderObjects(container, mousePos.x, mousePos.y)); GlStateManager.translate(container.getGuiLeft(), container.getGuiTop(), -100F); GuiHelper.enable3DRender(); GlStateManager.pushMatrix(); for (Slot slot : container.inventorySlots.inventorySlots) { GlStateTracker.pushState(); drawHandlers.forEach(handler -> handler.renderSlotOverlay(container, slot)); GlStateTracker.popState(); } GlStateManager.popMatrix(); GlStateTracker.popState(); } @SubscribeEvent public void tooltipPreEvent(RenderTooltipEvent.Pre event) { event.setY(MathHelper.clip(event.getY(), 8, event.getScreenHeight() - 8)); } @SubscribeEvent public void itemTooltipEvent(ItemTooltipEvent event) { if (instanceTooltipHandlers != null && Minecraft.getMinecraft().currentScreen != null) { GuiScreen screen = Minecraft.getMinecraft().currentScreen; instanceTooltipHandlers.forEach(handler -> handler.handleItemDisplayName(screen, event.getItemStack(), event.getToolTip())); } } }