mirror of
https://github.com/GTNewHorizons/NotEnoughItems.git
synced 2026-11-15 09:44:44 +00:00
Compare commits
15
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9203eddcdb | ||
|
|
fd5871b59b | ||
|
|
fbaae94df3 | ||
|
|
620809cfc4 | ||
|
|
bcbd3c4c0a | ||
|
|
72a8be0204 | ||
|
|
a33bfab8a2 | ||
|
|
7084928860 | ||
|
|
9edea34dc7 | ||
|
|
282b0d45da | ||
|
|
e748c6779b | ||
|
|
75e8270bad | ||
|
|
c4c7d6d055 | ||
|
|
2630d887eb | ||
|
|
f8cc9bd0e6 |
No files matched your search
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -9,9 +9,6 @@ import java.io.InputStreamReader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@@ -48,20 +45,12 @@ import codechicken.nei.recipe.GuiRecipeTab;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
import cpw.mods.fml.client.CustomModLoadingErrorDisplayException;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||
import cpw.mods.fml.common.gameevent.TickEvent;
|
||||
import cpw.mods.fml.common.gameevent.TickEvent.Phase;
|
||||
|
||||
public class ClientHandler {
|
||||
|
||||
private static String[] defaultSerialHandlers = {
|
||||
"WayofTime.alchemicalWizardry.client.nei.NEIAlchemyRecipeHandler" };
|
||||
private static String[] defaultHeightHackHandlerRegex = { "buildcraft.compat.nei.*",
|
||||
"cofh.thermalexpansion.plugins.nei.handlers.*", "crazypants.enderio.nei.*",
|
||||
"forestry.factory.recipes.nei.*", "ic2.neiIntegration.core.recipehandler.*", "mariculture.plugins.nei.*",
|
||||
"redgear.brewcraft.plugins.nei.*", "tconstruct.plugins.nei.*",
|
||||
"WayofTime.alchemicalWizardry.client.nei.*", };
|
||||
private static String[] defaultHandlerOrdering = {
|
||||
"# Each line in this file should either be a comment (starts with '#') or an ordering.",
|
||||
"# Ordering lines are <handler ID>,<ordering number>.",
|
||||
@@ -165,16 +154,19 @@ public class ClientHandler {
|
||||
if (!file.exists()) {
|
||||
try (FileWriter writer = new FileWriter(file)) {
|
||||
NEIClientConfig.logger.info("Creating default serial handlers list {}", file);
|
||||
Collection<String> toSave = Loader.isModLoaded("dreamcraft") ? Collections.singletonList("")
|
||||
: Arrays.asList(defaultSerialHandlers);
|
||||
IOUtils.writeLines(toSave, "\n", writer);
|
||||
URL defaultSerialHandlersResource = ClientHandler.class
|
||||
.getResource("/assets/nei/cfg/serialhandlers.cfg");
|
||||
if (defaultSerialHandlersResource != null) {
|
||||
IOUtils.copy(defaultSerialHandlersResource.openStream(), writer);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to save default serial handlers list to file {}", file, e);
|
||||
}
|
||||
}
|
||||
try (FileReader reader = new FileReader(file)) {
|
||||
NEIClientConfig.logger.info("Loading serial handlers from file {}", file);
|
||||
NEIClientConfig.serialHandlers = new HashSet<>(IOUtils.readLines(reader));
|
||||
NEIClientConfig.serialHandlers = IOUtils.readLines(reader).stream().filter((line) -> !line.startsWith("#"))
|
||||
.collect(Collectors.toCollection(HashSet::new));
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to load serial handlers from file {}", file, e);
|
||||
}
|
||||
@@ -185,8 +177,11 @@ public class ClientHandler {
|
||||
if (!file.exists()) {
|
||||
try (FileWriter writer = new FileWriter(file)) {
|
||||
NEIClientConfig.logger.info("Creating default height hack handlers list {}", file);
|
||||
Collection<String> toSave = Arrays.asList(defaultHeightHackHandlerRegex);
|
||||
IOUtils.writeLines(toSave, "\n", writer);
|
||||
URL defaultHeightHackHandlersResource = ClientHandler.class
|
||||
.getResource("/assets/nei/cfg/heighthackhandlers.cfg");
|
||||
if (defaultHeightHackHandlersResource != null) {
|
||||
IOUtils.copy(defaultHeightHackHandlersResource.openStream(), writer);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to save default height hack handlers list to file {}", file, e);
|
||||
}
|
||||
@@ -194,7 +189,8 @@ public class ClientHandler {
|
||||
|
||||
try (FileReader reader = new FileReader(file)) {
|
||||
NEIClientConfig.logger.info("Loading height hack handlers from file {}", file);
|
||||
NEIClientConfig.heightHackHandlerRegex = IOUtils.readLines(reader).stream().map(Pattern::compile)
|
||||
NEIClientConfig.heightHackHandlerRegex = IOUtils.readLines(reader).stream()
|
||||
.filter((line) -> !line.startsWith("#")).map(Pattern::compile)
|
||||
.collect(Collectors.toCollection(HashSet::new));
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to load height hack handlers from file {}", file, e);
|
||||
|
||||
@@ -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,121 @@ 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 <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
|
||||
@@ -327,6 +455,13 @@ public class ItemsGrid {
|
||||
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() {
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -171,6 +171,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);
|
||||
|
||||
@@ -135,6 +135,13 @@ public class IMCHandler {
|
||||
NEIClientConfig.logger.warn("Missing handlerID for registerCatalystInfo!");
|
||||
return;
|
||||
}
|
||||
final String modId = tag.hasKey("modId") ? tag.getString("modId") : null;
|
||||
final boolean requiresMod = tag.getBoolean("modRequired");
|
||||
final String excludedModId = tag.hasKey("excludedModId") ? tag.getString("excludedModId") : null;
|
||||
|
||||
if (requiresMod && modId != null && !Loader.isModLoaded(modId)) return;
|
||||
if (excludedModId != null && Loader.isModLoaded(excludedModId)) return;
|
||||
|
||||
final String itemName = tag.getString("itemName");
|
||||
final String nbtInfo = tag.hasKey("nbtInfo") ? tag.getString("nbtInfo") : null;
|
||||
if (itemName.isEmpty()) {
|
||||
@@ -170,7 +177,7 @@ public class IMCHandler {
|
||||
final String itemName = tag.getString("itemName");
|
||||
final String nbtInfo = tag.hasKey("nbtInfo") ? tag.getString("nbtInfo") : null;
|
||||
if (itemName.isEmpty()) {
|
||||
NEIClientConfig.logger.warn(String.format("Missing itemName for registerCatalystInfo in `%s`!", handlerID));
|
||||
NEIClientConfig.logger.warn(String.format("Missing itemName for removeCatalystInfo in `%s`!", handlerID));
|
||||
return;
|
||||
}
|
||||
final ItemStack itemStack = NEIServerUtils.getModdedItem(itemName, nbtInfo);
|
||||
|
||||
@@ -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<? 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;
|
||||
|
||||
@@ -28,28 +28,27 @@ public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
|
||||
|
||||
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);
|
||||
@@ -59,10 +58,22 @@ public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
|
||||
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) {
|
||||
|
||||
@@ -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<H extends IRecipeHandler> 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();
|
||||
@@ -100,6 +106,8 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
|
||||
private int yShift = 0;
|
||||
|
||||
private boolean isHeightHackApplied = false;
|
||||
|
||||
protected GuiRecipe(GuiScreen prevgui) {
|
||||
super(new ContainerRecipe());
|
||||
recipeTabs = new GuiRecipeTabs(this);
|
||||
@@ -116,9 +124,14 @@ public abstract class GuiRecipe<H extends IRecipeHandler> 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
|
||||
* fluid mouseover handling is broken. This helper class fixes these old mods by hacking the {@link #height}
|
||||
* tooltip and click zone handling is broken. This helper class fixes these old mods by hacking the {@link #height}
|
||||
* property's value so that these old mods' calculations return the correct value for the new height.
|
||||
*
|
||||
* <p>
|
||||
@@ -128,40 +141,68 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
private class HeightHack implements AutoCloseable {
|
||||
|
||||
private final int trueHeight;
|
||||
private final int trueGuiTop;
|
||||
|
||||
private HeightHack() {
|
||||
trueHeight = height;
|
||||
trueGuiTop = guiTop;
|
||||
|
||||
boolean applyHeightHack = NEIClientConfig.heightHackHandlerRegex.stream()
|
||||
isHeightHackApplied = NEIClientConfig.heightHackHandlerRegex.stream()
|
||||
.map(pattern -> pattern.matcher(handler.getHandlerId())).anyMatch(Matcher::matches);
|
||||
if (applyHeightHack) {
|
||||
// The old mods use the calculation ((height - 166) / 2) to compute the y-value of
|
||||
// the top edge of the NEI window.
|
||||
// guiTop is exactly that: the y-value of the top edge of the NEI window.
|
||||
// So we set height to be equal to the inverse of this calculation, applied to
|
||||
// guiTop, so that old mods get the right result back when they use this calculation.
|
||||
if (isHeightHackApplied) {
|
||||
// guiTop is the top edge of the recipe screen on the y-axis. Old recipe handlers expect a single paging
|
||||
// widget at the top and at the bottom of the recipe screen with a height of 16px, but GTNH NEI move the
|
||||
// bottom paging widget to the top following JEI's UI increasing the forbidden zone at the top to 32px.
|
||||
// To fix these old recipe handlers we move guiTop down 16px so that they can keep working with the old
|
||||
// 16px gap.
|
||||
guiTop += 16;
|
||||
|
||||
// The old NEI recipe screen had a fixed width and height and was always centered on the screen. Legacy
|
||||
// recipe handlers use the calculation ((height - 166) / 2) to compute the y-value of the top edge of
|
||||
// the NEI recipe screen. GTNH NEI now has a flexible recipe screen length and is no longer centered
|
||||
// vertically, so in order for the top-of-screen calculation to return the correct result, we have to
|
||||
// hack the height field with an inverse of the calculation using the actual top of the recipe screen
|
||||
// stored in guiTop.
|
||||
height = (2 * guiTop) + 166;
|
||||
|
||||
// For reference, in case we ever need to modify width as well:
|
||||
// the legacy calculation used for width is ((width - 176) / 2), which should
|
||||
// evaluate to be equal to guiWidth (the x-value of the left edge of the NEI window).
|
||||
// So if we wanted to override width as well, we'd do this:
|
||||
// the legacy calculation used for width is ((width - 176) / 2), which should evaluate to be equal to
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
guiTop = trueGuiTop;
|
||||
height = trueHeight;
|
||||
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
|
||||
|
||||
@@ -198,14 +239,24 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
|
||||
final int recipesPerPage = getRecipesPerPage();
|
||||
overlayButtons = new GuiButton[recipesPerPage];
|
||||
final int xOffset = limitToOneRecipe ? (xSize / 2) : (width / 2);
|
||||
final int yOffset = limitToOneRecipe ? -14 : guiTop;
|
||||
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,
|
||||
yOffset + 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;
|
||||
@@ -232,41 +283,17 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
initOverlayButtons();
|
||||
}
|
||||
|
||||
public List<GuiButton> 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);
|
||||
}
|
||||
|
||||
@@ -438,6 +465,11 @@ public abstract class GuiRecipe<H extends IRecipeHandler> 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();
|
||||
}
|
||||
@@ -454,9 +486,9 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
@Override
|
||||
public List<String> handleItemTooltip(GuiContainer gui, ItemStack stack, int mousex, int mousey,
|
||||
List<String> currenttip) {
|
||||
// Height hacking is probably not needed as it doesn't look like any mods check mouse
|
||||
// position for this method.
|
||||
for (int i : getRecipeIndices()) currenttip = handler.handleItemTooltip(this, stack, currenttip, i);
|
||||
try (HeightHack heightHack = new HeightHack()) {
|
||||
for (int i : getRecipeIndices()) currenttip = handler.handleItemTooltip(this, stack, currenttip, i);
|
||||
}
|
||||
|
||||
return currenttip;
|
||||
}
|
||||
@@ -542,6 +574,12 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
final int recipesPerPage = getRecipesPerPage();
|
||||
for (int i = page * recipesPerPage; i < handler.numRecipes() && i < (page + 1) * recipesPerPage; i++) {
|
||||
Point p = getRecipePosition(i);
|
||||
// Legacy recipe handlers only expect a single paging widget at the top of the recipe screen, in contrast,
|
||||
// GTNH NEI moves the recipe paging widget from the bottom to the top, which means said legacy handlers will
|
||||
// position item slots 16px too high in the screen.
|
||||
if (isHeightHackApplied) {
|
||||
p.translate(0, 16);
|
||||
}
|
||||
|
||||
List<PositionedStack> stacks = handler.getIngredientStacks(i);
|
||||
for (PositionedStack stack : stacks) slotcontainer.addSlot(stack, p.x, p.y);
|
||||
@@ -552,11 +590,13 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
PositionedStack result = handler.getResultStack(i);
|
||||
if (result != null) slotcontainer.addSlot(result, p.x, p.y);
|
||||
|
||||
List<PositionedStack> 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<PositionedStack> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -590,21 +630,24 @@ public abstract class GuiRecipe<H extends IRecipeHandler> 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<PositionedStack> ingredients = handler.getIngredientStacks(i);
|
||||
if (itemPresenceCacheRecipe != i || itemPresenceCacheSlots == null
|
||||
@@ -624,28 +667,27 @@ public abstract class GuiRecipe<H extends IRecipeHandler> 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);
|
||||
@@ -656,7 +698,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> 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);
|
||||
@@ -668,10 +710,12 @@ public abstract class GuiRecipe<H extends IRecipeHandler> 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;
|
||||
@@ -688,7 +732,11 @@ public abstract class GuiRecipe<H extends IRecipeHandler> 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() + 40);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -724,7 +772,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
}
|
||||
|
||||
private int getRecipesPerPage() {
|
||||
return getRecipesPerPage(handlerInfo);
|
||||
return limitToOneRecipe ? 1 : getRecipesPerPage(handlerInfo);
|
||||
}
|
||||
|
||||
private int getRecipesPerPage(HandlerInfo handlerInfo) {
|
||||
@@ -735,7 +783,14 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
}
|
||||
|
||||
public Point getRecipePosition(int recipe) {
|
||||
return new Point(5, 32 + yShift + ((recipe % getRecipesPerPage()) * handlerInfo.getHeight()));
|
||||
// Legacy recipe handlers using the height hack might use getRecipePosition in combination with guiTop/height to
|
||||
// position certain elements like tooltips. Since guiTop is moved down by 16px during height hacking, we need to
|
||||
// reduce the vertical shift here to 16px instead of 32px.
|
||||
return new Point(
|
||||
5,
|
||||
(isHeightHackApplied ? 16 : 32) - (limitToOneRecipe ? 25 : 0)
|
||||
+ yShift
|
||||
+ ((recipe % getRecipesPerPage()) * handlerInfo.getHeight()));
|
||||
}
|
||||
|
||||
public abstract ArrayList<H> getCurrentRecipeHandlers();
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# Each line in this file should either be a comment (starts with '#') or a fully qualified class name (that includes the
|
||||
# package name) for a recipe handler. Wildcard patterns ('*') can be used to catch multiple classes with a single entry.
|
||||
# If you delete this file, it will be regenerated with the default height hacked handlers list.
|
||||
buildcraft.compat.nei.*
|
||||
cofh.thermalexpansion.plugins.nei.handlers.*
|
||||
crazypants.enderio.nei.*
|
||||
forestry.factory.recipes.nei.*
|
||||
ic2.neiIntegration.core.recipehandler.*
|
||||
mariculture.plugins.nei.*
|
||||
redgear.brewcraft.plugins.nei.*
|
||||
tconstruct.plugins.nei.*
|
||||
WayofTime.alchemicalWizardry.client.nei.*
|
||||
exnihilo.compatibility.nei.*
|
||||
blusunrize.immersiveengineering.client.nei.*
|
||||
@@ -0,0 +1,6 @@
|
||||
# This version of NEI loads recipes in parallel. Some recipe handlers have not been designed with that in mind and might
|
||||
# crash. List these handlers in this file to force them to be loaded a single thread. Each line in this file should
|
||||
# either be a comment (starts with '#') or a fully qualified class name (that includes the package name) for a recipe
|
||||
# handler.
|
||||
# If you delete this file, it will be regenerated with the default height hacked handlers list.
|
||||
WayofTime.alchemicalWizardry.client.nei.NEIAlchemyRecipeHandler
|
||||
@@ -373,11 +373,11 @@ NEIArcFurnaceHandlerCarrot Ingot,Immersive Engineering,minecraft:carrot,,Immersi
|
||||
NEIArcFurnaceHandlerExtraction,Immersive Engineering,minecraft:glowstone_dust,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
|
||||
blusunrize.immersiveengineering.client.nei.NEIShaderBagHandler,Immersive Engineering,ImmersiveEngineering:shaderBag,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
|
||||
blusunrize.immersiveengineering.client.nei.NEIBlueprintHandler,Immersive Engineering,ImmersiveEngineering:woodenDevice:5,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
|
||||
blusunrize.immersiveengineering.client.nei.NEICokeOvenHandler,Immersive Engineering,ImmersiveEngineering:stoneDecoration:1,,ImmersiveEngineering,TRUE,,,71,166,5,,,,,,
|
||||
blusunrize.immersiveengineering.client.nei.NEIBlastFurnaceHandler,Immersive Engineering,ImmersiveEngineering:stoneDecoration:2,,ImmersiveEngineering,TRUE,,,71,166,5,,,,,,
|
||||
blusunrize.immersiveengineering.client.nei.NEISqueezerHandler,Immersive Engineering,ImmersiveEngineering:metalMultiblock:2,,ImmersiveEngineering,TRUE,,,71,166,5,,,,,,
|
||||
blusunrize.immersiveengineering.client.nei.NEIFermenterHandler,Immersive Engineering,ImmersiveEngineering:metalMultiblock:3,,ImmersiveEngineering,TRUE,,,71,166,5,,,,,,
|
||||
blusunrize.immersiveengineering.client.nei.NEIRefineryHandler,Immersive Engineering,ImmersiveEngineering:metalMultiblock:4,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
|
||||
blusunrize.immersiveengineering.client.nei.NEICokeOvenHandler,Immersive Engineering,ImmersiveEngineering:stoneDecoration:1,,ImmersiveEngineering,TRUE,,,71,166,2,,,,,,
|
||||
blusunrize.immersiveengineering.client.nei.NEIBlastFurnaceHandler,Immersive Engineering,ImmersiveEngineering:stoneDecoration:2,,ImmersiveEngineering,TRUE,,,71,166,2,,,,,,
|
||||
blusunrize.immersiveengineering.client.nei.NEISqueezerHandler,Immersive Engineering,ImmersiveEngineering:metalMultiblock:2,,ImmersiveEngineering,TRUE,,1,64,166,2,,,,,,
|
||||
blusunrize.immersiveengineering.client.nei.NEIFermenterHandler,Immersive Engineering,ImmersiveEngineering:metalMultiblock:3,,ImmersiveEngineering,TRUE,,1,64,166,2,,,,,,
|
||||
blusunrize.immersiveengineering.client.nei.NEIRefineryHandler,Immersive Engineering,ImmersiveEngineering:metalMultiblock:4,,ImmersiveEngineering,TRUE,,,65,166,2,,,,,,
|
||||
blusunrize.immersiveengineering.client.nei.NEIBottlingMachineHandler,Immersive Engineering,minecraft:glass_bottle,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
|
||||
blusunrize.immersiveengineering.client.nei.NEIMetalPressHandler,Immersive Engineering,ImmersiveEngineering:metalMultiblock:13,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,
|
||||
blusunrize.immersiveengineering.client.nei.NEICrusherHandler,Immersive Engineering,ImmersiveEngineering:metalMultiblock:5,,ImmersiveEngineering,TRUE,,,71,166,5,,,,,,
|
||||
@@ -410,13 +410,13 @@ cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCharger,Thermal Expansio
|
||||
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCraftingMachine,Thermal Expansion,ThermalExpansion:Frame,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
|
||||
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCraftingSecure,Thermal Expansion,ThermalExpansion:material:16,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
|
||||
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCraftingUpgrade,Thermal Expansion,ThermalExpansion:Frame:3,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
|
||||
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCrucible,Thermal Expansion,ThermalExpansion:Machine:4,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
|
||||
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerCrucible,Thermal Expansion,ThermalExpansion:Machine:4,,ThermalExpansion,TRUE,,,65,166,2,,,,,,
|
||||
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerFurnace,Thermal Expansion,ThermalExpansion:Machine:0,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
|
||||
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerInsolator,Thermal Expansion,ThermalExpansion:Machine:11,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
|
||||
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerInsolator,Thermal Expansion,ThermalExpansion:Machine:11,,ThermalExpansion,TRUE,,,65,166,2,,,,,,
|
||||
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerPulverizer,Thermal Expansion,ThermalExpansion:Machine:1,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
|
||||
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerSawmill,Thermal Expansion,ThermalExpansion:Machine:2,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
|
||||
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerSmelter,Thermal Expansion,ThermalExpansion:Machine:3,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
|
||||
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerTransposer,Thermal Expansion,ThermalExpansion:Machine:5,,ThermalExpansion,TRUE,,,65,166,5,,,,,,
|
||||
cofh.thermalexpansion.plugins.nei.handlers.RecipeHandlerTransposer,Thermal Expansion,ThermalExpansion:Machine:5,,ThermalExpansion,TRUE,,,65,166,2,,,,,,
|
||||
mekanism.client.nei.ChemicalCrystallizerRecipeHandler,Mekanism,Mekanism:MachineBlock2:8,,Mekanism,TRUE,,,79,,4,,,,,,
|
||||
mekanism.client.nei.ChemicalDissolutionChamberRecipeHandler,Mekanism,Mekanism:MachineBlock2:6,,Mekanism,TRUE,,,79,,4,,,,,,
|
||||
mekanism.client.nei.ChemicalInfuserRecipeHandler,Mekanism,Mekanism:MachineBlock2:2,,Mekanism,TRUE,,,80,,4,,,,,,
|
||||
@@ -437,7 +437,7 @@ mekanism.client.nei.ShapelessMekanismRecipeHandler,Mekanism,minecraft:crafting_t
|
||||
mekanism.client.nei.SolarNeutronRecipeHandler,Mekanism,Mekanism:MachineBlock3:1,,Mekanism,TRUE,,,70,,5,,,,,,
|
||||
mekanism.client.nei.ThermalEvaporationRecipeHandler,Mekanism,Mekanism:BasicBlock:14,,Mekanism,TRUE,,,62,,5,,,,,,
|
||||
exnihilo.compatibility.nei.RecipeHandlerHammer,Ex Nihilo,exnihilo:hammer_iron,,exnihilo,TRUE,,,58,,5,,,,,,
|
||||
exnihilo.compatibility.nei.RecipeHandlerSieve,Ex Nihilo,exnihilo:sifting_table,,exnihilo,TRUE,,,130,,2,,,,,,
|
||||
exnihilo.compatibility.nei.RecipeHandlerSieve,Ex Nihilo,exnihilo:sifting_table,,exnihilo,TRUE,,,130,,1,,,,,,
|
||||
gregtech.Alloy,GregTech-Addon,gregtech_addon:machine:56,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
|
||||
gregtech.Assembler,GregTech-Addon,gregtech_addon:machine:60,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
|
||||
gregtech.Bender,GregTech-Addon,gregtech_addon:machine:59,,gregtech_addon,TRUE,,15,145,166,2,,,,,,
|
||||
|
||||
|
@@ -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
|
||||
nei.presets.label.selected=%s Presets
|
||||
Reference in new issue
Block a user