diff --git a/README.md b/README.md index 8ec5676b..b7ecebe0 100644 --- a/README.md +++ b/README.md @@ -27,13 +27,6 @@ If you have issues with NEI outside of the GTNH modpack you may report them in t * Remove TMI style * Removed inventory Load/Save state -## Development -Before launching, you need to add -``` --Dfml.coreMods.load=codechicken.nei.asm.NEICorePlugin -``` -as a command line argument to the VM. - ## License GTNH Modifications Copyright (c) 2019-2022 mitchej123 and the GTNH Team diff --git a/settings.gradle b/settings.gradle index 01ea5f12..57484daf 100644 --- a/settings.gradle +++ b/settings.gradle @@ -26,3 +26,6 @@ blowdryerSetup { github('GTNewHorizons/ExampleMod1.7.10', 'tag', '0.2.0') //devLocal '.' // Use this when testing config updates locally } + +rootProject.name = "NotEnoughItems" + diff --git a/src/main/java/codechicken/nei/BookmarkPanel.java b/src/main/java/codechicken/nei/BookmarkPanel.java index 0b4671b2..71198783 100644 --- a/src/main/java/codechicken/nei/BookmarkPanel.java +++ b/src/main/java/codechicken/nei/BookmarkPanel.java @@ -84,6 +84,10 @@ public class BookmarkPanel extends PanelWidget { protected boolean[] todoSpaces; protected int todoItemsCount = 0; + public BookmarkGrid() { + this.setShowRecipeTooltips(true); + } + public void setViewMode(BookmarkViewMode mode) { if (viewMode == mode) { return; @@ -464,7 +468,7 @@ public class BookmarkPanel extends PanelWidget { final ItemStack normalizedA = StackInfo.loadFromNBT(nbTagA); BookmarkRecipeId recipeId = null; - if (handlerName != "" && ingredients != null && !ingredients.isEmpty()) { + if (handlerName != "" && ingredients != null) { recipeId = new BookmarkRecipeId(handlerName, ingredients); } @@ -474,7 +478,7 @@ public class BookmarkPanel extends PanelWidget { BGrid.removeRecipe(idx, saveIngredients); } else { - if (saveIngredients && handlerName != "" && ingredients != null && !ingredients.isEmpty()) { + if (saveIngredients && handlerName != "" && ingredients != null) { final Map unique = new HashMap<>(); final ArrayList sorted = new ArrayList<>(); diff --git a/src/main/java/codechicken/nei/ItemsGrid.java b/src/main/java/codechicken/nei/ItemsGrid.java index 8da187c0..7ed8c055 100644 --- a/src/main/java/codechicken/nei/ItemsGrid.java +++ b/src/main/java/codechicken/nei/ItemsGrid.java @@ -1,19 +1,24 @@ package codechicken.nei; import static codechicken.lib.gui.GuiDraw.drawRect; +import static codechicken.lib.gui.GuiDraw.getMousePosition; +import java.awt.Point; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import javax.annotation.Nullable; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.shader.Framebuffer; +import net.minecraft.inventory.Slot; import net.minecraft.item.ItemStack; import org.lwjgl.opengl.GL11; @@ -22,6 +27,9 @@ import codechicken.lib.vec.Rectangle4i; import codechicken.nei.ItemPanel.ItemPanelSlot; import codechicken.nei.api.GuiInfo; import codechicken.nei.guihook.GuiContainerManager; +import codechicken.nei.recipe.BookmarkRecipeId; +import codechicken.nei.recipe.GuiCraftingRecipe; +import codechicken.nei.recipe.GuiRecipe; import codechicken.nei.recipe.StackInfo; public class ItemsGrid { @@ -43,6 +51,7 @@ public class ItemsGrid { protected int rows; protected int columns; + protected boolean showRecipeTooltips = false; protected boolean[] invalidSlotMap; @@ -150,6 +159,10 @@ public class ItemsGrid { refreshBuffer = true; } + public void setShowRecipeTooltips(boolean show) { + this.showRecipeTooltips = show; + } + public void refresh(GuiContainer gui) { updateGuiOverlapSlots(gui); shiftPage(0); @@ -244,6 +257,116 @@ public class ItemsGrid { } } + private int recipeTooltipSlotIdx = -1; + private int recipeTooltipLines = 2; + private Runnable recipeTooltipUpdater = null; + private GuiRecipe recipeTooltipGui = null; + + public void update() { + if (recipeTooltipUpdater != null) { + recipeTooltipUpdater.run(); + recipeTooltipUpdater = null; + } + if (recipeTooltipGui != null) { + recipeTooltipGui.updateAsTooltip(); + } + } + + private static List listOrEmptyList(final List listOrNull) { + return listOrNull == null ? Collections.emptyList() : listOrNull; + } + + private void drawRecipeTooltip(int mousex, int mousey, List itemTooltip) { + final Minecraft mc = Minecraft.getMinecraft(); + ItemPanelSlot focused = getSlotMouseOver(mousex, mousey); + if (focused == null) { + recipeTooltipSlotIdx = -1; + recipeTooltipGui = null; + return; + } + final List mask = getMask(); + + int slotIdx = -1; + for (int i = 0; i < mask.size(); i++) { + if (mask.get(i) == null) { + continue; + } + if (focused.slotIndex != mask.get(i)) { + continue; + } + slotIdx = i; + break; + } + if (slotIdx == -1) { + recipeTooltipSlotIdx = -1; + recipeTooltipGui = null; + return; + } + + final Point mouseover = getMousePosition(); + final ItemPanelSlot panelSlot = ItemPanels.bookmarkPanel.getSlotMouseOver(mouseover.x, mouseover.y); + final BookmarkRecipeId recipeId; + if (panelSlot != null) { + recipeId = ItemPanels.bookmarkPanel.getBookmarkRecipeId(panelSlot.slotIndex); + } else { + recipeId = ItemPanels.bookmarkPanel.getBookmarkRecipeId(focused.item); + } + if (recipeId == null) { + return; + } + + if (slotIdx != recipeTooltipSlotIdx) { + recipeTooltipSlotIdx = slotIdx; + recipeTooltipGui = null; + recipeTooltipUpdater = () -> { + recipeTooltipGui = GuiCraftingRecipe.createRecipeGui("item", false, false, false, focused.item); + if (recipeTooltipGui != null) { + recipeTooltipGui.limitToOneRecipe(); + recipeTooltipGui.initGui(true); + recipeTooltipGui.guiTop = 0; + recipeTooltipGui.guiLeft = 0; + } + recipeTooltipLines = Math.max(1, itemTooltip.size()); + }; + } + if (recipeTooltipGui == null) { + return; + } + + GL11.glPushMatrix(); + final float tooltipYOffset; + if (mousey - marginTop > height / 2) { + tooltipYOffset = mousey - recipeTooltipGui.getHeightAsWidget() + 8; + } else { + tooltipYOffset = mousey + ((recipeTooltipLines < 2) ? 1 : 3 + ((recipeTooltipLines - 1) * 10)); + } + GL11.glTranslatef(mousex, tooltipYOffset, 500); + + final GuiContainer gui; + if (mc.currentScreen instanceof GuiRecipe) { + gui = ((GuiRecipe) mc.currentScreen).firstGui; + } else if (mc.currentScreen instanceof GuiContainer) { + gui = (GuiContainer) mc.currentScreen; + } else { + gui = null; + } + recipeTooltipGui.drawGuiContainerBackgroundLayer(0.0f, -100, -100); + if (recipeTooltipGui.slotcontainer != null) { + @SuppressWarnings("unchecked") + List slots = (List) recipeTooltipGui.slotcontainer.inventorySlots; + for (Slot slot : slots) { + if (slot != null && slot.getStack() != null) { + GuiContainerManager.drawItem(slot.xDisplayPosition, slot.yDisplayPosition, slot.getStack()); + } + } + } + recipeTooltipGui.drawGuiContainerForegroundLayer(-100, -100); + for (GuiButton btn : recipeTooltipGui.getOverlayButtons()) { + btn.drawButton(mc, -100, -100); + } + GL11.glPopMatrix(); + } + protected void drawSlotOutline(@Nullable ItemPanelSlot focused, int slotIdx, Rectangle4i rect) { if (focused != null && focused.slotIndex == slotIdx) { drawRect(rect.x, rect.y, rect.w, rect.h, 0xee555555); // highlight @@ -329,6 +452,16 @@ public class ItemsGrid { } } + public void postDrawTooltips(int mousex, int mousey, List tooltip) { + if (NEIClientConfig.showRecipeTooltips() && showRecipeTooltips) { + try { + drawRecipeTooltip(mousex, mousey, tooltip); + } catch (Exception e) { + NEIClientConfig.logger.warn("Cannot draw recipe tooltip", e); + } + } + } + public void setVisible() { if (getItems().isEmpty() && getMessageOnEmpty() != null) { LayoutManager.addWidget(messageLabel); diff --git a/src/main/java/codechicken/nei/LayoutManager.java b/src/main/java/codechicken/nei/LayoutManager.java index 162e99be..b5dce47e 100644 --- a/src/main/java/codechicken/nei/LayoutManager.java +++ b/src/main/java/codechicken/nei/LayoutManager.java @@ -280,6 +280,13 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH } } + @Override + public void postRenderTooltips(GuiContainer gui, int mousex, int mousey, List tooltip) { + if (!isHidden() && isEnabled()) { + for (Widget widget : drawWidgets) widget.postDrawTooltips(mousex, mousey, tooltip); + } + } + @Override public List handleTooltip(GuiContainer gui, int mousex, int mousey, List currenttip) { if (!isHidden() && isEnabled() && GuiContainerManager.shouldShowTooltip(gui)) { diff --git a/src/main/java/codechicken/nei/NEIClientConfig.java b/src/main/java/codechicken/nei/NEIClientConfig.java index a692152f..95127e65 100644 --- a/src/main/java/codechicken/nei/NEIClientConfig.java +++ b/src/main/java/codechicken/nei/NEIClientConfig.java @@ -242,6 +242,9 @@ public class NEIClientConfig { tag.getTag("inventory.bookmarksAnimationEnabled").setComment("REI Style Animation in Bookmarks") .getBooleanValue(true); API.addOption(new OptionToggleButton("inventory.bookmarksAnimationEnabled", true)); + tag.getTag("inventory.recipeTooltipsEnabled").setComment("Show recipe tooltips in Bookmarks") + .getBooleanValue(true); + API.addOption(new OptionToggleButton("inventory.recipeTooltipsEnabled", true)); tag.getTag("inventory.showRecipeMarker").setComment("Show Recipe Marker").getBooleanValue(false); API.addOption(new OptionToggleButton("inventory.showRecipeMarker", true)); @@ -559,6 +562,10 @@ public class NEIClientConfig { return getBooleanSetting("inventory.bookmarksAnimationEnabled"); } + public static boolean showRecipeTooltips() { + return getBooleanSetting("inventory.recipeTooltipsEnabled"); + } + public static boolean showRecipeMarker() { return getBooleanSetting("inventory.showRecipeMarker"); } diff --git a/src/main/java/codechicken/nei/PanelWidget.java b/src/main/java/codechicken/nei/PanelWidget.java index fb6bc971..f0a53c1a 100644 --- a/src/main/java/codechicken/nei/PanelWidget.java +++ b/src/main/java/codechicken/nei/PanelWidget.java @@ -1,6 +1,7 @@ package codechicken.nei; import java.util.ArrayList; +import java.util.List; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.item.ItemStack; @@ -171,6 +172,11 @@ public abstract class PanelWidget extends Widget { } } + @Override + public void update() { + grid.update(); + } + @Override public void draw(int mousex, int mousey) { grid.draw(mousex, mousey); @@ -185,6 +191,11 @@ public abstract class PanelWidget extends Widget { } } + @Override + public void postDrawTooltips(int mx, int my, List tooltip) { + grid.postDrawTooltips(mx, my, tooltip); + } + @Override public void mouseDragged(int mousex, int mousey, int button, long heldTime) { if (mouseDownSlot >= 0 && draggedStack == null diff --git a/src/main/java/codechicken/nei/Widget.java b/src/main/java/codechicken/nei/Widget.java index 7dc978d8..08967c3b 100644 --- a/src/main/java/codechicken/nei/Widget.java +++ b/src/main/java/codechicken/nei/Widget.java @@ -14,6 +14,8 @@ public abstract class Widget { public void postDraw(int mx, int my) {} + public void postDrawTooltips(int mx, int my, List tooltip) {} + public boolean handleClick(int mx, int my, int button) { return true; } diff --git a/src/main/java/codechicken/nei/guihook/GuiContainerManager.java b/src/main/java/codechicken/nei/guihook/GuiContainerManager.java index 31185ae2..12549170 100644 --- a/src/main/java/codechicken/nei/guihook/GuiContainerManager.java +++ b/src/main/java/codechicken/nei/guihook/GuiContainerManager.java @@ -514,6 +514,10 @@ public class GuiContainerManager { if (tooltip.size() > 0) tooltip.set(0, tooltip.get(0) + GuiDraw.TOOLTIP_LINESPACE); // add space after 'title' drawPagedTooltip(font, mousex + 12, mousey - 12, tooltip); + + for (IContainerDrawHandler drawHandler : drawHandlers) { + drawHandler.postRenderTooltips(window, mousex, mousey, tooltip); + } } private static int tooltipPage; diff --git a/src/main/java/codechicken/nei/guihook/IContainerDrawHandler.java b/src/main/java/codechicken/nei/guihook/IContainerDrawHandler.java index 503cdc0f..e12d1b36 100644 --- a/src/main/java/codechicken/nei/guihook/IContainerDrawHandler.java +++ b/src/main/java/codechicken/nei/guihook/IContainerDrawHandler.java @@ -1,5 +1,7 @@ package codechicken.nei.guihook; +import java.util.List; + import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.inventory.Slot; @@ -30,6 +32,17 @@ public interface IContainerDrawHandler { */ public void postRenderObjects(GuiContainer gui, int mousex, int mousey); + /** + * Use this to draw things that should be drawn just after vanilla slot tooltips, on top of buttons and other + * usually always-on-top widgets. + * + * @param gui An instance of the currentscreen + * @param mousex The x position of the mouse in pixels from left + * @param mousey The y position of the mouse in pixels from top + * @param tooltip The contents of the tooltip that has previously been drawn + */ + default void postRenderTooltips(GuiContainer gui, int mousex, int mousey, List tooltip) {} + /** * Render something over a slot before the item in the slot. * diff --git a/src/main/java/codechicken/nei/recipe/BookmarkRecipeId.java b/src/main/java/codechicken/nei/recipe/BookmarkRecipeId.java index beac2cc8..b10b23c3 100644 --- a/src/main/java/codechicken/nei/recipe/BookmarkRecipeId.java +++ b/src/main/java/codechicken/nei/recipe/BookmarkRecipeId.java @@ -121,6 +121,43 @@ public class BookmarkRecipeId { return arr; } + /** + * Ensures the {@link BookmarkRecipeId#recipetype} and {@link BookmarkRecipeId#position} fields point to a valid + * recipe. This is needed, because the recipe IDs are loaded lazily on first use. + * + * @param recipeHandlers The subset of recipe handlers to search for the recipe + */ + public void updateTargetRecipe(List recipeHandlers) { + if (this.recipetype == -1 || this.position == -1) { + this.recipetype = 0; + this.position = 0; + + if (this.handlerName != null) { + + for (int j = 0; j < recipeHandlers.size(); j++) { + IRecipeHandler localHandler = recipeHandlers.get(j); + HandlerInfo localHandlerInfo = GuiRecipeTab.getHandlerInfo(localHandler); + + if (localHandlerInfo.getHandlerName().equals(this.handlerName)) { + + if (!this.ingredients.isEmpty()) { + for (int i = 0; i < localHandler.numRecipes(); i++) { + + if (this.equalsIngredients(localHandler.getIngredientStacks(i))) { + this.recipetype = j; + this.position = i; + break; + } + } + } + + break; + } + } + } + } + } + public boolean equals(Object anObject) { if (this == anObject) { return true; diff --git a/src/main/java/codechicken/nei/recipe/GuiCraftingRecipe.java b/src/main/java/codechicken/nei/recipe/GuiCraftingRecipe.java index 487e0d0c..59f20489 100644 --- a/src/main/java/codechicken/nei/recipe/GuiCraftingRecipe.java +++ b/src/main/java/codechicken/nei/recipe/GuiCraftingRecipe.java @@ -28,28 +28,27 @@ public class GuiCraftingRecipe extends GuiRecipe { public static boolean openRecipeGui(String outputId, final Boolean overlay, final Boolean shift, Object... results) { + return createRecipeGui(outputId, overlay, shift, true, results) != null; + } + + public static GuiRecipe createRecipeGui(String outputId, final Boolean overlay, final Boolean shift, + final boolean open, Object... results) { final Minecraft mc = NEIClientUtils.mc(); final BookmarkRecipeId recipeId = "item".equals(outputId) ? getRecipeId(mc.currentScreen, (ItemStack) results[0]) : getCurrentRecipe(mc.currentScreen); - if (overlay && recipeId == null) return false; + if (overlay && recipeId == null) return null; - final RecipeHandlerQuery recipeQuery = new RecipeHandlerQuery<>( - h -> h.getRecipeHandler(outputId, results), - craftinghandlers, - serialCraftingHandlers, - "Error while looking up crafting recipe", - "outputId: " + outputId, - "results: " + Arrays.toString(results)); - - final ArrayList handlers = recipeQuery.runWithProfiling("recipe.concurrent.crafting"); + final ArrayList handlers = getCraftingHandlers(outputId, results); if (!handlers.isEmpty()) { GuiCraftingRecipe gui = new GuiCraftingRecipe(handlers, recipeId); - mc.displayGuiScreen(gui); + if (open) { + mc.displayGuiScreen(gui); + } if (recipeId != null) { gui.openTargetRecipe(gui.recipeId); @@ -59,10 +58,22 @@ public class GuiCraftingRecipe extends GuiRecipe { gui.overlayRecipe(gui.recipeId.position, shift); } - return true; + return gui; } - return false; + return null; + } + + public static ArrayList getCraftingHandlers(String outputId, Object... results) { + final RecipeHandlerQuery recipeQuery = new RecipeHandlerQuery<>( + h -> h.getRecipeHandler(outputId, results), + craftinghandlers, + serialCraftingHandlers, + "Error while looking up crafting recipe", + "outputId: " + outputId, + "results: " + Arrays.toString(results)); + + return recipeQuery.runWithProfiling("recipe.concurrent.crafting"); } protected static BookmarkRecipeId getRecipeId(GuiScreen gui, ItemStack stackover) { diff --git a/src/main/java/codechicken/nei/recipe/GuiRecipe.java b/src/main/java/codechicken/nei/recipe/GuiRecipe.java index b18c1fc8..0b12499e 100644 --- a/src/main/java/codechicken/nei/recipe/GuiRecipe.java +++ b/src/main/java/codechicken/nei/recipe/GuiRecipe.java @@ -1,5 +1,7 @@ package codechicken.nei.recipe; +import static codechicken.lib.gui.GuiDraw.fontRenderer; + import java.awt.Point; import java.awt.Rectangle; import java.util.ArrayList; @@ -11,8 +13,10 @@ import java.util.regex.Matcher; import java.util.stream.Collectors; import java.util.stream.IntStream; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.client.renderer.OpenGlHelper; import net.minecraft.client.renderer.RenderHelper; @@ -59,6 +63,8 @@ public abstract class GuiRecipe extends GuiContainer i private static final int buttonWidth = 13; private static final int buttonHeight = 12; + private boolean limitToOneRecipe = false; + // Background image final DrawableResource bgTop = new DrawableBuilder("nei:textures/gui/recipebg.png", 0, BG_TOP_Y, 176, BG_TOP_HEIGHT) .build(); @@ -122,6 +128,11 @@ public abstract class GuiRecipe extends GuiContainer i } } + /** Changes the GUI mode to only display one recipe at a time, e.g. for tooltip usage */ + public void limitToOneRecipe() { + limitToOneRecipe = true; + } + /** * Many old mods assumed a fixed NEI window height of {@code 166} pixels. Now that this is no longer the case, their * tooltip and click zone handling is broken. This helper class fixes these old mods by hacking the {@link #height} @@ -135,10 +146,12 @@ public abstract class GuiRecipe extends GuiContainer i private final int trueHeight; private final int trueGuiTop; + private final GuiScreen trueGui; private HeightHack() { trueHeight = height; trueGuiTop = guiTop; + trueGui = Minecraft.getMinecraft().currentScreen; isHeightHackApplied = NEIClientConfig.heightHackHandlerRegex.stream() .map(pattern -> pattern.matcher(handler.getHandlerId())).anyMatch(Matcher::matches); @@ -163,6 +176,12 @@ public abstract class GuiRecipe extends GuiContainer i // guiWidth (the x-value of the left edge of the NEI recipe screen). So if we wanted to override width // as well, we'd do this: // width = (2 * guiWidth) + 176; + + // Recipe handlers may assume the current screen is the GuiRecipe object, which is not the case in + // recipe tooltips drawn on the bookmarks panel with the main inventory open. + if (limitToOneRecipe) { + Minecraft.getMinecraft().currentScreen = GuiRecipe.this; + } } } @@ -170,16 +189,33 @@ public abstract class GuiRecipe extends GuiContainer i public void close() { guiTop = trueGuiTop; height = trueHeight; + Minecraft.getMinecraft().currentScreen = trueGui; isHeightHackApplied = false; } } @Override - @SuppressWarnings("unchecked") public void initGui() { + initGui(false); + } + + @SuppressWarnings("unchecked") + public void initGui(boolean asWidget) { xSize = 176; ySize = Math.min(Math.max(height - 68, 166), 370); - super.initGui(); + if (!asWidget) { + super.initGui(); + } else { + this.guiLeft = (this.width - this.xSize) / 2; + this.mc = Minecraft.getMinecraft(); + this.fontRendererObj = mc.fontRenderer; + ScaledResolution scaledresolution = new ScaledResolution( + this.mc, + this.mc.displayWidth, + this.mc.displayHeight); + this.width = scaledresolution.getScaledWidth(); + this.height = scaledresolution.getScaledHeight(); + } guiTop = (height - ySize) / 2 + 10; currenthandlers = getCurrentRecipeHandlers(); // Probably don't comment me out @@ -216,14 +252,23 @@ public abstract class GuiRecipe extends GuiContainer i final int recipesPerPage = getRecipesPerPage(); overlayButtons = new GuiButton[recipesPerPage]; + final int xOffset = limitToOneRecipe ? ((xSize / 2) - 2) : (width / 2); + final String overlayKeyName = NEIClientConfig + .getKeyName(NEIClientConfig.getKeyBinding("gui.overlay_use"), true); for (int i = 0; i < recipesPerPage; i++) { overlayButtons[i] = new GuiNEIButton( OVERLAY_BUTTON_ID_START + i, - (width / 2) + 65, - guiTop + 16 + (handlerInfo.getHeight() * (i + 1)) - 2, + xOffset + 65, + 16 + (handlerInfo.getHeight() * (i + 1)) - 2, buttonWidth, buttonHeight, "?"); + if (overlayKeyName != null && limitToOneRecipe) { + overlayButtons[i].visible = true; + overlayButtons[i].displayString = overlayKeyName; + overlayButtons[i].width = fontRenderer.getStringWidth(overlayKeyName) + 6; + overlayButtons[i].xPosition = xOffset + 85 - overlayButtons[i].width; + } } Collections.addAll(buttonList, overlayButtons); itemPresenceCacheRecipe = -1; @@ -250,41 +295,17 @@ public abstract class GuiRecipe extends GuiContainer i initOverlayButtons(); } + public List getOverlayButtons() { + return Collections.unmodifiableList(Arrays.asList(overlayButtons)); + } + public void openTargetRecipe(BookmarkRecipeId recipeId) { if (recipeId == null) { return; } - if (recipeId.recipetype == -1 || recipeId.position == -1) { - recipeId.recipetype = 0; - recipeId.position = 0; - - if (recipeId.handlerName != null) { - - for (int j = 0; j < currenthandlers.size(); j++) { - H localHandler = currenthandlers.get(j); - HandlerInfo localHandlerInfo = GuiRecipeTab.getHandlerInfo(localHandler); - - if (localHandlerInfo.getHandlerName().equals(recipeId.handlerName)) { - - if (!recipeId.ingredients.isEmpty()) { - for (int i = 0; i < localHandler.numRecipes(); i++) { - - if (recipeId.equalsIngredients(localHandler.getIngredientStacks(i))) { - recipeId.recipetype = j; - recipeId.position = i; - break; - } - } - } - - break; - } - } - } - } - + recipeId.updateTargetRecipe(currenthandlers); setRecipePage(recipeId.recipetype, recipeId.position); } @@ -456,6 +477,11 @@ public abstract class GuiRecipe extends GuiContainer i @Override public void updateScreen() { super.updateScreen(); + updateAsTooltip(); + } + + /** updateScreen() that's safe to call when this isn't the currently open GUI */ + public void updateAsTooltip() { handler.onUpdate(); refreshPage(); } @@ -576,11 +602,13 @@ public abstract class GuiRecipe extends GuiContainer i PositionedStack result = handler.getResultStack(i); if (result != null) slotcontainer.addSlot(result, p.x, p.y); - List catalysts = RecipeCatalysts.getRecipeCatalysts(handler); - for (PositionedStack catalyst : catalysts) { - int xOffset = -GuiRecipeCatalyst.ingredientSize + 1; - int yOffset = BG_TOP_Y + GuiRecipeCatalyst.fullBorder; - slotcontainer.addSlot(catalyst, xOffset, yOffset); + if (!limitToOneRecipe) { + List catalysts = RecipeCatalysts.getRecipeCatalysts(handler); + for (PositionedStack catalyst : catalysts) { + int xOffset = -GuiRecipeCatalyst.ingredientSize + 1; + int yOffset = BG_TOP_Y + GuiRecipeCatalyst.fullBorder; + slotcontainer.addSlot(catalyst, xOffset, yOffset); + } } } } @@ -614,21 +642,24 @@ public abstract class GuiRecipe extends GuiContainer i } @Override - protected void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { + public void drawGuiContainerForegroundLayer(int mouseX, int mouseY) { GuiContainerManager.enable2DRender(); final int recipesPerPage = getRecipesPerPage(); - String s = handler.getRecipeName().trim(); - fontRendererObj.drawStringWithShadow(s, (xSize - fontRendererObj.getStringWidth(s)) / 2, 5, 0xffffff); - s = NEIClientUtils.translate("recipe.page", page + 1, (handler.numRecipes() - 1) / recipesPerPage + 1); - fontRendererObj.drawStringWithShadow(s, (xSize - fontRendererObj.getStringWidth(s)) / 2, 19, 0xffffff); + final int ySkip = limitToOneRecipe ? 25 : 0; + if (!limitToOneRecipe) { + String s = handler.getRecipeName().trim(); + fontRendererObj.drawStringWithShadow(s, (xSize - fontRendererObj.getStringWidth(s)) / 2, 5, 0xffffff); + s = NEIClientUtils.translate("recipe.page", page + 1, (handler.numRecipes() - 1) / recipesPerPage + 1); + fontRendererObj.drawStringWithShadow(s, (xSize - fontRendererObj.getStringWidth(s)) / 2, 19, 0xffffff); + } final boolean drawItemPresence = NEIClientConfig.isJEIStyleItemPresenceOverlayVisible(); GL11.glPushMatrix(); - GL11.glTranslatef(5, 32 + yShift, 0); + GL11.glTranslatef(5, 32 - ySkip + yShift, 0); try (HeightHack heightHack = new HeightHack()) { for (int i = page * recipesPerPage; i < handler.numRecipes() && i < (page + 1) * recipesPerPage; i++) { handler.drawForeground(i); - if (drawItemPresence && isMouseOverOverlayButton(i - page * recipesPerPage) + if (drawItemPresence && (isMouseOverOverlayButton(i - page * recipesPerPage) || limitToOneRecipe) && firstGui.inventorySlots != null) { List ingredients = handler.getIngredientStacks(i); if (itemPresenceCacheRecipe != i || itemPresenceCacheSlots == null @@ -648,28 +679,27 @@ public abstract class GuiRecipe extends GuiContainer i } @Override - protected void drawGuiContainerBackgroundLayer(float f, int mouseX, int mouseY) { + public void drawGuiContainerBackgroundLayer(float f, int mouseX, int mouseY) { final int recipesPerPage = getRecipesPerPage(); + final int ySkip = limitToOneRecipe ? 25 : 0; GL11.glColor4f(1, 1, 1, 1); - final int j = (width - xSize) / 2; - final int k = guiTop; - drawBackgroundTiled(j, k); + drawBackgroundTiled(guiLeft, guiTop); - drawRect( - guiLeft + borderPadding + buttonWidth - 1, - nexttype.yPosition, - guiLeft + xSize - borderPadding - buttonWidth, - nexttype.yPosition + buttonHeight, - 0x30000000); - drawRect( - guiLeft + borderPadding + buttonWidth - 1, - nextpage.yPosition, - guiLeft + xSize - borderPadding - buttonWidth, - nextpage.yPosition + buttonHeight, - 0x30000000); + if (NEIClientConfig.areJEIStyleTabsVisible() && !limitToOneRecipe) { + drawRect( + guiLeft + borderPadding + buttonWidth - 1, + nexttype.yPosition, + guiLeft + xSize - borderPadding - buttonWidth, + nexttype.yPosition + buttonHeight, + 0x30000000); + drawRect( + guiLeft + borderPadding + buttonWidth - 1, + nextpage.yPosition, + guiLeft + xSize - borderPadding - buttonWidth, + nextpage.yPosition + buttonHeight, + 0x30000000); - if (NEIClientConfig.areJEIStyleTabsVisible()) { RenderHelper.enableGUIStandardItemLighting(); OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f); recipeTabs.draw(mouseX, mouseY); @@ -680,7 +710,7 @@ public abstract class GuiRecipe extends GuiContainer i } GL11.glPushMatrix(); - GL11.glTranslatef(j + 5, k + 32 + yShift, 0); + GL11.glTranslatef(guiLeft + 5, guiTop - ySkip + 32 + yShift, 0); try (HeightHack heightHack = new HeightHack()) { for (int i = page * recipesPerPage; i < handler.numRecipes() && i < (page + 1) * recipesPerPage; i++) { handler.drawBackground(i); @@ -692,10 +722,12 @@ public abstract class GuiRecipe extends GuiContainer i private void drawBackgroundTiled(int j, int k) { // Draw the top + final int ySkip = limitToOneRecipe ? 25 : 0; + final int handlerHeight = limitToOneRecipe ? getHeightAsWidget() : ySize; bgTop.draw(j, k + BG_TOP_Y); // Maybe Tile the middle - final int tiledHeight = ySize - BG_TOP_HEIGHT - BG_BOTTOM_HEIGHT; + final int tiledHeight = handlerHeight - ySkip - BG_TOP_HEIGHT - BG_BOTTOM_HEIGHT; if (tiledHeight > 0) { final int yTileCount = tiledHeight / BG_MIDDLE_HEIGHT; @@ -712,7 +744,11 @@ public abstract class GuiRecipe extends GuiContainer i } // Draw the bottom - bgBottom.draw(j, k + ySize - BG_BOTTOM_HEIGHT); + bgBottom.draw(j, k + handlerHeight - ySkip - BG_BOTTOM_HEIGHT); + } + + public int getHeightAsWidget() { + return (handlerInfo == null) ? ySize : (handlerInfo.getHeight() + 56); } @Override @@ -748,7 +784,7 @@ public abstract class GuiRecipe extends GuiContainer i } private int getRecipesPerPage() { - return getRecipesPerPage(handlerInfo); + return limitToOneRecipe ? 1 : getRecipesPerPage(handlerInfo); } private int getRecipesPerPage(HandlerInfo handlerInfo) { @@ -764,7 +800,9 @@ public abstract class GuiRecipe extends GuiContainer i // reduce the vertical shift here to 16px instead of 32px. return new Point( 5, - (isHeightHackApplied ? 16 : 32) + yShift + ((recipe % getRecipesPerPage()) * handlerInfo.getHeight())); + (isHeightHackApplied ? 16 : 32) - (limitToOneRecipe ? 25 : 0) + + yShift + + ((recipe % getRecipesPerPage()) * handlerInfo.getHeight())); } public abstract ArrayList getCurrentRecipeHandlers(); diff --git a/src/main/resources/assets/nei/lang/en_US.lang b/src/main/resources/assets/nei/lang/en_US.lang index 3eb88b9a..2b069814 100644 --- a/src/main/resources/assets/nei/lang/en_US.lang +++ b/src/main/resources/assets/nei/lang/en_US.lang @@ -152,6 +152,9 @@ nei.options.inventory.saveCurrentRecipeInBookmarksEnabled.false=Disabled nei.options.inventory.useNBTInBookmarks=Use NBT in Bookmarks nei.options.inventory.useNBTInBookmarks.true=Yes nei.options.inventory.useNBTInBookmarks.false=No +nei.options.inventory.recipeTooltipsEnabled=Show recipe tooltips in Bookmarks +nei.options.inventory.recipeTooltipsEnabled.true=Yes +nei.options.inventory.recipeTooltipsEnabled.false=No nei.options.inventory.bookmarksAnimationEnabled=REI Style Animation in Bookmarks nei.options.inventory.bookmarksAnimationEnabled.true=Yes nei.options.inventory.bookmarksAnimationEnabled.false=No @@ -342,4 +345,4 @@ nei.presets.whitelist.tooltip=Whitelist nei.presets.textfield.tooltip.1=Enter - save nei.presets.textfield.tooltip.2=Escape - cancel nei.presets.label.tooltip=Double click to edit -nei.presets.label.selected=%s Presets \ No newline at end of file +nei.presets.label.selected=%s Presets