Compare commits

...
Author SHA1 Message Date
June Awesome 4058f23490 testing if this works 2026-03-22 18:53:26 -04:00
slprime 0ba14091fb Refactor DebugHandlerWidget (#900) 2026-03-22 14:10:10 +02:00
slprimeandUltraProdigy 6ed0be7961 Add Repair Handler (#899)
Co-authored-by: UltraProdigy <[email protected]>
2026-03-21 15:04:09 +02:00
slprime d40b951cce Fix areStacksSameTypeWithNBT damage check (#896) 2026-03-19 14:43:45 +02:00
slprime ecdf7892ce updateBuildScript (#895) 2026-03-19 09:39:59 +02:00
slprime 1eaaac94bc Fix filtered permutations (#893) 2026-03-18 01:25:27 +02:00
35 changed files with 1351 additions and 830 deletions

No files matched your search

+10 -10
View File
@@ -1,12 +1,12 @@
#This file is generated by updateDaemonJvm
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/df211d3c3eefdc408b462041881bc575/redirect
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/b41931cf1e70bc8e08d7dd19c343ef00/redirect
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/4945f00643ec68e7c7a6b66f90124f89/redirect
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/93aeea858331bd6bb00ba94759830234/redirect
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/3426ffcaa54c3f62406beb1f1ab8b179/redirect
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/f636c800fdb3f9ae33f019dfa048ba72/redirect
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/df211d3c3eefdc408b462041881bc575/redirect
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/93aeea858331bd6bb00ba94759830234/redirect
toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/3cd7045fca9a72cd9bc7d14a385e594c/redirect
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/552c7bffe0370c66410a51c55985b511/redirect
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/c5ee947fbfb70bc347d8d531e3a578c4/redirect
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/5ee463876563a46fff651cce1bc53a4c/redirect
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/c5ee947fbfb70bc347d8d531e3a578c4/redirect
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/5ee463876563a46fff651cce1bc53a4c/redirect
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/e1118b4c7c2858d28154d086dbff010e/redirect
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/faa12903720d410b387cc69ccafb1a74/redirect
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/c5ee947fbfb70bc347d8d531e3a578c4/redirect
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/5ee463876563a46fff651cce1bc53a4c/redirect
toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/a4c09dd2e2d7079373d30e524bbc2829/redirect
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/b96cb7670c095245220e7d01d5927b58/redirect
toolchainVersion=25
Binary file not shown.
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Vendored
+1 -1
View File
@@ -57,7 +57,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/b631911858264c0b6e4d6603d677ff5218766cee/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
+1 -1
View File
@@ -17,7 +17,7 @@ pluginManagement {
}
plugins {
id 'com.gtnewhorizons.gtnhsettingsconvention' version '2.0.21'
id 'com.gtnewhorizons.gtnhsettingsconvention' version '2.0.24'
}
@@ -0,0 +1,147 @@
package codechicken.nei;
import net.minecraft.client.gui.GuiRepair;
import net.minecraft.client.gui.inventory.GuiBrewingStand;
import net.minecraft.client.gui.inventory.GuiCrafting;
import net.minecraft.client.gui.inventory.GuiFurnace;
import net.minecraft.client.gui.inventory.GuiInventory;
import net.minecraft.nbt.NBTTagCompound;
import codechicken.nei.api.API;
import codechicken.nei.recipe.BrewingOverlayHandler;
import codechicken.nei.recipe.BrewingRecipeHandler;
import codechicken.nei.recipe.DefaultOverlayHandler;
import codechicken.nei.recipe.FireworkRecipeHandler;
import codechicken.nei.recipe.FuelRecipeHandler;
import codechicken.nei.recipe.FurnaceRecipeHandler;
import codechicken.nei.recipe.InformationHandler;
import codechicken.nei.recipe.ProfilerRecipeHandler;
import codechicken.nei.recipe.RepairOverlayHandler;
import codechicken.nei.recipe.RepairRecipeHandler;
import codechicken.nei.recipe.ShapedRecipeHandler;
import codechicken.nei.recipe.ShapelessRecipeHandler;
import cpw.mods.fml.common.event.FMLInterModComms;
public class IMCForNEI {
public static void IMCSender() {
API.registerRecipeHandler(new ShapedRecipeHandler());
API.registerUsageHandler(new ShapedRecipeHandler());
sendHandler("codechicken.nei.recipe.ShapedRecipeHandler", "minecraft:crafting_table");
API.registerRecipeHandler(new ShapelessRecipeHandler());
API.registerUsageHandler(new ShapelessRecipeHandler());
sendHandler("codechicken.nei.recipe.ShapelessRecipeHandler", "minecraft:crafting_table");
API.registerRecipeHandler(new FireworkRecipeHandler());
API.registerUsageHandler(new FireworkRecipeHandler());
sendHandler("codechicken.nei.recipe.FireworkRecipeHandler", "minecraft:fireworks");
API.registerRecipeHandler(new FurnaceRecipeHandler());
API.registerUsageHandler(new FurnaceRecipeHandler());
sendHandler("codechicken.nei.recipe.FurnaceRecipeHandler", "minecraft:furnace");
API.registerRecipeHandler(new BrewingRecipeHandler());
API.registerUsageHandler(new BrewingRecipeHandler());
sendHandler("codechicken.nei.recipe.BrewingRecipeHandler", "minecraft:brewing_stand");
API.registerRecipeHandler(new FuelRecipeHandler());
API.registerUsageHandler(new FuelRecipeHandler());
sendFuelRecipeHandler();
API.registerRecipeHandler(new InformationHandler());
API.registerUsageHandler(new InformationHandler());
sendInformationHandler();
API.registerRecipeHandler(new RepairRecipeHandler());
API.registerUsageHandler(new RepairRecipeHandler());
sendRepairHandler();
sendCatalyst("repair", "minecraft:anvil");
API.registerGuiOverlay(GuiCrafting.class, "crafting");
API.registerGuiOverlay(GuiInventory.class, "crafting2x2", 63, 20);
API.registerGuiOverlay(GuiFurnace.class, "smelting");
API.registerGuiOverlay(GuiFurnace.class, "fuel");
API.registerGuiOverlay(GuiBrewingStand.class, "brewing");
API.registerGuiOverlay(GuiRepair.class, "repair", 2, 37);
API.registerGuiOverlayHandler(GuiCrafting.class, new DefaultOverlayHandler(), "crafting");
API.registerGuiOverlayHandler(GuiInventory.class, new DefaultOverlayHandler(63, 20), "crafting2x2");
API.registerGuiOverlayHandler(GuiBrewingStand.class, new BrewingOverlayHandler(), "brewing");
API.registerGuiOverlayHandler(GuiRepair.class, new RepairOverlayHandler(), "repair");
API.registerRecipeHandler(new ProfilerRecipeHandler(true));
API.registerUsageHandler(new ProfilerRecipeHandler(false));
}
private static void sendHandler(String aName, String aBlock) {
NBTTagCompound aNBT = new NBTTagCompound();
aNBT.setString("handler", aName);
aNBT.setString("modName", "Minecraft");
aNBT.setString("modId", "minecraft");
aNBT.setString("itemName", aBlock);
aNBT.setInteger("handlerWidth", 166);
aNBT.setInteger("handlerHeight", 65);
aNBT.setBoolean("multipleWidgetsAllowed", true);
aNBT.setInteger("yShift", 0);
FMLInterModComms.sendMessage("NotEnoughItems", "registerHandlerInfo", aNBT);
}
private static void sendRepairHandler() {
NBTTagCompound aNBT = new NBTTagCompound();
aNBT.setString("handler", "codechicken.nei.recipe.RepairRecipeHandler");
aNBT.setString("modName", "Minecraft");
aNBT.setString("modId", "minecraft");
aNBT.setString("itemName", "minecraft:anvil");
aNBT.setInteger("handlerHeight", 39);
aNBT.setInteger("handlerWidth", 166);
aNBT.setBoolean("multipleWidgetsAllowed", true);
aNBT.setBoolean("showFavoritesButton", false);
aNBT.setInteger("yShift", 0);
FMLInterModComms.sendMessage("NotEnoughItems", "registerHandlerInfo", aNBT);
}
private static void sendFuelRecipeHandler() {
NBTTagCompound aNBT = new NBTTagCompound();
aNBT.setString("handler", "codechicken.nei.recipe.FuelRecipeHandler");
aNBT.setString("modName", "Minecraft");
aNBT.setString("modId", "minecraft");
aNBT.setString("imageResource", "nei:textures/nei_tabbed_sprites.png");
aNBT.setInteger("imageX", 80);
aNBT.setInteger("imageY", 0);
aNBT.setInteger("imageWidth", 14);
aNBT.setInteger("imageHeight", 14);
aNBT.setInteger("handlerHeight", 65);
aNBT.setInteger("handlerWidth", 166);
aNBT.setBoolean("multipleWidgetsAllowed", true);
aNBT.setInteger("yShift", 0);
FMLInterModComms.sendMessage("NotEnoughItems", "registerHandlerInfo", aNBT);
}
private static void sendInformationHandler() {
NBTTagCompound aNBT = new NBTTagCompound();
aNBT.setString("handler", "codechicken.nei.recipe.InformationHandler");
aNBT.setString("modName", "Not Enough Items");
aNBT.setString("modId", "nei");
aNBT.setString("imageResource", "nei:textures/nei_tabbed_sprites.png");
aNBT.setInteger("imageX", 96);
aNBT.setInteger("imageY", 0);
aNBT.setInteger("imageWidth", 16);
aNBT.setInteger("imageHeight", 16);
aNBT.setInteger("handlerHeight", 65);
aNBT.setInteger("handlerWidth", 166);
aNBT.setBoolean("multipleWidgetsAllowed", true);
aNBT.setInteger("yShift", 0);
FMLInterModComms.sendMessage("NotEnoughItems", "registerHandlerInfo", aNBT);
}
private static void sendCatalyst(String aName, String aStack) {
NBTTagCompound aNBT = new NBTTagCompound();
aNBT.setString("handlerID", aName);
aNBT.setString("itemName", aStack);
aNBT.setInteger("priority", 0);
FMLInterModComms.sendMessage("NotEnoughItems", "registerCatalystInfo", aNBT);
}
}
@@ -32,6 +32,7 @@ import codechicken.nei.api.ItemFilter.ItemFilterProvider;
import codechicken.nei.api.ItemInfo;
import codechicken.nei.recipe.InformationHandler;
import codechicken.nei.recipe.RecipeHandlerRef;
import codechicken.nei.recipe.RepairRecipeHandler;
import codechicken.nei.search.TooltipFilter;
import codechicken.nei.util.ItemUntranslator;
import cpw.mods.fml.common.FMLLog;
@@ -433,6 +434,7 @@ public class ItemList {
loadFinished = true;
RepairRecipeHandler.findRepairRecipesOnceParallel();
RecipeHandlerRef.clearCache();
FavoriteRecipes.reload();
SubsetWidget.updateHiddenItems();
@@ -66,9 +66,9 @@ import codechicken.nei.guihook.IContainerInputHandler;
import codechicken.nei.guihook.IContainerObjectHandler;
import codechicken.nei.guihook.IContainerTooltipHandler;
import codechicken.nei.recipe.AutoCraftingManager;
import codechicken.nei.recipe.DebugHandlerWidget;
import codechicken.nei.recipe.GuiRecipeTab;
import codechicken.nei.recipe.RecipeCatalysts;
import codechicken.nei.recipe.debug.DebugHandlerWidget;
public class LayoutManager implements IContainerInputHandler, IContainerTooltipHandler, IContainerDrawHandler,
IContainerObjectHandler, IKeyStateTracker {
@@ -92,7 +92,6 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
public static SubsetWidget dropDown;
public static SearchField searchField;
public static ItemZoom itemZoom;
public static DebugHandlerWidget recipeHandlerWidget;
public static ButtonCycled options;
public static ButtonCycled bookmarksButton;
@@ -406,8 +405,6 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
itemZoom = new ItemZoom();
recipeHandlerWidget = new DebugHandlerWidget();
dropDown = new SubsetWidget();
searchField = new SearchField("search");
API.addItemFilter(searchField);
@@ -786,8 +783,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
addWidget(dropDown);
}
addWidget(recipeHandlerWidget);
recipeHandlerWidget.setVisible();
addWidget(DebugHandlerWidget.instance);
}
public static LayoutStyle getLayoutStyle(int id) {
@@ -56,12 +56,10 @@ import codechicken.nei.config.OptionToggleButtonBoubs;
import codechicken.nei.config.OptionUtilities;
import codechicken.nei.config.preset.GuiPresetList;
import codechicken.nei.event.NEIConfigsLoadedEvent;
import codechicken.nei.recipe.DebugHandlerWidget;
import codechicken.nei.recipe.GuiRecipeTab;
import codechicken.nei.recipe.IRecipeHandler;
import codechicken.nei.recipe.InformationHandler;
import codechicken.nei.recipe.RecipeCatalysts;
import codechicken.nei.recipe.RecipeInfo;
import codechicken.nei.util.ItemUntranslator;
import codechicken.nei.util.NEIKeyboardUtils;
import codechicken.obfuscator.ObfuscationRun;
@@ -149,6 +147,7 @@ public class NEIClientConfig {
API.addOption(new OptionToggleButton("inventory.widgetsenabled"));
tag.getTag("findFuelsParallel").getBooleanValue(true);
tag.getTag("showRepairOnlyForDamageableItems").getBooleanValue(true);
tag.getTag("inventory.autocrafting").getBooleanValue(true);
tag.getTag("inventory.dynamicFontSize").getBooleanValue(true);
@@ -978,7 +977,6 @@ public class NEIClientConfig {
// main NEI config loading
ItemInfo.load();
GuiInfo.load();
RecipeInfo.load();
HeldItemHandler.load();
LayoutManager.load();
NEIController.load();
@@ -1018,8 +1016,6 @@ public class NEIClientConfig {
// API. I don't expect any handler to do this, but who knows what modders have come up with...
pluginNEIConfigLoaded = true;
MinecraftForge.EVENT_BUS.post(new NEIConfigsLoadedEvent());
DebugHandlerWidget.loadHandlerInfoPatch();
ItemList.loadItems.restart();
}
}.start();
@@ -104,6 +104,7 @@ public class NEIModContainer extends DummyModContainer {
public void init(FMLInitializationEvent event) {
if (CommonUtils.isClient()) {
ClientHandler.load();
IMCForNEI.IMCSender();
}
ServerHandler.load();
}
@@ -183,7 +183,7 @@ public class NEIServerUtils {
public static boolean areStacksSameTypeWithNBT(ItemStack stack1, ItemStack stack2) {
return stack1 != null && stack2 != null
&& stack1.getItem() == stack2.getItem()
&& (!stack2.getHasSubtypes() || stack2.getItemDamage() == stack1.getItemDamage())
&& (stack2.isItemStackDamageable() || stack2.getItemDamage() == stack1.getItemDamage())
&& NBTHelper.matchTag(stack1.getTagCompound(), stack2.getTagCompound());
}
@@ -93,7 +93,8 @@ public class IMCHandler {
final boolean multipleWidgetsAllowed = tag.hasKey("multipleWidgetsAllowed")
? tag.getBoolean("multipleWidgetsAllowed")
: tag.hasKey("maxRecipesPerPage") && tag.getInteger("maxRecipesPerPage") > 1;
info.setHandlerDimensions(handlerWidth, handlerHeight, multipleWidgetsAllowed);
info.setHandlerDimensions(handlerWidth, handlerHeight);
info.setMultipleWidgetsAllowed(multipleWidgetsAllowed);
} catch (NumberFormatException ignored) {
NEIClientConfig.logger.info("Error setting handler dimensions for {}", handler);
}
@@ -1,718 +0,0 @@
package codechicken.nei.recipe;
import java.awt.Point;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.stream.Collectors;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.util.EnumChatFormatting;
import org.apache.commons.io.IOUtils;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
import codechicken.lib.gui.GuiDraw;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.Button;
import codechicken.nei.ClientHandler;
import codechicken.nei.FormattedTextField;
import codechicken.nei.LayoutManager;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.TextField;
import codechicken.nei.Widget;
import codechicken.nei.drawable.DrawableBuilder;
import codechicken.nei.drawable.DrawableResource;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.guihook.IContainerInputHandler;
import codechicken.nei.recipe.TemplateRecipeHandler.RecipeTransferRect;
public class DebugHandlerWidget extends Widget implements IContainerInputHandler {
private static abstract class IntegerField extends TextField {
protected int defaultValue = 0;
public IntegerField(String ident, int defaultValue) {
super(ident);
this.defaultValue = defaultValue;
this.h = LINE_HEIGHT;
this.z = 2;
((FormattedTextField) field).setPlaceholder(Integer.toString(this.defaultValue));
}
@Override
protected void initInternalTextField() {
field = new FormattedTextField(Minecraft.getMinecraft().fontRenderer, 0, 0, 0, 0) {
@Override
public String getText() {
String text = super.getText();
return !isFocused() && this.placeholder.equals(text) ? "" : text;
}
@Override
protected boolean beforeWrite(String text) {
if (text == null || text.isEmpty()) return true;
try {
return Integer.parseInt(text) >= 0;
} catch (NumberFormatException e) {
return false;
}
}
@Override
public boolean textboxKeyTyped(char keyChar, int keyID) {
if (!isFocused()) return false;
if (super.textboxKeyTyped(keyChar, keyID)) {
return true;
} else if (keyID == Keyboard.KEY_DOWN) {
setText(Integer.toString(getInteger() - 1));
return true;
} else if (keyID == Keyboard.KEY_UP) {
setText(Integer.toString(getInteger() + 1));
return true;
}
return false;
}
};
field.setMaxStringLength(maxSearchLength);
field.setCursorPositionZero();
}
protected int getInteger() {
try {
return Integer.parseInt(text());
} catch (NumberFormatException nfe) {
return this.defaultValue;
}
}
@Override
public boolean onMouseWheel(int i, int mx, int my) {
if (!contains(mx, my)) return false;
setText(Integer.toString(getInteger() + i));
return true;
}
}
private final int[] COLORS = new int[] { 0x2200FF00, 0x22FF0000, 0x220000FF, 0x2200FFFF, 0x22FF00FF, 0x22FFFF00 };
private IRecipeHandler handler;
private HandlerInfo handlerInfo;
private static final int WINDOW_WIDTH = 176;
private static final int LINE_HEIGHT = 16;
private static final int INLINE_PADDING = 6;
private static final int LABEL_WIDTH = 50;
private IntegerField order;
private IntegerField yShift;
private IntegerField handlerHeight;
private IntegerField handlerWidth;
private Button multipleWidgetsAllowed;
private Button useCustomScroll;
private Point dragPoint = null;
public boolean showWidget = false;
private static final int BORDER_PADDING = 6;
private static final int TRANSPARENCY_BORDER = 4;
private static final String TOOLTIP_PREFIX = "debug.RecipeHandler.";
private static final Map<String, String> TOOLTIP_KEYS = new HashMap<>();
static {
TOOLTIP_KEYS.put("Name", TOOLTIP_PREFIX + "Name");
TOOLTIP_KEYS.put("ID", TOOLTIP_PREFIX + "Id");
TOOLTIP_KEYS.put("Key", TOOLTIP_PREFIX + "Key");
TOOLTIP_KEYS.put("H.Hack", TOOLTIP_PREFIX + "HHack");
TOOLTIP_KEYS.put("Mod Name", TOOLTIP_PREFIX + "ModName");
TOOLTIP_KEYS.put("Mod ID", TOOLTIP_PREFIX + "ModId");
TOOLTIP_KEYS.put("Order", TOOLTIP_PREFIX + "Order");
TOOLTIP_KEYS.put("yShift", TOOLTIP_PREFIX + "yShift");
TOOLTIP_KEYS.put("Multi Widgets", TOOLTIP_PREFIX + "MultiWidgets");
TOOLTIP_KEYS.put("Height", TOOLTIP_PREFIX + "Height");
TOOLTIP_KEYS.put("Width", TOOLTIP_PREFIX + "Width");
TOOLTIP_KEYS.put("Use Custom Scroll", TOOLTIP_PREFIX + "UseCustomScroll");
}
private final DrawableResource BG_TEXTURE = new DrawableBuilder(
"nei:textures/gui/recipebg.png",
0,
0,
176 + TRANSPARENCY_BORDER * 2,
166 + TRANSPARENCY_BORDER * 2).build();
public DebugHandlerWidget() {
GuiContainerManager.addInputHandler(this);
this.order = new IntegerField("order", 0) {
@Override
public void onTextChange(String oldText) {
if (NEIClientConfig.handlerOrdering.get(handler.getOverlayIdentifier()) != null) {
if (getInteger() != NEIClientConfig.handlerOrdering.get(handler.getOverlayIdentifier())) {
updatePatch(5, getInteger(), this.defaultValue);
}
} else if (NEIClientConfig.handlerOrdering.get(handler.getHandlerId()) != null) {
if (getInteger() != NEIClientConfig.handlerOrdering.get(handler.getHandlerId())) {
updatePatch(5, getInteger(), this.defaultValue);
}
}
}
};
this.yShift = new IntegerField("yShift", 0) {
@Override
public void onTextChange(String oldText) {
if (getInteger() != handlerInfo.getYShift()) {
handlerInfo.setYShift(getInteger());
updatePatch(1, getInteger(), this.defaultValue);
}
}
};
this.multipleWidgetsAllowed = new Button() {
{
this.h = LINE_HEIGHT;
this.z = 2;
}
public String getRenderLabel() {
return handlerInfo.isMultipleWidgetsAllowed() ? "On" : "Off";
}
@Override
public boolean onButtonPress(boolean rightclick) {
handlerInfo.setHandlerDimensions(
handlerInfo.getWidth(),
handlerInfo.getHeight(),
!handlerInfo.isMultipleWidgetsAllowed());
updatePatch(4, handlerInfo.isMultipleWidgetsAllowed() ? 1 : 0, 1);
return true;
}
};
this.handlerHeight = new IntegerField("handlerHeight", HandlerInfo.DEFAULT_HEIGHT) {
@Override
public void draw(int mx, int my) {
this.field.setEnabled(handler.getRecipeHeight(0) <= 0);
super.draw(mx, my);
}
@Override
public void onTextChange(String oldText) {
if (getInteger() != handlerInfo.getHeight()) {
handlerInfo.setHandlerDimensions(
handlerInfo.getWidth(),
getInteger(),
handlerInfo.isMultipleWidgetsAllowed());
updatePatch(2, getInteger(), this.defaultValue);
}
}
};
this.handlerWidth = new IntegerField("handlerWidth", HandlerInfo.DEFAULT_WIDTH) {
@Override
public void onTextChange(String oldText) {
if (getInteger() != handlerInfo.getWidth()) {
handlerInfo.setHandlerDimensions(
getInteger(),
handlerInfo.getHeight(),
handlerInfo.isMultipleWidgetsAllowed());
updatePatch(3, getInteger(), this.defaultValue);
}
}
};
this.useCustomScroll = new Button() {
{
this.h = LINE_HEIGHT;
this.z = 2;
}
public String getRenderLabel() {
return handlerInfo.getUseCustomScroll() ? "On" : "Off";
}
@Override
public boolean onButtonPress(boolean rightclick) {
handlerInfo.setUseCustomScroll(!handlerInfo.getUseCustomScroll());
updatePatch(6, handlerInfo.getUseCustomScroll() ? 1 : 0, 0);
return true;
}
};
this.w = WINDOW_WIDTH;
this.h = 10 + 13 * LINE_HEIGHT;
this.x = 10;
this.y = 50;
this.z = 1;
}
private void updatePatch(int key, int value, int defaultValue) {
final String handlerKey = getHandlerID(handler);
if (!patches.containsKey(handlerKey)) {
patches.put(handlerKey, new String[] { handlerKey, null, null, null, null, null, null });
}
if (value == defaultValue) {
patches.get(handlerKey)[key] = null;
} else {
patches.get(handlerKey)[key] = String.valueOf(value);
}
saveHandlerInfoPatch();
if (NEIClientUtils.getGuiContainer() instanceof GuiRecipe<?>recipe) {
recipe.forceRefreshPage();
}
}
private void drawKeyLabel(String keyLabel, int topShift) {
final String displayLabel = translateDisplayLabel(keyLabel);
GuiDraw.drawString(
NEIClientUtils.cropText(GuiDraw.fontRenderer, displayLabel, LABEL_WIDTH),
this.x + INLINE_PADDING,
topShift,
0x66555555,
false);
GuiDraw.drawString(":", this.x + INLINE_PADDING + LABEL_WIDTH, topShift, 0x66555555, false);
}
private void drawDetail(String keyLabel, String valueLabel, int topShift, int spaceWidth) {
drawKeyLabel(keyLabel, topShift);
GuiDraw.drawString(
NEIClientUtils.cropText(
GuiDraw.fontRenderer,
valueLabel,
this.w - INLINE_PADDING * 2 - LABEL_WIDTH - spaceWidth),
this.x + INLINE_PADDING + LABEL_WIDTH + spaceWidth,
topShift,
0xffffff);
}
private void drawControl(String keyLabel, Widget field, int topShift, int spaceWidth) {
drawKeyLabel(keyLabel, topShift);
field.x = this.x + INLINE_PADDING + LABEL_WIDTH + spaceWidth;
field.y = topShift - 4;
field.w = this.w - INLINE_PADDING * 2 - LABEL_WIDTH - spaceWidth;
}
private static String translateTooltipLabel(String label) {
String key = TOOLTIP_KEYS.get(label);
String text = label;
if (key == null) {
return EnumChatFormatting.WHITE + EnumChatFormatting.getTextWithoutFormattingCodes(text);
}
text = NEIClientUtils.translate(key);
return EnumChatFormatting.WHITE + EnumChatFormatting.getTextWithoutFormattingCodes(text);
}
private static String translateDisplayLabel(String label) {
String key = TOOLTIP_KEYS.get(label);
if (key == null) {
return label;
}
return NEIClientUtils.translate(key);
}
@Override
public void draw(int mx, int my) {
if (this.handler != null) {
final int spaceWidth = GuiDraw.fontRenderer.getStringWidth(": ");
int topShift = this.y + BORDER_PADDING + 12 + 6;
GL11.glColor4f(1F, 1F, 1F, 1F);
GL11.glScaled(1, 1, 2f);
GL11.glDisable(GL11.GL_DEPTH_TEST);
BG_TEXTURE.draw(
this.x - TRANSPARENCY_BORDER,
this.y - TRANSPARENCY_BORDER,
this.w + TRANSPARENCY_BORDER * 2,
this.h + TRANSPARENCY_BORDER * 2,
BORDER_PADDING + TRANSPARENCY_BORDER,
BORDER_PADDING + TRANSPARENCY_BORDER,
BORDER_PADDING + TRANSPARENCY_BORDER,
BORDER_PADDING + TRANSPARENCY_BORDER);
GuiDraw.drawRect(
this.x + INLINE_PADDING,
this.y + BORDER_PADDING,
this.w - INLINE_PADDING * 2,
12,
0x30000000);
GuiDraw.drawStringC(
NEIClientUtils.translate("debug.RecipeHandler.title"),
this.x + this.w / 2,
this.y + BORDER_PADDING + 2,
0xffffff);
for (Map.Entry<String, String> entry : getDetailsInfo().entrySet()) {
drawDetail(entry.getKey(), entry.getValue(), topShift, spaceWidth);
topShift += LINE_HEIGHT;
}
drawControl("Order", this.order, topShift, spaceWidth);
topShift += LINE_HEIGHT;
drawControl("yShift", this.yShift, topShift, spaceWidth);
topShift += LINE_HEIGHT;
drawControl("Multi Widgets", this.multipleWidgetsAllowed, topShift, spaceWidth);
topShift += LINE_HEIGHT;
drawControl("Height", this.handlerHeight, topShift, spaceWidth);
topShift += LINE_HEIGHT;
drawControl("Width", this.handlerWidth, topShift, spaceWidth);
topShift += LINE_HEIGHT;
drawControl("Use Custom Scroll", this.useCustomScroll, topShift, spaceWidth);
topShift += LINE_HEIGHT;
GL11.glScaled(1, 1, 1 / 2f);
}
}
private Map<String, String> getDetailsInfo() {
final Map<String, String> lines = new LinkedHashMap<>();
final boolean isHeightHackApplied = NEIClientConfig.heightHackHandlerRegex.stream()
.map(pattern -> pattern.matcher(this.handler.getHandlerId())).anyMatch(Matcher::matches);
lines.put("Name", this.handler.getRecipeName());
lines.put("ID", this.handler.getOverlayIdentifier());
lines.put("Key", this.handler.getHandlerId());
lines.put("H.Hack", String.valueOf(isHeightHackApplied));
lines.put("Mod Name", this.handlerInfo.getModName());
lines.put("Mod ID", this.handlerInfo.getModId());
return lines;
}
public void setVisible() {
if (showWidget && this.handler != null) {
LayoutManager.addWidget(this.order);
LayoutManager.addWidget(this.yShift);
LayoutManager.addWidget(this.handlerHeight);
LayoutManager.addWidget(this.handlerWidth);
LayoutManager.addWidget(this.multipleWidgetsAllowed);
LayoutManager.addWidget(this.useCustomScroll);
}
}
@Override
public void update() {
final GuiContainer gui = NEIClientUtils.getGuiContainer();
if (showWidget && gui instanceof GuiRecipe recipe) {
if (this.handler != recipe.getHandler()) {
this.handler = recipe.getHandler();
this.handlerInfo = GuiRecipeTab.getHandlerInfo(handler);
this.order.setText(String.valueOf(NEIClientConfig.getHandlerOrder(this.handler)));
this.yShift.setText(String.valueOf(this.handlerInfo.getYShift()));
this.handlerHeight.setText(String.valueOf(this.handlerInfo.getHeight()));
this.handlerWidth.setText(String.valueOf(this.handlerInfo.getWidth()));
}
} else {
this.handler = null;
this.handlerInfo = null;
showWidget = false;
}
}
@Override
public List<String> handleTooltip(int mx, int my, List<String> tooltip) {
if (this.handler != null) {
final int spaceWidth = GuiDraw.fontRenderer.getStringWidth(": ");
final int leftShift = this.x + INLINE_PADDING;
if (mx >= leftShift && mx < this.x + WINDOW_WIDTH - INLINE_PADDING) {
int topShift = this.y + BORDER_PADDING + 12 + 6;
for (Map.Entry<String, String> entry : getDetailsInfo().entrySet()) {
if (my >= topShift && my < topShift + LINE_HEIGHT) {
if (mx < leftShift + LABEL_WIDTH + spaceWidth) {
tooltip.add(translateTooltipLabel(entry.getKey()));
} else {
tooltip.add(String.valueOf(entry.getValue()));
}
return tooltip;
}
topShift += LINE_HEIGHT;
}
String[] controlLabels = new String[] { "Order", "yShift", "Multi Widgets", "Height", "Width",
"Use Custom Scroll" };
for (String label : controlLabels) {
if (my >= topShift && my < topShift + LINE_HEIGHT) {
tooltip.add(translateTooltipLabel(label));
return tooltip;
}
topShift += LINE_HEIGHT;
}
}
}
return tooltip;
}
@Override
public boolean keyTyped(GuiContainer gui, char keyChar, int keyCode) {
if (NEIClientConfig.getBooleanSetting("inventory.guirecipe.handlerInfo") && showWidget
&& keyCode == Keyboard.KEY_C
&& NEIClientUtils.controlKey()) {
final int spaceWidth = GuiDraw.fontRenderer.getStringWidth(": ");
final Point mouse = GuiDraw.getMousePosition();
if (mouse.x >= this.x + INLINE_PADDING + LABEL_WIDTH + spaceWidth
&& mouse.x < this.x + WINDOW_WIDTH - INLINE_PADDING) {
int topShift = this.y + BORDER_PADDING + 12 + 6;
for (Map.Entry<String, String> entry : getDetailsInfo().entrySet()) {
if (mouse.y >= topShift && mouse.y < topShift + LINE_HEIGHT) {
GuiScreen.setClipboardString(entry.getValue());
return true;
}
topShift += LINE_HEIGHT;
}
}
}
return false;
}
@Override
public boolean mouseClicked(GuiContainer gui, int mousex, int mousey, int button) {
return false;
}
@Override
public void onKeyTyped(GuiContainer gui, char keyChar, int keyID) {}
@Override
public boolean lastKeyTyped(GuiContainer gui, char keyChar, int keyID) {
if (NEIClientConfig.getBooleanSetting("inventory.guirecipe.handlerInfo") && keyID == Keyboard.KEY_D
&& NEIClientUtils.shiftKey()) {
showWidget = !showWidget;
return true;
} else if (this.handler != null) {
return this.order.focused() || this.yShift.focused()
|| this.handlerHeight.focused()
|| this.handlerWidth.focused();
}
return false;
}
@Override
public void onMouseClicked(GuiContainer gui, int mousex, int mousey, int button) {
if (this.handler != null
&& new Rectangle4i(this.x + INLINE_PADDING, this.y + BORDER_PADDING, this.w - INLINE_PADDING * 2, 12)
.contains(mousex, mousey)) {
this.dragPoint = new Point(mousex, mousey);
}
}
@Override
public boolean contains(int px, int py) {
return this.handler != null && super.contains(px, py);
}
@Override
public void onMouseUp(GuiContainer gui, int mousex, int mousey, int button) {
this.dragPoint = null;
}
@Override
public boolean mouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled) {
return false;
}
@Override
public void onMouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled) {}
@Override
public boolean handleClickExt(int mx, int my, int button) {
return false;
}
@Override
public void onMouseDragged(GuiContainer gui, int mousex, int mousey, int button, long heldTime) {
if (this.dragPoint != null) {
this.x -= this.dragPoint.x - mousex;
this.y -= this.dragPoint.y - mousey;
this.dragPoint.move(mousex, mousey);
}
}
public void drawGuiPlaceholder(NEIRecipeWidget widget) {
if (!showWidget) return;
NEIClientUtils.gl2DRenderContext(() -> {
// background
GuiDraw.drawRect(
widget.x,
widget.y,
widget.w,
widget.h,
COLORS[widget.handlerRef.recipeIndex % COLORS.length]);
// center cross
GuiDraw.drawRect(widget.x + widget.w / 2 - 1, widget.y, 1, widget.h, 0x88ffffff);
GuiDraw.drawRect(widget.x, widget.y + widget.h / 2 - 1, widget.w, 1, 0x88ffffff);
// blue-line-top (grid-top)
GuiDraw.drawRect(widget.x + 14, widget.y + 5, widget.w - 38, 1, 0xff0000aa);
// blue-line-bottom {grid-bottom}
GuiDraw.drawRect(widget.x + 14, widget.y + widget.h - 7, widget.w - 38, 1, 0xff0000aa);
// blue-left (grid start)
GuiDraw.drawRect(widget.x + 24, widget.y + (widget.h - 16) / 2, 1, 16, 0xffaa00aa);
// purple (before favorite)
GuiDraw.drawRect(
widget.x + Math.min(168, widget.w) - 27,
widget.y + widget.h - 6 - GuiRecipeButton.BUTTON_HEIGHT * 2 - 4,
GuiRecipeButton.BUTTON_WIDTH,
1,
0xffaa00aa);
// green ()
GuiDraw.drawRect(
widget.x + Math.min(168, widget.w) - 35,
widget.y + widget.h - 6 - GuiRecipeButton.BUTTON_HEIGHT - 3,
20,
1,
0xff00aa00);
// purple space before bottom grid
GuiDraw.drawRect(
widget.x + 14,
widget.y + widget.h - 7 - GuiRecipeButton.BUTTON_WIDTH / 2,
38,
1,
0xffaa00aa);
if (widget.handlerRef.handler instanceof TemplateRecipeHandler handler) {
int yShift = widget.getHandlerInfo().getYShift();
for (RecipeTransferRect rect : handler.transferRects) {
GuiDraw.drawRect(
widget.x + rect.rect.x,
widget.y + yShift + rect.rect.y,
rect.rect.width,
rect.rect.height,
0x40ff0000);
}
}
});
}
private static Map<String, String[]> patches = new HashMap<>();
public static void loadHandlerInfoPatch() {
ClientHandler.loadSettingsFile("handlers.patch", lines -> {
for (String line : lines.collect(Collectors.toCollection(HashSet::new))) {
final String[] parts = line.split(",");
final String handler = parts[0];
if (GuiRecipeTab.handlerMap.containsKey(handler)) {
final HandlerInfo info = GuiRecipeTab.handlerMap.get(handler);
final int yShift = intOrDefault(parts[1], info.getYShift());
final int height = intOrDefault(parts[2], info.getHeight());
final int width = intOrDefault(parts[3], info.getWidth());
final boolean isMultipleWidgetsAllowed = intOrDefault(
parts[4],
info.isMultipleWidgetsAllowed() ? 1 : 0) == 1;
final int order = intOrDefault(parts[5], NEIClientConfig.handlerOrdering.getOrDefault(handler, 0));
final boolean useCustomScroll = intOrDefault(parts[6], info.getUseCustomScroll() ? 1 : 0) == 1;
info.setYShift(yShift);
info.setHandlerDimensions(width, height, isMultipleWidgetsAllowed);
info.setUseCustomScroll(useCustomScroll);
NEIClientConfig.handlerOrdering.put(handler, order);
}
patches.put(handler, parts);
}
});
}
private static void saveHandlerInfoPatch() {
final List<String> lines = new ArrayList<>();
for (String[] line : patches.values()) {
lines.add(String.join(",", line));
}
final File path = new File(NEIClientConfig.configDir, "handlers.patch");
try (FileOutputStream output = new FileOutputStream(path)) {
IOUtils.writeLines(lines, "\n", output, StandardCharsets.UTF_8);
} catch (IOException e) {}
}
private static int intOrDefault(String str, int defaultValue) {
if (str == null || str.equals("")) return defaultValue;
try {
return Integer.parseInt(str);
} catch (NumberFormatException e) {
return defaultValue;
}
}
private static String getHandlerID(IRecipeHandler handler) {
if (GuiRecipeTab.handlerMap.containsKey(handler.getHandlerId())) {
return handler.getHandlerId();
} else if (handler instanceof TemplateRecipeHandler) {
return handler.getOverlayIdentifier();
}
return null;
}
}
@@ -98,10 +98,14 @@ public class DefaultOverlayHandler implements IOverlayHandler {
&& presenceOverlay(firstGui, handler, recipeIndex).stream().allMatch(state -> state.isPresent());
}
protected Slot getCraftingResultSlot(GuiContainer gui) {
return gui.inventorySlots.inventorySlots.stream().filter(slot -> slot instanceof SlotCrafting).findFirst()
.orElse(null);
}
@Override
public boolean craft(GuiContainer firstGui, IRecipeHandler handler, int recipeIndex, int multiplier) {
final Slot craftingSlot = firstGui.inventorySlots.inventorySlots.stream()
.filter(slot -> slot instanceof SlotCrafting).findFirst().orElse(null);
final Slot craftingSlot = getCraftingResultSlot(firstGui);
if (craftingSlot == null) {
return false;
@@ -145,7 +149,7 @@ public class DefaultOverlayHandler implements IOverlayHandler {
/**
* Gets the slots in the crafting matrix for the given GUI and recipe handler.
*
*
* @param gui
* @param handler
* @return
@@ -194,9 +198,10 @@ public class DefaultOverlayHandler implements IOverlayHandler {
}
private void moveIngredients(GuiContainer gui, List<IngredientDistribution> assignedIngredients, int multiplier) {
final Slot craftingSlot = getCraftingResultSlot(gui);
for (Slot slot : gui.inventorySlots.inventorySlots) {
if (slot instanceof SlotCrafting || !slot.getHasStack()
if (slot == craftingSlot || !slot.getHasStack()
|| !canMoveFrom(slot, gui)
|| !slot.canTakeStack(gui.mc.thePlayer))
continue;
@@ -422,8 +427,8 @@ public class DefaultOverlayHandler implements IOverlayHandler {
return null;
}
protected boolean canStack(ItemStack stack1, ItemStack stack2) {
if (stack1 == null || stack2 == null) return true;
return NEIClientUtils.areStacksSameTypeCraftingWithNBT(stack1, stack2);
protected boolean canStack(ItemStack dst, ItemStack src) {
if (dst == null || src == null) return true;
return NEIClientUtils.areStacksSameTypeCraftingWithNBT(dst, src);
}
}
@@ -96,10 +96,11 @@ public class GuiOverlayButton extends GuiRecipeButton {
super(handlerRef, x, y, handlerRef.recipeIndex + BUTTON_ID_SHIFT, "+");
this.firstGui = firstGui != null && firstGui.inventorySlots != null ? firstGui : null;
this.canUseOverlayRenderer = this.firstGui != null && handlerRef.getRecipeOverlayRenderer(firstGui) != null;
this.canFillCraftingGrid = this.firstGui != null && this.handlerRef.canFillCraftingGrid(this.firstGui);
this.hasOverlay = this.canUseOverlayRenderer
|| this.firstGui != null && handlerRef.getOverlayHandler(firstGui) != null;
if (this.firstGui != null) {
this.canUseOverlayRenderer = this.handlerRef.getRecipeOverlayRenderer(this.firstGui) != null;
this.canFillCraftingGrid = this.handlerRef.canFillCraftingGrid(this.firstGui);
this.hasOverlay = this.canUseOverlayRenderer || this.handlerRef.getOverlayHandler(this.firstGui) != null;
}
setRequireShiftForOverlayRecipe(NEIClientConfig.requireShiftForOverlayRecipe());
ingredientsOverlay();
@@ -783,7 +783,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
return this.recipeCatalyst;
}
protected void forceRefreshPage() {
public void forceRefreshPage() {
this.currenthandlers.sort(NEIClientConfig.HANDLER_COMPARATOR);
final int currentPage = this.handlerPages.getCurrentPageIndex();
@@ -33,6 +33,7 @@ import codechicken.nei.Widget;
import codechicken.nei.drawable.DrawableResource;
import codechicken.nei.event.NEIRegisterHandlerInfosEvent;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.recipe.debug.DebugHandlerWidget;
import cpw.mods.fml.common.Loader;
public abstract class GuiRecipeTab extends Widget {
@@ -258,7 +259,8 @@ public abstract class GuiRecipeTab extends Widget {
final int handlerHeight = intOrDefault(record.get("handlerHeight"), HandlerInfo.DEFAULT_HEIGHT);
final int handlerWidth = intOrDefault(record.get("handlerWidth"), HandlerInfo.DEFAULT_WIDTH);
final boolean multipleWidgetsAllowed = intOrDefault(record.get("maxRecipesPerPage"), 1) > 1;
info.setHandlerDimensions(handlerWidth, handlerHeight, multipleWidgetsAllowed);
info.setHandlerDimensions(handlerWidth, handlerHeight);
info.setMultipleWidgetsAllowed(multipleWidgetsAllowed);
} catch (NumberFormatException ignored) {
NEIClientConfig.logger.info("Error setting handler dimensions for " + handler);
}
@@ -292,11 +294,12 @@ public abstract class GuiRecipeTab extends Widget {
}
NEIClientConfig.logger.info("Sending {}", NEIRegisterHandlerInfosEvent.class.getSimpleName());
MinecraftForge.EVENT_BUS.post(new NEIRegisterHandlerInfosEvent());
DebugHandlerWidget.instance.loadHandlerInfoPatch();
}
private static HandlerInfo getDefaultHandlerInfo() {
final HandlerInfo info = new HandlerInfo("Unknown", "Unknown", "Unknown", false, "");
info.setHandlerDimensions(HandlerInfo.DEFAULT_WIDTH, HandlerInfo.DEFAULT_HEIGHT, false);
info.setHandlerDimensions(HandlerInfo.DEFAULT_WIDTH, HandlerInfo.DEFAULT_HEIGHT);
return info;
}
@@ -45,13 +45,13 @@ public class HandlerInfo {
@Deprecated
public void setHandlerDimensions(int height, int width, int maxRecipesPerPage) {
setHandlerDimensions(width, height, maxRecipesPerPage > 1);
setHandlerDimensions(width, height);
setMultipleWidgetsAllowed(maxRecipesPerPage > 1);
}
public void setHandlerDimensions(int width, int height, boolean multipleWidgetsAllowed) {
public void setHandlerDimensions(int width, int height) {
this.height = height;
this.width = width;
this.multipleWidgetsAllowed = multipleWidgetsAllowed;
}
public boolean setItem(String itemId, String nbtString) {
@@ -102,6 +102,10 @@ public class HandlerInfo {
return this.multipleWidgetsAllowed ? Integer.MAX_VALUE : 1;
}
public void setMultipleWidgetsAllowed(boolean multipleWidgetsAllowed) {
this.multipleWidgetsAllowed = multipleWidgetsAllowed;
}
public boolean isMultipleWidgetsAllowed() {
return this.multipleWidgetsAllowed;
}
@@ -22,7 +22,6 @@ import org.lwjgl.opengl.GL12;
import codechicken.lib.gui.GuiDraw;
import codechicken.nei.FavoriteRecipes;
import codechicken.nei.LayoutManager;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.NEIServerUtils;
@@ -33,6 +32,7 @@ import codechicken.nei.api.ShortcutInputHandler;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.recipe.GuiRecipeButton.UpdateRecipeButtonsEvent;
import codechicken.nei.recipe.Recipe.RecipeId;
import codechicken.nei.recipe.debug.DebugHandlerWidget;
import codechicken.nei.util.NEIMouseUtils;
public class NEIRecipeWidget extends Widget {
@@ -127,18 +127,18 @@ public class NEIRecipeWidget extends Widget {
final UpdateRecipeButtonsEvent.Post postEvent = new UpdateRecipeButtonsEvent.Post(
guiRecipe,
this,
getDefatulButtons());
getDefaultButtons());
MinecraftForge.EVENT_BUS.post(postEvent);
return postEvent.buttonList;
}
} else {
return getDefatulButtons();
return getDefaultButtons();
}
}
protected List<GuiRecipeButton> getDefatulButtons() {
protected List<GuiRecipeButton> getDefaultButtons() {
GuiContainer guiContainer = NEIClientUtils.getGuiContainer();
final List<GuiRecipeButton> buttons = new ArrayList<>();
final boolean showFavorites = NEIClientConfig.favoritesEnabled() && handlerInfo.getShowFavoritesButton();
@@ -169,7 +169,7 @@ public class NEIRecipeWidget extends Widget {
if (this.update) {
this.update = false;
if (!NEIClientUtils.shiftKey() && (this.cycleticks++) / 20 != this.lastcycle || this.lastcycle == -1) {
if (!NEIClientUtils.shiftKey() && ((this.cycleticks++) / 20) != this.lastcycle || this.lastcycle == -1) {
this.lastcycle = this.cycleticks / 20;
updatePermutations();
}
@@ -252,7 +252,7 @@ public class NEIRecipeWidget extends Widget {
}
}
LayoutManager.recipeHandlerWidget.drawGuiPlaceholder(this);
DebugHandlerWidget.instance.drawGuiPlaceholder(this);
}
@Override
@@ -381,15 +381,15 @@ public class NEIRecipeWidget extends Widget {
for (PositionedStack pStack : getCatalysts()) {
if (pStack.contains(mousex - this.x, mousey - this.y - yShift)) {
hovered = pStack;
break;
}
}
}
if (hovered == null || hovered.items.length <= 1) {
if (hovered == null || this.permutations.getOrDefault(hovered, Collections.emptyList()).size() <= 1) {
this.acceptsFollowingTooltipLineHandler = null;
} else if ((this.acceptsFollowingTooltipLineHandler == null
|| this.acceptsFollowingTooltipLineHandler.tooltipGUID != hovered)
&& this.permutations.getOrDefault(hovered, Collections.emptyList()).size() > 1) {
} else if (this.acceptsFollowingTooltipLineHandler == null
|| this.acceptsFollowingTooltipLineHandler.tooltipGUID != hovered) {
this.acceptsFollowingTooltipLineHandler = AcceptsFollowingTooltipLineHandler
.of(hovered, this.permutations.get(hovered), hovered.item);
}
@@ -588,6 +588,7 @@ public class NEIRecipeWidget extends Widget {
private void updatePermutationsFor(PositionedStack pStack) {
List<ItemStack> perms = this.permutations.get(pStack);
int favoriteIndex = this.favoriteIndexes.getOrDefault(pStack, -1);
boolean needsUpdate = false;
if (perms == null) {
perms = pStack.getFilteredPermutations();
@@ -602,9 +603,10 @@ public class NEIRecipeWidget extends Widget {
this.permutations.put(pStack, perms);
this.favoriteIndexes.put(pStack, favoriteIndex);
needsUpdate = true;
}
if (perms.size() > 1) {
if (perms.size() > 1 || needsUpdate) {
final int size = favoriteIndex != -1 ? favoriteIndex + 1 : perms.size();
if (size > 0) {
@@ -4,16 +4,11 @@ import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
import net.minecraft.client.gui.inventory.GuiBrewingStand;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.gui.inventory.GuiCrafting;
import net.minecraft.client.gui.inventory.GuiFurnace;
import net.minecraft.client.gui.inventory.GuiInventory;
import com.google.common.base.Objects;
import codechicken.nei.OffsetPositioner;
import codechicken.nei.api.API;
import codechicken.nei.api.IOverlayHandler;
import codechicken.nei.api.IStackPositioner;
@@ -96,33 +91,4 @@ public class RecipeInfo {
return offset == null ? new int[] { 5, 11 } : offset;
}
public static void load() {
API.registerRecipeHandler(new ShapedRecipeHandler());
API.registerUsageHandler(new ShapedRecipeHandler());
API.registerRecipeHandler(new ShapelessRecipeHandler());
API.registerUsageHandler(new ShapelessRecipeHandler());
API.registerRecipeHandler(new FireworkRecipeHandler());
API.registerUsageHandler(new FireworkRecipeHandler());
API.registerRecipeHandler(new FurnaceRecipeHandler());
API.registerUsageHandler(new FurnaceRecipeHandler());
API.registerRecipeHandler(new BrewingRecipeHandler());
API.registerUsageHandler(new BrewingRecipeHandler());
API.registerRecipeHandler(new FuelRecipeHandler());
API.registerUsageHandler(new FuelRecipeHandler());
API.registerRecipeHandler(new InformationHandler());
API.registerUsageHandler(new InformationHandler());
API.registerGuiOverlay(GuiCrafting.class, "crafting");
API.registerGuiOverlay(GuiInventory.class, "crafting2x2", 63, 20);
API.registerGuiOverlay(GuiFurnace.class, "smelting");
API.registerGuiOverlay(GuiFurnace.class, "fuel");
API.registerGuiOverlay(GuiBrewingStand.class, "brewing");
API.registerGuiOverlayHandler(GuiCrafting.class, new DefaultOverlayHandler(), "crafting");
API.registerGuiOverlayHandler(GuiInventory.class, new DefaultOverlayHandler(63, 20), "crafting2x2");
API.registerGuiOverlayHandler(GuiBrewingStand.class, new BrewingOverlayHandler(), "brewing");
API.registerRecipeHandler(new ProfilerRecipeHandler(true));
API.registerUsageHandler(new ProfilerRecipeHandler(false));
}
}
@@ -0,0 +1,24 @@
package codechicken.nei.recipe;
import java.util.List;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.inventory.Slot;
import codechicken.nei.PositionedStack;
public class RepairOverlayHandler extends DefaultOverlayHandler {
@Override
public boolean canCraft(GuiContainer firstGui, IRecipeHandler handler, int recipeIndex) {
return false;
}
@Override
public Slot[][] mapIngredSlots(GuiContainer gui, List<PositionedStack> ingredients) {
final List<Slot> slots = gui.inventorySlots.inventorySlots;
return new Slot[][] { { slots.get(0) }, { slots.get(1) } };
}
}
@@ -0,0 +1,233 @@
package codechicken.nei.recipe;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import net.minecraft.client.gui.GuiRepair;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.ItemStack;
import codechicken.nei.ItemList;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.PositionedStack;
import codechicken.nei.RestartableTask;
import codechicken.nei.drawable.DrawableBuilder;
import codechicken.nei.drawable.DrawableResource;
public class RepairRecipeHandler extends TemplateRecipeHandler {
private final DrawableResource BG_TEXTURE = new DrawableBuilder("nei:textures/gui/repair.png", 0, 0, 168, 36)
.setTextureSize(168, 36).build();
private static final RestartableTask reloadRepairRecipesTask = new RestartableTask("NEI Repair Recipe Reloading") {
@Override
public void execute() {
new RepairRecipeHandler().buildCache();
}
};
private static class ItemStackKey {
private final ItemStack stack;
public ItemStackKey(ItemStack stack) {
this.stack = stack;
}
@Override
public int hashCode() {
return stack.getItem().hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj instanceof ItemStackKey objeKey) {
return NEIClientUtils.areStacksSameTypeWithNBT(stack, objeKey.stack);
}
return false;
}
}
private static class DamagablePositionedStack extends PositionedStack {
public DamagablePositionedStack(Object item, int x, int y) {
super(item, x, y);
}
@Override
public boolean contains(ItemStack ingredient) {
return ingredient.getItemDamage() > 0 && NEIClientUtils.areStacksSameTypeWithNBT(this.item, ingredient);
}
}
private static List<RepairPair> cachedRecipes;
private static final int LEFT_X = 25;
private static final int RIGHT_X = 74;
private static final int OUTPUT_X = 132;
private static final int SLOT_Y = 10;
public class RepairPair extends CachedRecipe {
final List<PositionedStack> ingredients = new ArrayList<>(2);
final PositionedStack result;
RepairPair(ItemStack left, Object right, ItemStack result) {
ingredients.add(new DamagablePositionedStack(left, LEFT_X, SLOT_Y));
ingredients.add(new PositionedStack(right, RIGHT_X, SLOT_Y));
this.result = new PositionedStack(result, OUTPUT_X, SLOT_Y);
}
@Override
public List<PositionedStack> getIngredients() {
return this.ingredients;
}
@Override
public PositionedStack getResult() {
return this.result;
}
}
public static void findRepairRecipesOnceParallel() {
reloadRepairRecipesTask.restart();
}
private void buildCache() {
final Map<ItemStackKey, RepairPair> recipes = new HashMap<>();
for (ItemStack itemstack1 : ItemList.items) {
recipes.computeIfAbsent(new ItemStackKey(itemstack1), key -> this.getRepairRecipe(key.stack));
}
cachedRecipes = recipes.values().stream().filter(recipe -> recipe != null).collect(Collectors.toList());
}
private RepairPair getRepairRecipe(ItemStack itemstack1) {
if (!itemstack1.isItemStackDamageable()) return null;
final List<ItemStack> permutations = new ArrayList<>();
for (ItemStack itemstack2 : ItemList.items) {
if (itemstack1.getItem().getIsRepairable(itemstack1, itemstack2)) {
final ItemStack right = itemstack2.copy();
right.stackSize = 4;
permutations.add(right);
}
}
if (permutations.isEmpty()) return null;
final int maxDamage = itemstack1.getMaxDamage();
final ItemStack result = itemstack1.copy();
final ItemStack left = itemstack1.copy();
left.setItemDamage(maxDamage - 1);
result.setItemDamage(left.getItemDamageForDisplay() - (maxDamage / 4) * 4);
return new RepairPair(left, permutations, result);
}
@Override
public TemplateRecipeHandler newInstance() {
if (cachedRecipes == null) {
buildCache();
}
return super.newInstance();
}
@Override
public void loadCraftingRecipes(String outputId, Object... results) {
if (outputId.equals(getOverlayIdentifier()) && getClass() == RepairRecipeHandler.class) {
arecipes.addAll(cachedRecipes);
} else if (!NEIClientConfig.getBooleanSetting("showRepairOnlyForDamageableItems")) {
super.loadCraftingRecipes(outputId, results);
}
}
@Override
public void loadCraftingRecipes(ItemStack result) {
for (RepairPair recipe : cachedRecipes) {
if (recipe.getResult().contains(result)) arecipes.add(recipe);
}
}
@Override
public void loadUsageRecipes(String inputId, Object... ingredients) {
if (inputId.equals(getOverlayIdentifier()) && getClass() == RepairRecipeHandler.class) {
loadCraftingRecipes(getOverlayIdentifier());
} else {
super.loadUsageRecipes(inputId, ingredients);
}
}
@Override
public void loadUsageRecipes(ItemStack ingredient) {
final boolean showRepairOnlyForDamageableItems = NEIClientConfig
.getBooleanSetting("showRepairOnlyForDamageableItems");
for (RepairPair recipe : cachedRecipes) {
final List<PositionedStack> ingredients = recipe.getIngredients();
if (ingredients.get(0).contains(ingredient)) {
arecipes.add(recipe);
} else if (!showRepairOnlyForDamageableItems && ingredients.get(1).contains(ingredient)) {
arecipes.add(new RepairPair(ingredients.get(0).item, ingredient, recipe.getResult().item));
}
}
if (arecipes.isEmpty()) {
final RepairPair recipe = getRepairRecipe(ingredient);
if (recipe != null) {
arecipes.add(recipe);
}
}
}
@Override
public void loadTransferRects() {
transferRects.add(new RecipeTransferRect(new Rectangle(100, 11, 22, 15), getOverlayIdentifier()));
}
@Override
public String getRecipeName() {
return NEIClientUtils.translate("recipe.repair");
}
@Override
public String getGuiTexture() {
return "nei:textures/gui/repair.png";
}
@Override
public String getOverlayIdentifier() {
return "repair";
}
@Override
public Class<? extends GuiContainer> getGuiClass() {
return GuiRepair.class;
}
@Override
public void drawBackground(int recipe) {
BG_TEXTURE.draw(0, 0);
}
@Override
public void drawForeground(int recipe) {}
}
@@ -256,6 +256,10 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
return rect.hashCode();
}
public Rectangle getRect() {
return rect;
}
Rectangle rect;
String outputId;
Object[] results;
@@ -0,0 +1,37 @@
package codechicken.nei.recipe.debug;
import java.util.function.Consumer;
import codechicken.nei.Button;
import codechicken.nei.NEIClientUtils;
public class CheckboxWidget extends Button implements IUpdatableWidget {
protected Consumer<CheckboxWidget> onChange;
protected boolean value;
public CheckboxWidget(Consumer<CheckboxWidget> onChange) {
super();
this.onChange = onChange;
this.h = 16;
this.z = 2;
}
@Override
public String getRenderLabel() {
return this.value ? NEIClientUtils.translate("debug.RecipeHandler.checkbox.on")
: NEIClientUtils.translate("debug.RecipeHandler.checkbox.off");
}
@Override
public boolean onButtonPress(boolean rightclick) {
this.value = !this.value;
onChange.accept(this);
return true;
}
public void updateValue(String newValue) {
this.value = Boolean.parseBoolean(newValue);
}
}
@@ -0,0 +1,618 @@
package codechicken.nei.recipe.debug;
import java.awt.Point;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.stream.Collectors;
import net.minecraft.client.gui.inventory.GuiContainer;
import org.apache.commons.io.IOUtils;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
import codechicken.lib.gui.GuiDraw;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.ClientHandler;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.Widget;
import codechicken.nei.drawable.DrawableBuilder;
import codechicken.nei.drawable.DrawableResource;
import codechicken.nei.recipe.GuiRecipe;
import codechicken.nei.recipe.GuiRecipeButton;
import codechicken.nei.recipe.GuiRecipeTab;
import codechicken.nei.recipe.HandlerInfo;
import codechicken.nei.recipe.IRecipeHandler;
import codechicken.nei.recipe.NEIRecipeWidget;
import codechicken.nei.recipe.TemplateRecipeHandler;
import codechicken.nei.recipe.TemplateRecipeHandler.RecipeTransferRect;
import codechicken.nei.scroll.ScrollContainer;
public class DebugHandlerWidget extends Widget {
private static class HandlerInfoRecord {
public String handlerKey;
public int yShift;
public int width;
public int height;
public boolean multiWidgets;
public int order;
public boolean useCustomScroll;
public boolean showFavorites;
public boolean showOverlay;
private String csvLine;
public HandlerInfoRecord(String handlerKey, HandlerInfo info) {
this.handlerKey = handlerKey;
this.yShift = info.getYShift();
this.width = info.getWidth();
this.height = info.getHeight();
this.multiWidgets = info.isMultipleWidgetsAllowed();
this.order = NEIClientConfig.handlerOrdering.getOrDefault(handlerKey, 0);
this.useCustomScroll = info.getUseCustomScroll();
this.showFavorites = info.getShowFavoritesButton();
this.showOverlay = info.getShowOverlayButton();
this.csvLine = toCsvLine();
}
public void applyTo(HandlerInfo info) {
info.setYShift(this.yShift);
info.setHandlerDimensions(this.width, this.height);
info.setMultipleWidgetsAllowed(this.multiWidgets);
info.setUseCustomScroll(this.useCustomScroll);
info.setShowFavoritesButton(this.showFavorites);
info.setShowOverlayButton(this.showOverlay);
NEIClientConfig.handlerOrdering.put(this.handlerKey, this.order);
}
public String toCsvLine() {
return String.join(
",",
handlerKey,
String.valueOf(yShift),
String.valueOf(height),
String.valueOf(width),
String.valueOf(multiWidgets ? 1 : 0),
String.valueOf(order),
String.valueOf(useCustomScroll ? 1 : 0),
String.valueOf(showFavorites ? 1 : 0),
String.valueOf(showOverlay ? 1 : 0));
}
public boolean isUnmodified() {
return this.csvLine.equals(this.toCsvLine());
}
}
private static final int WINDOW_WIDTH = 176;
private static final int LINE_HEIGHT = 16;
private static final int INLINE_PADDING = 6;
private static final int LABEL_WIDTH = 50;
private static final String TOOLTIP_PREFIX = "debug.RecipeHandler.";
private static final String HEADER = "HandlerId,YShift,Height,Width,MultiWidgets,Order,UseCustomScroll,ShowFavorites,ShowOverlay";
private final int[] COLORS = new int[] { 0x2200FF00, 0x22FF0000, 0x220000FF, 0x2200FFFF, 0x22FF00FF, 0x22FFFF00 };
public static DebugHandlerWidget instance = new DebugHandlerWidget();
private ScrollContainer container = new ScrollContainer();
private final Map<String, IUpdatableWidget> values = new LinkedHashMap<>();
private Map<String, HandlerInfoRecord> patches = new HashMap<>();
private IRecipeHandler handler;
private HandlerInfo handlerInfo;
private HandlerInfoRecord record;
private Point dragPoint = null;
private boolean showWidget = false;
private final DrawableResource BG_TEXTURE = new DrawableBuilder(
"nei:textures/gui/recipebg.png",
0,
0,
176 + TRANSPARENCY_BORDER * 2,
166 + TRANSPARENCY_BORDER * 2).build();
private static final int BORDER_PADDING = 6;
private static final int TRANSPARENCY_BORDER = 4;
public DebugHandlerWidget() {
this.w = WINDOW_WIDTH;
this.x = 10;
this.y = 50;
this.z = 4;
this.container.x = this.x + INLINE_PADDING;
this.container.y = this.y + 5 + LINE_HEIGHT;
this.container.w = this.w - INLINE_PADDING * 2;
int y = 0;
y = addInfoWidget("Name", y);
y = addInfoWidget("Id", y);
y = addInfoWidget("Key", y);
y = addInfoWidget("HHack", y);
y = addInfoWidget("ModName", y);
y = addInfoWidget("ModId", y);
y = addInfoWidget("Override", y);
y = addTextFieldWidget("Order", 0, (field, oldText) -> {
if (field.getInteger() != record.order) {
record.order = field.getInteger();
saveHandlerInfoPatch();
}
}, y);
y = addTextFieldWidget("yShift", 0, (field, oldText) -> {
if (field.getInteger() != handlerInfo.getYShift()) {
handlerInfo.setYShift(field.getInteger());
record.yShift = field.getInteger();
saveHandlerInfoPatch();
}
}, y);
y = addCheckboxWidget("MultiWidgets", button -> {
handlerInfo.setMultipleWidgetsAllowed(button.value);
record.multiWidgets = button.value;
saveHandlerInfoPatch();
}, y);
final LabelWidget readonly = new LabelWidget(0xffffff, true);
readonly.y = y;
readonly.w = 57;
readonly.x = this.w - INLINE_PADDING * 2 - readonly.w;
this.values.put("height_readonly", readonly);
y = addTextFieldWidget("Height", HandlerInfo.DEFAULT_HEIGHT, (field, oldText) -> {
if (field.getInteger() != handlerInfo.getHeight()) {
handlerInfo.setHandlerDimensions(handlerInfo.getWidth(), field.getInteger());
record.height = field.getInteger();
saveHandlerInfoPatch();
}
}, y);
y = addTextFieldWidget("Width", HandlerInfo.DEFAULT_WIDTH, (field, oldText) -> {
if (field.getInteger() != handlerInfo.getWidth()) {
handlerInfo.setHandlerDimensions(field.getInteger(), handlerInfo.getHeight());
record.width = field.getInteger();
saveHandlerInfoPatch();
}
}, y);
y = addCheckboxWidget("UseCustomScroll", button -> {
handlerInfo.setUseCustomScroll(button.value);
record.useCustomScroll = button.value;
saveHandlerInfoPatch();
}, y);
y = addCheckboxWidget("ShowFavorites", button -> {
handlerInfo.setShowFavoritesButton(button.value);
record.showFavorites = button.value;
saveHandlerInfoPatch();
}, y);
y = addCheckboxWidget("ShowOverlay", button -> {
handlerInfo.setShowOverlayButton(button.value);
record.showOverlay = button.value;
saveHandlerInfoPatch();
}, y);
this.h = 10 + LINE_HEIGHT + y;
this.container.h = this.h - INLINE_PADDING * 2 - LINE_HEIGHT;
}
private int addInfoWidget(String key, int y) {
final LabelWidget label = new LabelWidget(0x888888, false);
final LabelWidget value = new LabelWidget(0xffffff, true);
label.y = value.y = y;
label.w = LABEL_WIDTH;
value.x = LABEL_WIDTH + 5;
value.w = this.w - INLINE_PADDING * 2 - value.x;
label.updateValue(NEIClientUtils.translate(TOOLTIP_PREFIX + key));
this.container.addWidget(label);
this.container.addWidget(value);
this.values.put(key.toLowerCase(), value);
return y + value.h + 1;
}
private int addTextFieldWidget(String key, int defaultValue, BiConsumer<IntegerField, String> onChange, int y) {
final LabelWidget label = new LabelWidget(0x888888, false);
final IntegerField value = new IntegerField(key, onChange, defaultValue);
label.y = value.y = y;
value.w = 60;
value.x = this.w - INLINE_PADDING * 2 - value.w;
label.w = value.x;
label.updateValue(NEIClientUtils.translate(TOOLTIP_PREFIX + key));
this.container.addWidget(label);
this.container.addWidget(value);
this.values.put(key.toLowerCase(), value);
return y + value.h + 1;
}
private int addCheckboxWidget(String key, Consumer<CheckboxWidget> onChange, int y) {
final LabelWidget label = new LabelWidget(0x888888, false);
final CheckboxWidget value = new CheckboxWidget(onChange);
label.y = value.y = y;
value.w = 58;
value.x = this.w - INLINE_PADDING * 2 - value.w - 1;
label.w = value.x;
label.updateValue(NEIClientUtils.translate(TOOLTIP_PREFIX + key));
this.container.addWidget(label);
this.container.addWidget(value);
this.values.put(key.toLowerCase(), value);
return y + value.h + 1;
}
@Override
public void draw(int mx, int my) {
if (this.handler != null) {
GL11.glColor4f(1F, 1F, 1F, 1F);
GL11.glScaled(1, 1, 2f);
GL11.glDisable(GL11.GL_DEPTH_TEST);
BG_TEXTURE.draw(
this.x - TRANSPARENCY_BORDER,
this.y - TRANSPARENCY_BORDER,
this.w + TRANSPARENCY_BORDER * 2,
this.h + TRANSPARENCY_BORDER * 2,
BORDER_PADDING + TRANSPARENCY_BORDER,
BORDER_PADDING + TRANSPARENCY_BORDER,
BORDER_PADDING + TRANSPARENCY_BORDER,
BORDER_PADDING + TRANSPARENCY_BORDER);
GuiDraw.drawRect(
this.x + INLINE_PADDING,
this.y + BORDER_PADDING,
this.w - INLINE_PADDING * 2,
12,
0x30000000);
GuiDraw.drawStringC(
NEIClientUtils.translate("debug.RecipeHandler.title"),
this.x + this.w / 2,
this.y + BORDER_PADDING + 2,
0xffffff);
this.container.draw(mx, my);
GL11.glScaled(1, 1, 1 / 2f);
}
}
@Override
public void update() {
final GuiContainer gui = NEIClientUtils.getGuiContainer();
if (this.showWidget && gui instanceof GuiRecipe recipe) {
if (this.handler != recipe.getHandler()) {
this.handler = recipe.getHandler();
this.handlerInfo = GuiRecipeTab.getHandlerInfo(handler);
this.record = this.patches.computeIfAbsent(
getHandlerID(handler),
handlerKey -> new HandlerInfoRecord(handlerKey, handlerInfo));
final boolean isHeightHackApplied = NEIClientConfig.heightHackHandlerRegex.stream()
.map(pattern -> pattern.matcher(this.handler.getHandlerId())).anyMatch(Matcher::matches);
this.values.get("name").updateValue(this.handler.getRecipeName());
this.values.get("id").updateValue(this.handler.getOverlayIdentifier());
this.values.get("key").updateValue(this.handler.getHandlerId());
this.values.get("hhack").updateValue(
isHeightHackApplied ? NEIClientUtils.translate("debug.RecipeHandler.yes")
: NEIClientUtils.translate("debug.RecipeHandler.no"));
this.values.get("modname").updateValue(this.handlerInfo.getModName());
this.values.get("modid").updateValue(this.handlerInfo.getModId());
this.values.get("order").updateValue(String.valueOf(this.record.order));
this.values.get("yshift").updateValue(String.valueOf(this.record.yShift));
this.values.get("height").updateValue(String.valueOf(this.record.height));
this.values.get("height_readonly").updateValue(String.valueOf(this.record.height));
this.values.get("width").updateValue(String.valueOf(this.record.width));
this.values.get("multiwidgets").updateValue(String.valueOf(this.record.multiWidgets));
this.values.get("usecustomscroll").updateValue(String.valueOf(this.record.useCustomScroll));
this.values.get("showfavorites").updateValue(String.valueOf(this.record.showFavorites));
this.values.get("showoverlay").updateValue(String.valueOf(this.record.showOverlay));
this.values.get("override").updateValue(
this.record.isUnmodified() ? NEIClientUtils.translate("debug.RecipeHandler.no")
: NEIClientUtils.translate("debug.RecipeHandler.yes"));
this.container.removeIf(
widget -> this.values.get("height") == widget || this.values.get("height_readonly") == widget);
if (handler.getRecipeHeight(0) > 0) {
this.container.addWidget((Widget) this.values.get("height_readonly"));
} else {
this.container.addWidget((Widget) this.values.get("height"));
}
}
} else {
this.handler = null;
this.record = null;
this.handlerInfo = null;
this.showWidget = false;
}
this.container.update();
}
@Override
public List<String> handleTooltip(int mx, int my, List<String> tooltip) {
return this.handler != null ? this.container.handleTooltip(mx, my, tooltip) : tooltip;
}
@Override
public Map<String, String> handleHotkeys(int mousex, int mousey, Map<String, String> hotkeys) {
return this.handler != null ? this.container.handleHotkeys(mousex, mousey, hotkeys) : hotkeys;
}
@Override
public boolean handleKeyPress(int keyID, char keyChar) {
if (NEIClientConfig.getBooleanSetting("inventory.guirecipe.handlerInfo") && keyID == Keyboard.KEY_D
&& NEIClientUtils.shiftKey()) {
this.showWidget = !this.showWidget;
return true;
} else if (this.handler != null) {
if (this.container.handleKeyPress(keyID, keyChar)) {
return true;
}
this.container.lastKeyTyped(keyID, keyChar);
return this.container.isFocused();
}
return false;
}
@Override
public void onGuiClick(int mx, int my) {
if (this.handler != null) {
this.container.onGuiClick(mx, my);
}
}
@Override
public boolean handleClick(int mx, int my, int button) {
if (this.handler != null) {
if (new Rectangle4i(this.x + INLINE_PADDING, this.y + BORDER_PADDING, this.w - INLINE_PADDING * 2, 12)
.contains(mx, my)) {
this.dragPoint = new Point(mx, my);
}
this.container.handleClick(mx, my, button);
}
return this.handler != null;
}
@Override
public boolean contains(int px, int py) {
return this.handler != null && super.contains(px, py);
}
@Override
public void mouseUp(int mx, int my, int button) {
this.dragPoint = null;
if (this.handler != null) {
this.container.mouseUp(mx, my, button);
}
}
@Override
public boolean onMouseWheel(int scrolled, int mousex, int mousey) {
if (this.handler != null && contains(mousex, mousey)) {
this.container.onMouseWheel(scrolled, mousex, mousey);
return true;
}
return false;
}
@Override
public boolean handleClickExt(int mx, int my, int button) {
return this.handler != null && this.container.handleClickExt(mx, my, button);
}
@Override
public void mouseDragged(int mx, int my, int button, long heldTime) {
if (this.dragPoint != null) {
this.x -= this.dragPoint.x - mx;
this.y -= this.dragPoint.y - my;
this.container.y = this.y + INLINE_PADDING + LINE_HEIGHT;
this.container.x = this.x + INLINE_PADDING;
this.dragPoint.move(mx, my);
}
}
public void drawGuiPlaceholder(NEIRecipeWidget widget) {
if (!this.showWidget) return;
NEIClientUtils.gl2DRenderContext(() -> {
// background
GuiDraw.drawRect(
widget.x,
widget.y,
widget.w,
widget.h,
COLORS[widget.getRecipeHandlerRef().recipeIndex % COLORS.length]);
// center cross
GuiDraw.drawRect(widget.x + widget.w / 2 - 1, widget.y, 1, widget.h, 0x88ffffff);
GuiDraw.drawRect(widget.x, widget.y + widget.h / 2 - 1, widget.w, 1, 0x88ffffff);
// blue-line-top (grid-top)
GuiDraw.drawRect(widget.x + 14, widget.y + 5, widget.w - 38, 1, 0xff0000aa);
// blue-line-bottom {grid-bottom}
GuiDraw.drawRect(widget.x + 14, widget.y + widget.h - 7, widget.w - 38, 1, 0xff0000aa);
// blue-left (grid start)
GuiDraw.drawRect(widget.x + 24, widget.y + (widget.h - 16) / 2, 1, 16, 0xffaa00aa);
// purple (before favorite)
GuiDraw.drawRect(
widget.x + Math.min(168, widget.w) - 27,
widget.y + widget.h - 6 - GuiRecipeButton.BUTTON_HEIGHT * 2 - 4,
GuiRecipeButton.BUTTON_WIDTH,
1,
0xffaa00aa);
// green ()
GuiDraw.drawRect(
widget.x + Math.min(168, widget.w) - 35,
widget.y + widget.h - 6 - GuiRecipeButton.BUTTON_HEIGHT - 3,
20,
1,
0xff00aa00);
// purple space before bottom grid
GuiDraw.drawRect(
widget.x + 14,
widget.y + widget.h - 7 - GuiRecipeButton.BUTTON_WIDTH / 2,
38,
1,
0xffaa00aa);
if (widget.getRecipeHandlerRef().handler instanceof TemplateRecipeHandler handler) {
int yShift = widget.getHandlerInfo().getYShift();
for (RecipeTransferRect rect : handler.transferRects) {
GuiDraw.drawRect(
widget.x + rect.getRect().x,
widget.y + yShift + rect.getRect().y,
rect.getRect().width,
rect.getRect().height,
0x40ff0000);
}
}
});
}
public void loadHandlerInfoPatch() {
ClientHandler.loadSettingsFile("handlers.patch", lines -> {
for (String line : lines.collect(Collectors.toCollection(HashSet::new))) {
if (HEADER.equals(line)) continue;
final String[] parts = Arrays.copyOf((line + ",null,null,null,null,null,null,null,null").split(","), 9);
final String handler = parts[0];
if (GuiRecipeTab.handlerMap.containsKey(handler)) {
final HandlerInfo info = GuiRecipeTab.handlerMap.get(handler);
final HandlerInfoRecord record = patches
.computeIfAbsent(handler, handlerKey -> new HandlerInfoRecord(handler, info));
record.yShift = intOrDefault(parts[1], info.getYShift());
record.height = intOrDefault(parts[2], info.getHeight());
record.width = intOrDefault(parts[3], info.getWidth());
record.multiWidgets = intOrDefault(parts[4], info.isMultipleWidgetsAllowed() ? 1 : 0) == 1;
record.order = intOrDefault(parts[5], NEIClientConfig.handlerOrdering.getOrDefault(handler, 0));
record.useCustomScroll = intOrDefault(parts[6], info.getUseCustomScroll() ? 1 : 0) == 1;
record.showFavorites = intOrDefault(parts[7], info.getShowFavoritesButton() ? 1 : 0) == 1;
record.showOverlay = intOrDefault(parts[8], info.getShowOverlayButton() ? 1 : 0) == 1;
record.applyTo(info);
}
}
});
}
private void saveHandlerInfoPatch() {
final List<String> lines = new ArrayList<>();
lines.add(HEADER);
for (HandlerInfoRecord record : patches.values()) {
if (!record.csvLine.equals(record.toCsvLine())) {
lines.add(record.toCsvLine());
}
}
final File path = new File(NEIClientConfig.configDir, "handlers.patch");
try (FileOutputStream output = new FileOutputStream(path)) {
IOUtils.writeLines(lines, "\n", output, StandardCharsets.UTF_8);
} catch (IOException e) {}
if (this.record != null) {
this.values.get("override").updateValue(
this.record.isUnmodified() ? NEIClientUtils.translate("debug.RecipeHandler.no")
: NEIClientUtils.translate("debug.RecipeHandler.yes"));
}
if (NEIClientUtils.getGuiContainer() instanceof GuiRecipe<?>recipe) {
recipe.forceRefreshPage();
}
}
private int intOrDefault(String str, int defaultValue) {
if (str == null || str.isEmpty()) return defaultValue;
try {
return Integer.parseInt(str);
} catch (NumberFormatException e) {
return defaultValue;
}
}
private String getHandlerID(IRecipeHandler handler) {
if (GuiRecipeTab.handlerMap.containsKey(handler.getHandlerId())) {
return handler.getHandlerId();
} else if (handler instanceof TemplateRecipeHandler) {
return handler.getOverlayIdentifier();
}
return handler.getHandlerId();
}
}
@@ -0,0 +1,7 @@
package codechicken.nei.recipe.debug;
public interface IUpdatableWidget {
public void updateValue(String newValue);
}
@@ -0,0 +1,94 @@
package codechicken.nei.recipe.debug;
import java.util.function.BiConsumer;
import net.minecraft.client.Minecraft;
import org.lwjgl.input.Keyboard;
import codechicken.nei.FormattedTextField;
import codechicken.nei.TextField;
public class IntegerField extends TextField implements IUpdatableWidget {
protected int defaultValue = 0;
protected BiConsumer<IntegerField, String> onChange;
public IntegerField(String ident, BiConsumer<IntegerField, String> onChange, int defaultValue) {
super(ident);
this.onChange = onChange;
this.defaultValue = defaultValue;
this.h = 16;
this.z = 2;
((FormattedTextField) field).setPlaceholder(Integer.toString(this.defaultValue));
}
@Override
protected void initInternalTextField() {
field = new FormattedTextField(Minecraft.getMinecraft().fontRenderer, 0, 0, 0, 0) {
@Override
public String getText() {
final String text = super.getText();
return !isFocused() && this.placeholder.equals(text) ? "" : text;
}
@Override
protected boolean beforeWrite(String text) {
if (text == null || text.isEmpty()) return true;
try {
Integer.parseInt(text);
return true;
} catch (NumberFormatException e) {
return false;
}
}
@Override
public boolean textboxKeyTyped(char keyChar, int keyID) {
if (!isFocused()) return false;
if (super.textboxKeyTyped(keyChar, keyID)) {
return true;
} else if (keyID == Keyboard.KEY_DOWN) {
setText(Integer.toString(getInteger() - 1));
return true;
} else if (keyID == Keyboard.KEY_UP) {
setText(Integer.toString(getInteger() + 1));
return true;
}
return false;
}
};
field.setMaxStringLength(maxSearchLength);
field.setCursorPositionZero();
}
protected int getInteger() {
try {
return Integer.parseInt(text());
} catch (NumberFormatException nfe) {
return this.defaultValue;
}
}
@Override
public boolean onMouseWheel(int i, int mx, int my) {
if (!contains(mx, my)) return false;
setText(Integer.toString(getInteger() + i));
return true;
}
public void updateValue(String newValue) {
setText(newValue);
}
@Override
public void onTextChange(String oldText) {
onChange.accept(this, oldText);
}
}
@@ -0,0 +1,74 @@
package codechicken.nei.recipe.debug;
import java.awt.Point;
import java.util.List;
import java.util.Map;
import net.minecraft.client.gui.GuiScreen;
import org.lwjgl.input.Keyboard;
import codechicken.lib.gui.GuiDraw;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.Widget;
import codechicken.nei.util.NEIMouseUtils;
public class LabelWidget extends Widget implements IUpdatableWidget {
protected int color;
protected boolean shadow;
protected String value = "";
protected String croppedValue;
public LabelWidget(int color, boolean shadow) {
this.color = color;
this.shadow = shadow;
this.h = 16;
this.z = 2;
}
@Override
public void draw(int mx, int my) {
GuiDraw.drawString(this.croppedValue, this.x, this.y + (this.h - 8) / 2, this.color, this.shadow);
}
public void updateValue(String newValue) {
this.value = newValue;
this.croppedValue = NEIClientUtils.cropText(GuiDraw.fontRenderer, this.value, this.w);
}
@Override
public List<String> handleTooltip(int mx, int my, List<String> tooltip) {
if (contains(mx, my)) {
tooltip.add(this.value);
}
return tooltip;
}
@Override
public boolean handleKeyPress(int keyID, char keyChar) {
final Point mouse = GuiDraw.getMousePosition();
if (contains(mouse.x, mouse.y) && Keyboard.KEY_C == keyID && NEIClientUtils.controlKey()) {
GuiScreen.setClipboardString(this.value);
return true;
}
return false;
}
@Override
public Map<String, String> handleHotkeys(int mousex, int mousey, Map<String, String> hotkeys) {
if (contains(mousex, mousey)) {
hotkeys.put(
NEIClientUtils.getKeyName(NEIClientUtils.CTRL_HASH + Keyboard.KEY_C, NEIMouseUtils.MOUSE_BTN_NONE),
NEIClientUtils.translate("debug.RecipeHandler.copy"));
}
return hotkeys;
}
}
@@ -2,6 +2,7 @@ package codechicken.nei.scroll;
import java.awt.Point;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.function.Predicate;
@@ -38,7 +39,7 @@ public class ScrollContainer extends WidgetContainer {
protected int paddingBlockStart = 0;
protected int paddingBlockEnd = 0;
protected final Map<Widget, Point> relativePostion = new HashMap<>();
protected final Map<Widget, Point> relativePosition = new HashMap<>();
protected ScrollBar horizontalScrollBar;
protected ScrollBar verticalScrollBar;
protected int fade = 0;
@@ -80,23 +81,40 @@ public class ScrollContainer extends WidgetContainer {
@Override
public void clear() {
for (Map.Entry<Widget, Point> entry : this.relativePosition.entrySet()) {
entry.getKey().x = entry.getValue().x;
entry.getKey().y = entry.getValue().y;
}
super.clear();
this.relativePostion.clear();
this.relativePosition.clear();
}
@Override
public boolean removeIf(Predicate<Widget> filter) {
this.relativePostion.keySet().removeIf(filter);
final Iterator<Map.Entry<Widget, Point>> it = this.relativePosition.entrySet().iterator();
while (it.hasNext()) {
final Map.Entry<Widget, Point> entry = it.next();
if (filter.test(entry.getKey())) {
entry.getKey().x = entry.getValue().x;
entry.getKey().y = entry.getValue().y;
it.remove();
}
}
return super.removeIf(filter);
}
public void addWidget(Widget widget) {
super.addWidget(widget);
this.relativePostion.put(widget, new Point(widget.x, widget.y));
this.relativePosition.put(widget, new Point(widget.x, widget.y));
}
public Point getWidgetPosition(Widget widget) {
return this.relativePostion.get(widget);
return this.relativePosition.get(widget);
}
public void setPaddingInline(int start, int end) {
@@ -275,7 +293,7 @@ public class ScrollContainer extends WidgetContainer {
this.actualHeight = 0;
this.actualWidth = 0;
for (Map.Entry<Widget, Point> entry : this.relativePostion.entrySet()) {
for (Map.Entry<Widget, Point> entry : this.relativePosition.entrySet()) {
entry.getKey().x = entry.getValue().x;
entry.getKey().y = entry.getValue().y;
}
@@ -385,6 +403,10 @@ public class ScrollContainer extends WidgetContainer {
@Override
public boolean handleKeyPress(int keyCode, char keyChar) {
if (super.handleKeyPress(keyCode, keyChar)) {
return true;
}
if (this.isFocused()) {
switch (keyCode) {
case Keyboard.KEY_UP:
@@ -402,7 +424,7 @@ public class ScrollContainer extends WidgetContainer {
}
}
return super.handleKeyPress(keyCode, keyChar);
return false;
}
}
+10 -17
View File
@@ -1,11 +1,4 @@
handler,modName,itemName,nbtInfo,modId,modRequired,excludedModId,yShift,handlerHeight,handlerWidth,maxRecipesPerPage,imageResource,imageX,imageY,imageWidth,imageHeight,itemNotes,useCustomScroll
codechicken.nei.recipe.BrewingRecipeHandler,Minecraft,minecraft:brewing_stand,,minecraft,FALSE,,,65,166,5,,,,,,,
codechicken.nei.recipe.FireworkRecipeHandler,Minecraft,minecraft:fireworks,,minecraft,FALSE,,,65,166,5,,,,,,,
codechicken.nei.recipe.FurnaceRecipeHandler,Minecraft,minecraft:furnace,,minecraft,FALSE,,,65,166,5,,,,,,,
codechicken.nei.recipe.ShapedRecipeHandler,Minecraft,minecraft:crafting_table,,minecraft,FALSE,,,65,166,5,,,,,,,
codechicken.nei.recipe.ShapelessRecipeHandler,Minecraft,minecraft:crafting_table,,minecraft,FALSE,,,65,166,5,,,,,,,
codechicken.nei.recipe.FuelRecipeHandler,Minecraft,,,minecraft,FALSE,,,65,166,5,nei:textures/nei_tabbed_sprites.png,80,0,14,14,,
codechicken.nei.recipe.InformationHandler,Not Enough Items,,,nei,FALSE,,,65,166,1,nei:textures/nei_tabbed_sprites.png,96,0,16,16,,
advsolar.client.nei.MTRecipeHandler,Advanced Solar Panels,AdvancedSolarPanel:BlockMolecularTransformer,,AdvancedSolarPanel,TRUE,,,68,,5,,,,,,,
appeng.integration.modules.NEIHelpers.NEIAEShapedRecipeHandler,Applied Energistics 2,appliedenergistics2:item.ItemMultiPart:380,,appliedenergistics2,TRUE,,,65,,5,,,,,,,
appeng.integration.modules.NEIHelpers.NEIAEShapelessRecipeHandler,Applied Energistics 2,appliedenergistics2:item.ItemMultiPart:380,,appliedenergistics2,TRUE,,,65,,5,,,,,,,
@@ -13,8 +6,8 @@ appeng.integration.modules.NEIHelpers.NEIFacadeRecipeHandler,Applied Energistics
appeng.integration.modules.NEIHelpers.NEIGrinderRecipeHandler,Applied Energistics 2,appliedenergistics2:tile.BlockGrinder,,appliedenergistics2,TRUE,,,,,,,,,,,,
appeng.integration.modules.NEIHelpers.NEIInscriberRecipeHandler,Applied Energistics 2,appliedenergistics2:tile.BlockInscriber,,appliedenergistics2,TRUE,,,70,,5,,,,,,,
appeng.integration.modules.NEIHelpers.NEIWorldCraftingHandler,Applied Energistics 2,appliedenergistics2:item.ItemMultiMaterial:9,,appliedenergistics2,TRUE,,,85,,5,,,,,,There's only some explanatory text for fluix crystals and QEDs,
appeng.integration.modules.NEIHelpers.NEICellViewHandler,Applied Energistics 2,appliedenergistics2:item.ItemBasicStorageCell.64k,,appliedenergistics2,TRUE,,,180,,1,,,,,,,,
com.glodblock.github.nei.NEICellViewHandler,AE2 Fluid Crafting,ae2fc:multi_fluid_storage64,,ae2fc,TRUE,,,,,1,,,,,,,,
appeng.integration.modules.NEIHelpers.NEICellViewHandler,Applied Energistics 2,appliedenergistics2:item.ItemBasicStorageCell.64k,,appliedenergistics2,TRUE,,,180,,1,,,,,,,
com.glodblock.github.nei.NEICellViewHandler,AE2 Fluid Crafting,ae2fc:multi_fluid_storage64,,ae2fc,TRUE,,,,,1,,,,,,,
aroma1997.core.recipes.nei.ShapedAromicRecipeHandler,AromaBackup,minecraft:crafting_table,,AromaBackup,TRUE,,,65,,5,,,,,,,
aroma1997.core.recipes.nei.ShapelessAromicRecipeHandler,AromaBackup,minecraft:crafting_table,,AromaBackup,TRUE,,,,,,,,,,,,
fox.spiteful.avaritia.compat.nei.CompressionHandler,Avaritia,Avaritia:Neutronium_Compressor,,Avaritia,TRUE,,,50,,6,,,,,,,
@@ -95,7 +88,7 @@ gt.recipe.alloysmelter,GregTech,gregtech:gt.blockmachines:201,,gregtech,TRUE,gre
gt.recipe.arcfurnace,GregTech,gregtech:gt.blockmachines:651,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
gt.recipe.assembler,GregTech,gregtech:gt.blockmachines:211,,gregtech,TRUE,gregapi_post,6,145,166,2,,,,,,,
gt.recipe.autoclave,GregTech,gregtech:gt.blockmachines:571,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
gt.recipe.blastfurnace,GregTech,gregtech:gt.blockmachines:1000,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
gt.recipe.blastfurnace,GregTech,gregtech:gt.blockmachines:1000,,gregtech,TRUE,gregapi_post,6,135,166,2,nei:textures/multiblocks/electric_blast_furnace.png,80,0,14,18,,
gt.recipe.brewer,GregTech,gregtech:gt.blockmachines:491,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
gt.recipe.byproductlist,GregTech,gregtech:gt.metaitem.01:2019,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
gt.recipe.canner,GregTech,gregtech:gt.blockmachines:231,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
@@ -161,7 +154,7 @@ gt.recipe.thermalcentrifuge,GregTech,gregtech:gt.blockmachines:381,,gregtech,TRU
gt.recipe.thermalgeneratorfuel,GregTech,IC2:blockGenerator:1,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
gt.recipe.unpackager,GregTech,gregtech:gt.blockmachines:411,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
gt.recipe.uuamplifier,GregTech,gregtech:gt.blockmachines:471,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
gt.recipe.vacuumfreezer,GregTech,gregtech:gt.blockmachines:1002,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
gt.recipe.vacuumfreezer,GregTech,gregtech:gt.blockmachines:1002,,gregtech,TRUE,gregapi_post,6,135,166,2,nei:textures/multiblocks/vacuum_freezer.png,80,0,12,12,,
gt.recipe.wiremill,GregTech,gregtech:gt.blockmachines:351,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
ic.recipe.recycler,GregTech,gregtech:gt.blockmachines:331,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
pers.gwyog.gtneioreplugin.plugin.gregtech5.PluginGT5SmallOreStat,GregTech,gregtech:gt.blockores:85,,gregtech,TRUE,,,145,,2,,,,,,,
@@ -358,7 +351,7 @@ vazkii.botania.client.integration.nei.recipe.RecipeHandlerRunicAltar,Botania,Bot
vazkii.botania.client.integration.nei.recipe.RecipeHandlerManaPool,Botania,Botania:pool,,Botania,TRUE,,,90,137,4,,,,,,,
vazkii.botania.client.integration.nei.recipe.RecipeHandlerElvenTrade,Botania,Botania:alfheimPortal,,Botania,TRUE,,,90,130,4,,,,,,,
vazkii.botania.client.integration.nei.recipe.RecipeHandlerBrewery,Botania,Botania:brewery,,Botania,TRUE,,,,,4,,,,,,,
vazkii.botania.client.integration.nei.recipe.RecipeHandlerPureDaisy,Botania,Botania:specialFlower,"{type:puredaisy}",Botania,TRUE,,,,,4,,,,,,,
vazkii.botania.client.integration.nei.recipe.RecipeHandlerPureDaisy,Botania,Botania:specialFlower,{type:puredaisy},Botania,TRUE,,,,,4,,,,,,,
vazkii.botania.client.integration.nei.recipe.RecipeHandlerLexicaBotania,Botania,Botania:lexicon,,Botania,TRUE,,,,,,,,,,,,
com.jaquadro.minecraft.storagedrawers.integration.notenoughitems.UpgradeItemRecipeHandler,Storage Drawers,minecraft:crafting_table,,StorageDrawers,TRUE,,,65,166,5,,,,,,,
ieArcFurnace,Immersive Engineering,ImmersiveEngineering:graphiteElectrode,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,,
@@ -535,7 +528,7 @@ vazkii.botania.client.integration.nei.RecipeHandlerRunicAltar,Botania,Botania:ru
vazkii.botania.client.integration.nei.RecipeHandlerManaPool,Botania,Botania:pool,,Botania,TRUE,,,90,137,4,,,,,,,
vazkii.botania.client.integration.nei.RecipeHandlerElvenTrade,Botania,Botania:alfheimPortal,,Botania,TRUE,,,90,130,4,,,,,,,
vazkii.botania.client.integration.nei.RecipeHandlerBrewery,Botania,Botania:brewery,,Botania,TRUE,,,,,4,,,,,,,
vazkii.botania.client.integration.nei.RecipeHandlerPureDaisy,Botania,Botania:specialFlower,"{type:puredaisy}",Botania,TRUE,,,,,4,,,,,,,
vazkii.botania.client.integration.nei.RecipeHandlerPureDaisy,Botania,Botania:specialFlower,{type:puredaisy},Botania,TRUE,,,,,4,,,,,,,
vazkii.botania.client.integration.nei.RecipeHandlerLexicaBotania,Botania,Botania:lexicon,,Botania,TRUE,,,,,,,,,,,,
neiplugins.forge.OreDictionaryList,NEIPlugins,minecraft:book,,NEIPlugins,TRUE,,,,,,,,,,,,
neiplugins.forge.FluidRegistryList,NEIPlugins,minecraft:bucket,,NEIPlugins,TRUE,,,,,,,,,,,,
@@ -611,7 +604,7 @@ com.cout970.magneticraft.compat.nei.CraftingGrinder,Magneticraft,Magneticraft:gr
com.cout970.magneticraft.compat.nei.CraftingPolymerizer,Magneticraft,Magneticraft:polimerizer_control,,Magneticraft,TRUE,,,,,,,,,,,,
com.cout970.magneticraft.compat.nei.CraftingBiomassBurner,Magneticraft,Magneticraft:biomassburner,,Magneticraft,TRUE,,,,,,,,,,,,
com.cout970.magneticraft.compat.nei.CraftingSifter,Magneticraft,Magneticraft:sifter_control,,Magneticraft,TRUE,,,,,,,,,,,,
pneumaticCraft.common.thirdparty.nei.NEIRefineryManager,PneumaticCraft,PneumaticCraft:refinery,,PneumaticCraft,TRUE,,"",80,,4,,,,,,,
pneumaticCraft.common.thirdparty.nei.NEIRefineryManager,PneumaticCraft,PneumaticCraft:refinery,,PneumaticCraft,TRUE,,,80,,4,,,,,,,
pneumaticCraft.common.thirdparty.nei.NEIPlasticMixerManager,PneumaticCraft,PneumaticCraft:plasticMixer,,PneumaticCraft,TRUE,,,,,,,,,,,,
pneumaticCraft.common.thirdparty.nei.NEIAmadronTradeManager,PneumaticCraft,PneumaticCraft:amadronTablet,,PneumaticCraft,TRUE,,,,,,,,,,,,
pneumaticCraft.common.thirdparty.nei.NEIUVLightBoxManager,PneumaticCraft,PneumaticCraft:uvLightBox,,PneumaticCraft,TRUE,,,,,,,,,,,,
@@ -621,7 +614,7 @@ pneumaticCraft.common.thirdparty.nei.NEIAssemblyControllerRecipeManager,Pneumati
pneumaticCraft.common.thirdparty.nei.NEIPressureChamberRecipeManager,PneumaticCraft,PneumaticCraft:pressureChamberInterface,,PneumaticCraft,TRUE,,,130,,2,,,,,,,
exter.foundry.integration.nei.InductionCrucibleFurnaceRecipeHandler,Foundry,foundry:foundryMachine:0,,foundry,TRUE,,,,,,,,,,,,
exter.foundry.integration.nei.AlloyMixerRecipeHandler,Foundry,foundry:foundryMachine:2,,foundry,TRUE,,,,,,,,,,,,
exter.foundry.integration.nei.MetalCasterRecipeHandler,Foundry,foundry:foundryMachine:1,"",foundry,TRUE,,,,,,,,,,,,
exter.foundry.integration.nei.MetalCasterRecipeHandler,Foundry,foundry:foundryMachine:1,,foundry,TRUE,,,,,,,,,,,,
exter.foundry.integration.nei.InfuserRecipeHandler,Foundry,foundry:foundryMachine:3,,foundry,TRUE,,,,,,,,,,,,
exter.foundry.integration.nei.InfuserSubstanceRecipeHandler,Foundry,foundry:foundryMachine:3,,foundry,TRUE,,,,,,,,,,,,
exter.foundry.integration.nei.AlloyFurnaceRecipeHandler,Foundry,foundry:alloyFurnace,,foundry,TRUE,,,,,,,,,,,,
@@ -633,7 +626,7 @@ net.dries007.tfcnei.recipeHandlers.LoomRecipeHandler,TerraFirmaCraft,terrafirmac
net.dries007.tfcnei.recipeHandlers.KnappingRecipeHandler,TerraFirmaCraft,terrafirmacraft:item.LooseRock,,terrafirmacraft,TRUE,,,96,166,3,,,,,,,
net.dries007.tfcnei.recipeHandlers.BarrelRecipeHandler,TerraFirmaCraft,terrafirmacraft:Barrel,,terrafirmacraft,TRUE,,,65,166,5,,,,,,,
net.dries007.tfcnei.recipeHandlers.AlloyRecipeHandler,TerraFirmaCraft,terrafirmacraft:Crucible,,terrafirmacraft,TRUE,,,65,166,5,,,,,,,
net.dries007.tfcnei.recipeHandlers.HeatRecipeHandler,TerraFirmaCraft,terrafirmacraft:Firepit,,terrafirmacraft,TRUE,,,65,166,5,"",,,,,,
net.dries007.tfcnei.recipeHandlers.HeatRecipeHandler,TerraFirmaCraft,terrafirmacraft:Firepit,,terrafirmacraft,TRUE,,,65,166,5,,,,,,,
techreborn.compat.nei.FustionReacorRecipeHandler,TechReborn,techreborn:fusioncontrolcomputer,,techreborn,TRUE,,,,,,,,,,,,
techreborn.compat.nei.recipes.VacuumFreezerRecipeHandler,TechReborn,techreborn:vacuumfreezer,,techreborn,TRUE,,,,,,,,,,,,
techreborn.compat.nei.recipes.ImplosionCompressorRecipeHandler,TechReborn,techreborn:implosioncompressor,,techreborn,TRUE,,,,,,,,,,,,
@@ -656,4 +649,4 @@ straywolfe.cookingwithtfc.client.nei.CookingPotRecipeHandler,Cooking with TFC,co
straywolfe.cookingwithtfc.client.nei.ClayOvenRecipeHandler,Cooking with TFC,cookingwithtfc:item.clayOvenWall,,cookingwithtfc,TRUE,,,,,,,,,,,,
factorization.nei.RecipeMixer,Factorization,factorization:FzBlock:18,,factorization,TRUE,,,,,,,,,,,,
ua.pp.shurgent.tfctech.nei.WireDrawBenchRecipeHandler,Shurgent's TFCTech Addon,tfctech:item.Wire Draw Bench,,tfctech,TRUE,,,,,,,,,,,,
mekanism.client.nei.ElectrolyticSeparatorRecipeHandler,Mekanism,Mekanism:MachineBlock2:4,,Mekanism,TRUE,,,,,,,,,,,,
mekanism.client.nei.ElectrolyticSeparatorRecipeHandler,Mekanism,Mekanism:MachineBlock2:4,,Mekanism,TRUE,,,,,,,,,,,,
1 handler modName itemName nbtInfo modId modRequired excludedModId yShift handlerHeight handlerWidth maxRecipesPerPage imageResource imageX imageY imageWidth imageHeight itemNotes useCustomScroll
codechicken.nei.recipe.BrewingRecipeHandler Minecraft minecraft:brewing_stand minecraft FALSE 65 166 5
codechicken.nei.recipe.FireworkRecipeHandler Minecraft minecraft:fireworks minecraft FALSE 65 166 5
codechicken.nei.recipe.FurnaceRecipeHandler Minecraft minecraft:furnace minecraft FALSE 65 166 5
codechicken.nei.recipe.ShapedRecipeHandler Minecraft minecraft:crafting_table minecraft FALSE 65 166 5
codechicken.nei.recipe.ShapelessRecipeHandler Minecraft minecraft:crafting_table minecraft FALSE 65 166 5
codechicken.nei.recipe.FuelRecipeHandler Minecraft minecraft FALSE 65 166 5 nei:textures/nei_tabbed_sprites.png 80 0 14 14
codechicken.nei.recipe.InformationHandler Not Enough Items nei FALSE 65 166 1 nei:textures/nei_tabbed_sprites.png 96 0 16 16
2 advsolar.client.nei.MTRecipeHandler Advanced Solar Panels AdvancedSolarPanel:BlockMolecularTransformer AdvancedSolarPanel TRUE 68 5
3 appeng.integration.modules.NEIHelpers.NEIAEShapedRecipeHandler Applied Energistics 2 appliedenergistics2:item.ItemMultiPart:380 appliedenergistics2 TRUE 65 5
4 appeng.integration.modules.NEIHelpers.NEIAEShapelessRecipeHandler Applied Energistics 2 appliedenergistics2:item.ItemMultiPart:380 appliedenergistics2 TRUE 65 5
6 appeng.integration.modules.NEIHelpers.NEIGrinderRecipeHandler Applied Energistics 2 appliedenergistics2:tile.BlockGrinder appliedenergistics2 TRUE
7 appeng.integration.modules.NEIHelpers.NEIInscriberRecipeHandler Applied Energistics 2 appliedenergistics2:tile.BlockInscriber appliedenergistics2 TRUE 70 5
8 appeng.integration.modules.NEIHelpers.NEIWorldCraftingHandler Applied Energistics 2 appliedenergistics2:item.ItemMultiMaterial:9 appliedenergistics2 TRUE 85 5 There's only some explanatory text for fluix crystals and QEDs
9 appeng.integration.modules.NEIHelpers.NEICellViewHandler Applied Energistics 2 appliedenergistics2:item.ItemBasicStorageCell.64k appliedenergistics2 TRUE 180 1
10 com.glodblock.github.nei.NEICellViewHandler AE2 Fluid Crafting ae2fc:multi_fluid_storage64 ae2fc TRUE 1
11 aroma1997.core.recipes.nei.ShapedAromicRecipeHandler AromaBackup minecraft:crafting_table AromaBackup TRUE 65 5
12 aroma1997.core.recipes.nei.ShapelessAromicRecipeHandler AromaBackup minecraft:crafting_table AromaBackup TRUE
13 fox.spiteful.avaritia.compat.nei.CompressionHandler Avaritia Avaritia:Neutronium_Compressor Avaritia TRUE 50 6
88 gt.recipe.arcfurnace GregTech gregtech:gt.blockmachines:651 gregtech TRUE gregapi_post 6 135 166 2
89 gt.recipe.assembler GregTech gregtech:gt.blockmachines:211 gregtech TRUE gregapi_post 6 145 166 2
90 gt.recipe.autoclave GregTech gregtech:gt.blockmachines:571 gregtech TRUE gregapi_post 6 135 166 2
91 gt.recipe.blastfurnace GregTech gregtech:gt.blockmachines:1000 gregtech TRUE gregapi_post 6 135 166 2 nei:textures/multiblocks/electric_blast_furnace.png 80 0 14 18
92 gt.recipe.brewer GregTech gregtech:gt.blockmachines:491 gregtech TRUE gregapi_post 6 135 166 2
93 gt.recipe.byproductlist GregTech gregtech:gt.metaitem.01:2019 gregtech TRUE gregapi_post 6 135 166 2
94 gt.recipe.canner GregTech gregtech:gt.blockmachines:231 gregtech TRUE gregapi_post 6 135 166 2
154 gt.recipe.thermalgeneratorfuel GregTech IC2:blockGenerator:1 gregtech TRUE gregapi_post 6 135 166 2
155 gt.recipe.unpackager GregTech gregtech:gt.blockmachines:411 gregtech TRUE gregapi_post 6 135 166 2
156 gt.recipe.uuamplifier GregTech gregtech:gt.blockmachines:471 gregtech TRUE gregapi_post 6 135 166 2
157 gt.recipe.vacuumfreezer GregTech gregtech:gt.blockmachines:1002 gregtech TRUE gregapi_post 6 135 166 2 nei:textures/multiblocks/vacuum_freezer.png 80 0 12 12
158 gt.recipe.wiremill GregTech gregtech:gt.blockmachines:351 gregtech TRUE gregapi_post 6 135 166 2
159 ic.recipe.recycler GregTech gregtech:gt.blockmachines:331 gregtech TRUE gregapi_post 6 135 166 2
160 pers.gwyog.gtneioreplugin.plugin.gregtech5.PluginGT5SmallOreStat GregTech gregtech:gt.blockores:85 gregtech TRUE 145 2
351 vazkii.botania.client.integration.nei.recipe.RecipeHandlerManaPool Botania Botania:pool Botania TRUE 90 137 4
352 vazkii.botania.client.integration.nei.recipe.RecipeHandlerElvenTrade Botania Botania:alfheimPortal Botania TRUE 90 130 4
353 vazkii.botania.client.integration.nei.recipe.RecipeHandlerBrewery Botania Botania:brewery Botania TRUE 4
354 vazkii.botania.client.integration.nei.recipe.RecipeHandlerPureDaisy Botania Botania:specialFlower {type:puredaisy} Botania TRUE 4
355 vazkii.botania.client.integration.nei.recipe.RecipeHandlerLexicaBotania Botania Botania:lexicon Botania TRUE
356 com.jaquadro.minecraft.storagedrawers.integration.notenoughitems.UpgradeItemRecipeHandler Storage Drawers minecraft:crafting_table StorageDrawers TRUE 65 166 5
357 ieArcFurnace Immersive Engineering ImmersiveEngineering:graphiteElectrode ImmersiveEngineering TRUE 65 166 5
528 vazkii.botania.client.integration.nei.RecipeHandlerManaPool Botania Botania:pool Botania TRUE 90 137 4
529 vazkii.botania.client.integration.nei.RecipeHandlerElvenTrade Botania Botania:alfheimPortal Botania TRUE 90 130 4
530 vazkii.botania.client.integration.nei.RecipeHandlerBrewery Botania Botania:brewery Botania TRUE 4
531 vazkii.botania.client.integration.nei.RecipeHandlerPureDaisy Botania Botania:specialFlower {type:puredaisy} Botania TRUE 4
532 vazkii.botania.client.integration.nei.RecipeHandlerLexicaBotania Botania Botania:lexicon Botania TRUE
533 neiplugins.forge.OreDictionaryList NEIPlugins minecraft:book NEIPlugins TRUE
534 neiplugins.forge.FluidRegistryList NEIPlugins minecraft:bucket NEIPlugins TRUE
604 com.cout970.magneticraft.compat.nei.CraftingPolymerizer Magneticraft Magneticraft:polimerizer_control Magneticraft TRUE
605 com.cout970.magneticraft.compat.nei.CraftingBiomassBurner Magneticraft Magneticraft:biomassburner Magneticraft TRUE
606 com.cout970.magneticraft.compat.nei.CraftingSifter Magneticraft Magneticraft:sifter_control Magneticraft TRUE
607 pneumaticCraft.common.thirdparty.nei.NEIRefineryManager PneumaticCraft PneumaticCraft:refinery PneumaticCraft TRUE 80 4
608 pneumaticCraft.common.thirdparty.nei.NEIPlasticMixerManager PneumaticCraft PneumaticCraft:plasticMixer PneumaticCraft TRUE
609 pneumaticCraft.common.thirdparty.nei.NEIAmadronTradeManager PneumaticCraft PneumaticCraft:amadronTablet PneumaticCraft TRUE
610 pneumaticCraft.common.thirdparty.nei.NEIUVLightBoxManager PneumaticCraft PneumaticCraft:uvLightBox PneumaticCraft TRUE
614 pneumaticCraft.common.thirdparty.nei.NEIPressureChamberRecipeManager PneumaticCraft PneumaticCraft:pressureChamberInterface PneumaticCraft TRUE 130 2
615 exter.foundry.integration.nei.InductionCrucibleFurnaceRecipeHandler Foundry foundry:foundryMachine:0 foundry TRUE
616 exter.foundry.integration.nei.AlloyMixerRecipeHandler Foundry foundry:foundryMachine:2 foundry TRUE
617 exter.foundry.integration.nei.MetalCasterRecipeHandler Foundry foundry:foundryMachine:1 foundry TRUE
618 exter.foundry.integration.nei.InfuserRecipeHandler Foundry foundry:foundryMachine:3 foundry TRUE
619 exter.foundry.integration.nei.InfuserSubstanceRecipeHandler Foundry foundry:foundryMachine:3 foundry TRUE
620 exter.foundry.integration.nei.AlloyFurnaceRecipeHandler Foundry foundry:alloyFurnace foundry TRUE
626 net.dries007.tfcnei.recipeHandlers.KnappingRecipeHandler TerraFirmaCraft terrafirmacraft:item.LooseRock terrafirmacraft TRUE 96 166 3
627 net.dries007.tfcnei.recipeHandlers.BarrelRecipeHandler TerraFirmaCraft terrafirmacraft:Barrel terrafirmacraft TRUE 65 166 5
628 net.dries007.tfcnei.recipeHandlers.AlloyRecipeHandler TerraFirmaCraft terrafirmacraft:Crucible terrafirmacraft TRUE 65 166 5
629 net.dries007.tfcnei.recipeHandlers.HeatRecipeHandler TerraFirmaCraft terrafirmacraft:Firepit terrafirmacraft TRUE 65 166 5
630 techreborn.compat.nei.FustionReacorRecipeHandler TechReborn techreborn:fusioncontrolcomputer techreborn TRUE
631 techreborn.compat.nei.recipes.VacuumFreezerRecipeHandler TechReborn techreborn:vacuumfreezer techreborn TRUE
632 techreborn.compat.nei.recipes.ImplosionCompressorRecipeHandler TechReborn techreborn:implosioncompressor techreborn TRUE
649 straywolfe.cookingwithtfc.client.nei.ClayOvenRecipeHandler Cooking with TFC cookingwithtfc:item.clayOvenWall cookingwithtfc TRUE
650 factorization.nei.RecipeMixer Factorization factorization:FzBlock:18 factorization TRUE
651 ua.pp.shurgent.tfctech.nei.WireDrawBenchRecipeHandler Shurgent's TFCTech Addon tfctech:item.Wire Draw Bench tfctech TRUE
652 mekanism.client.nei.ElectrolyticSeparatorRecipeHandler Mekanism Mekanism:MachineBlock2:4 Mekanism TRUE
@@ -525,6 +525,7 @@ nei.options.tools.dump.handlers.mode.0=CSV
nei.options.tools.dump.handlers.mode.1=Json
nei.debug.RecipeHandler.title=Debug Recipe Handler
nei.debug.RecipeHandler.copy=Copy
nei.debug.RecipeHandler.Name=Name
nei.debug.RecipeHandler.Id=ID
nei.debug.RecipeHandler.Key=Key
@@ -536,7 +537,14 @@ nei.debug.RecipeHandler.yShift=yShift
nei.debug.RecipeHandler.MultiWidgets=Multi Widgets
nei.debug.RecipeHandler.Height=Height
nei.debug.RecipeHandler.Width=Width
nei.debug.RecipeHandler.ShowFavorites=Show Favorites
nei.debug.RecipeHandler.ShowOverlay=Show Overlays
nei.debug.RecipeHandler.UseCustomScroll=Use Custom Scroll
nei.debug.RecipeHandler.Override=Override
nei.debug.RecipeHandler.checkbox.on=On
nei.debug.RecipeHandler.checkbox.off=Off
nei.debug.RecipeHandler.yes=Yes
nei.debug.RecipeHandler.no=No
nei.recipe.page=Page %s/%s
nei.recipe.tooltip=Recipes
@@ -556,6 +564,7 @@ nei.recipe.firework=Fireworks
nei.recipe.firework.tooltip0=Dyes add colours to the charges
nei.recipe.firework.tooltip1=Recolouring adds fade colours to the charge
nei.recipe.firework.tooltip2=Multiple charges can be spawned from one rocket
nei.recipe.repair=Repair
nei.recipe.brewing=Brewing
nei.recipe.profiler.crafting=Crafting Profiling
nei.recipe.profiler.usage=Usage Profiling
Binary file not shown.

After

Width:  |  Height:  |  Size: 726 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB