Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/recipe-tooltip' into dev
Browse files Browse the repository at this point in the history
# Conflicts:
#	README.md
  • Loading branch information
Dream-Master committed Jul 6, 2023
2 parents 42055d4 + e748c67 commit 81e2c9b
Show file tree
Hide file tree
Showing 9 changed files with 319 additions and 84 deletions.
3 changes: 3 additions & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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"

4 changes: 4 additions & 0 deletions src/main/java/codechicken/nei/BookmarkPanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ public static class BookmarkGrid extends ItemsGrid {
protected boolean[] todoSpaces;
protected int todoItemsCount = 0;

public BookmarkGrid() {
this.setShowRecipeTooltips(true);
}

public void setViewMode(BookmarkViewMode mode) {
if (viewMode == mode) {
return;
Expand Down
135 changes: 135 additions & 0 deletions src/main/java/codechicken/nei/ItemsGrid.java
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -22,6 +27,9 @@
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 {
Expand All @@ -43,6 +51,7 @@ public class ItemsGrid {

protected int rows;
protected int columns;
protected boolean showRecipeTooltips = false;

protected boolean[] invalidSlotMap;

Expand Down Expand Up @@ -150,6 +159,10 @@ protected void onGridChanged() {
refreshBuffer = true;
}

public void setShowRecipeTooltips(boolean show) {
this.showRecipeTooltips = show;
}

public void refresh(GuiContainer gui) {
updateGuiOverlapSlots(gui);
shiftPage(0);
Expand Down Expand Up @@ -244,6 +257,121 @@ private void drawSlotOutlines(int mousex, int mousey) {
}
}

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 <T> List<T> listOrEmptyList(final List<T> listOrNull) {
return listOrNull == null ? Collections.emptyList() : listOrNull;
}

private void drawRecipeTooltip(int mousex, int mousey) {
final Minecraft mc = Minecraft.getMinecraft();
ItemPanelSlot focused = getSlotMouseOver(mousex, mousey);
if (focused == null) {
recipeTooltipSlotIdx = -1;
recipeTooltipGui = null;
return;
}
final List<Integer> 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 = 2;
if (focused.item != null && mc.currentScreen instanceof GuiContainer) {
final List<String> tooltip = GuiContainerManager
.itemDisplayNameMultiline(focused.item, (GuiContainer) mc.currentScreen, true);
recipeTooltipLines = tooltip.size();
}
};
}
if (recipeTooltipGui == null) {
return;
}

GL11.glPushMatrix();
final float tooltipYOffset;
if (mousey > height / 2) {
tooltipYOffset = mousey - recipeTooltipGui.getHeightAsWidget() + 8;
} else {
tooltipYOffset = mousey - 7 + (recipeTooltipLines * 10);
}
GL11.glTranslatef(mousex, tooltipYOffset, 100);

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<Slot> slots = (List<Slot>) 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
Expand Down Expand Up @@ -327,6 +455,13 @@ public void draw(int mousex, int mousey) {
drawSlotOutlines(mousex, mousey);
drawItems();
}
if (NEIClientConfig.showRecipeTooltips() && showRecipeTooltips) {
try {
drawRecipeTooltip(mousex, mousey);
} catch (Exception e) {
NEIClientConfig.logger.warn("Cannot draw recipe tooltip", e);
}
}
}

public void setVisible() {
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/codechicken/nei/NEIClientConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,9 @@ public boolean onClick(int button) {
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));

Expand Down Expand Up @@ -551,6 +554,10 @@ public static boolean areBookmarksAnimated() {
return getBooleanSetting("inventory.bookmarksAnimationEnabled");
}

public static boolean showRecipeTooltips() {
return getBooleanSetting("inventory.recipeTooltipsEnabled");
}

public static boolean showRecipeMarker() {
return getBooleanSetting("inventory.showRecipeMarker");
}
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/codechicken/nei/PanelWidget.java
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,11 @@ public void setVisible() {
}
}

@Override
public void update() {
grid.update();
}

@Override
public void draw(int mousex, int mousey) {
grid.draw(mousex, mousey);
Expand Down
37 changes: 37 additions & 0 deletions src/main/java/codechicken/nei/recipe/BookmarkRecipeId.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,43 @@ protected JsonArray convertIngredientsToJsonArray(List<NBTTagCompound> ingredien
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<? extends IRecipeHandler> 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;
Expand Down
37 changes: 24 additions & 13 deletions src/main/java/codechicken/nei/recipe/GuiCraftingRecipe.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,27 @@ public static boolean openRecipeGui(String outputId, Object... results) {

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<ICraftingHandler> recipeQuery = new RecipeHandlerQuery<>(
h -> h.getRecipeHandler(outputId, results),
craftinghandlers,
serialCraftingHandlers,
"Error while looking up crafting recipe",
"outputId: " + outputId,
"results: " + Arrays.toString(results));

final ArrayList<ICraftingHandler> handlers = recipeQuery.runWithProfiling("recipe.concurrent.crafting");
final ArrayList<ICraftingHandler> 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);
Expand All @@ -59,10 +58,22 @@ public static boolean openRecipeGui(String outputId, final Boolean overlay, fina
gui.overlayRecipe(gui.recipeId.position, shift);
}

return true;
return gui;
}

return false;
return null;
}

public static ArrayList<ICraftingHandler> getCraftingHandlers(String outputId, Object... results) {
final RecipeHandlerQuery<ICraftingHandler> 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) {
Expand Down
Loading

0 comments on commit 81e2c9b

Please sign in to comment.