Compare commits

..
52 Commits
Author SHA1 Message Date
Maya 48934d621f update 2025-01-25 13:17:03 -06:00
slprimeandslprime 0bbb889f39 Change Permutation Filter (#598)
Co-authored-by: slprime <[email protected]>
2025-01-25 13:16:28 -06:00
Martin Robertz af55a6b191 update
(cherry picked from commit bd7e8d05fa)
2025-01-21 17:55:50 +01:00
slprimeandslprime b3e1f23683 Restore Issue 583 (#593)
Co-authored-by: slprime <[email protected]>
2025-01-21 10:50:16 -06:00
slprimeandslprime 39578a4419 Update Render Cache after window resize (#592)
Co-authored-by: slprime <[email protected]>
2025-01-19 11:33:26 -06:00
e3574800c0 Subset Widget Improvement (#577)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Martin Robertz <[email protected]>
Co-authored-by: Caedis <[email protected]>
Co-authored-by: Maya <[email protected]>
2025-01-16 21:12:26 +01:00
Martin Robertz 5cd7556e6a update 2025-01-16 12:44:42 +01:00
80c2cba778 Created Grid Rendering Cache Mode (#573)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Martin Robertz <[email protected]>
Co-authored-by: Caedis <[email protected]>
2025-01-15 23:23:16 -06:00
Glease 31173a1fbd fix memory leak fixes not working for MP (#590)
#258 addresses the memory leak in ItemMobSpawner. Unfortunately the clean up handler is not consistently called on every world unloaded. This PR fixes this issue by moving the call out of that if block
2025-01-10 17:11:52 +08:00
Caedis fd08a93554 Fix NPE in ItemsTooltipLineHandler (#589) 2025-01-10 10:42:23 +02:00
Martin Robertz 4dace1f6e5 update 2025-01-09 21:05:10 +01:00
0c0cf37eb0 Add 'Hide Item List Until Searching' option (#572)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Martin Robertz <[email protected]>
Co-authored-by: Maya <[email protected]>
2025-01-09 07:53:27 +00:00
Chris Stone 3ec4f8dd68 Add mod handlers for mods in Per Fabrica Ad Astra modpack (#587) 2025-01-08 12:30:34 -06:00
lailani-fandlailani-f e0dd6847cb Item List Sort: Ensure access to shared private field is atomic (#584)
Co-authored-by: lailani-f <>
2025-01-04 14:03:53 +00:00
slprimeandslprime 6374c162ba Fixed NEI reload when changing dimension (#583)
Co-authored-by: slprime <[email protected]>
2024-12-31 19:33:21 +01:00
8dd36f1c4a Add RenderTooltipEvent Compat (#574)
Co-authored-by: Martin Robertz <[email protected]>
Co-authored-by: Maya <[email protected]>
2024-12-28 23:00:02 -06:00
4613ade468 Change OptionIntegerField Width (#575)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Maya <[email protected]>
2024-12-29 02:36:53 +00:00
ca7030df72 Add Space Mode Settings to Search (#571)
Co-authored-by: slprime <[email protected]>
Co-authored-by: boubou19 <[email protected]>
2024-12-23 10:21:28 +00:00
Martin Robertz b32f25c2ce update 2024-12-22 11:38:38 +01:00
4be7a30578 Fix Accept Folowing for custom recipe handlers (#570)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Martin Robertz <[email protected]>
2024-12-22 03:01:44 +01:00
Martin Robertz 7ac3e32635 update 2024-12-17 20:36:35 +01:00
Martin Robertz 088d37a11a update 2024-12-17 20:36:29 +01:00
slprime 6a787dd5b7 Clear Search Filter Cache after Change Settings (#569) 2024-12-17 13:15:41 -06:00
c305649b95 Optimize TooltipItemFilter; ItemFilter limited cache (#565)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Martin Robertz <[email protected]>
2024-12-07 15:29:09 +01:00
slprimeandslprime b5d2815eab Fix CME in registerRectsToGuis during plugin loading (#566)
Co-authored-by: slprime <[email protected]>
2024-12-07 10:32:00 +01:00
slprimeandslprime 6049d0e9c3 Fix restoring collapsible items state (#564)
Co-authored-by: slprime <[email protected]>
2024-12-05 20:25:17 +01:00
9288fc4575 Fix Zoom Position in Right Panel (#559)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Ethryan <[email protected]>
2024-12-03 06:52:51 +01:00
Alexdoru ec749ecc8e Fix mob spawners spawning mobs at world 0 0 0 (#563) 2024-12-03 02:39:34 +01:00
Alexdoru 7471a82bca fix the handlerordering.csv being empty when created (#561) 2024-12-01 16:56:02 +01:00
kstvr32 3f3c1791cb Fix handler ordering config (#560) 2024-11-29 20:28:13 +00:00
a0e16835c2 Fix Presets Scroll; Fix Placeholder position in the quantity field; Hide rendering error in chat; (#555)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Martin Robertz <[email protected]>
2024-11-17 16:31:10 +01:00
Martin Robertz e9ce5cf72b update 2024-11-16 15:32:06 +01:00
slprimeandslprime fac011b67e Fix Zoom Position (#554)
Co-authored-by: slprime <[email protected]>
2024-11-15 10:20:32 +01:00
Worive f9c8ac504e Fix typo for cycledIngredientsTooltip.false in English(#553) 2024-11-14 14:27:14 +00:00
Maya f97711a33a add issue templates 2024-11-11 04:43:49 -06:00
kurrycat b2934c4910 replace GL immediate draw with Tessellator calls for chunk bounds rendering (#549) 2024-10-22 09:29:00 +02:00
Dream Master 759ea69c9f update 2024-10-13 22:01:17 +02:00
36a2cafdac Small Fixes (#543)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Martin Robertz <[email protected]>
2024-10-13 22:00:06 +02:00
Maya 6100012f5b Add Helioflare Power Forge (Gorge) to smelting catalysts (#544) 2024-10-13 21:48:11 +02:00
slprimeandslprime 2e5781beb5 fix catalysts in multiblock structure recipes when shown bookmarks recipe tooltip (#542)
Co-authored-by: slprime <[email protected]>
2024-10-06 12:10:05 +02:00
Alexdoru 43918f3bb1 give names to NEI threads (#540) 2024-10-04 21:46:29 +02:00
AtHisF1nestandMarcin Siekierski a41299dfca fix issue #17509 (#539)
Co-authored-by: Marcin Siekierski <[email protected]>
2024-10-02 17:21:50 +02:00
slprimeandslprime ee060b9253 Small Fixes (#536)
* Small Fixes

* fix shift+v

* fix subset zindex

---------

Co-authored-by: slprime <[email protected]>
2024-09-28 18:05:06 +02:00
Jon 82a2273995 Update en_US.lang (#534) 2024-09-15 22:10:18 +02:00
06fadcc362 Try fix Item Render & GuiRecipeHandler (#528)
Co-authored-by: slprime <[email protected]>
Co-authored-by: Martin Robertz <[email protected]>
2024-09-15 16:57:55 +02:00
slprimeandslprime b328fd3db1 Fix DraggedStack in Bookmarks (#527)
Co-authored-by: slprime <[email protected]>
2024-09-12 18:14:00 +02:00
Martin Robertz 9563ebfe5a update 2024-09-07 18:18:02 +02:00
slprimeandslprime d9143c584e Rename GT Classes; Correct show Meta Keys (#525)
Co-authored-by: slprime <[email protected]>
2024-09-07 14:49:46 +02:00
slprimeandslprime 65652e5896 Small fixes & changes (#523)
* fix hotkeys

* code cleanup

* fix recipe tooltip overlay

* search item by original name

* overlay button refactoring

* fix subset filter

* change keyname; issue 524

* cleanup code

* move overlayformat logic

---------

Co-authored-by: slprime <[email protected]>
2024-09-01 22:19:12 +02:00
slprimeandslprime bd5e991a84 NEI Optimization (#519)
* NEI Optimization

* save setting after death

---------

Co-authored-by: slprime <[email protected]>
2024-08-29 22:14:52 +02:00
glowredman 165afa2910 Small Cleanup (#518)
* Deobfuscate parameters

* Fix generics

* Replace deprecated methods

* Add `serialVersionUID`s

* Fix static access

* Add default switch case

* Close OutputStreams

* Fix wrong variable usage

* Explicitly declare exceptions
2024-08-29 20:07:14 +02:00
glowredman 2507634196 Allow any Character to be used as Search-Prefix (#522)
* Allow any character to be used as prefix

* Enable Jabel

* Add back search mode settings and add ingame setting for prefixes

* Implement prefix redefinitions
2024-08-29 08:17:00 +02:00
102 changed files with 3634 additions and 2425 deletions

No files matched your search

+62
View File
@@ -0,0 +1,62 @@
name: Report Bug
description: "Report a bug."
body:
- type: markdown
attributes:
value: "A bug/crash report with sufficient information and logs to reproduce and track down."
- type: input
id: discord
attributes:
label: Your GTNH Discord Username
description: Leave empty if you don't have one, but this will make it harder to contact you if we need additional info.
placeholder: "Example: Fake#1234"
- type: input
id: version
attributes:
label: Mod Version
description: "What version of the Mod are you using?"
placeholder: "Example: 1.0.0"
validations:
required: true
- type: textarea
id: report
attributes:
label: Bug Report
description: "Relevant information, as well as relevant logs attached such as `logs/fml-client-latest.log."
placeholder: "Example: https://mclo.gs/ OR submit the file to github by dragging it to this textbox."
validations:
required: true
- type: dropdown
id: java
attributes:
label: Java Version
description: What Java version are you using? It's worth mentioning that if you play on Java9+ you should try update to latest minor release (e.g. prefer Java 17.0.6 over 17.0.2) of that version.
options:
- Java 8
- Java 9
- Java 11
- Java 17
- Java 19
- Java 20
- Java 21
- Other (Please Specify)
validations:
required: true
- type: textarea
id: modlist
attributes:
label: Mod List or GTNH Pack Version
description: "List of mods, ideally a minimal reproducible set (can be retrieved from latest.log). If using GTNH please indicate pack version and any changed mods, not the entire modlist."
placeholder: "List of mods or GTNH Pack version goes here"
validations:
required: true
- type: checkboxes
id: final
attributes:
label: Final Checklist
description: Certify that you read things
options:
- label: "I have searched the issues and haven't found a similar issue."
required: true
@@ -0,0 +1,28 @@
name: Feature Request
description: "Request a feature."
body:
- type: markdown
attributes:
value: "Please use this form to request features. We ask you check if it was already requested though"
- type: input
id: discord
attributes:
label: Your GTNH Discord Username
description: Leave empty if you don't have one, but this will make it harder to contact you if we need additional info.
placeholder: "Example: Wumpus#1234"
- type: textarea
id: request
attributes:
label: Feature Request
description: "Relevant information, as well as relevant images"
placeholder: "Example: https://mclo.gs/ OR submit the file to github by dragging it to this textbox."
validations:
required: true
- type: checkboxes
id: final
attributes:
label: Final Checklist
description: Certify that you read things
options:
- label: "I have searched the issues and haven't found a similar issue."
required: true
+3 -1
View File
@@ -1,6 +1,8 @@
// Add your dependencies here
dependencies {
api('com.github.GTNewHorizons:CodeChickenCore:1.3.6:dev')
api('com.github.GTNewHorizons:CodeChickenCore:1.4.1:dev')
implementation('com.github.GTNewHorizons:GTNHLib:0.6.5:dev')
shadowImplementation('org.apache.commons:commons-csv:1.10.0')
}
+2 -2
View File
@@ -41,11 +41,11 @@ developmentEnvironmentUserName = Developer
# Enables using modern Java syntax (up to version 17) via Jabel, while still targeting JVM 8.
# See https://github.com/bsideup/jabel for details on how this works.
enableModernJavaSyntax = false
enableModernJavaSyntax = true
# Enables injecting missing generics into the decompiled source code for a better coding experience.
# Turns most publicly visible List, Map, etc. into proper List<E>, Map<K, V> types.
enableGenericInjection = false
enableGenericInjection = true
# Generate a class with a String field for the mod version named as defined below.
# If generateGradleTokenClass is empty or not missing, no such class will be generated.
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-8.9-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
+1 -1
View File
@@ -17,7 +17,7 @@ pluginManagement {
}
plugins {
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.26'
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.31'
}
@@ -130,9 +130,12 @@ public class BookmarkPanel extends PanelWidget {
}
public void setEndRowIndex(BookmarkGrid BGrid, int rowIndex) {
this.endRowIndex = rowIndex;
this.endItemIndexTop = getTopItemIndex(BGrid, rowIndex);
this.endItemIndexBottom = getBottomItemIndex(BGrid, rowIndex);
if (BGrid.getRowItemIndex(rowIndex, true) >= 0) {
this.endRowIndex = rowIndex;
this.endItemIndexTop = getTopItemIndex(BGrid, rowIndex);
this.endItemIndexBottom = getBottomItemIndex(BGrid, rowIndex);
}
}
public boolean hasEndRow() {
@@ -226,12 +229,12 @@ public class BookmarkPanel extends PanelWidget {
}
}
public static enum BookmarkViewMode {
public enum BookmarkViewMode {
DEFAULT,
TODO_LIST
}
public static enum BookmarkLoadingState {
public enum BookmarkLoadingState {
LOADING,
LOADED
}
@@ -954,7 +957,7 @@ public class BookmarkPanel extends PanelWidget {
this.realItems.add(stackA);
this.metadata.add(meta);
if (animate && !NEIClientConfig.shouldCacheItemRendering() && NEIClientConfig.areBookmarksAnimated()) {
if (animate && NEIClientConfig.getGridRenderingCacheMode() == 0 && NEIClientConfig.areBookmarksAnimated()) {
this.animation.put(stackA, 0f);
}
@@ -1037,8 +1040,9 @@ public class BookmarkPanel extends PanelWidget {
}
}
protected boolean shouldCacheItemRendering() {
return NEIClientConfig.shouldCacheItemRendering() && this.focusedGroupId == -1;
@Override
protected int getGridRenderingCacheMode() {
return this.focusedGroupId == -1 ? NEIClientConfig.getGridRenderingCacheMode() : 0;
}
@Override
@@ -1294,8 +1298,7 @@ public class BookmarkPanel extends PanelWidget {
RenderHelper.enableGUIStandardItemLighting();
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
GL11.glDisable(GL11.GL_DEPTH_TEST);
@SuppressWarnings("unchecked")
List<Slot> slots = (List<Slot>) this.gui.slotcontainer.inventorySlots;
List<Slot> slots = this.gui.slotcontainer.inventorySlots;
for (Slot slot : slots) {
if (slot != null && slot.getStack() != null) {
@@ -1764,7 +1767,12 @@ public class BookmarkPanel extends PanelWidget {
return namespaces.size();
}
public void setBookmarkFile(String worldPath) {
public void load() {
String worldPath = "global";
if (NEIClientConfig.getBooleanSetting("inventory.bookmarks.worldSpecific")) {
worldPath = NEIClientConfig.getWorldPath();
}
final File dir = new File(CommonUtils.getMinecraftDir(), "saves/NEI/" + worldPath);
@@ -1782,16 +1790,15 @@ public class BookmarkPanel extends PanelWidget {
if (defaultBookmarks.exists()) {
try {
bookmarkFile.createNewFile();
if (bookmarkFile.createNewFile()) {
InputStream src = new FileInputStream(defaultBookmarks);
OutputStream dst = new FileOutputStream(bookmarkFile);
InputStream src = new FileInputStream(defaultBookmarks);
OutputStream dst = new FileOutputStream(bookmarkFile);
IOUtils.copy(src, dst);
src.close();
dst.close();
IOUtils.copy(src, dst);
src.close();
dst.close();
}
} catch (IOException e) {}
}
}
@@ -2053,7 +2060,7 @@ public class BookmarkPanel extends PanelWidget {
public void setVisible() {
super.setVisible();
if (grid.getPerPage() > 0) {
if (grid.getPerPage() > 0 && getNamespaceSize() > 1) {
LayoutManager.addWidget(namespacePrev);
LayoutManager.addWidget(namespaceNext);
LayoutManager.addWidget(namespaceLabel);
@@ -2106,6 +2113,9 @@ public class BookmarkPanel extends PanelWidget {
@Override
public void mouseDragged(int mousex, int mousey, int button, long heldTime) {
if (mouseDownSlot >= grid.realItems.size()) {
mouseDownSlot = -1;
}
if (this.groupingItem != null) {
final int overRowIndex = (mousey - grid.marginTop) / BookmarkGrid.SLOT_SIZE;
@@ -2238,8 +2248,7 @@ public class BookmarkPanel extends PanelWidget {
if (button == 0 && NEIClientUtils.shiftKey() && mouseDownSlot >= 0 && this.sortableItem == null) {
ItemPanelSlot mouseOverSlot = getSlotMouseOver(mousex, mousey);
if (grid.getItem(mouseDownSlot) != null
&& (mouseOverSlot == null || mouseOverSlot.slotIndex != mouseDownSlot || heldTime > 250)) {
if (mouseOverSlot == null || mouseOverSlot.slotIndex != mouseDownSlot || heldTime > 250) {
final BookmarkGrid BGrid = (BookmarkGrid) grid;
final ItemStackMetadata meta = BGrid.getMetadata(mouseDownSlot);
final List<ItemStack> items = new ArrayList<>();
@@ -2497,20 +2506,19 @@ public class BookmarkPanel extends PanelWidget {
translate("bookmark.group.toggle_crafting_chain.key"),
translate("bookmark.group.toggle_crafting_chain"));
String keyName = NEIClientConfig.getKeyName(NEIClientConfig.getKeyBinding("gui.remove_recipe"), true);
String keyName = NEIClientConfig.getKeyName("gui.remove_recipe");
if (keyName != null) {
hotkeys.put(keyName, translate("bookmark.group.remove_recipe"));
}
if (BookmarkContainerInfo.getBookmarkContainerHandler(gui) != null) {
keyName = NEIClientConfig.getKeyName(NEIClientConfig.getKeyBinding("gui.bookmark_pull_items"), true);
keyName = NEIClientConfig.getKeyName("gui.bookmark_pull_items");
if (keyName != null) {
hotkeys.put(keyName, translate("bookmark.group.pull_items"));
}
keyName = NEIClientConfig
.getKeyName(NEIClientConfig.getKeyBinding("gui.bookmark_pull_items_ingredients"), true);
keyName = NEIClientConfig.getKeyName("gui.bookmark_pull_items_ingredients");
if (keyName != null) {
hotkeys.put(keyName, translate("bookmark.group.pull_items_ingredients"));
}
@@ -2533,20 +2541,19 @@ public class BookmarkPanel extends PanelWidget {
hotkeys.put(translate("bookmark.group.sorting.key"), translate("bookmark.group.sorting"));
}
String keyName = NEIClientConfig.getKeyName(NEIClientConfig.getKeyBinding("gui.remove_recipe"), true);
String keyName = NEIClientConfig.getKeyName("gui.remove_recipe");
if (keyName != null) {
hotkeys.put(keyName, translate("bookmark.group.remove_recipe"));
}
if (BookmarkContainerInfo.getBookmarkContainerHandler(gui) != null) {
keyName = NEIClientConfig.getKeyName(NEIClientConfig.getKeyBinding("gui.bookmark_pull_items"), true);
keyName = NEIClientConfig.getKeyName("gui.bookmark_pull_items");
if (keyName != null) {
hotkeys.put(keyName, translate("bookmark.group.pull_items"));
}
keyName = NEIClientConfig
.getKeyName(NEIClientConfig.getKeyBinding("gui.bookmark_pull_items_ingredients"), true);
keyName = NEIClientConfig.getKeyName("gui.bookmark_pull_items_ingredients");
if (keyName != null) {
hotkeys.put(keyName, translate("bookmark.group.pull_items_ingredients"));
}
@@ -2578,6 +2585,21 @@ public class BookmarkPanel extends PanelWidget {
return currenttip;
}
@Override
public boolean contains(int px, int py) {
if (new Rectangle4i(pagePrev.x + pagePrev.w, pagePrev.y, pageNext.x - (pagePrev.x + pagePrev.w), pagePrev.h)
.contains(px, py)) {
return true;
}
if (((BookmarkGrid) grid).getHoveredRowIndex(true) != -1) {
return true;
}
return super.contains(px, py);
}
@Override
public List<String> handleItemTooltip(GuiContainer gui, ItemStack itemstack, int mousex, int mousey,
List<String> currenttip) {
@@ -2723,8 +2745,9 @@ public class BookmarkPanel extends PanelWidget {
}
public boolean pullBookmarkItems(int groupId, boolean onlyIngredients) {
IBookmarkContainerHandler containerHandler = BookmarkContainerInfo
.getBookmarkContainerHandler(getGuiContainer());
final GuiContainer guiContainer = getGuiContainer();
final IBookmarkContainerHandler containerHandler = BookmarkContainerInfo
.getBookmarkContainerHandler(guiContainer);
if (containerHandler == null) {
return false;
@@ -2733,7 +2756,6 @@ public class BookmarkPanel extends PanelWidget {
final BookmarkGrid BGrid = (BookmarkGrid) grid;
final ArrayList<ItemStack> items = new ArrayList<>();
final ItemStackMap<Long> uniqueItems = new ItemStackMap<>();
final BookmarkGroup group = groupId >= 0 ? BGrid.groups.get(groupId) : null;
ItemStackMetadata meta;
for (int idx = 0; idx < BGrid.realItems.size(); idx++) {
@@ -2741,6 +2763,7 @@ public class BookmarkPanel extends PanelWidget {
if (groupId == -1 || groupId == meta.groupId) {
final ItemStack stack = BGrid.getItem(idx);
final BookmarkGroup group = BGrid.groups.get(meta.groupId);
if (!onlyIngredients || meta.ingredient && (group == null || group.crafting == null
|| group.crafting.inputs.containsKey(BGrid.realItems.get(idx)))) {
@@ -2765,7 +2788,7 @@ public class BookmarkPanel extends PanelWidget {
return false;
}
containerHandler.pullBookmarkItemsFromContainer(getGuiContainer(), items);
containerHandler.pullBookmarkItemsFromContainer(guiContainer, items);
return true;
}
}
+79 -134
View File
@@ -1,19 +1,19 @@
package codechicken.nei;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
@@ -30,17 +30,16 @@ import net.minecraftforge.client.event.RenderWorldLastEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.world.WorldEvent;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.apache.commons.io.IOUtils;
import com.google.common.collect.Lists;
import codechicken.core.ClassDiscoverer;
import codechicken.core.ClientUtils;
import codechicken.core.GuiModListScroll;
import codechicken.lib.packet.PacketCustom;
import codechicken.nei.api.API;
import codechicken.nei.api.IConfigureNEI;
import codechicken.nei.api.ItemInfo;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.recipe.GuiRecipeTab;
@@ -55,15 +54,8 @@ import cpw.mods.fml.relauncher.SideOnly;
public class ClientHandler {
private static String[] defaultHandlerOrdering = {
"# Each line in this file should either be a comment (starts with '#') or an ordering.",
"# Ordering lines are <handler ID>,<ordering number>.",
"# Handlers will be sorted in order of number ascending, so smaller numbers first.",
"# Any handlers that are missing from this file will be assigned to 0.", "# Negative numbers are fine.",
"# If you delete this file, it will be regenerated with all registered handler IDs.", };
private static ClientHandler instance;
private ArrayList<EntityItem> SMPmagneticItems = new ArrayList<>();
private final ArrayList<EntityItem> SMPmagneticItems = new ArrayList<>();
private World lastworld;
private GuiScreen lastGui;
@@ -148,6 +140,7 @@ public class ClientHandler {
public static void preInit() {
loadSerialHandlers();
loadHiddenItems();
loadHeightHackHandlers();
loadHiddenHandlers();
loadEnableAutoFocus();
@@ -155,100 +148,69 @@ public class ClientHandler {
StackInfo.loadGuidFilters();
}
public static void loadSerialHandlers() {
File file = NEIClientConfig.serialHandlersFile;
public static void loadSettingsFile(String resource, Consumer<Stream<String>> callback) {
loadSettingsFile(resource, (file, writer) -> {
String folder = resource.substring(resource.lastIndexOf(".") + 1);
URL defaultResource = ClientHandler.class.getResource("/assets/nei/" + folder + "/" + resource);
if (defaultResource != null) {
try {
IOUtils.copy(defaultResource.openStream(), writer);
} catch (IOException e) {}
}
}, callback);
}
public static void loadSettingsFile(String resource, BiConsumer<File, FileWriter> createDefault,
Consumer<Stream<String>> callback) {
File file = new File(NEIClientConfig.configDir, resource);
if (!file.exists()) {
try (FileWriter writer = new FileWriter(file)) {
NEIClientConfig.logger.info("Creating default serial handlers list {}", file);
URL defaultSerialHandlersResource = ClientHandler.class
.getResource("/assets/nei/cfg/serialhandlers.cfg");
if (defaultSerialHandlersResource != null) {
IOUtils.copy(defaultSerialHandlersResource.openStream(), writer);
}
NEIClientConfig.logger.info("Creating default '{}' {}", resource, file);
createDefault.accept(file, writer);
} catch (IOException e) {
NEIClientConfig.logger.error("Failed to save default serial handlers list to file {}", file, e);
NEIClientConfig.logger.error("Failed to save default '{}' to file {}", resource, file, e);
}
}
try (FileReader reader = new FileReader(file)) {
NEIClientConfig.logger.info("Loading serial handlers from file {}", file);
NEIClientConfig.serialHandlers = IOUtils.readLines(reader).stream().filter((line) -> !line.startsWith("#"))
.collect(Collectors.toCollection(HashSet::new));
NEIClientConfig.logger.info("Loading '{}' file {}", resource, file);
callback.accept(
IOUtils.readLines(reader).stream().filter(line -> !line.startsWith("#") && !line.trim().isEmpty()));
} catch (IOException e) {
NEIClientConfig.logger.error("Failed to load serial handlers from file {}", file, e);
NEIClientConfig.logger.error("Failed to load '{}' file {}", resource, file, e);
}
}
public static void loadSerialHandlers() {
loadSettingsFile(
"serialhandlers.cfg",
lines -> NEIClientConfig.serialHandlers = lines.collect(Collectors.toCollection(HashSet::new)));
}
public static void loadHeightHackHandlers() {
File file = NEIClientConfig.heightHackHandlersFile;
if (!file.exists()) {
try (FileWriter writer = new FileWriter(file)) {
NEIClientConfig.logger.info("Creating default height hack handlers list {}", file);
URL defaultHeightHackHandlersResource = ClientHandler.class
.getResource("/assets/nei/cfg/heighthackhandlers.cfg");
if (defaultHeightHackHandlersResource != null) {
IOUtils.copy(defaultHeightHackHandlersResource.openStream(), writer);
}
} catch (IOException e) {
NEIClientConfig.logger.error("Failed to save default height hack handlers list to file {}", file, e);
}
}
try (FileReader reader = new FileReader(file)) {
NEIClientConfig.logger.info("Loading height hack handlers from file {}", file);
NEIClientConfig.heightHackHandlerRegex = IOUtils.readLines(reader).stream()
.filter((line) -> !line.startsWith("#")).map(Pattern::compile)
.collect(Collectors.toCollection(HashSet::new));
} catch (IOException e) {
NEIClientConfig.logger.error("Failed to load height hack handlers from file {}", file, e);
}
loadSettingsFile(
"heighthackhandlers.cfg",
lines -> NEIClientConfig.heightHackHandlerRegex = lines.map(Pattern::compile)
.collect(Collectors.toCollection(HashSet::new)));
}
public static void loadHiddenHandlers() {
File file = NEIClientConfig.hiddenHandlersFile;
if (!file.exists()) {
try (FileWriter writer = new FileWriter(file)) {
NEIClientConfig.logger.info("Creating default hidden handlers list {}", file);
URL defaultHeightHackHandlersResource = ClientHandler.class
.getResource("/assets/nei/cfg/hiddenhandlers.cfg");
if (defaultHeightHackHandlersResource != null) {
IOUtils.copy(defaultHeightHackHandlersResource.openStream(), writer);
}
} catch (IOException e) {
NEIClientConfig.logger.error("Failed to save default hidden handlers list to file {}", file, e);
}
}
try (FileReader reader = new FileReader(file)) {
NEIClientConfig.logger.info("Loading hidden handlers from file {}", file);
NEIClientConfig.hiddenHandlers = IOUtils.readLines(reader).stream().filter((line) -> !line.startsWith("#"))
.collect(Collectors.toCollection(HashSet::new));
} catch (IOException e) {
NEIClientConfig.logger.error("Failed to load hidden handlers from file {}", file, e);
}
loadSettingsFile(
"hiddenhandlers.cfg",
lines -> NEIClientConfig.hiddenHandlers = lines.collect(Collectors.toCollection(HashSet::new)));
}
public static void loadEnableAutoFocus() {
File file = NEIClientConfig.enableAutoFocusFile;
if (!file.exists()) {
try (FileWriter writer = new FileWriter(file)) {
NEIClientConfig.logger.info("Creating default enable auto focus list {}", file);
URL defaultEnableAutoFocusResource = ClientHandler.class
.getResource("/assets/nei/cfg/enableautofocus.cfg");
if (defaultEnableAutoFocusResource != null) {
IOUtils.copy(defaultEnableAutoFocusResource.openStream(), writer);
}
} catch (IOException e) {
NEIClientConfig.logger.error("Failed to save default enable auto focus list to file {}", file, e);
}
}
loadSettingsFile(
"enableautofocus.cfg",
lines -> AutoFocusWidget.enableAutoFocusPrefixes = lines
.collect(Collectors.toCollection(ArrayList::new)));
}
try (FileReader reader = new FileReader(file)) {
NEIClientConfig.logger.info("Loading enable auto focus from file {}", file);
AutoFocusWidget.enableAutoFocusPrefixes = IOUtils.readLines(reader).stream()
.filter((line) -> !line.startsWith("#")).collect(Collectors.toCollection(ArrayList::new));
} catch (IOException e) {
NEIClientConfig.logger.error("Failed to load enable auto focus from file {}", file, e);
}
public static void loadHiddenItems() {
loadSettingsFile("hiddenitems.cfg", lines -> lines.forEach(API::hideItem));
}
public static void load() {
@@ -265,55 +227,38 @@ public class ClientHandler {
}
public static void postInit() {
loadHandlerOrdering();
GuiContainerManager.registerReloadResourceListener();
}
public static void loadHandlerOrdering() {
File file = NEIClientConfig.handlerOrderingFile;
if (!file.exists()) {
try (FileWriter writer = new FileWriter(file)) {
NEIClientConfig.logger.info("Creating default handler ordering CSV {}", file);
List<String> toWrite = Lists.newArrayList(defaultHandlerOrdering);
GuiRecipeTab.handlerMap.keySet().stream().sorted()
.forEach(handlerId -> toWrite.add(String.format("%s,0", handlerId)));
final String COMMA_DELIMITER = ",";
final String[] defaultHandlerOrdering = {
"# Each line in this file should either be a comment (starts with '#') or an ordering.",
"# Ordering lines are <handler ID>,<ordering number>.",
"# Handlers will be sorted in order of number ascending, so smaller numbers first.",
"# Any handlers that are missing from this file will be assigned to 0.", "# Negative numbers are fine.",
"# If you delete this file, it will be regenerated with all registered handler IDs.", };
loadSettingsFile("handlerordering.csv", (file, writer) -> {
List<String> toWrite = Lists.newArrayList(defaultHandlerOrdering);
GuiRecipeTab.handlerMap.keySet().stream().sorted()
.forEach(handlerId -> toWrite.add(String.format("%s" + COMMA_DELIMITER + "0", handlerId)));
try {
IOUtils.writeLines(toWrite, "\n", writer);
} catch (IOException e) {
NEIClientConfig.logger.error("Failed to save default handler ordering to file {}", file, e);
}
}
} catch (IOException e) {}
}, lines -> lines.map(line -> line.split(COMMA_DELIMITER)).filter(parts -> parts.length == 2).forEach(parts -> {
String handlerId = parts[0];
int ordering = Integer.parseInt(parts[1]);
NEIClientConfig.handlerOrdering.put(handlerId, ordering);
}));
}
URL url;
try {
url = file.toURI().toURL();
} catch (MalformedURLException e) {
NEIClientConfig.logger.info("Invalid URL for handler ordering CSV.");
e.printStackTrace();
return;
}
public static void loadPluginsList() {
final ClassDiscoverer classDiscoverer = new ClassDiscoverer(
test -> test.startsWith("NEI") && test.endsWith("Config.class"),
IConfigureNEI.class);
try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()))) {
NEIClientConfig.logger.info("Loading handler ordering from file {}", file);
CSVParser csvParser = CSVFormat.EXCEL.withCommentMarker('#').parse(reader);
for (CSVRecord record : csvParser) {
final String handlerId = record.get(0);
int ordering;
try {
ordering = Integer.parseInt(record.get(1));
} catch (NumberFormatException e) {
NEIClientConfig.logger.error("Error parsing CSV record {}: {}", record, e);
continue;
}
NEIClientConfig.handlerOrdering.put(handlerId, ordering);
}
} catch (Exception e) {
NEIClientConfig.logger.info("Error parsing CSV");
e.printStackTrace();
}
NEIClientConfig.pluginsList.addAll(classDiscoverer.findClasses());
}
@SubscribeEvent
@@ -380,9 +325,8 @@ public class ClientHandler {
if (!Minecraft.getMinecraft().isSingleplayer()) // wait for server to initiate in singleplayer
NEIClientConfig.loadWorld("remote/" + ClientUtils.getServerIP().replace(':', '~'));
ItemMobSpawner.clearEntityReferences(world);
}
ItemMobSpawner.clearEntityReferences(world);
lastworld = world;
}
@@ -410,9 +354,10 @@ public class ClientHandler {
}
};
@SuppressWarnings("serial")
CustomModLoadingErrorDisplayException e = new CustomModLoadingErrorDisplayException() {
private static final long serialVersionUID = -5593387489666663375L;
@Override
public void initGui(GuiErrorScreen errorScreen, FontRenderer fontRenderer) {
Minecraft.getMinecraft().displayGuiScreen(errorGui);
@@ -1,227 +1,33 @@
package codechicken.nei;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTBase.NBTPrimitive;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.StatCollector;
import net.minecraftforge.oredict.OreDictionary;
import org.apache.commons.io.IOUtils;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import codechicken.nei.ItemList.AllMultiItemFilter;
import codechicken.nei.ItemList.AnyMultiItemFilter;
import codechicken.nei.ItemList.EverythingItemFilter;
import codechicken.nei.ItemList.NegatedItemFilter;
import codechicken.nei.ItemList.NothingItemFilter;
import codechicken.nei.PresetsList.Preset;
import codechicken.nei.PresetsList.PresetMode;
import codechicken.nei.api.ItemFilter;
import cpw.mods.fml.common.registry.GameData;
import codechicken.nei.util.ItemStackFilterParser;
public class CollapsibleItems {
protected static interface ISearchParserProvider {
public ItemFilter getFilter(String searchText);
default Predicate<String> getMatcher(String searchText) {
if (searchText.length() >= 3 && searchText.startsWith("r/") && searchText.endsWith("/")) {
try {
Pattern pattern = Pattern.compile(
searchText.substring(2, searchText.length() - 1),
Pattern.MULTILINE | Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
return value -> pattern.matcher(value).find();
} catch (PatternSyntaxException ignored) {}
} else if (!searchText.isEmpty()) {
return value -> value.toLowerCase().contains(searchText);
}
return null;
}
}
protected static class GroupTokenParser {
protected final HashMap<Character, ISearchParserProvider> searchProviders = new HashMap<>();
public void addProvider(char prefix, ISearchParserProvider provider) {
this.searchProviders.put(prefix, provider);
}
public ItemFilter getFilter(String filterText) {
final String[] parts = filterText.toLowerCase().trim().split("\\|");
final List<ItemFilter> searchTokens = Arrays.stream(parts).map(s -> parseSearchText(s))
.filter(s -> s != null && !s.filters.isEmpty()).collect(Collectors.toCollection(ArrayList::new));
if (searchTokens.isEmpty()) {
return new EverythingItemFilter();
} else if (searchTokens.size() == 1) {
return searchTokens.get(0);
} else {
return new AnyMultiItemFilter(searchTokens);
}
}
private AllMultiItemFilter parseSearchText(String filterText) {
if (filterText.isEmpty()) {
return null;
}
final String[] tokens = filterText.split("\\s+");
final AllMultiItemFilter searchTokens = new AllMultiItemFilter();
for (String token : tokens) {
token = token.trim();
boolean ignore = token.startsWith("!");
if (ignore) {
token = token.substring(1);
}
if (token.isEmpty()) {
continue;
}
ISearchParserProvider provider = this.searchProviders.get(token.charAt(0));
if (provider != null) {
token = token.substring(1);
} else {
provider = this.searchProviders.get('\0');
}
ItemFilter filter = parseToken(ignore ? "!" + token : token, provider);
if (filter != null) {
searchTokens.filters.add(filter);
}
}
return searchTokens;
}
private ItemFilter parseToken(String token, ISearchParserProvider provider) {
final String[] parts = token.split(",");
final AnyMultiItemFilter includeFilter = new AnyMultiItemFilter();
final AnyMultiItemFilter expludeFilter = new AnyMultiItemFilter();
final AllMultiItemFilter groupFilter = new AllMultiItemFilter();
for (String part : parts) {
boolean ignore = part.startsWith("!");
if (ignore) {
part = part.substring(1);
}
ItemFilter filter = provider.getFilter(part);
if (filter == null) {
continue;
}
if (ignore) {
expludeFilter.filters.add(filter);
} else {
includeFilter.filters.add(filter);
}
}
if (!includeFilter.filters.isEmpty()) {
groupFilter.filters.add(includeFilter);
}
if (!expludeFilter.filters.isEmpty()) {
groupFilter.filters.add(new NegatedItemFilter(expludeFilter));
}
return groupFilter.filters.isEmpty() ? null : groupFilter;
}
}
protected static class IdentifierFilter implements ISearchParserProvider {
@Override
public ItemFilter getFilter(String searchText) {
if (Pattern.matches("^\\d+(-\\d+)*$", searchText)) {
final Predicate<Integer> filter = generateDamageFilter(searchText);
return (stack) -> filter.test(stack.getItemDamage());
}
Predicate<String> matcher = getMatcher(searchText);
if (matcher != null) {
return stack -> matcher.test(getStringIdentifier(stack));
}
return null;
}
protected String getStringIdentifier(ItemStack stack) {
String name = GameData.getItemRegistry().getNameForObject(stack.getItem());
return name == null || name.isEmpty() ? "Unknown:Unknown" : name;
}
protected Predicate<Integer> generateDamageFilter(String searchText) {
String[] range = searchText.split("-");
if (range.length == 1) {
final int damage = Integer.parseInt(range[0]);
return (dmg) -> dmg == damage;
} else {
final int damageStart = Integer.parseInt(range[0]);
final int damageEnd = Integer.parseInt(range[1]);
return (dmg) -> dmg >= damageStart && dmg <= damageEnd;
}
}
}
protected static class OreDictionaryFilter implements ISearchParserProvider {
@Override
public ItemFilter getFilter(String searchText) {
Predicate<String> matcher = getMatcher(searchText);
if (matcher != null) {
return stack -> matches(stack, matcher);
}
return null;
}
protected boolean matches(ItemStack stack, Predicate<String> matcher) {
return IntStream.of(OreDictionary.getOreIDs(stack))
.anyMatch(id -> matcher.test(OreDictionary.getOreName(id)));
}
}
protected static class GroupItem {
public String guid;
@@ -229,11 +35,9 @@ public class CollapsibleItems {
public boolean expanded = false;
public String displayName = "";
public GroupItem() {}
public void setFilter(String filter) {
this.filter = CollapsibleItems.groupParser.getFilter(filter.trim());
this.guid = UUID.nameUUIDFromBytes(filter.getBytes()).toString();
this.filter = ItemStackFilterParser.parse(filter.trim());
this.guid = this.filter != null ? UUID.nameUUIDFromBytes(filter.getBytes()).toString() : "";
}
public void setFilter(ItemFilter filter, String guid) {
@@ -246,19 +50,17 @@ public class CollapsibleItems {
}
}
protected File statesFile;
protected static final GroupTokenParser groupParser = new GroupTokenParser();
protected final List<GroupItem> groups = new ArrayList<>();
protected final Map<ItemStack, Integer> cache = new ConcurrentHashMap<>();
private static final String STATE_KEY = "collapsibleitems";
static {
groupParser.addProvider('\0', new IdentifierFilter());
groupParser.addProvider('$', new OreDictionaryFilter());
}
protected static File statesFile;
protected static final List<GroupItem> groups = new ArrayList<>();
protected static final Map<ItemStack, Integer> cache = new ConcurrentHashMap<>();
public void reload() {
this.groups.clear();
this.cache.clear();
private CollapsibleItems() {}
public static void load() {
CollapsibleItems.groups.clear();
CollapsibleItems.cache.clear();
for (int i = PresetsList.presets.size() - 1; i >= 0; i--) {
Preset preset = PresetsList.presets.get(i);
@@ -271,49 +73,19 @@ public class CollapsibleItems {
}
if (NEIClientConfig.enableCollapsibleItems()) {
loadCollapsibleItems();
ClientHandler.loadSettingsFile(
"collapsibleitems.cfg",
lines -> parseFile(lines.collect(Collectors.toCollection(ArrayList::new))));
}
loadStates();
if (ItemList.loadFinished) {
LayoutManager.markItemsDirty();
}
}
protected void loadCollapsibleItems() {
File file = NEIClientConfig.collapsibleItemsFile;
if (!file.exists()) {
try (FileWriter writer = new FileWriter(file)) {
NEIClientConfig.logger.info("Creating default collapsible items list {}", file);
URL defaultCollapsibleItemsResource = ClientHandler.class
.getResource("/assets/nei/cfg/collapsibleitems.cfg");
if (defaultCollapsibleItemsResource != null) {
IOUtils.copy(defaultCollapsibleItemsResource.openStream(), writer);
}
} catch (IOException e) {
NEIClientConfig.logger.error("Failed to save default collapsible items list to file {}", file, e);
}
}
try (FileReader reader = new FileReader(file)) {
NEIClientConfig.logger.info("Loading collapsible items from file {}", file);
parseFile(IOUtils.readLines(reader));
} catch (IOException e) {
NEIClientConfig.logger.error("Failed to load collapsible items from file {}", file, e);
}
}
public void parseFile(List<String> itemStrings) {
private static void parseFile(List<String> itemStrings) {
final JsonParser parser = new JsonParser();
GroupItem group = new GroupItem();
for (String itemStr : itemStrings) {
if (itemStr.startsWith("#") || itemStr.trim().isEmpty()) {
continue;
}
try {
if (itemStr.startsWith("; ")) {
@@ -324,10 +96,10 @@ public class CollapsibleItems {
}
if (settings.get("unlocalizedName") != null) {
String displayName = StatCollector
.translateToLocal(settings.get("unlocalizedName").getAsString());
String unlocalizedName = settings.get("unlocalizedName").getAsString();
String displayName = StatCollector.translateToLocal(unlocalizedName);
if (!displayName.equals(settings.get("unlocalizedName").getAsString())) {
if (!displayName.equals(unlocalizedName)) {
group.displayName = displayName;
}
}
@@ -351,106 +123,109 @@ public class CollapsibleItems {
}
}
protected void addGroup(GroupItem group) {
private static void addGroup(GroupItem group) {
if (group == null || group.filter == null
|| group.filter instanceof EverythingItemFilter
|| group.filter instanceof NothingItemFilter)
return;
this.groups.add(group);
CollapsibleItems.groups.add(group);
}
public boolean isEmpty() {
return this.groups.isEmpty();
public static boolean isEmpty() {
return CollapsibleItems.groups.isEmpty();
}
public ItemFilter getItemFilter() {
public static ItemFilter getItemFilter() {
AnyMultiItemFilter filter = new AnyMultiItemFilter();
for (GroupItem group : this.groups) {
for (GroupItem group : CollapsibleItems.groups) {
filter.filters.add(group.filter);
}
return filter;
}
public void updateCache(final List<ItemStack> items) {
this.cache.clear();
try {
ItemList.forkJoinPool.submit(() -> items.parallelStream().forEach(stack -> {
GroupItem group = this.groups.stream().filter(g -> g.matches(stack)).findFirst().orElse(null);
if (group != null) {
this.cache.put(stack, this.groups.indexOf(group));
}
})).get();
} catch (Exception e) {
NEIClientConfig.logger.error("Error create collapsible items groups", e);
}
public static void clearCache() {
CollapsibleItems.cache.clear();
}
public int getGroupIndex(ItemStack stack) {
public static void putItem(ItemStack stack) {
final GroupItem group = CollapsibleItems.groups.stream().filter(g -> g.matches(stack)).findFirst().orElse(null);
if (group != null) {
CollapsibleItems.cache.put(stack, CollapsibleItems.groups.indexOf(group));
}
}
public static int getGroupIndex(ItemStack stack) {
if (stack == null) {
return -1;
}
return this.cache.getOrDefault(stack, -1);
return CollapsibleItems.cache.getOrDefault(stack, -1);
}
public String getDisplayName(int groupIndex) {
public static String getDisplayName(int groupIndex) {
if (groupIndex < this.groups.size()) {
return this.groups.get(groupIndex).displayName;
if (groupIndex < CollapsibleItems.groups.size()) {
return CollapsibleItems.groups.get(groupIndex).displayName;
}
return null;
}
public boolean isExpanded(int groupIndex) {
public static boolean isExpanded(int groupIndex) {
if (groupIndex < this.groups.size()) {
return this.groups.get(groupIndex).expanded;
if (groupIndex < CollapsibleItems.groups.size()) {
return CollapsibleItems.groups.get(groupIndex).expanded;
}
return true;
}
public void setExpanded(int groupIndex, boolean expanded) {
public static void setExpanded(int groupIndex, boolean expanded) {
if (groupIndex < this.groups.size()) {
this.groups.get(groupIndex).expanded = expanded;
saveStates();
if (groupIndex < CollapsibleItems.groups.size()) {
CollapsibleItems.groups.get(groupIndex).expanded = expanded;
}
}
public void toggleGroups(Boolean expanded) {
public static void toggleGroups(Boolean expanded) {
if (expanded == null) {
expanded = !this.groups.stream().filter(g -> g.expanded).findAny().isPresent();
expanded = CollapsibleItems.groups.stream().noneMatch(g -> g.expanded);
}
for (GroupItem group : this.groups) {
for (GroupItem group : CollapsibleItems.groups) {
group.expanded = expanded;
}
saveStates();
}
private void loadStates() {
public static void saveStates() {
NBTTagCompound list = new NBTTagCompound();
for (GroupItem group : CollapsibleItems.groups) {
list.setBoolean(group.guid, group.expanded);
}
if (NEIClientConfig.world != null) {
NEIClientConfig.world.nbt.setTag(STATE_KEY, list);
}
}
private static void loadStates() {
try {
if (NEIClientConfig.world.nbt.hasKey("collapsibleitems")) {
NBTTagCompound states = NEIClientConfig.world.nbt.getCompoundTag("collapsibleitems");
if (NEIClientConfig.world.nbt.hasKey(STATE_KEY)) {
NBTTagCompound states = NEIClientConfig.world.nbt.getCompoundTag(STATE_KEY);
@SuppressWarnings("unchecked")
final Map<String, NBTPrimitive> list = (Map<String, NBTPrimitive>) states.tagMap;
final Map<String, GroupItem> mapping = new HashMap<>();
for (GroupItem group : this.groups) {
for (GroupItem group : CollapsibleItems.groups) {
mapping.put(group.guid, group);
}
@@ -467,14 +242,4 @@ public class CollapsibleItems {
}
private void saveStates() {
NBTTagCompound list = new NBTTagCompound();
for (GroupItem group : this.groups) {
list.setBoolean(group.guid, group.expanded);
}
NEIClientConfig.world.nbt.setTag("collapsibleitems", list);
}
}
@@ -116,7 +116,6 @@ public class ContainerPotionCreator extends ContainerExtended {
if (!player.worldObj.isRemote) InventoryUtils.dropOnClose(player, potionInv);
}
@SuppressWarnings("unchecked")
@Override
public void handleServerPacket(PacketCustom packet) {
ItemStack potion = potionInv.getStackInSlot(0);
@@ -60,13 +60,13 @@ public class GuiExtendedCreativeInv extends GuiContainer implements INEIGuiHandl
}
@Override
protected void handleMouseClick(Slot p_146984_1_, int p_146984_2_, int p_146984_3_, int p_146984_4_) {
protected void handleMouseClick(Slot slotIn, int slotId, int clickedButton, int clickType) {
// Hack for armor slots, because they are outside the container
if (p_146984_1_ != null && p_146984_4_ == 4 && p_146984_1_.xDisplayPosition < 0) {
p_146984_4_ = 0;
if (slotIn != null && clickType == 4 && slotIn.xDisplayPosition < 0) {
clickType = 0;
}
super.handleMouseClick(p_146984_1_, p_146984_2_, p_146984_3_, p_146984_4_);
super.handleMouseClick(slotIn, slotId, clickedButton, clickType);
}
}
+24 -23
View File
@@ -15,14 +15,13 @@ public class GuiNEIButton extends GuiButton {
super(i, j, k, l, i1, s);
}
public void drawButton(Minecraft minecraft, int i, int j) {
public void drawButton(Minecraft minecraft, int x, int y) {
if (!visible) return;
FontRenderer fontrenderer = minecraft.fontRenderer;
minecraft.renderEngine.bindTexture(guiTex);
GL11.glColor4f(1, 1, 1, 1);
boolean flag = i >= xPosition && j >= yPosition && i < xPosition + width && j < yPosition + height;
int k = getHoverState(flag);
boolean mouseOver = x >= xPosition && y >= yPosition && x < xPosition + width && y < yPosition + height;
int k = getHoverState(mouseOver);
drawTexturedModalRect(xPosition, yPosition, 0, 46 + k * 20, width / 2, height / 2); // top left
drawTexturedModalRect(xPosition + width / 2, yPosition, 200 - width / 2, 46 + k * 20, width / 2, height / 2); // top
// right
@@ -40,25 +39,27 @@ public class GuiNEIButton extends GuiButton {
46 + k * 20 + 20 - height / 2,
width / 2,
height / 2); // bottom right
mouseDragged(minecraft, i, j);
mouseDragged(minecraft, x, y);
if (!enabled) drawCenteredString(
fontrenderer,
displayString,
xPosition + width / 2,
yPosition + (height - 8) / 2,
0xffa0a0a0);
else if (flag) drawCenteredString(
fontrenderer,
displayString,
xPosition + width / 2,
yPosition + (height - 8) / 2,
0xffffa0);
else drawCenteredString(
fontrenderer,
displayString,
xPosition + width / 2,
yPosition + (height - 8) / 2,
0xe0e0e0);
drawContent(minecraft, x, y, mouseOver);
}
protected int getTextColour(boolean mouseOver) {
int color = 0xe0e0e0;
if (!enabled) {
color = 0xffa0a0a0;
} else if (mouseOver) {
color = 0xffffa0;
}
return color;
}
protected void drawContent(Minecraft minecraft, int y, int x, boolean mouseOver) {
FontRenderer fontrenderer = minecraft.fontRenderer;
int color = getTextColour(mouseOver);
drawCenteredString(fontrenderer, displayString, xPosition + width / 2, yPosition + (height - 8) / 2, color);
}
}
@@ -1,12 +1,11 @@
package codechicken.nei;
import static codechicken.lib.gui.GuiDraw.drawRect;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.ItemStack;
import org.lwjgl.opengl.GL11;
import codechicken.lib.gui.GuiDraw;
import codechicken.nei.ItemPanel.ItemPanelSlot;
import codechicken.nei.recipe.GuiCraftingRecipe;
import codechicken.nei.recipe.GuiRecipe;
@@ -22,10 +21,14 @@ public class ItemHistoryPanel extends Widget {
grid = new ItemsGrid();
}
public boolean isEmpty() {
return grid.isEmpty();
}
public void draw(int mousex, int mousey) {
if (NEIClientConfig.getIntSetting("inventory.history.splittingMode") == 0) {
drawRect(x, y, w, h, NEIClientConfig.getSetting("inventory.history.historyColor").getHexValue());
GuiDraw.drawRect(x, y, w, h, NEIClientConfig.getSetting("inventory.history.historyColor").getHexValue());
} else {
drawSplittingArea(x, y, w, h, NEIClientConfig.getSetting("inventory.history.historyColor").getHexValue());
}
@@ -44,8 +47,8 @@ public class ItemHistoryPanel extends Widget {
grid.realItems.removeIf(historyStack -> StackInfo.equalItemAndNBT(historyStack, stack, true));
grid.realItems.add(0, is);
if (grid.realItems.size() > (grid.rows * grid.columns)) {
grid.realItems.remove(grid.rows * grid.columns);
if (grid.realItems.size() > Math.max(50, grid.rows * grid.columns)) {
grid.realItems.remove(grid.realItems.size() - 1);
}
grid.onItemsChanged();
@@ -69,10 +72,10 @@ public class ItemHistoryPanel extends Widget {
private void drawSplittingArea(int x, int y, int width, int height, int color) {
float alpha = (float) (color >> 24 & 255) / 255.0F;
float red = (float) (color >> 16 & 255) / 255.0F;
float green = (float) (color >> 8 & 255) / 255.0F;
float blue = (float) (color & 255) / 255.0F;
float alpha = (color >> 24 & 255) / 255.0F;
float red = (color >> 16 & 255) / 255.0F;
float green = (color >> 8 & 255) / 255.0F;
float blue = (color & 255) / 255.0F;
GL11.glPushMatrix();
+127 -59
View File
@@ -2,15 +2,17 @@ package codechicken.nei;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.StringJoiner;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinWorkerThread;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import net.minecraft.client.Minecraft;
import net.minecraft.item.Item;
@@ -25,6 +27,7 @@ import codechicken.nei.ThreadOperationTimer.TimeoutException;
import codechicken.nei.api.ItemFilter;
import codechicken.nei.api.ItemFilter.ItemFilterProvider;
import codechicken.nei.api.ItemInfo;
import codechicken.nei.search.TooltipFilter;
public class ItemList {
@@ -41,11 +44,10 @@ public class ItemList {
*/
public static final List<ItemFilterProvider> itemFilterers = new LinkedList<>();
public static final List<ItemsLoadedCallback> loadCallbacks = new LinkedList<>();
public static final CollapsibleItems collapsibleItems = new CollapsibleItems();
private static final HashSet<Item> erroredItems = new HashSet<>();
private static final HashSet<String> stackTraces = new HashSet<>();
private static final HashMap<ItemStack, Integer> ordering = new HashMap<>();
private static HashMap<ItemStack, Integer> ordering = new HashMap<>();
/**
* Unlike {@link LayoutManager#itemsLoaded}, this indicates whether item loading is actually finished or not.
*/
@@ -92,7 +94,19 @@ public class ItemList {
@Override
public boolean matches(ItemStack item) {
String displayName = EnumChatFormatting.getTextWithoutFormattingCodes(item.getDisplayName());
return !displayName.isEmpty() && pattern.matcher(displayName).find();
if (displayName != null && !displayName.isEmpty() && pattern.matcher(displayName).find()) {
return true;
}
if (item.hasDisplayName()) {
displayName = EnumChatFormatting
.getTextWithoutFormattingCodes(item.getItem().getItemStackDisplayName(item));
return displayName != null && !displayName.isEmpty() && pattern.matcher(displayName).find();
}
return false;
}
}
@@ -105,7 +119,7 @@ public class ItemList {
}
public AllMultiItemFilter(ItemFilter... filters) {
this(Arrays.asList(filters));
this(new LinkedList<>(Arrays.asList(filters)));
}
public AllMultiItemFilter() {
@@ -117,7 +131,8 @@ public class ItemList {
for (ItemFilter filter : filters) try {
if (filter != null && !filter.matches(item)) return false;
} catch (Exception e) {
NEIClientConfig.logger.error("Exception filtering " + item + " with " + filter, e);
NEIClientConfig.logger
.error("Exception filtering " + item + " with " + filter + " (" + e.getMessage() + ")", e);
}
return true;
@@ -139,9 +154,10 @@ public class ItemList {
@Override
public boolean matches(ItemStack item) {
for (ItemFilter filter : filters) try {
if (filter.matches(item)) return true;
if (filter != null && filter.matches(item)) return true;
} catch (Exception e) {
NEIClientConfig.logger.error("Exception filtering " + item + " with " + filter, e);
NEIClientConfig.logger
.error("Exception filtering " + item + " with " + filter + " (" + e.getMessage() + ")", e);
}
return false;
@@ -156,9 +172,10 @@ public class ItemList {
public static boolean itemMatchesAll(ItemStack item, List<ItemFilter> filters) {
for (ItemFilter filter : filters) {
try {
if (!filter.matches(item)) return false;
if (filter != null && !filter.matches(item)) return false;
} catch (Exception e) {
NEIClientConfig.logger.error("Exception filtering " + item + " with " + filter, e);
NEIClientConfig.logger
.error("Exception filtering " + item + " with " + filter + " (" + e.getMessage() + ")", e);
}
}
@@ -213,89 +230,124 @@ public class ItemList {
private String getTooltip(ItemStack stack) {
try {
@SuppressWarnings("unchecked")
final List<String> namelist = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false);
final StringJoiner sb = new StringJoiner("\n");
for (String name : namelist) {
sb.add(name);
}
return sb.toString();
return String.join("\n", stack.getTooltip(Minecraft.getMinecraft().thePlayer, false));
} catch (Throwable ignored) {}
return "";
}
private void updateOrdering(List<ItemStack> items) {
ItemList.ordering.clear();
ItemSorter.sort(items);
if (!ItemList.collapsibleItems.isEmpty()) {
HashMap<ItemStack, Integer> newOrdering = new HashMap<>();
if (!CollapsibleItems.isEmpty()) {
HashMap<Integer, Integer> groups = new HashMap<>();
int orderIndex = 0;
for (ItemStack stack : items) {
final int groupIndex = ItemList.collapsibleItems.getGroupIndex(stack);
final int groupIndex = CollapsibleItems.getGroupIndex(stack);
if (groupIndex == -1) {
ItemList.ordering.put(stack, orderIndex++);
newOrdering.put(stack, orderIndex++);
} else {
if (!groups.containsKey(groupIndex)) {
groups.put(groupIndex, orderIndex++);
}
ItemList.ordering.put(stack, groups.get(groupIndex));
newOrdering.put(stack, groups.get(groupIndex));
}
}
} else {
int orderIndex = 0;
for (ItemStack stack : items) {
ItemList.ordering.put(stack, orderIndex++);
newOrdering.put(stack, orderIndex++);
}
}
ItemList.ordering = newOrdering;
}
private List<ItemStack> getPermutations(Item item) {
final List<ItemStack> permutations = new LinkedList<>(ItemInfo.itemOverrides.get(item));
if (permutations.isEmpty()) {
item.getSubItems(item, null, permutations);
}
if (permutations.isEmpty()) {
damageSearch(item, permutations);
}
permutations.addAll(ItemInfo.itemVariants.get(item));
return permutations.stream()
.filter(
stack -> stack.getItem() != null && stack.getItem().delegate.name() != null
&& !ItemInfo.isHidden(stack))
.collect(Collectors.toList());
}
// For optimization it generate itemslist, permutations, orders & collapsibleitems
@Override
@SuppressWarnings("unchecked")
public void execute() {
// System.out.println("Executing NEI Item Loading");
if (!NEIClientConfig.isEnabled()) return;
ThreadOperationTimer timer = getTimer(NEIClientConfig.getItemLoadingTimeout());
LayoutManager.itemsLoaded = true;
loadFinished = false;
List<ItemStack> items = new LinkedList<>();
List<ItemStack> permutations = new LinkedList<>();
SearchField.searchParser.clearCache();
ItemSorter.instance.ordering.clear();
CollapsibleItems.clearCache();
TooltipFilter.clearCache();
List<ItemStack> items = new ArrayList<>();
ListMultimap<Item, ItemStack> itemMap = ArrayListMultimap.create();
ItemStackSet unique = new ItemStackSet();
timer.setLimit(NEIClientConfig.getItemLoadingTimeout());
for (Item item : (Iterable<Item>) Item.itemRegistry) {
if (interrupted()) return;
if (item == null || erroredItems.contains(item)) continue;
StreamSupport.stream(((Iterable<Item>) Item.itemRegistry).spliterator(), true).forEach(item -> {
if (item == null || item.delegate.name() == null || erroredItems.contains(item)) return;
try {
timer.reset(item);
permutations.clear();
permutations.addAll(ItemInfo.itemOverrides.get(item));
if (permutations.isEmpty()) item.getSubItems(item, null, permutations);
if (permutations.isEmpty()) damageSearch(item, permutations);
permutations.addAll(ItemInfo.itemVariants.get(item));
List<ItemStack> permutations = getPermutations(item);
timer.reset();
items.addAll(permutations);
itemMap.putAll(item, permutations);
for (ItemStack stack : permutations) {
if (!unique.contains(stack)) {
synchronized (unique) {
unique.add(stack);
}
synchronized (items) {
items.add(stack);
}
CollapsibleItems.putItem(stack);
}
}
synchronized (itemMap) {
itemMap.putAll(item, permutations);
}
} catch (Throwable t) {
NEIServerConfig.logger.error("Removing item: " + item + " from list.", t);
NEIServerConfig.logger.error("Removing item: {} from list.", item, t);
erroredItems.add(item);
}
});
int index = 0;
for (Item item : (Iterable<Item>) Item.itemRegistry) {
for (ItemStack stack : itemMap.get(item)) {
ItemSorter.instance.ordering.put(stack, index++);
}
}
if (interrupted()) return;
@@ -304,31 +356,43 @@ public class ItemList {
for (ItemsLoadedCallback callback : loadCallbacks) callback.itemsLoaded();
if (interrupted()) return;
ItemList.collapsibleItems.updateCache(items);
updateOrdering(items);
updateOrdering(ItemList.items);
new Thread(
() -> ItemList.items.parallelStream().forEach(TooltipFilter::getSearchTooltip),
"NEI Tooltip Filter Loader").start();
loadFinished = true;
SubsetWidget.updateHiddenItems();
updateFilter.restart();
}
};
public static ForkJoinPool getPool(int poolSize) {
public static ForkJoinPool forkJoinPool;
static {
final ForkJoinPool.ForkJoinWorkerThreadFactory factory = new ForkJoinPool.ForkJoinWorkerThreadFactory() {
private int workerId;
@Override
public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
worker.setName("NEI-worker-thread-" + workerId++);
return worker;
}
};
int poolSize = Runtime.getRuntime().availableProcessors() * 2 / 3;
if (poolSize < 1) poolSize = 1;
return new ForkJoinPool(poolSize);
forkJoinPool = new ForkJoinPool(poolSize, factory, null, false);
}
public static final int numProcessors = Runtime.getRuntime().availableProcessors();
public static ForkJoinPool forkJoinPool = getPool(numProcessors * 2 / 3);
public static final RestartableTask updateFilter = new RestartableTask("NEI Item Filtering") {
private int compare(ItemStack o1, ItemStack o2) {
return Integer.compare(ItemList.ordering.get(o1), ItemList.ordering.get(o2));
}
@Override
public void execute() {
if (!loadFinished) return;
ItemFilter filter = getItemListFilter();
ArrayList<ItemStack> filtered;
@@ -345,8 +409,12 @@ public class ItemList {
}
if (interrupted()) return;
filtered.sort(this::compare);
Comparator<ItemStack> comparator = Comparator.comparingInt(ItemList.ordering::get);
filtered.sort(comparator::compare);
if (interrupted()) return;
ItemPanel.updateItemList(filtered);
}
};
@@ -66,7 +66,7 @@ public class ItemMobSpawner extends ItemBlock {
}
@Override
public void addInformation(ItemStack itemstack, EntityPlayer par2EntityPlayer, List list, boolean par4) {
public void addInformation(ItemStack itemstack, EntityPlayer par2EntityPlayer, List<String> list, boolean par4) {
setDefaultTag(itemstack);
int meta = itemstack.getItemDamage();
if (meta == 0) {
@@ -106,9 +106,10 @@ public class ItemMobSpawner extends ItemBlock {
public static void loadSpawners(World world) {
if (loaded) return;
loaded = true;
HashMap<Class<Entity>, String> classToStringMapping = (HashMap<Class<Entity>, String>) EntityList.classToStringMapping;
HashMap<Class<Entity>, Integer> classToIDMapping = (HashMap<Class<Entity>, Integer>) EntityList.classToIDMapping;
for (Class<Entity> eclass : classToStringMapping.keySet()) {
Map<Class<? extends Entity>, String> classToStringMapping = EntityList.classToStringMapping;
@SuppressWarnings("unchecked")
Map<Class<? extends Entity>, Integer> classToIDMapping = (Map<Class<? extends Entity>, Integer>) EntityList.classToIDMapping;
for (Class<? extends Entity> eclass : classToStringMapping.keySet()) {
if (!EntityLiving.class.isAssignableFrom(eclass)) continue;
try {
EntityLiving entityliving = (EntityLiving) eclass.getConstructor(new Class[] { World.class })
@@ -131,7 +132,7 @@ public class ItemMobSpawner extends ItemBlock {
}
@Override
public void getSubItems(Item item, CreativeTabs tab, List list) {
public void getSubItems(Item item, CreativeTabs tab, List<ItemStack> list) {
if (!NEIClientConfig.hasSMPCounterPart()) list.add(new ItemStack(item));
else for (int i : IDtoNameMap.keySet()) list.add(new ItemStack(item, 1, i));
}
+13 -81
View File
@@ -41,9 +41,6 @@ public class ItemPanel extends PanelWidget {
return super.getStackMouseOver(mousex, mousey);
}
public Button more;
public Button less;
public ItemQuantityField quantity;
public ItemHistoryPanel historyPanel;
public Button toggleGroups;
@@ -98,7 +95,7 @@ public class ItemPanel extends PanelWidget {
this.groupItems.clear();
this.forceExpand = false;
if (!ItemList.collapsibleItems.isEmpty() && !this.newItems.isEmpty()) {
if (!CollapsibleItems.isEmpty() && !this.newItems.isEmpty()) {
final Set<Integer> groups = new HashSet<>();
boolean outsideGroup = false;
@@ -106,14 +103,14 @@ public class ItemPanel extends PanelWidget {
this.rawItems = new ArrayList<>(this.newItems);
for (ItemStack stack : this.newItems) {
final int groupIndex = ItemList.collapsibleItems.getGroupIndex(stack);
final int groupIndex = CollapsibleItems.getGroupIndex(stack);
if (groupIndex == -1) {
this.realItems.add(stack);
outsideGroup = true;
} else {
if (!groups.contains(groupIndex) || ItemList.collapsibleItems.isExpanded(groupIndex)) {
if (!groups.contains(groupIndex) || CollapsibleItems.isExpanded(groupIndex)) {
this.realItems.add(stack);
groups.add(groupIndex);
}
@@ -175,7 +172,7 @@ public class ItemPanel extends PanelWidget {
}
int idx = mask.get(slotIndex);
maskGroup.put(idx, ItemList.collapsibleItems.getGroupIndex(getItem(idx)));
maskGroup.put(idx, CollapsibleItems.getGroupIndex(getItem(idx)));
}
for (int slotIndex = 0; slotIndex < mask.size(); slotIndex++) {
@@ -197,8 +194,8 @@ public class ItemPanel extends PanelWidget {
MaskMetadata metadata = new MaskMetadata();
metadata.groupIndex = groupIndex;
metadata.displayName = ItemList.collapsibleItems.getDisplayName(groupIndex);
metadata.extended = this.forceExpand || ItemList.collapsibleItems.isExpanded(groupIndex);
metadata.displayName = CollapsibleItems.getDisplayName(groupIndex);
metadata.extended = this.forceExpand || CollapsibleItems.isExpanded(groupIndex);
metadata.bgColor = metadata.extended ? expandedColor : collapsedColor;
metadata.color = darkerColor(metadata.bgColor);
metadata.left = column == 0 || idx == 0
@@ -339,48 +336,12 @@ public class ItemPanel extends PanelWidget {
@Override
public boolean onButtonPress(boolean rightclick) {
ItemList.collapsibleItems.toggleGroups(rightclick ? false : null);
CollapsibleItems.toggleGroups(rightclick ? false : null);
ItemList.updateFilter.restart();
return true;
}
};
more = new Button("+") {
@Override
public boolean onButtonPress(boolean rightclick) {
if (rightclick) return false;
int modifier = NEIClientUtils.controlKey() ? 64 : NEIClientUtils.shiftKey() ? 10 : 1;
int quantity = NEIClientConfig.getItemQuantity() + modifier;
if (quantity < 0) {
quantity = 0;
}
ItemPanels.itemPanel.quantity.setText(Integer.toString(quantity));
return true;
}
};
less = new Button("-") {
@Override
public boolean onButtonPress(boolean rightclick) {
if (rightclick) return false;
int modifier = NEIClientUtils.controlKey() ? -64 : NEIClientUtils.shiftKey() ? -10 : -1;
int quantity = NEIClientConfig.getItemQuantity() + modifier;
if (quantity < 0) {
quantity = 0;
}
ItemPanels.itemPanel.quantity.setText(Integer.toString(quantity));
return true;
}
};
quantity = new ItemQuantityField("quantity");
historyPanel = new ItemHistoryPanel();
}
@@ -431,44 +392,21 @@ public class ItemPanel extends PanelWidget {
return 0;
}
final int BUTTON_SIZE = 20;
more.w = less.w = BUTTON_SIZE;
quantity.h = BUTTON_SIZE;
if (NEIClientConfig.isSearchWidgetCentered()) {
more.h = less.h = BUTTON_SIZE;
more.x = x + w - BUTTON_SIZE;
more.y = less.y = quantity.y = y + h - BUTTON_SIZE;
less.x = x;
quantity.x = x + BUTTON_SIZE + 2;
quantity.w = more.x - quantity.x - 2;
} else {
quantity.x = (int) (x + (w * 0.7)) + 3;
quantity.y = y + h - BUTTON_SIZE;
quantity.w = (int) ((w * 0.3) - BUTTON_SIZE - 1);
more.h = less.h = BUTTON_SIZE / 2;
more.y = y + h - (more.h * 2);
less.x = more.x = quantity.x + quantity.w;
less.y = more.y + more.h;
}
if (NEIClientConfig.showHistoryPanelWidget()) {
historyPanel.x = x;
historyPanel.w = w;
historyPanel.h = ItemsGrid.SLOT_SIZE * NEIClientConfig.getIntSetting("inventory.history.useRows");
if (NEIClientConfig.showItemQuantityWidget() || !NEIClientConfig.isSearchWidgetCentered()) {
historyPanel.y = quantity.y - historyPanel.h - PanelWidget.PADDING;
return quantity.h + historyPanel.h + PanelWidget.PADDING * 2;
historyPanel.y = LayoutManager.quantity.y - historyPanel.h - PanelWidget.PADDING;
return LayoutManager.quantity.h + historyPanel.h + PanelWidget.PADDING * 2;
} else {
historyPanel.y = y + h - historyPanel.h;
return historyPanel.h + PanelWidget.PADDING;
}
}
return quantity.h + PanelWidget.PADDING;
return LayoutManager.quantity.h + PanelWidget.PADDING;
}
@Override
@@ -476,17 +414,11 @@ public class ItemPanel extends PanelWidget {
super.setVisible();
if (grid.getPerPage() > 0) {
if (NEIClientConfig.showItemQuantityWidget()) {
LayoutManager.addWidget(more);
LayoutManager.addWidget(less);
LayoutManager.addWidget(quantity);
}
if (!ItemList.collapsibleItems.isEmpty()) {
if (!CollapsibleItems.isEmpty() && !grid.isEmpty()) {
LayoutManager.addWidget(toggleGroups);
}
if (NEIClientConfig.showHistoryPanelWidget()) {
if (NEIClientConfig.showHistoryPanelWidget() && (!grid.isEmpty() || !historyPanel.isEmpty())) {
LayoutManager.addWidget(historyPanel);
}
}
@@ -560,7 +492,7 @@ public class ItemPanel extends PanelWidget {
final MaskMetadata metadata = panelGrid.maskMetadata.get(hoverSlot.slotIndex);
if (metadata != null) {
ItemList.collapsibleItems.setExpanded(metadata.groupIndex, !metadata.extended);
CollapsibleItems.setExpanded(metadata.groupIndex, !metadata.extended);
panelGrid.setItems(panelGrid.rawItems);
return true;
}
@@ -44,6 +44,7 @@ public class ItemQuantityField extends TextField {
if (!focused() && intValue() == 0) {
field.setText(translate("itempanel.quantity.default"));
field.setCursorPositionZero();
field.setEnabled(false);
super.draw(mousex, mousey);
field.setEnabled(true);
+3 -14
View File
@@ -4,19 +4,19 @@ import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.StatCollector;
import codechicken.lib.config.ConfigTagParent;
import codechicken.nei.ItemList.ItemsLoadedCallback;
import codechicken.nei.api.API;
import codechicken.nei.api.ItemInfo;
import codechicken.nei.config.GuiItemSorter;
import codechicken.nei.config.OptionOpenGui;
public class ItemSorter implements Comparator<ItemStack>, ItemsLoadedCallback {
public class ItemSorter implements Comparator<ItemStack> {
public static class SortEntry {
@@ -44,12 +44,10 @@ public class ItemSorter implements Comparator<ItemStack>, ItemsLoadedCallback {
public static final ItemSorter instance = new ItemSorter();
// optimisations
public HashMap<ItemStack, Integer> ordering = null;
public Map<ItemStack, Integer> ordering = new HashMap<>();
public static void sort(List<ItemStack> items) {
try {
// items = (ArrayList<ItemStack>)
// items.parallelStream().sorted(instance).collect(Collectors.toList());
items.sort(instance);
} catch (Exception e) {
NEIClientConfig.logger.error("Exception sorting item list", e);
@@ -65,14 +63,6 @@ public class ItemSorter implements Comparator<ItemStack>, ItemsLoadedCallback {
return 0;
}
@Override
public void itemsLoaded() {
HashMap<ItemStack, Integer> newMap = new HashMap<>();
int i = 0;
for (ItemStack stack : ItemList.items) newMap.put(stack, i++);
ordering = newMap;
}
public static SortEntry find(String name) {
for (SortEntry e : entries) if (e.name.equals(name)) return e;
@@ -136,7 +126,6 @@ public class ItemSorter implements Comparator<ItemStack>, ItemsLoadedCallback {
list = fromSaveString(activeTag().getValue());
}
});
ItemList.loadCallbacks.add(instance);
}
public static String getSaveString(List<SortEntry> list) {
@@ -0,0 +1,119 @@
package codechicken.nei;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import codechicken.nei.recipe.StackInfo;
public class ItemStackAmount {
private final Map<NBTTagCompound, Long> itemMap = new LinkedHashMap<>();
public void putAll(ItemStackAmount amounts) {
for (Map.Entry<NBTTagCompound, Long> entry : amounts.itemMap.entrySet()) {
this.itemMap.put(entry.getKey(), entry.getValue() + this.itemMap.getOrDefault(entry.getKey(), 0L));
}
}
public void add(ItemStack item) {
add(item, (long) StackInfo.getAmount(item));
}
public void add(ItemStack stack, Long value) {
if (stack == null || stack.getItem() == null) return;
final NBTTagCompound key = StackInfo.itemStackToNBT(stack, false);
this.itemMap.put(key, value + this.itemMap.getOrDefault(key, 0L));
}
public Long get(ItemStack stack) {
if (stack == null || stack.getItem() == null) return null;
final NBTTagCompound key = StackInfo.itemStackToNBT(stack, false);
return this.itemMap.get(key);
}
public void put(ItemStack stack, long value) {
if (stack == null || stack.getItem() == null) return;
final NBTTagCompound key = StackInfo.itemStackToNBT(stack, false);
this.itemMap.put(key, value);
}
public long getOrDefault(ItemStack stack, long defaultAmount) {
final Long e = get(stack);
return e == null ? defaultAmount : e;
}
public void clear() {
this.itemMap.clear();
}
public Long remove(ItemStack stack) {
if (stack == null || stack.getItem() == null) return null;
final NBTTagCompound key = StackInfo.itemStackToNBT(stack, false);
return this.itemMap.remove(key);
}
public boolean removeIf(Predicate<Map.Entry<NBTTagCompound, Long>> predicate) {
return this.itemMap.entrySet().removeIf(predicate);
}
public Set<Map.Entry<NBTTagCompound, Long>> entrySet() {
return this.itemMap.entrySet();
}
public List<ItemStack> values() {
List<ItemStack> list = new ArrayList<>();
for (Map.Entry<NBTTagCompound, Long> entry : this.itemMap.entrySet()) {
list.add(StackInfo.loadFromNBT(entry.getKey(), Math.max(0, entry.getValue())));
}
return list;
}
public int size() {
return this.itemMap.size();
}
public boolean isEmpty() {
return this.itemMap.isEmpty();
}
public static ItemStackAmount of(ItemStackAmount map) {
ItemStackAmount result = new ItemStackAmount();
result.itemMap.putAll(map.itemMap);
return result;
}
public static ItemStackAmount of(ItemStackMap<Long> map) {
ItemStackAmount result = new ItemStackAmount();
for (ItemStackMap.Entry<Long> entry : map.entries()) {
result.put(entry.key, entry.value);
}
return result;
}
public static ItemStackAmount of(Iterable<ItemStack> items) {
ItemStackAmount result = new ItemStackAmount();
for (ItemStack stack : items) {
result.add(stack);
}
return result;
}
}
@@ -5,9 +5,11 @@ import static codechicken.lib.inventory.InventoryUtils.newItemStack;
import static net.minecraftforge.oredict.OreDictionary.WILDCARD_VALUE;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
@@ -24,8 +26,13 @@ public class ItemStackMap<T> {
public final int damage;
public final NBTTagCompound tag;
private final int hashCode;
public StackMetaKey(int damage, NBTTagCompound tag) {
if (tag != null && tag.hasNoTags()) {
tag = null;
}
this.hashCode = Objects.hashCode(damage, tag);
this.damage = damage;
this.tag = tag;
}
@@ -35,7 +42,7 @@ public class ItemStackMap<T> {
}
public int hashCode() {
return Objects.hashCode(damage, tag);
return this.hashCode;
}
public boolean equals(Object o) {
@@ -191,7 +198,7 @@ public class ItemStackMap<T> {
WILDCARD_TAG.setBoolean("*", true);
}
private final HashMap<Item, DetailMap> itemMap = new HashMap<>();
private final Map<Item, DetailMap> itemMap = new LinkedHashMap<>();
private int size;
public T get(ItemStack key) {
@@ -216,8 +223,22 @@ public class ItemStackMap<T> {
map.put(key, value);
}
public T computeIfAbsent(ItemStack key, Function<ItemStack, ? extends T> mappingFunction) {
T value;
if ((value = get(key)) == null) {
T newValue;
if ((newValue = mappingFunction.apply(key)) != null) {
put(key, newValue);
return newValue;
}
}
return value;
}
public void clear() {
itemMap.clear();
size = 0;
}
public T remove(ItemStack key) {
@@ -1,7 +1,5 @@
package codechicken.nei;
import java.util.List;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
@@ -29,11 +27,16 @@ public class ItemStackSet extends ItemStackMap<ItemStack> implements ItemFilter
put(item, item);
}
public ItemStackSet addAll(List<ItemStack> items) {
public ItemStackSet addAll(Iterable<ItemStack> items) {
for (ItemStack item : items) add(item);
return this;
}
public ItemStackSet removeAll(Iterable<ItemStack> items) {
for (ItemStack item : items) remove(item);
return this;
}
public boolean contains(ItemStack item) {
return get(item) != null;
}
+21 -20
View File
@@ -1,9 +1,5 @@
package codechicken.nei;
import static codechicken.lib.gui.GuiDraw.drawStringC;
import static codechicken.lib.gui.GuiDraw.fontRenderer;
import static codechicken.lib.gui.GuiDraw.getMousePosition;
import java.awt.Point;
import java.util.List;
@@ -15,6 +11,7 @@ import net.minecraft.item.ItemStack;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
import codechicken.lib.gui.GuiDraw;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.guihook.IContainerInputHandler;
import codechicken.nei.recipe.StackInfo;
@@ -61,37 +58,41 @@ public class ItemZoom extends Widget implements IContainerInputHandler {
GL11.glPopMatrix();
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
GuiContainerManager.enable2DRender();
if (NEIClientConfig.getBooleanSetting("inventory.itemzoom.showName")) {
String dispalyName = NEIClientUtils.cropText(fontRenderer, this.displayName, this.availableAreaWidth);
drawStringC(
String dispalyName = NEIClientUtils
.cropText(GuiDraw.fontRenderer, this.displayName, this.availableAreaWidth);
GuiDraw.drawStringC(
dispalyName,
(int) ((this.xPosition + size / 2) * screenScale),
(int) ((this.yPosition + size) * screenScale) + shiftText,
NEIClientConfig.getSetting("inventory.itemzoom.nameColor").getHexValue());
shiftText += fontRenderer.FONT_HEIGHT;
shiftText += GuiDraw.fontRenderer.FONT_HEIGHT;
}
if (NEIClientConfig.getBooleanSetting("inventory.itemzoom.enabled")
&& NEIClientConfig.getBooleanSetting("inventory.itemzoom.helpText")) {
int key = NEIClientConfig.getKeyBinding("gui.itemzoom_toggle");
String keyName = NEIClientConfig.getKeyName("gui.itemzoom_toggle");
if (key > 0) {
String helpText = NEIClientUtils
.translate("itemzoom.toggle", NEIClientConfig.getKeyName(key, true));
@SuppressWarnings("unchecked")
List<String> lines = fontRenderer.listFormattedStringToWidth(helpText, this.availableAreaWidth);
if (keyName != null) {
String helpText = NEIClientUtils.translate("itemzoom.toggle", keyName);
List<String> lines = GuiDraw.fontRenderer
.listFormattedStringToWidth(helpText, this.availableAreaWidth);
for (String line : lines) {
drawStringC(
GuiDraw.drawStringC(
line,
(int) ((this.xPosition + size / 2) * screenScale),
(int) ((this.yPosition + size) * screenScale) + 10 + shiftText,
0x66555555);
shiftText += fontRenderer.FONT_HEIGHT;
shiftText += GuiDraw.fontRenderer.FONT_HEIGHT;
}
}
}
GL11.glPopAttrib();
}
}
@@ -101,17 +102,17 @@ public class ItemZoom extends Widget implements IContainerInputHandler {
if (stack != null && (!NEIClientConfig.getBooleanSetting("inventory.itemzoom.onlySolid")
|| Block.getBlockFromItem(stack.getItem()).getMaterial().isSolid())) {
final float screenScale = 1.0f / getScreenScale();
final float availableAreaWidth = (gui.width - (gui.xSize + gui.width) / 2) * screenScale;
final float availableAreaWidth = (gui.width - gui.xSize) / 2 * screenScale;
final float availableAreaHeight = gui.height * screenScale;
final Point mouse = getMousePosition();
final Point mouse = GuiDraw.getMousePosition();
this.scale = Math.round(getZoomAmount(gui) * getPointSize(gui) / SLOT_SIZE);
this.yPosition = (availableAreaHeight - this.scale * SLOT_SIZE) / 2;
this.xPosition = (availableAreaWidth - this.scale * SLOT_SIZE) / 2;
this.availableAreaWidth = (int) (availableAreaWidth / screenScale);
if (ItemPanels.bookmarkPanel.contains(mouse.x, mouse.y)) {
this.xPosition += (gui.guiLeft + gui.xSize) * screenScale;;
if (availableAreaWidth / screenScale >= mouse.x) {
this.xPosition += gui.width * screenScale - availableAreaWidth;
}
try {
@@ -164,7 +165,7 @@ public class ItemZoom extends Widget implements IContainerInputHandler {
private ItemStack getStackMouseOver(GuiContainer gui) {
if (NEIClientConfig.getBooleanSetting("inventory.itemzoom.neiOnly")) {
final Point mouse = getMousePosition();
final Point mouse = GuiDraw.getMousePosition();
ItemStack stack = ItemPanels.itemPanel.getStackMouseOver(mouse.x, mouse.y);
if (stack == null) {
+138 -63
View File
@@ -17,6 +17,7 @@ import net.minecraft.client.shader.Framebuffer;
import net.minecraft.item.ItemStack;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL30;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.ItemPanel.ItemPanelSlot;
@@ -26,6 +27,119 @@ import codechicken.nei.recipe.StackInfo;
public class ItemsGrid {
private static class ScreenCapture {
private long nextCacheRefresh = 0;
private Framebuffer framebuffer;
public ScreenCapture() {
this.framebuffer = new Framebuffer(1, 1, true);
this.framebuffer.setFramebufferColor(0.0F, 0.0F, 0.0F, 0.0F);
Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false);
}
protected int getGridRenderingCacheFPS(int mode) {
return mode == 1 ? NEIClientConfig.getIntSetting("inventory.gridRenderingCacheFPS") : 0;
}
public boolean needRefresh(int mode) {
final Minecraft minecraft = Minecraft.getMinecraft();
return this.nextCacheRefresh == 0 || this.framebuffer.framebufferWidth != minecraft.displayWidth
|| framebuffer.framebufferHeight != minecraft.displayHeight
|| getGridRenderingCacheFPS(mode) > 0 && this.nextCacheRefresh < System.currentTimeMillis();
}
public void refreshBuffer() {
this.nextCacheRefresh = 0;
}
public void captureScreen(Runnable callback, int mode) {
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
resetFramebuffer();
this.framebuffer.bindFramebuffer(false);
/* Set up some rendering state needed for items to work correctly */
GL11.glDisable(GL11.GL_BLEND);
GL11.glDepthMask(true);
OpenGlHelper.glBlendFunc(
GL11.GL_SRC_ALPHA,
GL11.GL_ONE_MINUS_SRC_ALPHA,
GL11.GL_SRC_ALPHA,
GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
callback.run();
GL11.glPopAttrib();
Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false);
this.nextCacheRefresh = System.currentTimeMillis() + (1000 / Math.max(1, getGridRenderingCacheFPS(mode)));
}
private void resetFramebuffer() {
final Minecraft minecraft = Minecraft.getMinecraft();
if (this.framebuffer.framebufferWidth != minecraft.displayWidth
|| framebuffer.framebufferHeight != minecraft.displayHeight) {
this.framebuffer.createBindFramebuffer(minecraft.displayWidth, minecraft.displayHeight);
this.framebuffer.setFramebufferFilter(GL11.GL_NEAREST);
} else {
this.framebuffer.framebufferClear();
}
// copy depth buffer from MC (fix Angelica)
OpenGlHelper.func_153171_g(GL30.GL_READ_FRAMEBUFFER, minecraft.getFramebuffer().framebufferObject);
OpenGlHelper.func_153171_g(GL30.GL_DRAW_FRAMEBUFFER, this.framebuffer.framebufferObject);
GL30.glBlitFramebuffer(
0,
0,
minecraft.displayWidth,
minecraft.displayHeight,
0,
0,
minecraft.displayWidth,
minecraft.displayHeight,
GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_STENCIL_BUFFER_BIT,
GL11.GL_NEAREST);
}
public void renderCapturedScreen() {
this.framebuffer.bindFramebufferTexture();
final Tessellator tessellator = Tessellator.instance;
final Minecraft minecraft = Minecraft.getMinecraft();
final ScaledResolution scaledresolution = new ScaledResolution(
minecraft,
minecraft.displayWidth,
minecraft.displayHeight);
/* Set up some rendering state needed for items to work correctly */
GL11.glEnable(GL11.GL_BLEND);
OpenGlHelper
.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
GL11.glEnable(GL11.GL_TEXTURE_2D);
tessellator.startDrawingQuads();
tessellator.addVertexWithUV(0, scaledresolution.getScaledHeight_double(), 0.0, 0, 0);
tessellator.addVertexWithUV(
scaledresolution.getScaledWidth_double(),
scaledresolution.getScaledHeight_double(),
0.0,
1,
0);
tessellator.addVertexWithUV(scaledresolution.getScaledWidth_double(), 0, 0.0, 1, 1);
tessellator.addVertexWithUV(0, 0, 0, 0, 1);
tessellator.draw();
this.framebuffer.unbindFramebufferTexture();
}
}
public static final int SLOT_SIZE = 18;
protected int width;
@@ -49,10 +163,7 @@ public class ItemsGrid {
protected Label messageLabel = new Label(getMessageOnEmpty(), true);
@Nullable
private Framebuffer framebuffer = null;
protected boolean refreshBuffer = true;
protected ScreenCapture screenCapture = null;
public ArrayList<ItemStack> getItems() {
return realItems;
@@ -66,6 +177,10 @@ public class ItemsGrid {
return realItems.size();
}
public boolean isEmpty() {
return realItems.isEmpty();
}
public int indexOf(ItemStack stackA, boolean useNBT) {
for (int idx = 0; idx < realItems.size(); idx++) {
@@ -152,7 +267,9 @@ public class ItemsGrid {
}
protected void onGridChanged() {
refreshBuffer = true;
if (this.screenCapture != null) {
this.screenCapture.refreshBuffer();
}
this.gridMask = null;
}
@@ -280,34 +397,6 @@ public class ItemsGrid {
protected void afterDrawSlot(@Nullable ItemPanelSlot focused, int slotIdx, Rectangle4i rect) {}
private void blitExistingBuffer() {
Minecraft minecraft = Minecraft.getMinecraft();
GL11.glEnable(GL11.GL_BLEND);
OpenGlHelper.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
getFrameBuffer().bindFramebufferTexture();
GL11.glEnable(GL11.GL_TEXTURE_2D);
ScaledResolution res = new ScaledResolution(minecraft, minecraft.displayWidth, minecraft.displayHeight);
Tessellator tessellator = Tessellator.instance;
tessellator.startDrawingQuads();
tessellator.addVertexWithUV(0, res.getScaledHeight_double(), 0.0, 0, 0);
tessellator.addVertexWithUV(res.getScaledWidth_double(), res.getScaledHeight_double(), 0.0, 1, 0);
tessellator.addVertexWithUV(res.getScaledWidth_double(), 0, 0.0, 1, 1);
tessellator.addVertexWithUV(0, 0, 0, 0, 1);
tessellator.draw();
OpenGlHelper.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, GL11.GL_ONE, GL11.GL_ZERO);
}
private Framebuffer getFrameBuffer() {
if (framebuffer == null) {
framebuffer = new Framebuffer(1, 1, true);
framebuffer.setFramebufferColor(0.0F, 0.0F, 0.0F, 0.0F);
}
return framebuffer;
}
private void drawItems() {
GuiContainerManager.enableMatrixStackLogging();
@@ -321,8 +410,8 @@ public class ItemsGrid {
GuiContainerManager.disableMatrixStackLogging();
}
protected boolean shouldCacheItemRendering() {
return NEIClientConfig.shouldCacheItemRendering();
protected int getGridRenderingCacheMode() {
return NEIClientConfig.getGridRenderingCacheMode();
}
public void draw(int mousex, int mousey) {
@@ -331,36 +420,22 @@ public class ItemsGrid {
}
final ItemPanelSlot focused = getSlotMouseOver(mousex, mousey);
final int gridRenderingCacheMode = getGridRenderingCacheMode();
if (shouldCacheItemRendering()) {
beforeDrawItems(mousex, mousey, focused);
if (refreshBuffer) {
Minecraft minecraft = Minecraft.getMinecraft();
Framebuffer framebuffer = getFrameBuffer();
framebuffer.createBindFramebuffer(minecraft.displayWidth, minecraft.displayHeight);
framebuffer.framebufferClear();
framebuffer.bindFramebuffer(false);
if (gridRenderingCacheMode > 0) {
/* Set up some rendering state needed for items to work correctly */
GL11.glDisable(GL11.GL_BLEND);
GL11.glDepthMask(true);
OpenGlHelper.glBlendFunc(
GL11.GL_SRC_ALPHA,
GL11.GL_ONE_MINUS_SRC_ALPHA,
GL11.GL_SRC_ALPHA,
GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
drawItems();
Minecraft.getMinecraft().getFramebuffer().bindFramebuffer(false);
refreshBuffer = false;
if (this.screenCapture == null) {
this.screenCapture = new ScreenCapture();
}
beforeDrawItems(mousex, mousey, focused);
blitExistingBuffer();
if (this.screenCapture.needRefresh(gridRenderingCacheMode)) {
this.screenCapture.captureScreen(this::drawItems, gridRenderingCacheMode);
}
this.screenCapture.renderCapturedScreen();
} else {
beforeDrawItems(mousex, mousey, focused);
drawItems();
}
@@ -382,8 +457,8 @@ public class ItemsGrid {
return null;
}
final int overRow = (int) ((mousey - marginTop) / SLOT_SIZE);
final int overColumn = (int) ((mousex - marginLeft - paddingLeft) / SLOT_SIZE);
final int overRow = (mousey - marginTop) / SLOT_SIZE;
final int overColumn = (mousex - marginLeft - paddingLeft) / SLOT_SIZE;
final int slt = columns * overRow + overColumn;
if (overRow >= rows || overColumn >= columns) {
@@ -412,8 +487,8 @@ public class ItemsGrid {
return false;
}
final int r = (int) ((py - marginTop) / SLOT_SIZE);
final int c = (int) ((px - marginLeft - paddingLeft) / SLOT_SIZE);
final int r = (py - marginTop) / SLOT_SIZE;
final int c = (px - marginLeft - paddingLeft) / SLOT_SIZE;
return !isInvalidSlot(columns * r + c);
}
@@ -3,15 +3,10 @@ package codechicken.nei;
import static codechicken.lib.gui.GuiDraw.fontRenderer;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumChatFormatting;
import org.lwjgl.opengl.GL11;
@@ -24,8 +19,8 @@ import codechicken.nei.util.ReadableNumberConverter;
public class ItemsTooltipLineHandler implements ITooltipLineHandler {
protected static int MAX_COLUMNS = 11;
protected static int MARGIN_TOP = 2;
protected static final int MAX_COLUMNS = 11;
protected static final int MARGIN_TOP = 2;
protected String label;
protected EnumChatFormatting labelColor = EnumChatFormatting.GRAY;
@@ -37,7 +32,7 @@ public class ItemsTooltipLineHandler implements ITooltipLineHandler {
protected int rows = 0;
protected int length = 0;
public ItemsTooltipLineHandler(String label, List<ItemStack> items, boolean saveStackSize) {
public ItemsTooltipLineHandler(String label, List<ItemStack> items) {
this(label, items, true, 5);
}
@@ -59,7 +54,12 @@ public class ItemsTooltipLineHandler implements ITooltipLineHandler {
this.length,
Math.min(
this.columns * this.rows,
this.length > MAX_COLUMNS * maxRows ? (MAX_COLUMNS * maxRows - 1) : Integer.MAX_VALUE));
this.length > MAX_COLUMNS * maxRows ? (MAX_COLUMNS * maxRows) : Integer.MAX_VALUE));
if (this.items.size() > this.count) {
String text = "+" + (this.items.size() - this.count);
this.count -= (int) Math.ceil((float) (fontRenderer.getStringWidth(text) - 2) / ItemsGrid.SLOT_SIZE);
}
}
}
@@ -85,6 +85,7 @@ public class ItemsTooltipLineHandler implements ITooltipLineHandler {
fontRenderer.drawStringWithShadow(this.labelColor + this.label + ":", x, y, 0);
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
GL11.glPushMatrix();
RenderHelper.enableGUIStandardItemLighting();
@@ -100,47 +101,35 @@ public class ItemsTooltipLineHandler implements ITooltipLineHandler {
String stackSize = !this.saveStackSize || drawStack.stackSize == 0 ? ""
: ReadableNumberConverter.INSTANCE.toWideReadableForm(drawStack.stackSize);
GuiContainerManager
.drawItem(col * ItemsGrid.SLOT_SIZE, row * ItemsGrid.SLOT_SIZE, drawStack, true, stackSize);
drawItem(col * ItemsGrid.SLOT_SIZE, row * ItemsGrid.SLOT_SIZE, drawStack, stackSize);
}
if (this.count < this.items.size()) {
String text = "+" + (this.items.size() - this.count);
fontRenderer.drawStringWithShadow(
"+" + (this.items.size() - this.count),
(this.columns - 1) * ItemsGrid.SLOT_SIZE,
(this.rows - 1) * ItemsGrid.SLOT_SIZE + (ItemsGrid.SLOT_SIZE - fontRenderer.FONT_HEIGHT) / 2 - 1,
text,
MAX_COLUMNS * ItemsGrid.SLOT_SIZE - fontRenderer.getStringWidth(text) - 2,
(this.rows - 1) * ItemsGrid.SLOT_SIZE + (ItemsGrid.SLOT_SIZE - fontRenderer.FONT_HEIGHT) / 2,
0xee555555);
}
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
GL11.glPopMatrix();
GL11.glPopAttrib();
}
protected void drawItem(int x, int y, ItemStack drawStack, String stackSize) {
GuiContainerManager.drawItem(x, y, drawStack, true, stackSize);
}
private List<ItemStack> groupingItemStacks(List<ItemStack> items) {
final Map<String, Integer> count = new HashMap<>();
final Map<String, NBTTagCompound> unique = new LinkedHashMap<>();
final List<ItemStack> result = new ArrayList<>();
final List<ItemStack> result = ItemStackAmount.of(items).values();
for (ItemStack stack : items) {
final NBTTagCompound nbTag = StackInfo.itemStackToNBT(stack, true);
final String GUID = StackInfo.getItemStackGUID(stack);
if (!unique.containsKey(GUID)) {
count.put(GUID, nbTag.getInteger("Count"));
unique.put(GUID, nbTag);
} else {
count.put(GUID, count.get(GUID) + nbTag.getInteger("Count"));
}
}
for (String GUID : unique.keySet()) {
ItemStack stack = StackInfo.loadFromNBT(unique.get(GUID), count.get(GUID));
if (unique.get(GUID).hasKey("gtFluidName")) {
for (ItemStack stack : result) {
if (StackInfo.itemStackToNBT(stack).hasKey("gtFluidName")) {
stack.stackSize = 0;
}
result.add(stack);
}
return result;
@@ -0,0 +1,21 @@
package codechicken.nei;
import java.util.LinkedHashMap;
import java.util.Map;
// Simple LRUCache
public class LRUCache<K, V> extends LinkedHashMap<K, V> {
private final int capacity;
public LRUCache(int capacity) {
super(capacity, 0.75f, true);
this.capacity = capacity;
}
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > capacity;
}
}
+129 -55
View File
@@ -31,10 +31,11 @@ import static codechicken.nei.NEIClientUtils.toggleMagnetMode;
import static codechicken.nei.NEIClientUtils.toggleRaining;
import static codechicken.nei.NEIClientUtils.translate;
import java.awt.Point;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import net.minecraft.client.Minecraft;
@@ -78,13 +79,11 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
/**
* Sorted bottom first
*/
private static TreeSet<Widget> drawWidgets = new TreeSet<>(new WidgetZOrder(false));
private static Set<Widget> drawWidgets = new TreeSet<>(new WidgetZOrder(false));
/**
* Sorted top first
*/
private static TreeSet<Widget> controlWidgets = new TreeSet<>(new WidgetZOrder(true));
private static List<IContainerTooltipHandler> tooltipWidgets = new LinkedList<>();
private static Set<Widget> controlWidgets = new TreeSet<>(new WidgetZOrder(true));
public static ItemPanel itemPanel;
public static BookmarkPanel bookmarkPanel;
@@ -95,13 +94,8 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
public static ButtonCycled options;
public static ButtonCycled bookmarksButton;
@Deprecated
public static Button more;
@Deprecated
public static Button less;
@Deprecated
public static ItemQuantityField quantity;
public static Button delete;
@@ -149,8 +143,8 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
gui.guiTop = (gui.height - gui.ySize) / 2;
if (gui instanceof GuiContainerCreative && gui.buttonList.size() >= 2) {
GuiButton button1 = (GuiButton) gui.buttonList.get(0);
GuiButton button2 = (GuiButton) gui.buttonList.get(1);
GuiButton button1 = gui.buttonList.get(0);
GuiButton button2 = gui.buttonList.get(1);
button1.xPosition = gui.guiLeft;
button2.xPosition = gui.guiLeft + gui.xSize - 20;
}
@@ -171,14 +165,18 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
public void onMouseClicked(GuiContainer gui, int mousex, int mousey, int button) {
if (isHidden()) return;
for (Widget widget : controlWidgets) widget.onGuiClick(mousex, mousey);
for (Widget widget : controlWidgets) {
widget.onGuiClick(mousex, mousey);
}
}
@Override
public boolean mouseClicked(GuiContainer gui, int mousex, int mousey, int button) {
if (isHidden()) return false;
if (!isEnabled()) return options.contains(mousex, mousey) && options.handleClick(mousex, mousey, button);
if (!isEnabled()) {
return options.contains(mousex, mousey) && options.handleClick(mousex, mousey, button);
}
for (Widget widget : controlWidgets) {
widget.onGuiClick(mousex, mousey);
@@ -192,10 +190,22 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
@Override
public boolean objectUnderMouse(GuiContainer gui, int mousex, int mousey) {
if (!isHidden() && isEnabled())
for (Widget widget : drawWidgets) if (widget.contains(mousex, mousey)) return true;
return getWidgetUnderMouse(mousex, mousey) != null;
}
return false;
public Widget getWidgetUnderMouse(int mousex, int mousey) {
if (isHidden() || !isEnabled()) {
return null;
}
for (Widget widget : controlWidgets) {
if (widget.contains(mousex, mousey)) {
return widget;
}
}
return null;
}
public boolean keyTyped(GuiContainer gui, char keyChar, int keyID) {
@@ -251,12 +261,12 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
@Override
public ItemStack getStackUnderMouse(GuiContainer gui, int mousex, int mousey) {
if (!isHidden() && isEnabled()) {
for (Widget widget : drawWidgets) {
ItemStack stack = widget.getStackMouseOver(mousex, mousey);
if (stack != null) return stack;
}
final Widget focused = getWidgetUnderMouse(mousex, mousey);
if (focused != null) {
return focused.getStackMouseOver(mousex, mousey);
}
return null;
}
@@ -285,18 +295,32 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
@Override
public void postRenderTooltips(GuiContainer gui, int mousex, int mousey, List<String> tooltip) {
if (!isHidden() && isEnabled() && GuiContainerManager.shouldShowTooltip(gui)) {
for (Widget widget : drawWidgets) widget.postDrawTooltips(mousex, mousey, tooltip);
final Widget focused = getWidgetUnderMouse(mousex, mousey);
if (focused != null) {
focused.postDrawTooltips(mousex, mousey, tooltip);
}
}
}
@Override
public List<String> handleTooltip(GuiContainer gui, int mousex, int mousey, List<String> currenttip) {
if (!isHidden() && isEnabled() && GuiContainerManager.shouldShowTooltip(gui)) {
for (Widget widget : drawWidgets) currenttip = widget.handleTooltip(mousex, mousey, currenttip);
for (IContainerTooltipHandler tip : tooltipWidgets)
currenttip = tip.handleTooltip(gui, mousex, mousey, currenttip);
final Widget focused = getWidgetUnderMouse(mousex, mousey);
if (focused != null) {
currenttip = focused.handleTooltip(mousex, mousey, currenttip);
if (focused instanceof IContainerTooltipHandler tip) {
currenttip = tip.handleTooltip(gui, mousex, mousey, currenttip);
}
}
}
return currenttip;
}
@@ -314,8 +338,12 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
}
if (!isHidden() && isEnabled() && GuiContainerManager.shouldShowTooltip(gui)) {
for (IContainerTooltipHandler tip : tooltipWidgets)
final Point mouse = GuiDraw.getMousePosition();
final Widget focused = getWidgetUnderMouse(mouse.x, mouse.y);
if (focused instanceof IContainerTooltipHandler tip) {
currenttip = tip.handleItemDisplayName(gui, stack, currenttip);
}
}
return currenttip;
@@ -326,8 +354,11 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
List<String> currenttip) {
if (!isHidden() && isEnabled() && GuiContainerManager.shouldShowTooltip(gui)) {
for (IContainerTooltipHandler tip : tooltipWidgets)
final Widget focused = getWidgetUnderMouse(mousex, mousey);
if (focused instanceof IContainerTooltipHandler tip) {
currenttip = tip.handleItemTooltip(gui, itemstack, mousex, mousey, currenttip);
}
}
return currenttip;
@@ -337,8 +368,11 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
public Map<String, String> handleHotkeys(GuiContainer gui, int mousex, int mousey, Map<String, String> hotkeys) {
if (!isHidden() && isEnabled() && GuiContainerManager.shouldShowTooltip(gui)) {
for (IContainerTooltipHandler tip : tooltipWidgets)
final Widget focused = getWidgetUnderMouse(mousex, mousey);
if (focused instanceof IContainerTooltipHandler tip) {
hotkeys = tip.handleHotkeys(gui, mousex, mousey, hotkeys);
}
}
return hotkeys;
@@ -346,17 +380,12 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
public static void layout(GuiContainer gui) {
VisiblityData visiblity = new VisiblityData();
if (isHidden()) visiblity.showNEI = false;
if (isBookmarkPanelHidden()) visiblity.showBookmarkPanel = false;
if (gui.height - gui.ySize <= 40 && NEIClientConfig.isSearchWidgetCentered())
visiblity.showSearchSection = false;
if (visiblity.showBookmarkPanel || gui.guiTop <= 20) visiblity.showSubsetDropdown = false;
if (gui.guiLeft - 4 < 76) visiblity.showWidgets = false;
visiblity.showNEI = !isHidden();
visiblity.showBookmarkPanel = !isBookmarkPanelHidden();
visiblity.showSearchSection = !(gui.height - gui.ySize <= 40 && NEIClientConfig.isSearchWidgetCentered());
visiblity.showSubsetDropdown = NEIClientConfig.showSubsetWidget()
&& (gui.guiTop > 20 || visiblity.showSearchSection && !NEIClientConfig.subsetWidgetOnTop());
visiblity.showWidgets = gui.guiLeft - 4 > 76;
try {
GuiInfo.readLock.lock();
@@ -405,7 +434,8 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
@Override
public boolean onButtonPress(boolean rightclick) {
if (!rightclick) {
if (Keyboard.getEventKeyState() && getIsAccessibleControlEventKey()) {
if (Keyboard.getEventKeyState() && getIsAccessibleControlEventKey()
&& NEIClientConfig.canChangeCheatMode()) {
NEIClientConfig.cycleSetting("inventory.cheatmode", 3);
} else {
if (Keyboard.getEventKeyState() && (Keyboard.getEventKey() == Keyboard.KEY_LSHIFT
@@ -429,7 +459,10 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
else if (cheatMode == 2) modeColor = EnumChatFormatting.RED.toString();
String controlKeyLocalization = translate(Minecraft.isRunningOnMac ? "key.ctrl.mac" : "key.ctrl");
tooltip.add(modeColor + translate("inventory.options.tip.cheatmode." + cheatMode));
tooltip.add(modeColor + translate("inventory.options.tip.cheatmode.disable", controlKeyLocalization));
if (NEIClientConfig.canChangeCheatMode()) {
tooltip.add(
modeColor + translate("inventory.options.tip.cheatmode.disable", controlKeyLocalization));
}
}
@Override
@@ -462,9 +495,43 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
}
};
more = ItemPanels.itemPanel.more;
less = ItemPanels.itemPanel.less;
quantity = ItemPanels.itemPanel.quantity;
more = new Button("+") {
@Override
public boolean onButtonPress(boolean rightclick) {
if (rightclick) return false;
int modifier = NEIClientUtils.controlKey() ? 64 : NEIClientUtils.shiftKey() ? 10 : 1;
int quantity = NEIClientConfig.getItemQuantity() + modifier;
if (quantity < 0) {
quantity = 0;
}
LayoutManager.quantity.setText(Integer.toString(quantity));
return true;
}
};
less = new Button("-") {
@Override
public boolean onButtonPress(boolean rightclick) {
if (rightclick) return false;
int modifier = NEIClientUtils.controlKey() ? -64 : NEIClientUtils.shiftKey() ? -10 : -1;
int quantity = NEIClientConfig.getItemQuantity() + modifier;
if (quantity < 0) {
quantity = 0;
}
LayoutManager.quantity.setText(Integer.toString(quantity));
return true;
}
};
quantity = new ItemQuantityField("quantity");
delete = new Button() {
@Override
@@ -640,10 +707,9 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
if (!itemsLoaded) {
ItemList.loadItems.restart();
itemsLoaded = true;
}
overlayRenderer = null;
overlayRenderer = null;
getLayoutStyle().init();
layout(gui);
AutoFocusWidget.instance.load(gui);
@@ -673,12 +739,18 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
public static void updateWidgetVisiblities(GuiContainer gui, VisiblityData visiblity) {
drawWidgets = new TreeSet<>(new WidgetZOrder(false));
controlWidgets = new TreeSet<>(new WidgetZOrder(true));
tooltipWidgets.clear();
if (!visiblity.showNEI) return;
addWidget(options);
addWidget(bookmarksButton);
if (visiblity.showItemPanel && NEIClientConfig.showItemQuantityWidget()) {
addWidget(quantity);
addWidget(more);
addWidget(less);
}
if (visiblity.showItemPanel) {
addWidget(itemPanel);
itemPanel.setVisible();
@@ -689,9 +761,13 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
bookmarkPanel.setVisible();
}
searchField.setVisible(visiblity.showSearchSection);
if (visiblity.showSearchSection) {
if (visiblity.showSearchSection && NEIClientConfig.isSearchWidgetCentered()
|| visiblity.showItemPanel && !NEIClientConfig.isSearchWidgetCentered()) {
searchField.setVisible(true);
addWidget(searchField);
} else {
searchField.setVisible(false);
searchField.setFocus(false);
}
if (visiblity.showUtilityButtons) {
@@ -727,10 +803,6 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
public static void addWidget(Widget widget) {
drawWidgets.add(widget);
controlWidgets.add(widget);
if (widget instanceof IContainerTooltipHandler) {
tooltipWidgets.add((IContainerTooltipHandler) widget);
}
}
@Override
@@ -746,7 +818,9 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
public boolean mouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled) {
if (isHidden() || !isEnabled()) return false;
for (Widget widget : drawWidgets) if (widget.onMouseWheel(scrolled, mousex, mousey)) return true;
for (Widget widget : controlWidgets) {
if (widget.onMouseWheel(scrolled, mousex, mousey)) return true;
}
return false;
}
@@ -1,34 +1,20 @@
package codechicken.nei;
import static codechicken.lib.gui.GuiDraw.drawStringC;
import static codechicken.nei.LayoutManager.bookmarkPanel;
import static codechicken.nei.LayoutManager.bookmarksButton;
import static codechicken.nei.LayoutManager.delete;
import static codechicken.nei.LayoutManager.dropDown;
import static codechicken.nei.LayoutManager.gamemode;
import static codechicken.nei.LayoutManager.heal;
import static codechicken.nei.LayoutManager.itemPanel;
import static codechicken.nei.LayoutManager.itemPresenceOverlays;
import static codechicken.nei.LayoutManager.itemZoom;
import static codechicken.nei.LayoutManager.magnet;
import static codechicken.nei.LayoutManager.options;
import static codechicken.nei.LayoutManager.rain;
import static codechicken.nei.LayoutManager.searchField;
import static codechicken.nei.LayoutManager.timeButtons;
import static codechicken.nei.NEIClientConfig.canPerformAction;
import static codechicken.nei.NEIClientConfig.disabledActions;
import static codechicken.nei.NEIClientConfig.getMagnetMode;
import static codechicken.nei.NEIClientConfig.isEnabled;
import net.minecraft.client.gui.inventory.GuiContainer;
import org.lwjgl.opengl.GL11;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.api.LayoutStyle;
import codechicken.nei.drawable.DrawableBuilder;
public class LayoutStyleMinecraft extends LayoutStyle {
protected static final int BUTTON_SIZE = 20;
protected static final int MARGIN = 2;
public int buttonCount;
public int leftSize;
public int numButtons;
@@ -40,19 +26,21 @@ public class LayoutStyleMinecraft extends LayoutStyle {
@Override
public void init() {
delete.icon = new Image(144, 12, 12, 12);
rain.icon = new Image(120, 12, 12, 12);
gamemode.icons[0] = new Image(132, 12, 12, 12);
gamemode.icons[1] = new Image(156, 12, 12, 12);
gamemode.icons[2] = new Image(168, 12, 12, 12);
magnet.icon = new Image(180, 24, 12, 12);
timeButtons[0].icon = new Image(132, 24, 12, 12);
timeButtons[1].icon = new Image(120, 24, 12, 12);
timeButtons[2].icon = new Image(144, 24, 12, 12);
timeButtons[3].icon = new Image(156, 24, 12, 12);
heal.icon = new Image(168, 24, 12, 12);
itemPresenceOverlays[0] = new DrawableBuilder("nei:textures/nei_tabbed_sprites.png", 0, 40, 8, 8).build();
itemPresenceOverlays[1] = new DrawableBuilder("nei:textures/nei_tabbed_sprites.png", 8, 40, 8, 8).build();
LayoutManager.delete.icon = new Image(144, 12, 12, 12);
LayoutManager.rain.icon = new Image(120, 12, 12, 12);
LayoutManager.gamemode.icons[0] = new Image(132, 12, 12, 12);
LayoutManager.gamemode.icons[1] = new Image(156, 12, 12, 12);
LayoutManager.gamemode.icons[2] = new Image(168, 12, 12, 12);
LayoutManager.magnet.icon = new Image(180, 24, 12, 12);
LayoutManager.timeButtons[0].icon = new Image(132, 24, 12, 12);
LayoutManager.timeButtons[1].icon = new Image(120, 24, 12, 12);
LayoutManager.timeButtons[2].icon = new Image(144, 24, 12, 12);
LayoutManager.timeButtons[3].icon = new Image(156, 24, 12, 12);
LayoutManager.heal.icon = new Image(168, 24, 12, 12);
LayoutManager.itemPresenceOverlays[0] = new DrawableBuilder("nei:textures/nei_tabbed_sprites.png", 0, 40, 8, 8)
.build();
LayoutManager.itemPresenceOverlays[1] = new DrawableBuilder("nei:textures/nei_tabbed_sprites.png", 8, 40, 8, 8)
.build();
}
@Override
@@ -65,85 +53,177 @@ public class LayoutStyleMinecraft extends LayoutStyle {
reset();
leftSize = ItemPanels.bookmarkPanel.getWidth(gui);
numButtons = Math.max(leftSize / 18, 1);
numButtons = Math.max(leftSize / 20, 1);
delete.state = 0x4;
if (NEIController.getDeleteMode()) delete.state |= 1;
else if (!visiblity.enableDeleteMode) delete.state |= 2;
rain.state = 0x4;
if (disabledActions.contains("rain")) rain.state |= 2;
else if (NEIClientUtils.isRaining()) rain.state |= 1;
gamemode.state = 0x4;
if (NEIClientUtils.getGamemode() != 0) {
gamemode.state |= 0x1;
gamemode.index = NEIClientUtils.getGamemode() - 1;
} else {
if (NEIClientUtils.isValidGamemode("creative")) gamemode.index = 0;
else if (NEIClientUtils.isValidGamemode("creative+")) gamemode.index = 1;
else if (NEIClientUtils.isValidGamemode("adventure")) gamemode.index = 2;
LayoutManager.delete.state = 0x4;
if (NEIController.getDeleteMode()) {
LayoutManager.delete.state |= 1;
} else if (!visiblity.enableDeleteMode) {
LayoutManager.delete.state |= 2;
}
bookmarksButton.index = NEIClientConfig.isBookmarkPanelHidden() ? 0 : 1;
options.index = NEIClientConfig.getCheatMode();
magnet.state = 0x4 | (getMagnetMode() ? 1 : 0);
LayoutManager.rain.state = 0x4;
if (NEIClientConfig.disabledActions.contains("rain")) {
LayoutManager.rain.state |= 2;
} else if (NEIClientUtils.isRaining()) {
LayoutManager.rain.state |= 1;
}
if (canPerformAction("delete")) layoutButton(delete);
if (canPerformAction("rain")) layoutButton(rain);
if (NEIClientUtils.isValidGamemode("creative") || NEIClientUtils.isValidGamemode("creative+")
|| NEIClientUtils.isValidGamemode("adventure"))
layoutButton(gamemode);
if (canPerformAction("magnet")) layoutButton(magnet);
if (canPerformAction("time")) {
for (int i = 0; i < 4; i++) {
timeButtons[i].state = disabledActions.contains(NEIActions.timeZones[i]) ? 2 : 0;
layoutButton(timeButtons[i]);
LayoutManager.gamemode.state = 0x4;
if (NEIClientUtils.getGamemode() != 0) {
LayoutManager.gamemode.state |= 0x1;
LayoutManager.gamemode.index = NEIClientUtils.getGamemode() - 1;
} else {
if (NEIClientUtils.isValidGamemode("creative")) {
LayoutManager.gamemode.index = 0;
} else if (NEIClientUtils.isValidGamemode("creative+")) {
LayoutManager.gamemode.index = 1;
} else if (NEIClientUtils.isValidGamemode("adventure")) {
LayoutManager.gamemode.index = 2;
}
}
if (canPerformAction("heal")) layoutButton(heal);
LayoutManager.bookmarksButton.index = NEIClientConfig.isBookmarkPanelHidden() ? 0 : 1;
LayoutManager.options.index = NEIClientConfig.getCheatMode();
itemPanel.resize(gui);
bookmarkPanel.resize(gui);
itemZoom.resize(gui);
LayoutManager.magnet.state = 0x4 | (NEIClientConfig.getMagnetMode() ? 1 : 0);
options.x = isEnabled() ? 0 : 6;
options.y = isEnabled() ? gui.height - 22 : gui.height - 28;
options.w = 22;
options.h = 22;
if (NEIClientConfig.canPerformAction("delete")) {
layoutButton(LayoutManager.delete);
}
bookmarksButton.x = 24 + (isEnabled() ? 0 : 6);
bookmarksButton.y = isEnabled() ? gui.height - 22 : gui.height - 28;
bookmarksButton.w = 22;
bookmarksButton.h = 22;
if (NEIClientConfig.canPerformAction("rain")) {
layoutButton(LayoutManager.rain);
}
dropDown.h = 18;
dropDown.w = 150;
dropDown.y = 0;
dropDown.x = (gui.width - gui.xSize) / 2 + gui.xSize - dropDown.w;
if (NEIClientUtils.isValidGamemode("creative") || NEIClientUtils.isValidGamemode("creative+")
|| NEIClientUtils.isValidGamemode("adventure")) {
layoutButton(LayoutManager.gamemode);
}
searchField.h = 20;
if (NEIClientConfig.isSearchWidgetCentered()) {
searchField.w = 150;
searchField.x = (gui.width - searchField.w) / 2;
if (NEIClientConfig.canPerformAction("magnet")) {
layoutButton(LayoutManager.magnet);
}
if (NEIClientConfig.canPerformAction("time")) {
for (int i = 0; i < 4; i++) {
LayoutManager.timeButtons[i].state = NEIClientConfig.disabledActions.contains(NEIActions.timeZones[i])
? 2
: 0;
layoutButton(LayoutManager.timeButtons[i]);
}
}
if (NEIClientConfig.canPerformAction("heal")) {
layoutButton(LayoutManager.heal);
}
layoutFooter(gui, visiblity);
LayoutManager.itemPanel.resize(gui);
LayoutManager.bookmarkPanel.resize(gui);
LayoutManager.itemZoom.resize(gui);
}
protected void layoutFooter(GuiContainer gui, VisiblityData visiblity) {
LayoutManager.options.x = MARGIN;
LayoutManager.options.y = gui.height - BUTTON_SIZE - MARGIN;
LayoutManager.options.w = LayoutManager.options.h = BUTTON_SIZE;
LayoutManager.bookmarksButton.x = LayoutManager.options.x + LayoutManager.options.w + MARGIN;
LayoutManager.bookmarksButton.y = gui.height - BUTTON_SIZE - MARGIN;
LayoutManager.bookmarksButton.w = LayoutManager.bookmarksButton.h = BUTTON_SIZE;
final Rectangle4i searchArea = getSearchFieldArea(gui);
final Rectangle4i quantityArea = getQuantityFieldArea(visiblity);
LayoutManager.searchField.x = searchArea.x;
LayoutManager.searchField.y = searchArea.y;
LayoutManager.searchField.w = searchArea.w;
LayoutManager.searchField.h = searchArea.h;
if (!NEIClientConfig.subsetWidgetOnTop() && visiblity.showSubsetDropdown) {
LayoutManager.dropDown.x = searchArea.x;
LayoutManager.dropDown.y = searchArea.y;
LayoutManager.dropDown.h = LayoutManager.dropDown.w = BUTTON_SIZE;
LayoutManager.searchField.x += BUTTON_SIZE;
LayoutManager.searchField.w -= BUTTON_SIZE;
} else {
searchField.w = (int) (itemPanel.w * (NEIClientConfig.showItemQuantityWidget() ? 0.7 : 1));
searchField.x = itemPanel.x;
LayoutManager.dropDown.h = 16;
LayoutManager.dropDown.w = 150;
LayoutManager.dropDown.y = MARGIN;
LayoutManager.dropDown.x = (gui.width - LayoutManager.dropDown.w) / 2;
}
searchField.y = gui.height - searchField.h - 2;
if (!visiblity.showItemSection) {
searchField.setFocus(false);
if (quantityArea.w == ItemPanels.itemPanel.w) {
LayoutManager.more.w = LayoutManager.less.w = BUTTON_SIZE;
LayoutManager.more.h = LayoutManager.less.h = LayoutManager.quantity.h = quantityArea.h;
LayoutManager.more.y = LayoutManager.less.y = LayoutManager.quantity.y = quantityArea.y;
LayoutManager.less.x = quantityArea.x;
LayoutManager.more.x = quantityArea.x2() - BUTTON_SIZE;
LayoutManager.quantity.x = LayoutManager.less.x + LayoutManager.less.w + 1;
LayoutManager.quantity.w = LayoutManager.more.x - LayoutManager.quantity.x - 1;
} else {
LayoutManager.quantity.x = quantityArea.x;
LayoutManager.quantity.w = quantityArea.w - 18;
LayoutManager.quantity.y = LayoutManager.more.y = quantityArea.y;
LayoutManager.quantity.h = quantityArea.h;
LayoutManager.more.w = LayoutManager.less.w = 18;
LayoutManager.more.x = LayoutManager.less.x = LayoutManager.quantity.x + LayoutManager.quantity.w;
LayoutManager.more.h = LayoutManager.less.h = LayoutManager.quantity.h / 2;
LayoutManager.less.y = LayoutManager.more.y + LayoutManager.more.h;
}
}
private Rectangle4i getSearchFieldArea(GuiContainer gui) {
final Rectangle4i area = new Rectangle4i(0, 0, 0, BUTTON_SIZE);
if (NEIClientConfig.isSearchWidgetCentered()) {
area.w = gui.xSize - MARGIN * 2;
area.x = (gui.width - area.w) / 2;
area.y = gui.height - BUTTON_SIZE - MARGIN;
} else if (NEIClientConfig.showItemQuantityWidget()) {
area.w = ItemPanels.itemPanel.w - (int) Math.max(BUTTON_SIZE * 2.5f, ItemPanels.itemPanel.w * 0.3f) - 1;
area.x = ItemPanels.itemPanel.x;
area.y = ItemPanels.itemPanel.y + ItemPanels.itemPanel.h - BUTTON_SIZE;
} else {
area.w = ItemPanels.itemPanel.w;
area.x = ItemPanels.itemPanel.x;
area.y = ItemPanels.itemPanel.y + ItemPanels.itemPanel.h - BUTTON_SIZE;
}
return area;
}
private Rectangle4i getQuantityFieldArea(VisiblityData visiblity) {
final Rectangle4i area = new Rectangle4i(0, 0, 0, BUTTON_SIZE);
if (!visiblity.showSearchSection || NEIClientConfig.isSearchWidgetCentered()) {
area.w = ItemPanels.itemPanel.w;
area.x = ItemPanels.itemPanel.x;
} else {
area.w = (int) Math.max(BUTTON_SIZE * 2.5f, ItemPanels.itemPanel.w * 0.3f);
area.x = ItemPanels.itemPanel.x + ItemPanels.itemPanel.w - area.w;
}
area.y = ItemPanels.itemPanel.y + ItemPanels.itemPanel.h - BUTTON_SIZE;
return area;
}
public void layoutButton(Button button) {
button.x = 2 + (buttonCount % numButtons) * 19;
button.y = 2 + (buttonCount / numButtons) * 18;
button.h = 17;
button.w = button.contentWidth() + 6;
button.x = MARGIN + (buttonCount % numButtons) * (button.w + MARGIN);
button.y = MARGIN + (buttonCount / numButtons) * (button.h + MARGIN);
buttonCount++;
}
@@ -177,9 +257,16 @@ public class LayoutStyleMinecraft extends LayoutStyle {
@Override
public void drawSubsetTag(String text, int x, int y, int w, int h, int state, boolean mouseover) {
if (state == 1) GL11.glColor4f(0.65F, 0.65F, 0.65F, 1.0F);
else GL11.glColor4f(1, 1, 1, 1);
if (state == 1) {
GL11.glColor4f(0.65F, 0.65F, 0.65F, 1.0F);
} else {
GL11.glColor4f(1, 1, 1, 1);
}
LayoutManager.drawButtonBackground(x, y, w, h, false, state == 0 ? 0 : 1);
if (text != null) drawStringC(text, x, y, w, h, state == 2 ? 0xFFE0E0E0 : 0xFFA0A0A0);
if (text != null) {
drawStringC(text, x, y, w, h, mouseover ? 0xFFFFFFA0 : (state == 2 ? 0xFFE0E0E0 : 0xFFA0A0A0));
}
}
}
+360 -201
View File
@@ -6,6 +6,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.regex.Pattern;
@@ -24,9 +25,11 @@ import org.apache.logging.log4j.Logger;
import org.lwjgl.input.Keyboard;
import com.google.common.base.Objects;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.JsonParseException;
import codechicken.core.CCUpdateChecker;
import codechicken.core.ClassDiscoverer;
import codechicken.core.ClientUtils;
import codechicken.core.CommonUtils;
import codechicken.lib.config.ConfigFile;
@@ -75,12 +78,6 @@ public class NEIClientConfig {
public static ConfigSet world;
public static final File handlerFile = new File(configDir, "handlers.csv");
public static final File catalystFile = new File(configDir, "catalysts.csv");
public static final File serialHandlersFile = new File(configDir, "serialhandlers.cfg");
public static final File heightHackHandlersFile = new File(configDir, "heighthackhandlers.cfg");
public static final File handlerOrderingFile = new File(configDir, "handlerordering.csv");
public static final File hiddenHandlersFile = new File(configDir, "hiddenhandlers.csv");
public static final File enableAutoFocusFile = new File(configDir, "enableautofocus.cfg");
public static final File collapsibleItemsFile = new File(configDir, "collapsibleitems.cfg");
@Deprecated
public static File bookmarkFile;
@@ -100,6 +97,8 @@ public class NEIClientConfig {
// Any handler not in the map will be assigned to 0, and negative numbers are fine.
public static HashMap<String, Integer> handlerOrdering = new HashMap<>();
public static final Set<Class<?>> pluginsList = new HashSet<>();
// Function that extracts the handler ID from a handler, with special logic for
// TemplateRecipeHandler: prefer using the overlay ID if it exists.
public static final Function<IRecipeHandler, String> HANDLER_ID_FUNCTION = handler -> Objects
@@ -158,7 +157,7 @@ public class NEIClientConfig {
return getLockedMode() == -1 || getLockedMode() == index && NEIInfo.isValidMode(index);
}
});
checkCheatMode();
canChangeCheatMode();
tag.getTag("inventory.utilities").setDefaultValue("delete, magnet");
API.addOption(new OptionUtilities("inventory.utilities"));
@@ -167,76 +166,7 @@ public class NEIClientConfig {
API.addOption(new OptionGamemodes("inventory.gamemodes"));
ItemSorter.initConfig(tag);
tag.getTag("inventory.search.widgetPosition").setComment("Widget Position").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.search.widgetPosition", true));
tag.getTag("inventory.search.widgetAutofocus")
.setComment(
"Focus Search Widget on Open, blurs/unfocuses on mouse move unless typing has started first")
.getIntValue(0);
API.addOption(new OptionCycled("inventory.search.widgetAutofocus", 3, true));
tag.getTag("inventory.search.patternMode").setComment("Search Mode").getIntValue(1);
API.addOption(new OptionCycled("inventory.search.patternMode", 3, true));
tag.getTag("inventory.search.quoteDropItemName").setComment("Quote Drop Item Name").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.search.quoteDropItemName", true));
tag.getTag("inventory.search.modNameSearchMode").setComment("Search mode for Mod Names (prefix: @)")
.getIntValue(1);
API.addOption(new OptionCycled("inventory.search.modNameSearchMode", 3, true) {
@Override
public String getButtonText() {
return translateN(name + "." + value(), EnumChatFormatting.LIGHT_PURPLE + "@");
}
});
tag.getTag("inventory.search.tooltipSearchMode").setComment("Search mode for Tooltips (prefix: #)")
.getIntValue(0);
API.addOption(new OptionCycled("inventory.search.tooltipSearchMode", 3, true) {
@Override
public String getButtonText() {
return translateN(name + "." + value(), EnumChatFormatting.YELLOW + "#");
}
});
tag.getTag("inventory.search.identifierSearchMode").setComment("Search mode for identifier (prefix: &)")
.getIntValue(0);
API.addOption(new OptionCycled("inventory.search.identifierSearchMode", 3, true) {
@Override
public String getButtonText() {
return translateN(name + "." + value(), EnumChatFormatting.GOLD + "&");
}
});
tag.getTag("inventory.search.oreDictSearchMode").setComment("Search mode for Tag Names (prefix: $)")
.getIntValue(0);
API.addOption(new OptionCycled("inventory.search.oreDictSearchMode", 3, true) {
@Override
public String getButtonText() {
return translateN(name + "." + value(), EnumChatFormatting.AQUA + "$");
}
});
tag.getTag("inventory.search.subsetsSearchMode").setComment("Search mode for Item Subsets (prefix: %)")
.getIntValue(2);
API.addOption(new OptionCycled("inventory.search.subsetsSearchMode", 3, true) {
@Override
public String getButtonText() {
return translateN(name + "." + value(), EnumChatFormatting.DARK_PURPLE + "%");
}
});
setInventorySearchDefaults(tag);
tag.getTag("inventory.bookmarks.enabled").setComment("Enable/Disable Bookmark Panel").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.bookmarks.enabled", true));
@@ -248,7 +178,7 @@ public class NEIClientConfig {
@Override
public boolean onClick(int button) {
super.onClick(button);
initBookmarkFile(worldPath);
ItemPanels.bookmarkPanel.load();
return true;
}
});
@@ -303,6 +233,12 @@ public class NEIClientConfig {
.setComment("Require holding shift to move items when overlaying recipe").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.guirecipe.shiftOverlayRecipe", true));
tag.getTag("inventory.subsets.enabled").setComment("Enable/disable Subsets Dropdown").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.subsets.enabled", true));
tag.getTag("inventory.subsets.widgetPosition").setComment("Subsets Widget Position").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.subsets.widgetPosition", true));
tag.getTag("inventory.guirecipe.profile").getBooleanValue(false);
API.addOption(new OptionToggleButton("inventory.guirecipe.profile", true));
@@ -311,7 +247,7 @@ public class NEIClientConfig {
tag.getTag("inventory.history.historyColor").setComment("Color of the history area display")
.getHexValue(0xee555555);
API.addOption(new OptionIntegerField("inventory.history.historyColor"));
API.addOption(new OptionIntegerField("inventory.history.historyColor", 0, OptionIntegerField.UNSIGNED_INT_MAX));
tag.getTag("inventory.history.useRows").setComment("Rows used in historical areas").getIntValue(2);
API.addOption(new OptionIntegerField("inventory.history.useRows", 1, 5));
@@ -324,8 +260,11 @@ public class NEIClientConfig {
@Override
public boolean onClick(int button) {
super.onClick(button);
CollapsibleItems.saveStates();
CollapsibleItems.load();
LayoutManager.markItemsDirty();
return super.onClick(button);
return true;
}
});
@@ -334,11 +273,19 @@ public class NEIClientConfig {
tag.getTag("inventory.collapsibleItems.expandedColor")
.setComment("Color of the collapsible item expanded state").getHexValue(0x335555EE);
API.addOption(new OptionIntegerField("inventory.collapsibleItems.expandedColor"));
API.addOption(
new OptionIntegerField(
"inventory.collapsibleItems.expandedColor",
0,
OptionIntegerField.UNSIGNED_INT_MAX));
tag.getTag("inventory.collapsibleItems.collapsedColor")
.setComment("Color of the collapsible item collapsed state").getHexValue(0x335555EE);
API.addOption(new OptionIntegerField("inventory.collapsibleItems.collapsedColor"));
API.addOption(
new OptionIntegerField(
"inventory.collapsibleItems.collapsedColor",
0,
OptionIntegerField.UNSIGNED_INT_MAX));
API.addOption(
new OptionButton(
@@ -376,7 +323,7 @@ public class NEIClientConfig {
API.addOption(new OptionToggleButton("inventory.itemzoom.showName", true));
tag.getTag("inventory.itemzoom.nameColor").getHexValue(0xFFFFFFFF);
API.addOption(new OptionIntegerField("inventory.itemzoom.nameColor"));
API.addOption(new OptionIntegerField("inventory.itemzoom.nameColor", 0, OptionIntegerField.UNSIGNED_INT_MAX));
tag.getTag("inventory.itemIDs").getIntValue(1);
API.addOption(new OptionCycled("inventory.itemIDs", 3, true));
@@ -412,8 +359,10 @@ public class NEIClientConfig {
}
});
tag.getTag("inventory.cacheItemRendering").getBooleanValue(false);
API.addOption(new OptionToggleButton("inventory.cacheItemRendering", true));
tag.getTag("inventory.gridRenderingCacheFPS").getIntValue(8);
tag.getTag("inventory.gridRenderingCacheMode").getIntValue(0);
API.addOption(new OptionCycled("inventory.gridRenderingCacheMode", 3, true));
tag.getTag("itemLoadingTimeout").getIntValue(500);
@@ -428,18 +377,6 @@ public class NEIClientConfig {
tag.getTag("command.heal").setDefaultValue("");
API.addOption(new OptionTextField("command.heal"));
tag.getTag("inventory.worldSpecificPresets").setComment("Global or world specific presets")
.getBooleanValue(false);
API.addOption(new OptionToggleButton("inventory.worldSpecificPresets", true) {
@Override
public boolean onClick(int button) {
super.onClick(button);
initPresetsFile(worldPath);
return true;
}
});
tag.getTag("inventory.showItemQuantityWidget").setComment("Show Item Quantity Widget").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.showItemQuantityWidget", true));
@@ -499,6 +436,237 @@ public class NEIClientConfig {
});
}
private static void setInventorySearchDefaults(ConfigTagParent tag) {
tag.getTag("inventory.search.widgetPosition").setComment("Widget Position").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.search.widgetPosition", true));
tag.getTag("inventory.search.hideUntilSearching").setComment("Hide Items Until Searching")
.getBooleanValue(false);
API.addOption(new OptionToggleButton("inventory.search.hideUntilSearching", true) {
@Override
public boolean onClick(int button) {
super.onClick(button);
ItemList.updateFilter.restart();
return true;
}
});
tag.getTag("inventory.search.widgetAutofocus")
.setComment(
"Focus Search Widget on Open, blurs/unfocuses on mouse move unless typing has started first")
.getIntValue(0);
API.addOption(new OptionCycled("inventory.search.widgetAutofocus", 3, true));
tag.getTag("inventory.search.patternMode").setComment("Search Mode").getIntValue(1);
API.addOption(new OptionCycled("inventory.search.patternMode", 3, true) {
@Override
public boolean onClick(int button) {
SearchField.searchParser.clearCache();
return super.onClick(button);
}
});
tag.getTag("inventory.search.quoteDropItemName").setComment("Quote Drop Item Name").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.search.quoteDropItemName", true));
tag.getTag("inventory.search.format").setComment("Search Format (true: old format, false: custom format)")
.getBooleanValue(false);
API.addOption(new OptionToggleButton("inventory.search.format", true) {
@Override
public boolean onClick(int button) {
if (!super.onClick(button)) {
return false;
}
if (state()) {
NEIClientConfig.setIntSetting("inventory.search.spaceMode", 1);
NEIClientConfig.setIntSetting("inventory.search.modNameSearchMode", 0);
NEIClientConfig.setIntSetting("inventory.search.tooltipSearchMode", 0);
NEIClientConfig.setIntSetting("inventory.search.identifierSearchMode", 0);
NEIClientConfig.setIntSetting("inventory.search.oreDictSearchMode", 0);
NEIClientConfig.setIntSetting("inventory.search.subsetsSearchMode", 1);
tag.getTag("inventory.search.prefixRedefinitions").setValue("{\"%\": \"@\", \"@\": \"%\"}");
SearchField.searchParser.prefixRedefinitions.clear();
SearchField.searchParser.prefixRedefinitions.put('%', '@');
SearchField.searchParser.prefixRedefinitions.put('@', '%');
SearchField.searchParser.clearCache();
} else {
NEIClientConfig.setIntSetting("inventory.search.spaceMode", 0);
NEIClientConfig.setIntSetting("inventory.search.modNameSearchMode", 1);
NEIClientConfig.setIntSetting("inventory.search.tooltipSearchMode", 0);
NEIClientConfig.setIntSetting("inventory.search.identifierSearchMode", 0);
NEIClientConfig.setIntSetting("inventory.search.oreDictSearchMode", 0);
NEIClientConfig.setIntSetting("inventory.search.subsetsSearchMode", 1);
tag.getTag("inventory.search.prefixRedefinitions").setValue("{}");
SearchField.searchParser.prefixRedefinitions.clear();
SearchField.searchParser.clearCache();
}
return true;
}
});
tag.getTag("inventory.search.spaceMode").setComment("Search Space Rules").getIntValue(0);
API.addOption(new OptionCycled("inventory.search.spaceMode", 3, true) {
@Override
public boolean onClick(int button) {
// SearchField.searchParser.clearCache();
return super.onClick(button);
}
@Override
public boolean isEnabled() {
return !tag.getTag("inventory.search.format").getBooleanValue();
}
});
tag.getTag("inventory.search.modNameSearchMode").setComment("Search mode for Mod Names (prefix: @)")
.getIntValue(1);
API.addOption(new OptionCycled("inventory.search.modNameSearchMode", 3, true) {
@Override
public boolean onClick(int button) {
SearchField.searchParser.clearCache();
return super.onClick(button);
}
@Override
public String getButtonText() {
return translateN(
name + "." + value(),
EnumChatFormatting.LIGHT_PURPLE
+ String.valueOf(SearchField.searchParser.getRedefinedPrefix('@')));
}
@Override
public boolean isEnabled() {
return !tag.getTag("inventory.search.format").getBooleanValue();
}
});
tag.getTag("inventory.search.tooltipSearchMode").setComment("Search mode for Tooltips (prefix: #)")
.getIntValue(0);
API.addOption(new OptionCycled("inventory.search.tooltipSearchMode", 3, true) {
@Override
public boolean onClick(int button) {
SearchField.searchParser.clearCache();
return super.onClick(button);
}
@Override
public String getButtonText() {
return translateN(
name + "." + value(),
EnumChatFormatting.YELLOW + String.valueOf(SearchField.searchParser.getRedefinedPrefix('#')));
}
@Override
public boolean isEnabled() {
return !tag.getTag("inventory.search.format").getBooleanValue();
}
});
tag.getTag("inventory.search.identifierSearchMode").setComment("Search mode for identifier (prefix: &)")
.getIntValue(0);
API.addOption(new OptionCycled("inventory.search.identifierSearchMode", 3, true) {
@Override
public boolean onClick(int button) {
SearchField.searchParser.clearCache();
return super.onClick(button);
}
@Override
public String getButtonText() {
return translateN(
name + "." + value(),
EnumChatFormatting.GOLD + String.valueOf(SearchField.searchParser.getRedefinedPrefix('&')));
}
@Override
public boolean isEnabled() {
return !tag.getTag("inventory.search.format").getBooleanValue();
}
});
tag.getTag("inventory.search.oreDictSearchMode").setComment("Search mode for Tag Names (prefix: $)")
.getIntValue(0);
API.addOption(new OptionCycled("inventory.search.oreDictSearchMode", 3, true) {
@Override
public boolean onClick(int button) {
SearchField.searchParser.clearCache();
return super.onClick(button);
}
@Override
public String getButtonText() {
return translateN(
name + "." + value(),
EnumChatFormatting.AQUA + String.valueOf(SearchField.searchParser.getRedefinedPrefix('$')));
}
@Override
public boolean isEnabled() {
return !tag.getTag("inventory.search.format").getBooleanValue();
}
});
tag.getTag("inventory.search.subsetsSearchMode").setComment("Search mode for Item Subsets (prefix: %)")
.getIntValue(1);
API.addOption(new OptionCycled("inventory.search.subsetsSearchMode", 3, true) {
@Override
public boolean onClick(int button) {
SearchField.searchParser.clearCache();
return super.onClick(button);
}
@Override
public String getButtonText() {
return translateN(
name + "." + value(),
EnumChatFormatting.DARK_PURPLE
+ String.valueOf(SearchField.searchParser.getRedefinedPrefix('%')));
}
@Override
public boolean isEnabled() {
return !tag.getTag("inventory.search.format").getBooleanValue();
}
});
String prefixRedefinitions = tag.getTag("inventory.search.prefixRedefinitions").setComment(
"Redefine search prefixes by providing a char-to-char map (JSON). The keys are the original prefixes, the values the new ones. Example: { \"$\": \"€\", \"#\": \"+\", \"@\": \"°\", \"%\": \"!\" }")
.getValue("{}");
try {
TypeToken<Map<Character, Character>> typeToken = new TypeToken<Map<Character, Character>>() {
private static final long serialVersionUID = 1L;
};
Map<Character, Character> charMap = new Gson().fromJson(prefixRedefinitions, typeToken.getType());
SearchField.searchParser.prefixRedefinitions.putAll(charMap);
} catch (JsonParseException e) {
logger.warn("Failed to convert prefix redefinitions from JSON to CharToCharMap:", e);
}
}
private static void setDefaultKeyBindings() {
API.addHashBind("gui.recipe", Keyboard.KEY_R);
API.addHashBind("gui.usage", Keyboard.KEY_U);
@@ -554,23 +722,29 @@ public class NEIClientConfig {
}
public static void loadWorld(String worldPath) {
NEIClientConfig.worldPath = worldPath;
unloadWorld();
setInternalEnabled(true);
logger.debug("Loading " + (Minecraft.getMinecraft().isSingleplayer() ? "Local" : "Remote") + " World");
bootNEI(ClientUtils.getWorld());
final File specificDir = new File(CommonUtils.getMinecraftDir(), "saves/NEI/" + worldPath);
final boolean newWorld = !specificDir.exists();
if (!worldPath.equals(NEIClientConfig.worldPath)) {
NEIClientConfig.worldPath = worldPath;
if (newWorld) {
specificDir.mkdirs();
logger.debug("Loading " + (Minecraft.getMinecraft().isSingleplayer() ? "Local" : "Remote") + " World");
final File specificDir = new File(CommonUtils.getMinecraftDir(), "saves/NEI/" + worldPath);
final boolean newWorld = !specificDir.exists();
if (newWorld) {
specificDir.mkdirs();
}
world = new ConfigSet(new File(specificDir, "NEI.dat"), new ConfigFile(new File(specificDir, "NEI.cfg")));
bootNEI(ClientUtils.getWorld());
onWorldLoad(newWorld);
}
}
world = new ConfigSet(new File(specificDir, "NEI.dat"), new ConfigFile(new File(specificDir, "NEI.cfg")));
initBookmarkFile(worldPath);
initPresetsFile(worldPath);
onWorldLoad(newWorld);
public static String getWorldPath() {
return NEIClientConfig.worldPath;
}
private static void onWorldLoad(boolean newWorld) {
@@ -580,11 +754,12 @@ public class NEIClientConfig {
setWorldDefaults();
creativeInv = new ItemStack[54];
LayoutManager.searchField.setText(getSearchExpression());
ItemPanels.itemPanel.quantity.setText(Integer.toString(getItemQuantity()));
SubsetWidget.loadHidden();
LayoutManager.quantity.setText(Integer.toString(getItemQuantity()));
if (newWorld && Minecraft.getMinecraft().isSingleplayer()) world.config.getTag("inventory.cheatmode")
.setIntValue(NEIClientUtils.mc().playerController.isInCreativeMode() ? 2 : 0);
if (newWorld && Minecraft.getMinecraft().isSingleplayer()) {
world.config.getTag("inventory.cheatmode")
.setIntValue(NEIClientUtils.mc().playerController.isInCreativeMode() ? 2 : 0);
}
NEIInfo.load(ClientUtils.getWorld());
}
@@ -603,6 +778,9 @@ public class NEIClientConfig {
ItemPanels.bookmarkPanel.saveBookmarks();
}
SubsetWidget.saveHidden();
CollapsibleItems.saveStates();
if (world != null) {
world.saveNBT();
}
@@ -624,102 +802,66 @@ public class NEIClientConfig {
return hash != Keyboard.CHAR_NONE && hash == NEIClientUtils.getKeyHash();
}
public static String getKeyName(int keyBind, boolean useHash) {
return getKeyName(keyBind, useHash, false);
}
public static String getKeyName(String keyBind) {
final int hash = getKeyBinding(keyBind);
public static String getKeyName(int keyBind, boolean useHash, boolean showOnlyHash) {
String keyText = "";
if (useHash) {
final String DELIMITER = " + ";
if ((keyBind & NEIClientUtils.CTRL_HASH) != 0) {
keyText += NEIClientUtils.translate(Minecraft.isRunningOnMac ? "key.ctrl.mac" : "key.ctrl") + DELIMITER;
}
if ((keyBind & NEIClientUtils.SHIFT_HASH) != 0) {
keyText += "SHIFT" + DELIMITER;
}
if ((keyBind & NEIClientUtils.ALT_HASH) != 0) {
keyText += "ALT" + DELIMITER;
}
if (hash == Keyboard.CHAR_NONE) {
return null;
}
if (!showOnlyHash) {
keyText += Keyboard.getKeyName(unHashKey(keyBind));
}
return keyText;
}
public static int unHashKey(int keyBind) {
return keyBind & ~(NEIClientUtils.CTRL_HASH | NEIClientUtils.SHIFT_HASH | NEIClientUtils.ALT_HASH);
return NEIClientUtils.getKeyName(hash);
}
public static void bootNEI(World world) {
if (mainNEIConfigLoaded) return;
if (!mainNEIConfigLoaded) {
// main NEI config loading
ItemInfo.load(world);
GuiInfo.load();
RecipeInfo.load();
HeldItemHandler.load();
LayoutManager.load();
NEIController.load();
BookmarkContainerInfo.load();
mainNEIConfigLoaded = true;
// main NEI config loading
ItemInfo.load(world);
GuiInfo.load();
RecipeInfo.load();
HeldItemHandler.load();
LayoutManager.load();
NEIController.load();
BookmarkContainerInfo.load();
mainNEIConfigLoaded = true;
new Thread("NEI Plugin Loader") {
new Thread("NEI Plugin Loader") {
@Override
public void run() {
@Override
public void run() {
logger.debug("Started NEI plugin loading");
ClassDiscoverer classDiscoverer = new ClassDiscoverer(
test -> test.startsWith("NEI") && test.endsWith("Config.class"),
IConfigureNEI.class);
NEIClientConfig.pluginsList.parallelStream().forEach(clazz -> {
try {
IConfigureNEI config = (IConfigureNEI) clazz.getConstructor().newInstance();
config.loadConfig();
NEIModContainer.plugins.add(config);
logger.debug("Loaded {}", clazz.getName());
} catch (Throwable e) {
logger.error("Failed to Load {}", clazz.getName(), e);
}
});
classDiscoverer.findClasses();
RecipeCatalysts.loadCatalystInfo();
ItemPanels.bookmarkPanel.load();
SubsetWidget.loadHidden();
CollapsibleItems.load();
ItemSorter.loadConfig();
for (Class<?> clazz : classDiscoverer.classes) {
try {
IConfigureNEI config = (IConfigureNEI) clazz.newInstance();
config.loadConfig();
NEIModContainer.plugins.add(config);
logger.debug("Loaded " + clazz.getName());
} catch (Exception e) {
logger.error("Failed to Load " + clazz.getName(), e);
}
// Set pluginNEIConfigLoaded here before posting the NEIConfigsLoadedEvent. This used to be the
// other way around, but apparently if your modpack includes 800 mods the event poster might not
// return in time and cause issues when loading a world for a second time as configLoaded is still
// false. This may cause issues in case one of the event handler calls the (non-thread-safe) NEI
// 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());
ItemList.loadItems.restart();
}
RecipeCatalysts.loadCatalystInfo();
// Set pluginNEIConfigLoaded here before posting the NEIConfigsLoadedEvent. This used to be the other
// way around, but apparently if your modpack includes 800 mods the event poster might not return in
// time and cause issues when loading a world for a second time as configLoaded is still false. This may
// cause issues in case one of the event handler calls the (non-thread-safe) NEI API. I don't expect any
// handler to do this, but who knows what modders have come up with...
pluginNEIConfigLoaded = true;
logger.debug("NEI plugin loading finished");
MinecraftForge.EVENT_BUS.post(new NEIConfigsLoadedEvent());
}
}.start();
ItemSorter.loadConfig();
}
private static void initBookmarkFile(String worldPath) {
if (!global.config.getTag("inventory.bookmarks.worldSpecific").getBooleanValue()) {
worldPath = "global";
}.start();
} else {
ItemPanels.bookmarkPanel.load();
SubsetWidget.loadHidden();
ItemList.loadItems.restart();
}
ItemPanels.bookmarkPanel.setBookmarkFile(worldPath);
}
private static void initPresetsFile(String worldPath) {
if (!global.config.getTag("inventory.worldSpecificPresets").getBooleanValue()) {
worldPath = "global";
}
PresetsList.setPresetsFile(worldPath);
}
public static boolean isWorldSpecific(String setting) {
@@ -760,10 +902,22 @@ public class NEIClientConfig {
return getBooleanSetting("inventory.showItemQuantityWidget");
}
public static boolean hideItemsUntilSearching() {
return getBooleanSetting("inventory.search.hideUntilSearching");
}
public static boolean isSearchWidgetCentered() {
return getBooleanSetting("inventory.search.widgetPosition");
}
public static boolean showSubsetWidget() {
return getBooleanSetting("inventory.subsets.enabled");
}
public static boolean subsetWidgetOnTop() {
return getBooleanSetting("inventory.subsets.widgetPosition");
}
public static int searchWidgetAutofocus() {
return getIntSetting("inventory.search.widgetAutofocus");
}
@@ -844,8 +998,13 @@ public class NEIClientConfig {
return getIntSetting("inventory.cheatmode");
}
private static void checkCheatMode() {
if (getLockedMode() != -1) setIntSetting("inventory.cheatmode", getLockedMode());
public static boolean canChangeCheatMode() {
if (getLockedMode() != -1) {
setIntSetting("inventory.cheatmode", getLockedMode());
return false;
}
return true;
}
public static int getLockedMode() {
@@ -907,8 +1066,8 @@ public class NEIClientConfig {
return getBooleanSetting("inventory.history.enabled");
}
public static boolean shouldCacheItemRendering() {
return getBooleanSetting("inventory.cacheItemRendering") && OpenGlHelper.framebufferSupported;
public static int getGridRenderingCacheMode() {
return OpenGlHelper.framebufferSupported ? getIntSetting("inventory.gridRenderingCacheMode") : 0;
}
public static boolean enableCollapsibleItems() {
@@ -25,6 +25,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.StringJoiner;
import java.util.stream.Collectors;
import net.minecraft.client.Minecraft;
@@ -36,8 +37,6 @@ import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ChatComponentTranslation;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IChatComponent;
import net.minecraft.util.ResourceLocation;
@@ -58,11 +57,26 @@ public class NEIClientUtils extends NEIServerUtils {
/** Formats a number with group separator and at most 2 fraction digits. */
private static final Map<Locale, DecimalFormat> decimalFormatters = new HashMap<>();
private static final Map<Integer, Integer> keyHashMap = new HashMap<>();
public static final int ALT_HASH = 1 << 27;
public static final int SHIFT_HASH = 1 << 26;
public static final int CTRL_HASH = 1 << 25;
static {
keyHashMap.put(Keyboard.KEY_LSHIFT, SHIFT_HASH);
keyHashMap.put(Keyboard.KEY_RSHIFT, SHIFT_HASH);
keyHashMap.put(Keyboard.KEY_LCONTROL, CTRL_HASH);
keyHashMap.put(Keyboard.KEY_LCONTROL, CTRL_HASH);
keyHashMap.put(Keyboard.KEY_LMETA, CTRL_HASH);
keyHashMap.put(Keyboard.KEY_RMETA, CTRL_HASH);
keyHashMap.put(Keyboard.KEY_LMENU, ALT_HASH);
keyHashMap.put(Keyboard.KEY_LMENU, ALT_HASH);
}
public static Minecraft mc() {
return Minecraft.getMinecraft();
}
@@ -308,7 +322,7 @@ public class NEIClientUtils extends NEIServerUtils {
}
public static void sendCommand(String command, Object... args) {
if (command.length() == 0) return;
if (command.isEmpty()) return;
NumberFormat numberformat = NumberFormat.getIntegerInstance();
numberformat.setGroupingUsed(false);
@@ -438,11 +452,7 @@ public class NEIClientUtils extends NEIServerUtils {
if (Keyboard.getEventKeyState()) {
final int keycode = Keyboard.getEventKey();
if (keycode != Keyboard.KEY_LSHIFT && keycode != Keyboard.KEY_RSHIFT
&& keycode != Keyboard.KEY_LCONTROL
&& keycode != Keyboard.KEY_RCONTROL
&& keycode != Keyboard.KEY_LMENU
&& keycode != Keyboard.KEY_RMENU) {
if (!keyHashMap.containsKey(keycode)) {
return getMetaHash() + keycode;
}
}
@@ -450,6 +460,45 @@ public class NEIClientUtils extends NEIServerUtils {
return Keyboard.CHAR_NONE;
}
public static String getKeyHashName(int keyBind) {
StringJoiner keyText = new StringJoiner(" + ");
if ((keyBind & CTRL_HASH) != 0) {
keyText.add(translate(Minecraft.isRunningOnMac ? "key.ctrl.mac" : "key.ctrl"));
}
if ((keyBind & SHIFT_HASH) != 0) {
keyText.add(translate("key.shift"));
}
if ((keyBind & ALT_HASH) != 0) {
keyText.add(translate("key.alt"));
}
return keyText.toString();
}
public static String getKeyName(int keyBind) {
keyBind = keyHashMap.getOrDefault(keyBind, keyBind);
StringJoiner keyText = new StringJoiner(" + ");
String hashText = getKeyHashName(keyBind);
int keyID = unHashKey(keyBind);
if (!hashText.isEmpty()) {
keyText.add(hashText);
}
if (keyID != Keyboard.CHAR_NONE || hashText.isEmpty()) {
keyText.add(Keyboard.getKeyName(keyID));
}
return keyText.toString();
}
public static int unHashKey(int keyBind) {
return keyBind & ~(CTRL_HASH | SHIFT_HASH | ALT_HASH);
}
public static void playClickSound() {
mc().getSoundHandler()
.playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), 1.0F));
@@ -461,16 +510,9 @@ public class NEIClientUtils extends NEIServerUtils {
String stackTrace = cause + sw;
if (buffer.contains(stackTrace)) return;
System.err.println("Error while rendering: " + cause);
System.err.println("Error while rendering: " + cause + " (" + e.getMessage() + ")");
e.printStackTrace();
buffer.add(stackTrace);
EntityPlayer player = Minecraft.getMinecraft().thePlayer;
if (player != null) {
IChatComponent chat = new ChatComponentTranslation("nei.chat.render.error");
chat.getChatStyle().setColor(EnumChatFormatting.RED);
player.addChatComponentMessage(chat);
}
}
public static void reportErrorBuffered(Throwable e, Set<String> buffer, ItemStack cause) {
@@ -1,6 +1,7 @@
package codechicken.nei;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
@@ -38,6 +39,7 @@ public class NEIModContainer extends DummyModContainer {
public static LinkedList<IConfigureNEI> plugins = new LinkedList<>();
private static boolean gregTech5Loaded;
private static boolean gtnhLibLoaded;
public NEIModContainer() {
super(getModMetadata());
@@ -59,16 +61,23 @@ public class NEIModContainer extends DummyModContainer {
return gregTech5Loaded;
}
public static boolean isGTNHLibLoaded() {
return gtnhLibLoaded;
}
@Override
public Set<ArtifactVersion> getRequirements() {
Set<ArtifactVersion> deps = new HashSet<>();
deps.add(VersionParser.parseVersionReference("CodeChickenCore@[" + CodeChickenCorePlugin.version + ",)"));
deps.add(VersionParser.parseVersionReference("CodeChickenCore@[" + codechicken.core.asm.Tags.VERSION + ",)"));
return deps;
}
@Override
public List<ArtifactVersion> getDependencies() {
return new LinkedList<>(getRequirements());
List<ArtifactVersion> deps = new ArrayList<>();
deps.add(VersionParser.parseVersionReference("CodeChickenCore@[" + codechicken.core.asm.Tags.VERSION + ",)"));
deps.add(VersionParser.parseVersionReference("gtnhlib@[0.6.0,)"));
return deps;
}
private String description;
@@ -106,6 +115,7 @@ public class NEIModContainer extends DummyModContainer {
@Subscribe
public void preInit(FMLPreInitializationEvent event) {
gregTech5Loaded = Loader.isModLoaded("gregtech") && !Loader.isModLoaded("gregapi_post");
gtnhLibLoaded = Loader.isModLoaded("gtnhlib");
if (CommonUtils.isClient()) ClientHandler.preInit();
}
@@ -127,6 +137,8 @@ public class NEIModContainer extends DummyModContainer {
public void loadComplete(FMLLoadCompleteEvent event) {
if (CommonUtils.isClient()) {
GuiRecipeTab.loadHandlerInfo();
ClientHandler.loadPluginsList();
ClientHandler.loadHandlerOrdering();
}
}
@@ -197,7 +197,7 @@ public class NEIServerConfig {
FileReader r = new FileReader(file);
int line = 0;
for (String s : IOUtils.readLines(r)) {
if (s.charAt(0) == '#' || s.trim().length() == 0) continue;
if (s.charAt(0) == '#' || s.trim().isEmpty()) continue;
int delim = s.lastIndexOf('=');
if (delim < 0) {
logger.error("line " + line + ": Missing =");
@@ -89,9 +89,8 @@ public class NEIServerUtils {
else return player.inventory.getStackInSlot(slot);
}
@SuppressWarnings("unchecked")
public static void deleteAllItems(EntityPlayerMP player) {
for (Slot slot : (List<Slot>) player.openContainer.inventorySlots) slot.putStack(null);
for (Slot slot : player.openContainer.inventorySlots) slot.putStack(null);
player.sendContainerAndContentsToPlayer(player.openContainer, player.openContainer.getInventory());
}
@@ -171,7 +171,7 @@ public abstract class PanelWidget extends Widget implements IContainerTooltipHan
protected abstract int resizeFooter(GuiContainer gui);
public void setVisible() {
if (grid.getPerPage() > 0) {
if (grid.getPerPage() > 0 && !grid.isEmpty()) {
LayoutManager.addWidget(pagePrev);
LayoutManager.addWidget(pageNext);
LayoutManager.addWidget(pageLabel);
@@ -200,6 +200,10 @@ public abstract class PanelWidget extends Widget implements IContainerTooltipHan
@Override
public void mouseDragged(int mousex, int mousey, int button, long heldTime) {
if (mouseDownSlot >= grid.realItems.size()) {
mouseDownSlot = -1;
}
if (mouseDownSlot >= 0 && draggedStack == null
&& NEIClientUtils.getHeldItem() == null
&& NEIClientConfig.hasSMPCounterPart()) {
@@ -1,13 +1,20 @@
package codechicken.nei;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;
import codechicken.nei.ItemList.AllMultiItemFilter;
import codechicken.nei.api.ItemFilter;
import codechicken.nei.api.ItemInfo;
import codechicken.nei.recipe.GuiRecipe;
/**
* Simply an {@link ItemStack} with position. Mainly used in the recipe handlers.
*/
@@ -40,7 +47,7 @@ public class PositionedStack {
public void generatePermutations() {
if (permutated) return;
ArrayList<ItemStack> stacks = new ArrayList<>();
List<ItemStack> stacks = new ArrayList<>();
for (ItemStack item : items) {
if (item == null || item.getItem() == null) continue;
@@ -75,18 +82,60 @@ public class PositionedStack {
}
public PositionedStack copy() {
return new PositionedStack(items, relx, rely);
PositionedStack pStack = new PositionedStack(Arrays.asList(items), relx, rely, false);
pStack.permutated = this.permutated;
return pStack;
}
public List<ItemStack> getFilteredPermutations() {
return getFilteredPermutations(null);
}
public List<ItemStack> getFilteredPermutations(ItemFilter additionalFilter) {
List<ItemStack> items = Arrays.asList(this.items).stream().filter(getItemFilter(additionalFilter)::matches)
.collect(Collectors.toList());
if (items.isEmpty()) {
items.addAll(
Arrays.asList(this.items).stream().filter(item -> !ItemInfo.isHidden(item))
.collect(Collectors.toList()));
}
if (items.isEmpty()) {
items.addAll(Arrays.asList(this.items));
}
return items;
}
private ItemFilter getItemFilter(ItemFilter additionalFilter) {
return new AllMultiItemFilter(
additionalFilter,
item -> !ItemInfo.isHidden(item),
PresetsList.getItemFilter(),
GuiRecipe.getSearchItemFilter());
}
public boolean setPermutationToRender(ItemStack ingredient) {
for (int index = 0; index < this.items.length; index++) {
if (NEIServerUtils.areStacksSameTypeCraftingWithNBT(this.items[index], ingredient)) {
setPermutationToRender(index);
return true;
}
}
return false;
}
public void setPermutationToRender(int index) {
item = items[index].copy();
this.item = this.items[index].copy();
if (item.getItem() == null) {
item = new ItemStack(Blocks.fire);
} else if (item.getItemDamage() == OreDictionary.WILDCARD_VALUE && item.getItem() != null
&& item.getItem().isRepairable()) {
item.setItemDamage(0);
}
if (this.item.getItem() == null) {
this.item = new ItemStack(Blocks.fire);
} else if (this.item.getItemDamage() == OreDictionary.WILDCARD_VALUE && this.item.getItem().isRepairable()) {
this.item.setItemDamage(0);
}
}
public boolean contains(ItemStack ingredient) {
+13 -59
View File
@@ -4,8 +4,6 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashSet;
@@ -34,7 +32,7 @@ import codechicken.nei.util.NBTJson;
public class PresetsList {
public static enum PresetMode {
public enum PresetMode {
HIDE,
REMOVE,
GROUP;
@@ -145,62 +143,20 @@ public class PresetsList {
}
public static final List<Preset> presets = new ArrayList<>();
protected static File presetsFile;
protected static RecipesFilter recipeFilter = new RecipesFilter();
protected static ItemPanelFilter itemFilter = new ItemPanelFilter();
static {
API.addItemFilter(itemFilter);
API.addRecipeFilter(recipeFilter);
ItemList.loadCallbacks.add(PresetsList::itemsLoaded);
}
public static ItemFilter getItemFilter() {
return itemFilter.getFilter();
}
public static void itemsLoaded() {
recipeFilter.cache = null;
itemFilter.cache = null;
ItemList.collapsibleItems.reload();
}
public static void setPresetsFile(String worldPath) {
final File dir = new File(CommonUtils.getMinecraftDir(), "saves/NEI/" + worldPath);
if (!dir.exists()) {
dir.mkdirs();
}
presetsFile = new File(dir, "presets.ini");
if (!presetsFile.exists()) {
final File globalPresets = new File(CommonUtils.getMinecraftDir(), "saves/NEI/global/presets.ini");
final File configPresets = new File(NEIClientConfig.configDir, "presets.ini");
final File defaultBookmarks = configPresets.exists() ? configPresets : globalPresets;
if (defaultBookmarks.exists()) {
try {
presetsFile.createNewFile();
InputStream src = new FileInputStream(defaultBookmarks);
OutputStream dst = new FileOutputStream(presetsFile);
IOUtils.copy(src, dst);
src.close();
dst.close();
} catch (IOException e) {}
}
}
loadPresets();
}
protected static void loadPresets() {
public static void load() {
final File presetsFile = new File(CommonUtils.getMinecraftDir(), "saves/NEI/global/presets.ini");
if (presetsFile == null || !presetsFile.exists()) {
return;
@@ -236,15 +192,15 @@ public class PresetsList {
preset = new Preset();
}
if (settings.get("name") != null) {
if (settings.has("name")) {
preset.name = settings.get("name").getAsString();
}
if (settings.get("enabled") != null) {
if (settings.has("enabled")) {
preset.enabled = settings.get("enabled").getAsBoolean();
}
if (settings.get("mode") != null) {
if (settings.has("mode")) {
preset.mode = PresetMode.valueOf(settings.get("mode").getAsString());
}
@@ -260,17 +216,11 @@ public class PresetsList {
if (!preset.items.isEmpty()) {
presets.add(preset);
}
itemsLoaded();
}
public static void savePresets() {
if (presetsFile == null) {
return;
}
List<String> strings = new ArrayList<>();
final File presetsFile = new File(CommonUtils.getMinecraftDir(), "saves/NEI/global/presets.ini");
final List<String> strings = new ArrayList<>();
for (Preset preset : presets) {
JsonObject settings = new JsonObject();
@@ -289,7 +239,11 @@ public class PresetsList {
NEIClientConfig.logger.error("Filed to save presets list to file {}", presetsFile, e);
}
itemsLoaded();
recipeFilter.cache = null;
itemFilter.cache = null;
CollapsibleItems.saveStates();
CollapsibleItems.load();
LayoutManager.markItemsDirty();
}
}
+15 -5
View File
@@ -144,7 +144,8 @@ public class SearchField extends TextField implements ItemFilterProvider {
@Override
public int getTextColour() {
if (ItemPanels.itemPanel.getItems().isEmpty()) {
if (ItemPanels.itemPanel.getItems().isEmpty()
&& (!this.field.getText().isEmpty() || !NEIClientConfig.hideItemsUntilSearching())) {
return focused() ? 0xFFcc3300 : 0xFF993300;
} else {
return focused() ? 0xFFE0E0E0 : 0xFF909090;
@@ -243,18 +244,18 @@ public class SearchField extends TextField implements ItemFilterProvider {
search = search.substring(2, search.length() - 1);
} else {
final Matcher matcher = Pattern.compile("(\\?|\\*)").matcher(search);
String cleanedString = "";
final StringBuilder cleanedString = new StringBuilder();
int lastEndIndex = 0;
while (matcher.find()) {
cleanedString += Pattern.quote(search.substring(lastEndIndex, matcher.start()));
cleanedString.append(Pattern.quote(search.substring(lastEndIndex, matcher.start())));
switch (matcher.group(0).charAt(0)) {
case '?':
cleanedString += ".";
cleanedString.append(".");
break;
case '*':
cleanedString += ".+?";
cleanedString.append(".+?");
break;
default:
break;
@@ -266,6 +267,8 @@ public class SearchField extends TextField implements ItemFilterProvider {
search = cleanedString + Pattern.quote(search.substring(lastEndIndex, search.length()));
}
break;
default:
break;
}
if (!search.isEmpty()) {
@@ -300,6 +303,8 @@ public class SearchField extends TextField implements ItemFilterProvider {
case 2:
text = text.replaceAll("[{}()\\[\\].+*?^$\\\\|]", "\\\\$0");
break;
default:
break;
}
if (text.contains(" ") && NEIClientConfig.getBooleanSetting("inventory.search.quoteDropItemName")) {
@@ -311,6 +316,11 @@ public class SearchField extends TextField implements ItemFilterProvider {
@Override
public ItemFilter getFilter() {
if (field.getText().isEmpty() && NEIClientConfig.hideItemsUntilSearching()) {
return new NothingItemFilter();
}
return ((GuiSearchField) field).getFilter();
}
@@ -1,12 +1,12 @@
package codechicken.nei;
import java.util.List;
import java.util.StringJoiner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.minecraft.util.EnumChatFormatting;
import codechicken.nei.FormattedTextField.TextFormatter;
import codechicken.nei.SearchTokenParser.SearchToken;
public class SearchTextFormatter implements TextFormatter {
@@ -17,63 +17,50 @@ public class SearchTextFormatter implements TextFormatter {
}
public String format(String text) {
final String[] parts = text.split("\\|");
final Pattern splitPattern = searchParser.getSplitPattern();
final String[] parts = (text + "| ").split("\\|");
StringJoiner formattedText = new StringJoiner(EnumChatFormatting.GRAY + "|");
for (String filterText : parts) {
Matcher filterMatcher = splitPattern.matcher(filterText);
for (int i = 0; i < parts.length - 1; i++) {
final String filterText = parts[i];
final List<SearchToken> tokens = searchParser.splitSearchText(filterText);
StringBuilder formattedPart = new StringBuilder();
int startIndex = 0;
while (filterMatcher.find()) {
boolean ignore = "-".equals(filterMatcher.group(2));
String firstChar = filterMatcher.group(3);
String token = filterMatcher.group(4);
boolean quotes = token.length() > 1 && token.startsWith("\"") && token.endsWith("\"");
if (quotes) {
token = token.substring(1, token.length() - 1);
}
formattedPart.append(filterText.substring(startIndex, filterMatcher.start()));
for (SearchToken token : tokens) {
formattedPart.append(filterText.substring(startIndex, token.start));
EnumChatFormatting tokenColor = EnumChatFormatting.RESET;
if (!firstChar.isEmpty()) {
tokenColor = searchParser.getProvider(firstChar.charAt(0)).getHighlightedColor();
if (token.firstChar != null) {
tokenColor = searchParser.getProvider(token.firstChar).getHighlightedColor();
}
if (ignore) {
if (token.ignore) {
formattedPart.append(EnumChatFormatting.BLUE + "-");
}
if (!firstChar.isEmpty()) {
formattedPart.append(tokenColor + firstChar);
if (token.firstChar != null) {
formattedPart.append(tokenColor + String.valueOf(token.firstChar));
}
if (quotes) {
if (token.quotes) {
formattedPart.append(EnumChatFormatting.GOLD + "\"");
}
if (!token.isEmpty()) {
formattedPart.append(tokenColor + token);
if (!token.rawText.isEmpty()) {
formattedPart.append(tokenColor + token.rawText);
}
if (quotes) {
if (token.quotes) {
formattedPart.append(EnumChatFormatting.GOLD + "\"");
}
startIndex = filterMatcher.end();
startIndex = token.end;
}
formattedPart.append(filterText.substring(startIndex, filterText.length()));
formattedText.add(formattedPart);
}
if (text.endsWith("|")) {
formattedText.add("");
}
return formattedText.toString();
}
}
@@ -2,16 +2,17 @@ package codechicken.nei;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.Language;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import codechicken.nei.ItemList.AllMultiItemFilter;
@@ -30,24 +31,32 @@ public class SearchTokenParser {
NEVER;
public static SearchMode fromInt(int value) {
switch (value) {
case 0:
return ALWAYS;
case 1:
return PREFIX;
case 2:
return NEVER;
default:
return ALWAYS;
}
return switch (value) {
case 0 -> ALWAYS;
case 1 -> PREFIX;
default -> NEVER;
};
}
}
public static class SearchToken {
public boolean ignore = false;
public boolean quotes = false;
public Character firstChar = null;
public String[] words;
public String rawText = "";
public int start = 0;
public int end = 0;
}
public static interface ISearchParserProvider {
public ItemFilter getFilter(String searchText);
@SuppressWarnings("unchecked")
public static List<Language> getAllLanguages() {
return new ArrayList<>(Minecraft.getMinecraft().getLanguageManager().getLanguages());
}
@@ -74,8 +83,26 @@ public class SearchTokenParser {
}
}
private static class IsRegisteredItemFilter implements ItemFilter {
public ItemFilter filter;
public IsRegisteredItemFilter(ItemFilter filter) {
this.filter = filter;
}
@Override
public boolean matches(ItemStack item) {
return item != null && item.getItem() != null
&& item.getItem().delegate.name() != null
&& this.filter.matches(item);
}
}
protected final LRUCache<String, ItemFilter> filtersCache = new LRUCache<>(20);
protected final List<ISearchParserProvider> searchProviders;
protected final ProvidersCache providersCache = new ProvidersCache();
protected final Map<Character, Character> prefixRedefinitions = new HashMap<>();
public SearchTokenParser(List<ISearchParserProvider> searchProviders) {
this.searchProviders = searchProviders;
@@ -88,6 +115,11 @@ public class SearchTokenParser {
public void addProvider(ISearchParserProvider provider) {
this.searchProviders.add(provider);
this.providersCache.clear();
this.filtersCache.clear();
}
public void clearCache() {
this.filtersCache.clear();
}
protected List<ISearchParserProvider> getProviders() {
@@ -114,35 +146,103 @@ public class SearchTokenParser {
public ISearchParserProvider getProvider(char ch) {
return getProviders().stream()
.filter(provider -> provider.getSearchMode() == SearchMode.PREFIX && provider.getPrefix() == ch)
.filter(
provider -> provider.getSearchMode() == SearchMode.PREFIX
&& getRedefinedPrefix(provider.getPrefix()) == ch)
.findFirst().orElse(null);
}
public ItemFilter getFilter(String filterText) {
final String[] parts = EnumChatFormatting.getTextWithoutFormattingCodes(filterText).toLowerCase().split("\\|");
final List<ItemFilter> searchTokens = Arrays.stream(parts).map(s -> parseSearchText(s)).filter(s -> s != null)
.collect(Collectors.toCollection(ArrayList::new));
public synchronized ItemFilter getFilter(String filterText) {
filterText = EnumChatFormatting.getTextWithoutFormattingCodes(filterText).toLowerCase();
return this.filtersCache.computeIfAbsent(filterText, text -> {
final String[] parts = text.split("\\|");
final List<ItemFilter> searchTokens = Arrays.stream(parts).map(this::parseSearchText).filter(s -> s != null)
.collect(Collectors.toCollection(ArrayList::new));
if (searchTokens.isEmpty()) {
return new EverythingItemFilter();
} else if (searchTokens.size() == 1) {
return new IsRegisteredItemFilter(searchTokens.get(0));
} else {
return new IsRegisteredItemFilter(new AnyMultiItemFilter(searchTokens));
}
});
if (searchTokens.isEmpty()) {
return new EverythingItemFilter();
} else if (searchTokens.size() == 1) {
return searchTokens.get(0);
} else {
return new AnyMultiItemFilter(searchTokens);
}
}
public Pattern getSplitPattern() {
StringJoiner prefixes = new StringJoiner("");
prefixes.add(String.valueOf('\0'));
public List<SearchToken> splitSearchText(String filterText) {
if (filterText.isEmpty()) {
return Collections.emptyList();
}
final List<SearchToken> tokens = new ArrayList<>();
final String prefixes = getPrefixes();
final int spaceMode = NEIClientConfig.getIntSetting("inventory.search.spaceMode");
// The regular expression first tries to match a string that starts with a space or the beginning of the string,
// followed by a sequence of characters that do not contain special characters -"@#$%&, and ends with a space
// and the characters -"@#$%& or the end of the string.
final String patternPart1 = "(?<tokenA>(^|\\s+)(?:[^" + Pattern.quote(" -\"" + prefixes)
+ "]).+?(?=\\s+["
+ Pattern.quote("-\"" + prefixes)
+ "]|$))";
// If the first condition is not met, it tries to match a sequence of - characters, followed by @#$%&
// characters, then either a quoted string or non-space characters.
final String patternPart2 = "((?<ignore>-*)(?<firstChar>[" + Pattern.quote(prefixes)
+ "]*)(?<tokenB>\\\".*?(?:\\\"|$)|\\S+\\s*))";
final Pattern pattern = Pattern.compile(spaceMode == 0 ? patternPart2 : (patternPart1 + "|" + patternPart2));
final Matcher filterMatcher = pattern.matcher(filterText);
while (filterMatcher.find()) {
String firstChar = filterMatcher.group("firstChar");
SearchToken token = new SearchToken();
token.start = filterMatcher.start();
token.end = filterMatcher.end();
token.ignore = "-".equals(filterMatcher.group("ignore"));
token.rawText = spaceMode == 0 ? null : filterMatcher.group("tokenA");
if (firstChar != null && !firstChar.isEmpty()) {
token.firstChar = firstChar.charAt(0);
}
if (token.rawText == null) { // spaceMode == 0
token.rawText = filterMatcher.group("tokenB");
token.quotes = token.rawText.length() > 1 && token.rawText.startsWith("\"")
&& token.rawText.endsWith("\"");
if (token.quotes) {
token.rawText = token.rawText.substring(1, token.rawText.length() - 1);
}
token.words = new String[] { token.rawText.trim() };
} else if (spaceMode == 2) {
token.words = token.rawText.trim().split("\\s+");
} else {
token.words = new String[] { token.rawText.trim() };
}
tokens.add(token);
}
return tokens;
}
private String getPrefixes() {
StringBuilder prefixes = new StringBuilder().append('\0');
for (ISearchParserProvider provider : getProviders()) {
if (provider.getSearchMode() == SearchMode.PREFIX) {
prefixes.add(String.valueOf(provider.getPrefix()));
prefixes.append(getRedefinedPrefix(provider.getPrefix()));
}
}
return Pattern.compile("((-*)([" + Pattern.quote(prefixes.toString()) + "]*)(\\\".*?(?:\\\"|$)|\\S+))");
return prefixes.toString();
}
public char getRedefinedPrefix(char prefix) {
return this.prefixRedefinitions.getOrDefault(prefix, prefix);
}
private ItemFilter parseSearchText(String filterText) {
@@ -151,28 +251,19 @@ public class SearchTokenParser {
return null;
}
final Matcher filterMatcher = getSplitPattern().matcher(filterText);
final AllMultiItemFilter searchTokens = new AllMultiItemFilter();
final List<SearchToken> tokens = splitSearchText(filterText);
while (filterMatcher.find()) {
boolean ignore = "-".equals(filterMatcher.group(2));
String firstChar = filterMatcher.group(3);
String token = filterMatcher.group(4);
boolean quotes = token.length() > 1 && token.startsWith("\"") && token.endsWith("\"");
for (SearchToken token : tokens) {
if (!token.rawText.isEmpty()) {
ItemFilter result = parseToken(token);
if (quotes) {
token = token.substring(1, token.length() - 1);
}
if (!token.isEmpty()) {
ItemFilter result = parseToken(firstChar, token);
if (ignore) {
if (token.ignore) {
searchTokens.filters.add(new NegatedItemFilter(result));
} else {
searchTokens.filters.add(result);
}
} else if (!ignore) {
} else if (!token.ignore) {
searchTokens.filters.add(new NothingItemFilter());
}
}
@@ -180,21 +271,39 @@ public class SearchTokenParser {
return searchTokens;
}
private ItemFilter parseToken(String firstChar, String token) {
final ISearchParserProvider provider = firstChar.isEmpty() ? null : this.getProvider(firstChar.charAt(0));
private ItemFilter parseToken(SearchToken token) {
final ISearchParserProvider provider = token.firstChar == null ? null : this.getProvider(token.firstChar);
if (provider == null || provider.getSearchMode() == SearchMode.NEVER) {
final List<ItemFilter> filters = new ArrayList<>();
for (ISearchParserProvider _provider : getProviders()) {
if (_provider.getSearchMode() == SearchMode.ALWAYS) {
filters.add(_provider.getFilter(token));
AllMultiItemFilter filter = generateFilters(_provider, token.words);
if (!filter.filters.isEmpty()) {
filters.add(filter);
}
}
}
return filters.isEmpty() ? new NothingItemFilter() : new AnyMultiItemFilter(filters);
} else {
return provider.getFilter(token);
return generateFilters(provider, token.words);
}
}
private AllMultiItemFilter generateFilters(ISearchParserProvider provider, String[] words) {
final AllMultiItemFilter filters = new AllMultiItemFilter();
for (String work : words) {
final ItemFilter filter = provider.getFilter(work);
if (filter != null) {
filters.filters.add(filter);
}
}
return filters;
}
}
@@ -64,7 +64,6 @@ public class SpawnerRenderer implements IItemRenderer {
BossStatus.hasColorModifier = bossHasColorModifier;
}
@SuppressWarnings("incomplete-switch")
@Override
public void renderItem(ItemRenderType type, ItemStack item, Object... data) {
switch (type) {
@@ -75,6 +74,8 @@ public class SpawnerRenderer implements IItemRenderer {
case ENTITY:
renderInventoryItem((RenderBlocks) data[0], item);
break;
default:
break;
}
}
File diff suppressed because it is too large. Load diff
@@ -6,9 +6,9 @@ import cpw.mods.fml.common.FMLCommonHandler;
public class ThreadOperationTimer extends Thread {
@SuppressWarnings("serial")
public static class TimeoutException extends RuntimeException {
private static final long serialVersionUID = -8621458005263888185L;
public final Object operation;
public TimeoutException(String msg, Object op) {
@@ -11,6 +11,6 @@ public class WidgetZOrder implements Comparator<Widget> {
}
public int compare(Widget w1, Widget w2) {
return w1.z != w2.z ? ((topfirst ? w1.z > w2.z : w1.z < w2.z) ? 1 : -1) : 1;
return w1.z != w2.z ? ((topfirst ? w1.z < w2.z : w1.z > w2.z) ? 1 : -1) : 1;
}
}
@@ -17,6 +17,7 @@ import org.lwjgl.opengl.GL11;
import codechicken.lib.math.MathHelper;
import codechicken.nei.KeyManager.IKeyStateTracker;
import cpw.mods.fml.relauncher.ReflectionHelper;
public class WorldOverlayRenderer implements IKeyStateTracker {
@@ -26,12 +27,11 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
private static byte[] mobSpawnCache;
private static long mobOverlayUpdateTime;
private static String oregenPatternName;
private static boolean hasOregenPatternBeenSet = false;
public static void reset() {
mobOverlay = 0;
chunkOverlay = 0;
hasOregenPatternBeenSet = false;
oregenPatternName = null;
}
@Override
@@ -204,7 +204,9 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glLineWidth(1.5F);
GL11.glBegin(GL11.GL_LINES);
final Tessellator tess = Tessellator.instance;
tess.startDrawing(GL11.GL_LINES);
for (int cx = -4; cx <= 4; cx++) for (int cz = -4; cz <= 4; cz++) {
double x1 = ((entity.chunkCoordX + cx) << 4) - intOffsetX;
@@ -230,22 +232,22 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
double dist = Math.pow(1.5, -(cx * cx + cz * cz));
GL11.glColor4d(0.9, 0, 0, dist);
tess.setColorRGBA_F(0.9F, 0, 0, (float) dist);
if (cx >= 0 && cz >= 0) {
GL11.glVertex3d(x2, y1, z2);
GL11.glVertex3d(x2, y2, z2);
tess.addVertex(x2, y1, z2);
tess.addVertex(x2, y2, z2);
}
if (cx >= 0 && cz <= 0) {
GL11.glVertex3d(x2, y1, z1);
GL11.glVertex3d(x2, y2, z1);
tess.addVertex(x2, y1, z1);
tess.addVertex(x2, y2, z1);
}
if (cx <= 0 && cz >= 0) {
GL11.glVertex3d(x1, y1, z2);
GL11.glVertex3d(x1, y2, z2);
tess.addVertex(x1, y1, z2);
tess.addVertex(x1, y2, z2);
}
if (cx <= 0 && cz <= 0) {
GL11.glVertex3d(x1, y1, z1);
GL11.glVertex3d(x1, y2, z1);
tess.addVertex(x1, y1, z1);
tess.addVertex(x1, y2, z1);
}
if (cx == 0 && cz == 0) {
@@ -266,40 +268,31 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
y1 -= intOffsetY;
y2 -= intOffsetY;
GL11.glColor4d(0, 0.9, 0, 0.4);
tess.setColorRGBA_F(0, 0.9F, 0, 0.4F);
for (double y = (int) y1; y <= y2; y++) {
GL11.glVertex3d(x2, y, z1);
GL11.glVertex3d(x2, y, z2);
GL11.glVertex3d(x1, y, z1);
GL11.glVertex3d(x1, y, z2);
GL11.glVertex3d(x1, y, z2);
GL11.glVertex3d(x2, y, z2);
GL11.glVertex3d(x1, y, z1);
GL11.glVertex3d(x2, y, z1);
tess.addVertex(x2, y, z1);
tess.addVertex(x2, y, z2);
tess.addVertex(x1, y, z1);
tess.addVertex(x1, y, z2);
tess.addVertex(x1, y, z2);
tess.addVertex(x2, y, z2);
tess.addVertex(x1, y, z1);
tess.addVertex(x2, y, z1);
}
for (double h = 1; h <= 15; h++) {
GL11.glVertex3d(x1 + h, y1, z1);
GL11.glVertex3d(x1 + h, y2, z1);
GL11.glVertex3d(x1 + h, y1, z2);
GL11.glVertex3d(x1 + h, y2, z2);
GL11.glVertex3d(x1, y1, z1 + h);
GL11.glVertex3d(x1, y2, z1 + h);
GL11.glVertex3d(x2, y1, z1 + h);
GL11.glVertex3d(x2, y2, z1 + h);
tess.addVertex(x1 + h, y1, z1);
tess.addVertex(x1 + h, y2, z1);
tess.addVertex(x1 + h, y1, z2);
tess.addVertex(x1 + h, y2, z2);
tess.addVertex(x1, y1, z1 + h);
tess.addVertex(x1, y2, z1 + h);
tess.addVertex(x2, y1, z1 + h);
tess.addVertex(x2, y2, z1 + h);
}
} else if (chunkOverlay == 3) {
if (!hasOregenPatternBeenSet) {
try {
oregenPatternName = ((Enum<?>) Class.forName("gregtech.common.GT_Worldgenerator")
.getDeclaredField("oregenPattern").get(null)).name();
} catch (Exception ignored) {
oregenPatternName = "AXISSYMMETRICAL";
}
hasOregenPatternBeenSet = true;
}
int gx1;
int gz1;
if (oregenPatternName.equals("EQUAL_SPACING")) {
if (getOregenPatternName().equals("EQUAL_SPACING")) {
// gt oregen uses new regular pattern
gx1 = ((Math.floorDiv(entity.chunkCoordX, 3) * 3) << 4) - intOffsetX;
gz1 = ((Math.floorDiv(entity.chunkCoordZ, 3) * 3) << 4) - intOffsetZ;
@@ -319,55 +312,71 @@ public class WorldOverlayRenderer implements IKeyStateTracker {
int gx2 = gx1 + 48;
int gz2 = gz1 + 48;
GL11.glColor4d(0, 0.9, 0, 0.4);
tess.setColorRGBA_F(0, 0.9F, 0, 0.4F);
for (double y = (int) y1; y <= y2; y++) {
GL11.glVertex3d(gx2, y, gz1);
GL11.glVertex3d(gx2, y, gz2);
GL11.glVertex3d(gx1, y, gz1);
GL11.glVertex3d(gx1, y, gz2);
GL11.glVertex3d(gx1, y, gz2);
GL11.glVertex3d(gx2, y, gz2);
GL11.glVertex3d(gx1, y, gz1);
GL11.glVertex3d(gx2, y, gz1);
tess.addVertex(gx2, y, gz1);
tess.addVertex(gx2, y, gz2);
tess.addVertex(gx1, y, gz1);
tess.addVertex(gx1, y, gz2);
tess.addVertex(gx1, y, gz2);
tess.addVertex(gx2, y, gz2);
tess.addVertex(gx1, y, gz1);
tess.addVertex(gx2, y, gz1);
}
for (double h = 4; h <= 44; h += 4) {
if (h % 16 == 0) {
continue;
}
GL11.glVertex3d(gx1 + h, y1, gz1);
GL11.glVertex3d(gx1 + h, y2, gz1);
GL11.glVertex3d(gx1 + h, y1, gz2);
GL11.glVertex3d(gx1 + h, y2, gz2);
GL11.glVertex3d(gx1, y1, gz1 + h);
GL11.glVertex3d(gx1, y2, gz1 + h);
GL11.glVertex3d(gx2, y1, gz1 + h);
GL11.glVertex3d(gx2, y2, gz1 + h);
tess.addVertex(gx1 + h, y1, gz1);
tess.addVertex(gx1 + h, y2, gz1);
tess.addVertex(gx1 + h, y1, gz2);
tess.addVertex(gx1 + h, y2, gz2);
tess.addVertex(gx1, y1, gz1 + h);
tess.addVertex(gx1, y2, gz1 + h);
tess.addVertex(gx2, y1, gz1 + h);
tess.addVertex(gx2, y2, gz1 + h);
}
GL11.glColor4d(0, 0, 0.9, 0.4);
tess.setColorRGBA_F(0, 0, 0.9F, 0.4F);
gx1 += 23;
gz1 += 23;
gx2 = gx1 + 1;
gz2 = gz1 + 1;
GL11.glVertex3d(gx1, y1, gz1);
GL11.glVertex3d(gx1, y2, gz1);
GL11.glVertex3d(gx2, y1, gz1);
GL11.glVertex3d(gx2, y2, gz1);
GL11.glVertex3d(gx1, y1, gz2);
GL11.glVertex3d(gx1, y2, gz2);
GL11.glVertex3d(gx2, y1, gz2);
GL11.glVertex3d(gx2, y2, gz2);
tess.addVertex(gx1, y1, gz1);
tess.addVertex(gx1, y2, gz1);
tess.addVertex(gx2, y1, gz1);
tess.addVertex(gx2, y2, gz1);
tess.addVertex(gx1, y1, gz2);
tess.addVertex(gx1, y2, gz2);
tess.addVertex(gx2, y1, gz2);
tess.addVertex(gx2, y2, gz2);
}
}
}
GL11.glEnd();
tess.draw();
GL11.glEnable(GL11.GL_LIGHTING);
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glDisable(GL11.GL_BLEND);
}
private static String getOregenPatternName() {
if (oregenPatternName == null) {
try {
final ClassLoader loader = WorldOverlayRenderer.class.getClassLoader();
final Class<?> gtWorldGenerator = ReflectionHelper
.getClass(loader, "gregtech.common.GTWorldgenerator", "gregtech.common.GT_Worldgenerator");
oregenPatternName = ((Enum<?>) gtWorldGenerator.getDeclaredField("oregenPattern").get(null)).name();
} catch (Exception ignored) {
oregenPatternName = "AXISSYMMETRICAL";
}
}
return oregenPatternName;
}
public static void load() {
KeyManager.trackers.add(new WorldOverlayRenderer());
}
@@ -42,6 +42,7 @@ import codechicken.nei.recipe.IUsageHandler;
import codechicken.nei.recipe.RecipeCatalysts;
import codechicken.nei.recipe.RecipeInfo;
import codechicken.nei.recipe.StackInfo;
import codechicken.nei.util.ItemStackFilterParser;
/**
* This is the main class that handles item property configuration. WARNING: DO NOT access this class until the world
@@ -151,6 +152,14 @@ public class API {
}
}
public static void hideItem(String rule) {
ItemFilter filter = ItemStackFilterParser.parse(rule);
if (filter != null) {
ItemInfo.hiddenItemsRules.filters.add(filter);
LayoutManager.markItemsDirty();
}
}
/**
* Add or replace the name normally shown on the item tooltip
*/
@@ -15,7 +15,7 @@ import codechicken.nei.guihook.GuiContainerManager;
public class DefaultOverlayRenderer implements IRecipeOverlayRenderer {
public DefaultOverlayRenderer(List<PositionedStack> ai, IStackPositioner positioner) {
positioner = this.positioner = positioner;
this.positioner = positioner;
ingreds = new ArrayList<>();
for (PositionedStack stack : ai) ingreds.add(stack.copy());
ingreds = positioner.positionStacks(ingreds);
@@ -6,21 +6,20 @@ import java.util.Optional;
import java.util.stream.Collectors;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import codechicken.nei.PositionedStack;
import codechicken.nei.recipe.GuiOverlayButton.ItemOverlayState;
import codechicken.nei.recipe.IRecipeHandler;
public interface IOverlayHandler {
void overlayRecipe(GuiContainer firstGui, IRecipeHandler recipe, int recipeIndex, boolean shift);
default List<Boolean> presenceOverlay(GuiContainer firstGui, IRecipeHandler recipe, int recipeIndex) {
final List<Boolean> itemPresenceSlots = new ArrayList<>();
default List<ItemOverlayState> presenceOverlay(GuiContainer firstGui, IRecipeHandler recipe, int recipeIndex) {
final List<ItemOverlayState> itemPresenceSlots = new ArrayList<>();
final List<PositionedStack> ingredients = recipe.getIngredientStacks(recipeIndex);
@SuppressWarnings("unchecked")
final List<ItemStack> invStacks = ((List<Slot>) firstGui.inventorySlots.inventorySlots).stream()
final List<ItemStack> invStacks = firstGui.inventorySlots.inventorySlots.stream()
.filter(
s -> s != null && s.getStack() != null
&& s.getStack().stackSize > 0
@@ -30,9 +29,9 @@ public interface IOverlayHandler {
for (PositionedStack stack : ingredients) {
Optional<ItemStack> used = invStacks.stream().filter(is -> is.stackSize > 0 && stack.contains(is))
.findFirst();
.findAny();
itemPresenceSlots.add(used.isPresent());
itemPresenceSlots.add(new ItemOverlayState(stack, used.isPresent()));
if (used.isPresent()) {
ItemStack is = used.get();
+14 -38
View File
@@ -43,13 +43,14 @@ import com.google.common.collect.ArrayListMultimap;
import codechicken.core.featurehack.GameDataManipulator;
import codechicken.nei.InfiniteStackSizeHandler;
import codechicken.nei.InfiniteToolHandler;
import codechicken.nei.ItemList;
import codechicken.nei.ItemList.AnyMultiItemFilter;
import codechicken.nei.ItemList.PatternItemFilter;
import codechicken.nei.ItemMobSpawner;
import codechicken.nei.ItemStackMap;
import codechicken.nei.ItemStackSet;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.PopupInputHandler;
import codechicken.nei.PresetsList;
import codechicken.nei.SearchField.SearchParserProvider;
import codechicken.nei.SearchTokenParser.SearchMode;
import codechicken.nei.config.ArrayDumper;
@@ -82,6 +83,7 @@ public class ItemInfo {
public static final ArrayListMultimap<Layout, IHighlightHandler> highlightHandlers = ArrayListMultimap.create();
public static final ItemStackMap<String> nameOverrides = new ItemStackMap<>();
public static final ItemStackSet hiddenItems = new ItemStackSet();
public static final AnyMultiItemFilter hiddenItemsRules = new AnyMultiItemFilter();
public static final ItemStackSet finiteItems = new ItemStackSet();
public static final ArrayListMultimap<Item, ItemStack> itemOverrides = ArrayListMultimap.create();
public static final ArrayListMultimap<Item, ItemStack> itemVariants = ArrayListMultimap.create();
@@ -93,9 +95,10 @@ public class ItemInfo {
public static final HashMap<Item, String> itemOwners = new HashMap<>();
public static boolean isHidden(ItemStack stack) {
return hiddenItems.contains(stack);
return hiddenItems.contains(stack) || hiddenItemsRules.matches(stack);
}
@Deprecated
public static boolean isHidden(Item item) {
return hiddenItems.containsAll(item);
}
@@ -130,22 +133,14 @@ public class ItemInfo {
addInfiniteHandlers();
addInputHandlers();
addIDDumps();
addHiddenItemFilter();
addSearchProviders();
ItemList.loadCallbacks.add(TooltipFilter::populateSearchMap);
}
private static void addHiddenItemFilter() {
API.addItemFilter(() -> item -> !hiddenItems.contains(item));
RecipeItemInputHandler.load();
PresetsList.load();
}
private static void addSearchProviders() {
API.addSearchProvider(
new SearchParserProvider(
'\0',
"default",
EnumChatFormatting.RESET,
(pattern) -> new PatternItemFilter(pattern)) {
new SearchParserProvider('\0', "default", EnumChatFormatting.RESET, PatternItemFilter::new) {
@Override
public SearchMode getSearchMode() {
@@ -154,29 +149,12 @@ public class ItemInfo {
});
API.addSearchProvider(
new SearchParserProvider(
'@',
"modName",
EnumChatFormatting.LIGHT_PURPLE,
(pattern) -> new ModNameFilter(pattern)));
new SearchParserProvider('@', "modName", EnumChatFormatting.LIGHT_PURPLE, ModNameFilter::new));
API.addSearchProvider(
new SearchParserProvider(
'$',
"oreDict",
EnumChatFormatting.AQUA,
(pattern) -> new OreDictionaryFilter(pattern)));
new SearchParserProvider('$', "oreDict", EnumChatFormatting.AQUA, OreDictionaryFilter::new));
API.addSearchProvider(new SearchParserProvider('#', "tooltip", EnumChatFormatting.YELLOW, TooltipFilter::new));
API.addSearchProvider(
new SearchParserProvider(
'#',
"tooltip",
EnumChatFormatting.YELLOW,
(pattern) -> new TooltipFilter(pattern)));
API.addSearchProvider(
new SearchParserProvider(
'&',
"identifier",
EnumChatFormatting.GOLD,
(pattern) -> new IdentifierFilter(pattern)));
new SearchParserProvider('&', "identifier", EnumChatFormatting.GOLD, IdentifierFilter::new));
}
private static void addIDDumps() {
@@ -211,7 +189,7 @@ public class ItemInfo {
public String[] dump(Block block, int id, String name) {
final Item item = Item.getItemFromBlock(block);
return new String[] { name, Integer.toString(id), Boolean.toString(item != null),
ItemInfo.itemOwners.get(block), block.getClass().getCanonicalName(),
ItemInfo.itemOwners.get(item), block.getClass().getCanonicalName(),
item != null ? EnumChatFormatting.getTextWithoutFormattingCodes(
GuiContainerManager.itemDisplayNameShort(new ItemStack(item))) : "null" };
}
@@ -318,7 +296,6 @@ public class ItemInfo {
}
private static void addInputHandlers() {
GuiContainerManager.addInputHandler(new RecipeItemInputHandler());
GuiContainerManager.addInputHandler(new PopupInputHandler());
}
@@ -462,7 +439,6 @@ public class ItemInfo {
addEntityEgg(EntityIronGolem.class, 0xC5C2C1, 0xffe1cc);
}
@SuppressWarnings("unchecked")
private static void addEntityEgg(Class<?> entity, int i, int j) {
int id = (Integer) EntityList.classToIDMapping.get(entity);
EntityList.entityEggs.put(id, new EntityEggInfo(id, i, j));
@@ -520,6 +496,6 @@ public class ItemInfo {
@Deprecated
public static String getSearchName(ItemStack stack) {
return GuiContainerManager.concatenatedDisplayName(stack, true);
return GuiContainerManager.concatenatedDisplayName(stack, true).toLowerCase();
}
}
@@ -5,7 +5,9 @@ import static codechicken.lib.gui.GuiDraw.getMousePosition;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.ItemStack;
@@ -199,4 +201,8 @@ public abstract class ShortcutInputHandler {
return false;
}
public static Map<String, String> handleHotkeys(GuiContainer gui, int mousex, int mousey, ItemStack stack) {
return new HashMap<>();
}
}
@@ -66,16 +66,6 @@ public class NEITransformer implements IClassTransformer {
"func_149689_a",
"(Lnet/minecraft/world/World;IIILnet/minecraft/entity/EntityLivingBase;Lnet/minecraft/item/ItemStack;)V"),
asmblocks.get("spawnerPlaced")));
// Make MobSpawnerBaseLogic use getSpawnerWorld when creating new entities
transformer.add(
new MethodReplacer(
new ObfMapping(
"net/minecraft/tileentity/MobSpawnerBaseLogic",
"func_98281_h",
"()Lnet/minecraft/entity/Entity;"),
asmblocks.get("d_spawnerWorld"),
asmblocks.get("spawnerWorld")));
}
// Removes trailing seperators from NBTTagList/Compound.toString because OCD
@@ -75,26 +75,25 @@ public abstract class OptionButton extends Option {
}
public String getTooltip() {
String tip = null;
if (tooltip != null) {
String s = translateN(tooltip);
if (!s.equals(namespaced(tooltip))) {
tip = s;
return s;
}
}
if (tip == null && getPrefix() != null) {
if (getPrefix() != null) {
final int width = getStringWidth(getPrefix());
final Rectangle b = buttonSize();
if (width >= b.x) {
tip = translateN(name);
return translateN(name);
}
}
return tip;
return null;
}
public void drawPrefix() {
@@ -29,6 +29,18 @@ public class OptionCycled extends OptionButton {
return prefixed ? translateN(name) : null;
}
@Override
public String getTooltip() {
String tooltip = name + "." + value() + ".tip";
String s = translateN(tooltip);
if (!s.equals(namespaced(tooltip))) {
return s;
}
return super.getTooltip();
}
@Override
public boolean onClick(int button) {
return cycle();
@@ -1,11 +1,15 @@
package codechicken.nei.config;
import codechicken.lib.gui.GuiDraw;
public class OptionIntegerField extends OptionTextField {
public final int min;
public final int max;
public static final long UNSIGNED_INT_MAX = 0xFFFFFFFFL;
public OptionIntegerField(String name, int min, int max) {
public final long min;
public final long max;
public OptionIntegerField(String name, long min, long max) {
super(name);
this.min = min;
this.max = max;
@@ -15,13 +19,23 @@ public class OptionIntegerField extends OptionTextField {
this(name, Integer.MIN_VALUE, Integer.MAX_VALUE);
}
@Override
protected int getMaxInputWidth() {
if (renderTag().getValue().startsWith("0x")) {
return GuiDraw.getStringWidth("0x" + Long.toHexString(this.max).toUpperCase()) + 32;
}
return GuiDraw.getStringWidth(String.valueOf(this.max)) + 32;
}
@Override
public boolean isValidInput(String s) {
if (s.length() == 0) return true;
if (s.isEmpty()) return true;
try {
if (s.startsWith("0x")) {
Long.parseLong(s.substring(2), 16);
Long.parseUnsignedLong(s.substring(2), 16);
} else {
Integer.parseInt(s);
}
@@ -33,15 +47,15 @@ public class OptionIntegerField extends OptionTextField {
@Override
public boolean isValidValue(String s) {
if (s.length() == 0 || !isValidInput(s)) return false;
int i = 0;
if (s.isEmpty() || !isValidInput(s)) return false;
long i = 0;
if (s.startsWith("0x")) {
i = (int) Long.parseLong(s.substring(2), 16);
i = Long.parseUnsignedLong(s.substring(2), 16);
} else {
i = Integer.parseInt(s);
}
return i >= min && i <= max;
return i >= this.min && i <= this.max;
}
}
@@ -7,7 +7,6 @@ import java.awt.Rectangle;
import org.lwjgl.input.Keyboard;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIClientUtils;
public class OptionKeyBind extends OptionButton {
@@ -122,8 +121,12 @@ public class OptionKeyBind extends OptionButton {
@Override
public String getButtonText() {
final int metahash = Math.max(editing ? NEIClientUtils.getMetaHash() : getValue(), 0);
return NEIClientConfig.getKeyName(metahash, useHash, editing);
if (editing) {
return NEIClientUtils.getKeyHashName(NEIClientUtils.getMetaHash());
}
return NEIClientUtils.getKeyName(Math.max(getValue(), 0));
}
@Override
@@ -1,45 +1,36 @@
package codechicken.nei.config;
import static codechicken.lib.gui.GuiDraw.drawString;
import static codechicken.lib.gui.GuiDraw.getStringWidth;
import java.util.List;
import codechicken.lib.gui.GuiDraw;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.TextField;
import codechicken.nei.config.GuiOptionList.OptionScrollSlot;
public class OptionTextField extends Option {
private TextField textField = new TextField("test") {
protected final TextField textField = new TextField("test") {
{
this.h = 20;
}
@Override
public void onTextChange(String oldText) {
if (focused() && isValidValue(text())) if (!defaulting() || !text().equals(getTag().getValue())) // don't
// override
// global
// if text
// hasn't
// changed
// don't override global if text hasn't changed
if (focused() && isValidValue(text()) && (!defaulting() || !text().equals(getTag().getValue()))) {
getTag().setValue(text());
}
}
@Override
public void setFocus(boolean focus) {
if (!focus && !isValidValue(text())) setText(renderTag().getValue());
super.setFocus(focus);
}
};
public OptionTextField(String name) {
super(name);
textField.h = 20;
}
@Override
public void onAdded(OptionScrollSlot slot) {
super.onAdded(slot);
}
@Override
@@ -52,11 +43,16 @@ public class OptionTextField extends Option {
return translateN(name);
}
protected int getMaxInputWidth() {
return slot.slotWidth();
}
@Override
public void draw(int mousex, int mousey, float frame) {
drawString(getPrefix(), 10, 6, -1);
GuiDraw.drawString(getPrefix(), 10, 6, -1);
textField.w = slot.slotWidth() - getStringWidth(getPrefix()) - 16;
textField.w = Math
.max(60, Math.min(getMaxInputWidth(), slot.slotWidth() - GuiDraw.getStringWidth(getPrefix())) - 16);
textField.x = slot.slotWidth() - textField.w;
textField.draw(mousex, mousey);
}
@@ -17,6 +17,7 @@ public class OptionToggleButton extends OptionButton {
return renderTag().getBooleanValue();
}
@Override
public String getButtonText() {
return translateN(name + (state() ? ".true" : ".false"));
}
@@ -46,6 +46,8 @@ public class OptionUtilities extends OptionStringSet {
x += 24;
LayoutManager.drawIcon(x + 4, 4, new Image(132, 12, 12, 12));
x += 24;
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
RenderHelper.enableGUIStandardItemLighting();
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
ItemStack sword = new ItemStack(Items.diamond_sword);
@@ -55,5 +57,6 @@ public class OptionUtilities extends OptionStringSet {
GuiContainerManager.drawItem(x + 2, 2, new ItemStack(Items.potionitem));
x += 24;
GuiContainerManager.drawItem(x + 2, 2, new ItemStack(Blocks.stone));
GL11.glPopAttrib();
}
}
@@ -10,6 +10,7 @@ public abstract class RegistryDumper<T> extends DataDumper {
super(name);
}
@SuppressWarnings("unchecked")
@Override
public Iterable<String[]> dump(int mode) {
LinkedList<String[]> list = new LinkedList<>();
@@ -23,8 +23,8 @@ import codechicken.nei.config.Option;
public class GuiPresetList extends GuiOptionPane {
private final Option opt;
protected final static int SLOT_HEIGHT = 24;
protected final static int BUTTON_HEIGHT = 20;
protected static final int SLOT_HEIGHT = 24;
protected static final int BUTTON_HEIGHT = 20;
protected GuiCCButton createButton;
protected GuiCCButton toggleButton;
protected int sortingItemIndex = -1;
@@ -68,10 +68,6 @@ public class GuiPresetList extends GuiOptionPane {
}
}
protected void mouseClicked(int x, int y, int button) {
super.mouseClicked(x, y, button);
}
@Override
protected void mouseMovedOrUp(int x, int y, int button) {
super.mouseMovedOrUp(x, y, button);
@@ -151,7 +147,7 @@ public class GuiPresetList extends GuiOptionPane {
}
protected void togglePreset() {
boolean enabled = !PresetsList.presets.stream().filter(g -> g.enabled).findAny().isPresent();
boolean enabled = PresetsList.presets.stream().noneMatch(g -> g.enabled);
for (Preset preset : PresetsList.presets) {
preset.enabled = enabled;
@@ -13,7 +13,6 @@ import org.lwjgl.opengl.GL12;
import codechicken.core.gui.GuiWidget;
import codechicken.lib.gui.GuiDraw;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.ItemList.AllMultiItemFilter;
import codechicken.nei.ItemPanel.ItemPanelSlot;
import codechicken.nei.ItemsGrid;
import codechicken.nei.Label;
@@ -22,7 +21,6 @@ import codechicken.nei.PresetsList.Preset;
import codechicken.nei.PresetsList.PresetMode;
import codechicken.nei.TextField;
import codechicken.nei.api.ItemFilter;
import codechicken.nei.api.ItemInfo;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.guihook.IContainerTooltipHandler;
@@ -52,9 +50,7 @@ public class LeftPanel extends GuiWidget {
@Override
protected ItemFilter getFilter() {
Set<String> identifiers = preset.items;
return new AllMultiItemFilter(
item -> !ItemInfo.hiddenItems.contains(item),
item -> identifiers.contains(Preset.getIdentifier(item)));
return item -> identifiers.contains(Preset.getIdentifier(item));
}
@Override
@@ -146,6 +142,7 @@ public class LeftPanel extends GuiWidget {
grid.restartFilter();
}
@Override
public void mouseClicked(int x, int y, int button) {
grid.mouseClicked(x, y, button);
@@ -183,6 +180,7 @@ public class LeftPanel extends GuiWidget {
protected void onItemsChanges() {}
@Override
public void mouseMovedOrUp(int x, int y, int button) {
nameField.mouseUp(x, y, button);
@@ -203,6 +201,7 @@ public class LeftPanel extends GuiWidget {
}
}
@Override
public void mouseDragged(int x, int y, int button, long time) {
nameField.mouseDragged(x, y, button, time);
@@ -233,6 +232,7 @@ public class LeftPanel extends GuiWidget {
}
}
@Override
public void update() {
int CHECKBOX_WIDTH = (this.width - 12) / 3;
nameLabel.x = this.x + 2;
@@ -271,6 +271,7 @@ public class LeftPanel extends GuiWidget {
grid.refresh(null);
}
@Override
public void draw(int mousex, int mousey, float frame) {
nameLabel.draw(mousex, mousey);
nameField.draw(mousex, mousey);
@@ -305,7 +306,7 @@ public class LeftPanel extends GuiWidget {
}
}
if (tooltip.size() > 0) {
if (!tooltip.isEmpty()) {
tooltip.set(0, tooltip.get(0) + GuiDraw.TOOLTIP_LINESPACE); // add space after 'title'
}
@@ -320,8 +321,16 @@ public class LeftPanel extends GuiWidget {
return tooltip;
}
@Override
public void keyTyped(char c, int keycode) {
nameField.handleKeyPress(keycode, c);
}
@Override
public void mouseScrolled(int x, int y, int scroll) {
if (grid.contains(x, y)) {
grid.shiftPage(-scroll);
}
}
}
@@ -56,7 +56,7 @@ public abstract class PresetItemsGrid extends ItemsGrid {
}
};
public PresetItemsGrid() {
protected PresetItemsGrid() {
pageLabel = new Label("0/0", true);
@@ -15,7 +15,7 @@ import org.lwjgl.opengl.GL12;
import codechicken.core.gui.GuiWidget;
import codechicken.lib.gui.GuiDraw;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.ItemList;
import codechicken.nei.CollapsibleItems;
import codechicken.nei.ItemList.AllMultiItemFilter;
import codechicken.nei.ItemList.AnyMultiItemFilter;
import codechicken.nei.ItemList.NegatedItemFilter;
@@ -28,7 +28,6 @@ import codechicken.nei.PresetsList.Preset;
import codechicken.nei.SearchField.GuiSearchField;
import codechicken.nei.TextField;
import codechicken.nei.api.ItemFilter;
import codechicken.nei.api.ItemInfo;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.guihook.IContainerTooltipHandler;
import codechicken.nei.util.TextHistory;
@@ -55,11 +54,11 @@ public class RightPanel extends GuiWidget {
}
}
protected static abstract class PresetSearchField extends TextField {
protected abstract static class PresetSearchField extends TextField {
private static final TextHistory history = new TextHistory();
public PresetSearchField(String ident) {
protected PresetSearchField(String ident) {
super(ident);
}
@@ -134,9 +133,7 @@ public class RightPanel extends GuiWidget {
@Override
protected ItemFilter getFilter() {
AllMultiItemFilter filter = new AllMultiItemFilter();
filter.filters.add(item -> !ItemInfo.hiddenItems.contains(item));
filter.filters.add(searchField.getFilter());
AllMultiItemFilter filter = new AllMultiItemFilter(searchField.getFilter());
if (enabledPresets.isChecked()) {
AllMultiItemFilter andFilter = new AllMultiItemFilter();
@@ -145,7 +142,7 @@ public class RightPanel extends GuiWidget {
.collect(Collectors.toSet());
andFilter.filters.add(item -> !identifiers.contains(Preset.getIdentifier(item)));
andFilter.filters.add(new NegatedItemFilter(ItemList.collapsibleItems.getItemFilter()));
andFilter.filters.add(new NegatedItemFilter(CollapsibleItems.getItemFilter()));
if (slotIndex != -1) {
orFilter.filters.add(PresetsList.presets.get(slotIndex));
@@ -162,7 +159,7 @@ public class RightPanel extends GuiWidget {
protected boolean isSelected(ItemStack stack) {
if (mouseSelection != null && mouseSelection.items.contains(stack)) {
return mouseSelection.append != false;
return mouseSelection.append;
}
return preset.items.contains(Preset.getIdentifier(stack));
@@ -206,6 +203,7 @@ public class RightPanel extends GuiWidget {
grid.restartFilter();
}
@Override
public void mouseClicked(int x, int y, int button) {
grid.mouseClicked(x, y, button);
@@ -231,6 +229,7 @@ public class RightPanel extends GuiWidget {
protected void onItemsChanges() {}
@Override
public void mouseMovedOrUp(int x, int y, int button) {
searchField.mouseUp(x, y, button);
@@ -300,6 +299,7 @@ public class RightPanel extends GuiWidget {
return null;
}
@Override
public void mouseDragged(int x, int y, int button, long time) {
searchField.mouseDragged(x, y, button, time);
@@ -330,6 +330,7 @@ public class RightPanel extends GuiWidget {
}
}
@Override
public void update() {
enabledPresets.w = 20;
enabledPresets.h = INPUT_HEIGHT;
@@ -345,6 +346,7 @@ public class RightPanel extends GuiWidget {
grid.refresh(null);
}
@Override
public void draw(int mousex, int mousey, float frame) {
enabledPresets.draw(mousex, mousey);
searchField.draw(mousex, mousey);
@@ -372,7 +374,7 @@ public class RightPanel extends GuiWidget {
}
}
if (tooltip.size() > 0) {
if (!tooltip.isEmpty()) {
tooltip.set(0, tooltip.get(0) + GuiDraw.TOOLTIP_LINESPACE); // add space after 'title'
}
@@ -383,10 +385,12 @@ public class RightPanel extends GuiWidget {
return tooltip;
}
@Override
public void keyTyped(char c, int keycode) {
searchField.handleKeyPress(keycode, c);
}
@Override
public void mouseScrolled(int x, int y, int scroll) {
if (grid.contains(x, y)) {
grid.shiftPage(-scroll);
@@ -17,7 +17,6 @@ import cpw.mods.fml.common.eventhandler.Event;
* <br>
* This event is fired on the {@link MinecraftForge#EVENT_BUS}.
*/
@SuppressWarnings("unused")
public class NEIRegisterHandlerInfosEvent extends Event {
public void registerHandlerInfo(HandlerInfo info) {
@@ -16,7 +16,9 @@ import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Consumer;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
@@ -24,6 +26,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.entity.RenderItem;
import net.minecraft.client.resources.IResourceManager;
@@ -41,11 +44,14 @@ import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import codechicken.lib.gui.GuiDraw;
import codechicken.nei.ItemList;
import codechicken.nei.ItemStackSet;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.NEIModContainer;
import codechicken.nei.recipe.StackInfo;
import codechicken.nei.util.ReadableNumberConverter;
import codechicken.nei.util.RenderTooltipEventHelper;
public class GuiContainerManager {
@@ -54,6 +60,7 @@ public class GuiContainerManager {
@Override
public void onResourceManagerReload(IResourceManager p_110549_1_) {
renderingErrorItems.clear();
ItemList.loadItems.restart();
}
}
@@ -149,20 +156,21 @@ public class GuiContainerManager {
* @param includeHandlers If true tooltip handlers will add to the item tip
* @return A list of Strings representing the text to be displayed on each line of the tool tip.
*/
@SuppressWarnings("unchecked")
public static List<String> itemDisplayNameMultiline(ItemStack stack, GuiContainer gui, boolean includeHandlers) {
List<String> namelist = null;
try {
namelist = stack.getTooltip(
Minecraft.getMinecraft().thePlayer,
includeHandlers && Minecraft.getMinecraft().gameSettings.advancedItemTooltips);
} catch (Throwable ignored) {}
} catch (Throwable ignored) {
namelist = new ArrayList<>();
}
if (namelist == null) namelist = new ArrayList<>();
if (namelist.size() == 0) namelist.add("Unnamed");
if (namelist.get(0) == null || namelist.get(0).equals("")) namelist.set(0, "Unnamed");
if (namelist.isEmpty()) {
namelist.add("Unnamed");
} else if (namelist.get(0) == null || namelist.get(0).isEmpty()) {
namelist.set(0, "Unnamed");
}
if (includeHandlers) {
for (IContainerTooltipHandler handler : tooltipHandlers) {
@@ -237,7 +245,6 @@ public class GuiContainerManager {
public static String itemDisplayNameShort(ItemStack itemstack) {
try {
@SuppressWarnings("unchecked")
List<String> namelist = itemstack.getTooltip(Minecraft.getMinecraft().thePlayer, false);
if (!namelist.isEmpty() && !"".equals(namelist.get(0))) {
@@ -270,93 +277,59 @@ public class GuiContainerManager {
return EnumChatFormatting.getTextWithoutFormattingCodes(sb.toString());
}
public static void drawItem(int i, int j, ItemStack itemstack) {
drawItem(i, j, itemstack, false);
public static void drawItem(int offsetX, int offsetY, ItemStack itemstack) {
drawItem(offsetX, offsetY, itemstack, false);
}
public static void drawItem(int i, int j, ItemStack itemstack, boolean smallAmount) {
drawItem(i, j, itemstack, smallAmount, null);
public static void drawItem(int offsetX, int offsetY, ItemStack itemstack, boolean smallAmount) {
drawItem(offsetX, offsetY, itemstack, smallAmount, null);
}
public static void drawItem(int i, int j, ItemStack itemstack, boolean smallAmount, String stackSize) {
drawItem(i, j, itemstack, getFontRenderer(itemstack), smallAmount, stackSize);
public static void drawItem(int offsetX, int offsetY, ItemStack itemstack, boolean smallAmount, String quantity) {
drawItem(offsetX, offsetY, itemstack, getFontRenderer(itemstack), smallAmount, quantity);
}
public static void drawItem(int i, int j, ItemStack itemstack, FontRenderer fontRenderer) {
drawItem(i, j, itemstack, fontRenderer, false, null);
public static void drawItem(int offsetX, int offsetY, ItemStack itemstack, FontRenderer fontRenderer) {
drawItem(offsetX, offsetY, itemstack, fontRenderer, false, null);
}
private static int modelviewDepth = -1;
private static final HashSet<String> stackTraces = new HashSet<>();
private static final ItemStackSet renderingErrorItems = new ItemStackSet();
public static void drawItem(int i, int j, ItemStack itemstack, FontRenderer fontRenderer, boolean smallAmount,
String stackSize) {
enable3DRender();
// for lighting correction
boolean glRescale = GL11.glGetBoolean(GL12.GL_RESCALE_NORMAL);
float zLevel = drawItems.zLevel += 100F;
public static void drawItem(int offsetX, int offsetY, ItemStack itemstack, FontRenderer fontRenderer,
boolean smallAmount, String quantity) {
if (!renderingErrorItems.contains(itemstack)) {
safeItemRenderContext(itemstack, offsetX, offsetY, fontRenderer, () -> {
float scale = smallAmount ? 0.5f : 1f;
String stackSize = quantity;
try {
drawItems.renderItemAndEffectIntoGUI(fontRenderer, renderEngine, itemstack, i, j);
if (stackSize == null) {
if (itemstack.stackSize > 1) {
stackSize = ReadableNumberConverter.INSTANCE.toWideReadableForm(itemstack.stackSize);
if (stackSize == null) {
if (itemstack.stackSize > 1) {
stackSize = ReadableNumberConverter.INSTANCE.toWideReadableForm(itemstack.stackSize);
if (stackSize.length() == 3) {
scale = 0.8f;
} else if (stackSize.length() == 4) {
scale = 0.6f;
} else if (stackSize.length() > 4) {
scale = 0.5f;
}
} else {
stackSize = "";
if (stackSize.length() == 3) {
scale = 0.8f;
} else if (stackSize.length() == 4) {
scale = 0.6f;
} else if (stackSize.length() > 4) {
scale = 0.5f;
}
}
if (scale != 1f) {
if (!stackSize.isEmpty()) {
drawBigStackSize(i, j, stackSize, scale);
}
// stackSize = "". it needed for correct draw item with alpha and blend
drawItems.renderItemOverlayIntoGUI(fontRenderer, renderEngine, itemstack, i, j, "");
} else {
drawItems.renderItemOverlayIntoGUI(fontRenderer, renderEngine, itemstack, i, j, stackSize);
stackSize = "";
}
if (!checkMatrixStack()) throw new IllegalStateException("Modelview matrix stack too deep");
if (Tessellator.instance.isDrawing) throw new IllegalStateException("Still drawing");
} catch (Exception e) {
NEIClientUtils.reportErrorBuffered(e, stackTraces, itemstack);
restoreMatrixStack();
if (Tessellator.instance.isDrawing) Tessellator.instance.draw();
drawItems.zLevel = zLevel;
drawItems.renderItemIntoGUI(fontRenderer, renderEngine, new ItemStack(Blocks.fire), i, j);
renderingErrorItems.add(itemstack);
}
} else {
drawItems.renderItemIntoGUI(fontRenderer, renderEngine, new ItemStack(Blocks.fire), i, j);
}
if (glRescale) {
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
} else {
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
}
drawItems.renderItemAndEffectIntoGUI(fontRenderer, renderEngine, itemstack, offsetX, offsetY);
enable2DRender();
drawItems.zLevel = zLevel - 100;
if (scale != 1f && !stackSize.isEmpty()) {
drawBigStackSize(offsetX, offsetY, stackSize, scale);
stackSize = "";
}
drawItems.renderItemOverlayIntoGUI(fontRenderer, renderEngine, itemstack, offsetX, offsetY, stackSize);
});
}
// copy from appeng.client.render.AppEngRenderItem
@@ -366,19 +339,46 @@ public class GuiContainerManager {
enable2DRender();
GL11.glScaled(scale, scale, scale);
final int X = (int) (((float) offsetX + 16.0f - fontRenderer.getStringWidth(stackSize) * scale)
* inverseScaleFactor);
final int Y = (int) (((float) offsetY + 16.0f - 7.0f * scale) * inverseScaleFactor);
final int X = (int) ((offsetX + 16.0f - fontRenderer.getStringWidth(stackSize) * scale) * inverseScaleFactor);
final int Y = (int) ((offsetY + 16.0f - 7.0f * scale) * inverseScaleFactor);
fontRenderer.drawStringWithShadow(stackSize, X, Y, 16777215);
GL11.glScaled(inverseScaleFactor, inverseScaleFactor, inverseScaleFactor);
enable3DRender();
}
private static void safeItemRenderContext(ItemStack stack, int x, int y, FontRenderer fontRenderer,
Runnable callback) {
float zLevel = drawItems.zLevel += 100F;
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
enable3DRender();
if (!renderingErrorItems.contains(stack)) {
try {
callback.run();
if (!checkMatrixStack()) throw new IllegalStateException("Modelview matrix stack too deep");
if (Tessellator.instance.isDrawing) throw new IllegalStateException("Still drawing");
} catch (Exception e) {
NEIClientUtils.reportErrorBuffered(e, stackTraces, stack);
restoreMatrixStack();
if (Tessellator.instance.isDrawing) Tessellator.instance.draw();
drawItems.zLevel = zLevel;
drawItems.renderItemIntoGUI(fontRenderer, renderEngine, new ItemStack(Blocks.fire), x, y);
renderingErrorItems.add(stack);
}
} else {
drawItems.renderItemIntoGUI(fontRenderer, renderEngine, new ItemStack(Blocks.fire), x, y);
}
GL11.glPopAttrib();
drawItems.zLevel = zLevel - 100;
}
public static void registerReloadResourceListener() {
if (Minecraft.getMinecraft().getResourceManager() instanceof SimpleReloadableResourceManager) {
SimpleReloadableResourceManager manager = (SimpleReloadableResourceManager) Minecraft.getMinecraft()
.getResourceManager();
if (Minecraft.getMinecraft().getResourceManager() instanceof SimpleReloadableResourceManager manager) {
manager.registerReloadListener(new ResourcePackReloaded());
}
}
@@ -419,9 +419,9 @@ public class GuiContainerManager {
public GuiContainerManager(GuiContainer screen) {
window = screen;
if (screen instanceof IContainerTooltipHandler) {
if (screen instanceof IContainerTooltipHandler tooltipHandler) {
instanceTooltipHandlers = Collections.synchronizedList(new LinkedList<>());
instanceTooltipHandlers.add((IContainerTooltipHandler) screen);
instanceTooltipHandlers.add(tooltipHandler);
instanceTooltipHandlers.addAll(tooltipHandlers);
} else instanceTooltipHandlers = tooltipHandlers;
}
@@ -546,7 +546,6 @@ public class GuiContainerManager {
public void renderToolTips(int mousex, int mousey) {
List<String> tooltip = new LinkedList<>();
Map<String, String> hotkeys = new HashMap<>();
FontRenderer font = GuiDraw.fontRenderer;
synchronized (instanceTooltipHandlers) {
@@ -554,8 +553,8 @@ public class GuiContainerManager {
tooltip = handler.handleTooltip(window, mousex, mousey, tooltip);
}
ItemStack stack = getStackMouseOver(window);
if (tooltip.isEmpty() && shouldShowTooltip(window)) { // mouseover tip, not holding an item
ItemStack stack = getStackMouseOver(window);
font = getFontRenderer(stack);
if (stack != null) {
tooltip = itemDisplayNameMultiline(stack, window, true);
@@ -568,7 +567,55 @@ public class GuiContainerManager {
}
}
if (tooltip.size() > 0) tooltip.set(0, tooltip.get(0) + GuiDraw.TOOLTIP_LINESPACE); // add space after 'title'
if (!tooltip.isEmpty()) tooltip.set(0, tooltip.get(0) + GuiDraw.TOOLTIP_LINESPACE); // add space after 'title'
if (shouldShowTooltip(window)) {
List<String> hotkeystips = collectHotkeyTips(mousex, mousey);
if (!hotkeystips.isEmpty()) {
if (tooltip.isEmpty()) {
tooltip.addAll(hotkeystips);
} else {
tooltip.addAll(1, hotkeystips);
}
}
}
if (NEIModContainer.isGTNHLibLoaded() && !tooltip.isEmpty()) {
if (RenderTooltipEventHelper.post(stack, this.window, mousex, mousey, font)) {
return;
}
Consumer<List<String>> alternativeRenderer = RenderTooltipEventHelper.getAlternativeRenderer();
if (alternativeRenderer == null) {
drawPagedTooltip(
RenderTooltipEventHelper.getFont(),
RenderTooltipEventHelper.getX() + 12,
RenderTooltipEventHelper.getY() - 12,
tooltip);
} else {
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
RenderHelper.disableStandardItemLighting();
GL11.glDisable(GL11.GL_DEPTH_TEST);
GuiDraw.gui.incZLevel(300.0f);
alternativeRenderer.accept(tooltip);
GuiDraw.gui.incZLevel(-300.0f);
GL11.glEnable(GL11.GL_DEPTH_TEST);
RenderHelper.enableStandardItemLighting();
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
}
RenderTooltipEventHelper.flush();
} else {
drawPagedTooltip(font, mousex + 12, mousey - 12, tooltip);
}
for (IContainerDrawHandler drawHandler : drawHandlers) {
drawHandler.postRenderTooltips(window, mousex, mousey, tooltip);
}
}
private List<String> collectHotkeyTips(int mousex, int mousey) {
Map<String, String> hotkeys = new HashMap<>();
synchronized (instanceTooltipHandlers) {
for (IContainerTooltipHandler handler : instanceTooltipHandlers) {
@@ -577,38 +624,61 @@ public class GuiContainerManager {
}
if (!hotkeys.isEmpty()) {
List<String> hotkeystips = new ArrayList<>();
if (!NEIClientUtils.altKey()) {
tooltip.add(
1,
hotkeystips.add(
EnumChatFormatting.GRAY + translate(
"showHotkeys",
"" + EnumChatFormatting.GOLD + "ALT" + EnumChatFormatting.GRAY));
EnumChatFormatting.GOLD + translate("key.alt") + EnumChatFormatting.GRAY));
} else {
List<String> hotkeystips = new LinkedList<>();
Map<String, List<String>> messages = new HashMap<>();
hotkeys.remove(null);
hotkeys.remove("");
for (String key : hotkeys.keySet()) {
hotkeystips.add(getHotkeyTip(key, hotkeys.get(key)));
for (Map.Entry<String, String> entry : hotkeys.entrySet()) {
messages.computeIfAbsent(entry.getValue(), m -> new ArrayList<>()).add(entry.getKey());
}
hotkeystips.sort((a, b) -> Integer.compare(a.indexOf(" - "), b.indexOf(" - ")));
for (List<String> keys : messages.values()) {
Collections.sort(keys, (a, b) -> {
if (a.length() != b.length()) {
return Integer.compare(a.length(), b.length());
}
return a.compareTo(b);
});
}
messages.entrySet().stream().sorted((a, b) -> {
String sa = String.join("/", a.getValue());
String sb = String.join("/", b.getValue());
if (sa.length() != sb.length()) {
return Integer.compare(sa.length(), sb.length());
}
return sa.compareTo(sb);
}).map(entry -> getHotkeyTip(entry.getValue(), entry.getKey()))
.collect(Collectors.toCollection(() -> hotkeystips));
hotkeystips.set(
hotkeystips.size() - 1,
hotkeystips.get(hotkeystips.size() - 1) + GuiDraw.TOOLTIP_LINESPACE);
tooltip.addAll(1, hotkeystips);
}
return hotkeystips;
}
drawPagedTooltip(font, mousex + 12, mousey - 12, tooltip);
for (IContainerDrawHandler drawHandler : drawHandlers) {
drawHandler.postRenderTooltips(window, mousex, mousey, tooltip);
}
return Collections.emptyList();
}
private String getHotkeyTip(String key, String message) {
return EnumChatFormatting.GOLD + key + EnumChatFormatting.GRAY + " - " + message + EnumChatFormatting.RESET;
private String getHotkeyTip(List<String> keys, String message) {
return EnumChatFormatting.GOLD
+ String.join(EnumChatFormatting.DARK_GRAY + " / " + EnumChatFormatting.GOLD, keys)
+ EnumChatFormatting.GRAY
+ " - "
+ message
+ EnumChatFormatting.RESET;
}
private static int tooltipPage;
@@ -623,7 +693,19 @@ public class GuiContainerManager {
"inventory.tooltip.page",
tooltipPage + 1,
tooltips.size(),
NEIClientConfig.getKeyName(NEIClientConfig.getKeyBinding("gui.next_tooltip"), true)));
NEIClientConfig.getKeyName("gui.next_tooltip")));
}
if (NEIModContainer.isGTNHLibLoaded()) {
drawMultilineTip(
font,
x,
y,
tooltips.get(tooltipPage),
RenderTooltipEventHelper.getBackgroundStart(),
RenderTooltipEventHelper.getBackgroundEnd(),
RenderTooltipEventHelper.getBorderStart(),
RenderTooltipEventHelper.getBorderEnd());
return;
}
drawMultilineTip(font, x, y, tooltips.get(tooltipPage));
}
@@ -713,7 +795,7 @@ public class GuiContainerManager {
if (Keyboard.getEventKeyState() || (k == 0 && Character.isDefined(c))) {
try {
keyTyped(c, k);
} catch (java.lang.IndexOutOfBoundsException e) {
} catch (IndexOutOfBoundsException e) {
System.err.println("Caught out of bounds exception pressing " + c + " " + k);
e.printStackTrace();
}
@@ -736,43 +818,17 @@ public class GuiContainerManager {
* Delegate for changing item rendering for certain slots. Eg. Shrinking text for large itemstacks
*/
public void drawSlotItem(Slot slot, ItemStack stack, int x, int y, String quantity) {
// for lighting correction
boolean glRescale = GL11.glGetBoolean(GL12.GL_RESCALE_NORMAL);
float zLevel = drawItems.zLevel += 100F;
if (!renderingErrorItems.contains(stack)) {
try {
if (window instanceof IGuiSlotDraw) {
((IGuiSlotDraw) window).drawSlotItem(slot, stack, x, y, quantity);
} else {
if (quantity == null) {
quantity = stack != null && stack.stackSize > 1 ? String.valueOf(stack.stackSize) : "";
}
drawItems.renderItemAndEffectIntoGUI(fontRenderer, renderEngine, stack, x, y);
drawItems.renderItemOverlayIntoGUI(fontRenderer, renderEngine, stack, x, y, quantity);
}
} catch (Exception e) {
NEIClientUtils.reportErrorBuffered(e, stackTraces, stack);
restoreMatrixStack();
if (Tessellator.instance.isDrawing) Tessellator.instance.draw();
drawItems.zLevel = zLevel;
drawItems.renderItemIntoGUI(fontRenderer, renderEngine, new ItemStack(Blocks.fire), x, y);
renderingErrorItems.add(stack);
}
} else {
drawItems.renderItemIntoGUI(fontRenderer, renderEngine, new ItemStack(Blocks.fire), x, y);
if (window instanceof IGuiSlotDraw) {
safeItemRenderContext(
stack,
x,
y,
fontRenderer,
() -> ((IGuiSlotDraw) window).drawSlotItem(slot, stack, x, y, quantity));
} else if (stack != null) {
drawItem(x, y, stack, false, quantity);
}
if (glRescale) {
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
} else {
GL11.glDisable(GL12.GL_RESCALE_NORMAL);
}
drawItems.zLevel = zLevel - 100;
}
/**
@@ -21,6 +21,7 @@ import java.util.stream.Stream;
*/
final class HideousLinkedList<E> extends LinkedList<E> {
private static final long serialVersionUID = -8504433551965776915L;
private final List<E> backing;
HideousLinkedList(List<E> backing) {
@@ -23,7 +23,9 @@ public interface IContainerTooltipHandler {
* @param currenttip A list of strings, representing each line of the current tooltip as modified by other handlers
* @return The modified list. NOTE: Do not return null
*/
public List<String> handleTooltip(GuiContainer gui, int mousex, int mousey, List<String> currenttip);
default List<String> handleTooltip(GuiContainer gui, int mousex, int mousey, List<String> currenttip) {
return currenttip;
}
/**
* Use this for modifying the multiline display name of an item which may not necessarily be under the mouse.
@@ -35,7 +37,9 @@ public interface IContainerTooltipHandler {
* @param currenttip A list of strings, representing each line of the current tooltip as modified by other handlers
* @return The modified list. NOTE: Do not return null
*/
public List<String> handleItemDisplayName(GuiContainer gui, ItemStack itemstack, List<String> currenttip);
default List<String> handleItemDisplayName(GuiContainer gui, ItemStack itemstack, List<String> currenttip) {
return currenttip;
}
/**
* Use this for modifying the tooltips of items that are under the mouse. GuiContainerManager.shouldShowTooltip is
@@ -46,8 +50,10 @@ public interface IContainerTooltipHandler {
* @param currenttip A list of strings, representing each line of the current tooltip as modified by other handlers
* @return The modified list. NOTE: Do not return null
*/
public List<String> handleItemTooltip(GuiContainer gui, ItemStack itemstack, int mousex, int mousey,
List<String> currenttip);
default List<String> handleItemTooltip(GuiContainer gui, ItemStack itemstack, int mousex, int mousey,
List<String> currenttip) {
return currenttip;
}
/**
* Use this to specify a list of hotkeys that will work when hovering over an element that is under the mouse
@@ -25,16 +25,16 @@ public class BookmarkRecipeId {
for (Object pos : stacks) {
if (pos instanceof PositionedStack) {
pos = StackInfo.getItemStackWithMinimumDamage(((PositionedStack) pos).items);
if (pos instanceof PositionedStack item) {
pos = StackInfo.getItemStackWithMinimumDamage(item.items);
}
if (pos instanceof ItemStack) {
pos = StackInfo.itemStackToNBT((ItemStack) pos);
if (pos instanceof ItemStack item) {
pos = StackInfo.itemStackToNBT(item);
}
if (pos instanceof NBTTagCompound) {
ingredients.add((NBTTagCompound) pos);
if (pos instanceof NBTTagCompound item) {
ingredients.add(item);
}
}
}
@@ -16,17 +16,19 @@ import codechicken.lib.inventory.InventoryUtils;
import codechicken.nei.FastTransferManager;
import codechicken.nei.PositionedStack;
import codechicken.nei.api.IOverlayHandler;
import cpw.mods.fml.relauncher.ReflectionHelper;
@SuppressWarnings("rawtypes, unchecked")
public class DefaultOverlayHandler implements IOverlayHandler {
public static Class gtItem;
private static Class<?> gtItem;
static {
try {
gtItem = Class.forName("gregtech.api.items.GT_MetaBase_Item");
} catch (ClassNotFoundException ignored) {
gtItem = null;
final ClassLoader loader = DefaultOverlayHandler.class.getClassLoader();
gtItem = ReflectionHelper
.getClass(loader, "gregtech.api.items.MetaBaseItem", "gregtech.api.items.GT_MetaBase_Item");
} catch (Exception ignored) {
/* Do nothing */
}
}
@@ -85,20 +87,21 @@ public class DefaultOverlayHandler implements IOverlayHandler {
if (quantity != 0) moveIngredients(gui, assignedIngredients, quantity);
}
@SuppressWarnings("unchecked")
private boolean clearIngredients(GuiContainer gui, List<PositionedStack> ingreds) {
for (PositionedStack pstack : ingreds) for (Slot slot : (List<Slot>) gui.inventorySlots.inventorySlots)
if (slot.xDisplayPosition == pstack.relx + offsetx && slot.yDisplayPosition == pstack.rely + offsety) {
if (!slot.getHasStack()) continue;
for (PositionedStack pstack : ingreds) {
for (Slot slot : gui.inventorySlots.inventorySlots) {
if (slot.xDisplayPosition == pstack.relx + offsetx && slot.yDisplayPosition == pstack.rely + offsety) {
if (!slot.getHasStack()) continue;
FastTransferManager.clickSlot(gui, slot.slotNumber, 0, 1);
if (slot.getHasStack()) return false;
FastTransferManager.clickSlot(gui, slot.slotNumber, 0, 1);
if (slot.getHasStack()) return false;
}
}
}
return true;
}
@SuppressWarnings("unchecked")
private void moveIngredients(GuiContainer gui, List<IngredientDistribution> assignedIngredients, int quantity) {
for (IngredientDistribution distrib : assignedIngredients) {
if (distrib.slots.length == 0) continue;
@@ -112,7 +115,7 @@ public class DefaultOverlayHandler implements IOverlayHandler {
int slotTransferred = 0;
int slotTransferCap = pstack.getMaxStackSize();
for (Slot slot : (List<Slot>) gui.inventorySlots.inventorySlots) {
for (Slot slot : gui.inventorySlots.inventorySlots) {
if (!slot.getHasStack() || !canMoveFrom(slot, gui)) continue;
ItemStack stack = slot.getStack();
@@ -181,7 +184,7 @@ public class DefaultOverlayHandler implements IOverlayHandler {
assignedSlots.add(new LinkedList<>());
}
while (avaliableSlots.size() > 0 && remainingIngreds.size() > 0) {
while (!avaliableSlots.isEmpty() && !remainingIngreds.isEmpty()) {
for (Iterator<Integer> iterator = remainingIngreds.iterator(); iterator.hasNext();) {
int i = iterator.next();
boolean assigned = false;
@@ -199,8 +202,9 @@ public class DefaultOverlayHandler implements IOverlayHandler {
}
}
if (!assigned || istack.numSlots * istack.stack.getMaxStackSize() >= istack.invAmount)
if (!assigned || istack.numSlots * istack.stack.getMaxStackSize() >= istack.invAmount) {
iterator.remove();
}
}
}
@@ -245,9 +249,8 @@ public class DefaultOverlayHandler implements IOverlayHandler {
return assignedIngredients;
}
@SuppressWarnings("unchecked")
private void findInventoryQuantities(GuiContainer gui, List<DistributedIngred> ingredStacks) {
for (Slot slot : (List<Slot>) gui.inventorySlots.inventorySlots) /* work out how much we have to go round */ {
for (Slot slot : gui.inventorySlots.inventorySlots) /* work out how much we have to go round */ {
if (slot.getHasStack() && canMoveFrom(slot, gui)) {
ItemStack pstack = slot.getStack();
DistributedIngred istack = findIngred(ingredStacks, pstack);
@@ -272,13 +275,12 @@ public class DefaultOverlayHandler implements IOverlayHandler {
return slot.inventory instanceof InventoryPlayer;
}
@SuppressWarnings("unchecked")
public Slot[][] mapIngredSlots(GuiContainer gui, List<PositionedStack> ingredients) {
Slot[][] recipeSlotList = new Slot[ingredients.size()][];
for (int i = 0; i < ingredients.size(); i++) /* identify slots */ {
LinkedList<Slot> recipeSlots = new LinkedList<>();
PositionedStack pstack = ingredients.get(i);
for (Slot slot : (List<Slot>) gui.inventorySlots.inventorySlots) {
for (Slot slot : gui.inventorySlots.inventorySlots) {
if (slot.xDisplayPosition == pstack.relx + offsetx && slot.yDisplayPosition == pstack.rely + offsety) {
recipeSlots.add(slot);
break;
@@ -70,8 +70,7 @@ public class FillFluidContainerHandler extends INEIGuiAdapter {
}
return FluidContainerRegistry.fillFluidContainer(fluidStack, draggedStack);
} else if (draggedStack.getItem() instanceof IFluidContainerItem) {
IFluidContainerItem item = (IFluidContainerItem) draggedStack.getItem();
} else if (draggedStack.getItem() instanceof IFluidContainerItem item) {
if (item.getCapacity(draggedStack) > 0) {
item.drain(draggedStack, item.getCapacity(draggedStack), true);
@@ -51,7 +51,6 @@ public class FuelRecipeHandler extends FurnaceRecipeHandler {
return NEIClientUtils.translate("recipe.fuel");
}
@SuppressWarnings("unchecked")
private void loadAllSmelting() {
// Note: Not safe as written for parallelStream
final Map<ItemStack, ItemStack> smeltingRecipes = (Map<ItemStack, ItemStack>) FurnaceRecipes.smelting()
@@ -1,18 +1,19 @@
package codechicken.nei.recipe;
import static codechicken.lib.gui.GuiDraw.getMousePosition;
import java.awt.Point;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.function.Function;
import java.util.Set;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.item.ItemStack;
import codechicken.lib.gui.GuiDraw;
import codechicken.nei.ItemPanel.ItemPanelSlot;
import codechicken.nei.ItemPanels;
import codechicken.nei.NEIClientConfig;
@@ -24,6 +25,7 @@ public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
public static ArrayList<ICraftingHandler> craftinghandlers = new ArrayList<>();
public static ArrayList<ICraftingHandler> serialCraftingHandlers = new ArrayList<>();
private static Set<String> existingHandlers = new HashSet<>();
public static boolean openRecipeGui(String outputId, Object... results) {
return createRecipeGui(outputId, true, results) != null;
@@ -85,7 +87,7 @@ public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
public static ArrayList<ICraftingHandler> getCraftingHandlers(String outputId, Object... results) {
ArrayList<ICraftingHandler> craftinghandlers = GuiCraftingRecipe.craftinghandlers;
ArrayList<ICraftingHandler> serialCraftingHandlers = GuiCraftingRecipe.serialCraftingHandlers;
Function<ICraftingHandler, ICraftingHandler> recipeHandlerFunction;
UnaryOperator<ICraftingHandler> recipeHandlerFunction;
if ("recipeId".equals(outputId)) {
ItemStack stack = (ItemStack) results[0];
@@ -136,7 +138,7 @@ public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
}
}
final Point mouseover = getMousePosition();
final Point mouseover = GuiDraw.getMousePosition();
ItemPanelSlot panelSlot = ItemPanels.bookmarkPanel.getSlotMouseOver(mouseover.x, mouseover.y);
if (panelSlot != null) {
@@ -155,12 +157,24 @@ public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
public static void registerRecipeHandler(ICraftingHandler handler) {
final String handlerId = handler.getHandlerId();
if (craftinghandlers.stream().anyMatch(h -> h.getHandlerId().equals(handlerId))
|| serialCraftingHandlers.stream().anyMatch(h -> h.getHandlerId().equals(handlerId)))
if (existingHandlers.contains(handlerId)) {
return;
}
synchronized (existingHandlers) {
existingHandlers.add(handlerId);
}
if (NEIClientConfig.serialHandlers.contains(handlerId)) {
synchronized (serialCraftingHandlers) {
serialCraftingHandlers.add(handler);
}
} else {
synchronized (craftinghandlers) {
craftinghandlers.add(handler);
}
}
if (NEIClientConfig.serialHandlers.contains(handlerId)) serialCraftingHandlers.add(handler);
else craftinghandlers.add(handler);
}
@Override
@@ -9,7 +9,6 @@ import java.util.Optional;
import java.util.stream.Collectors;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import net.minecraftforge.client.event.GuiScreenEvent;
@@ -63,7 +62,44 @@ public class GuiOverlayButton extends GuiNEIButton {
}
}
private final static int OVERLAY_BUTTON_ID_START = 4;
public enum ItemOverlayFormat {
BACKGROUND,
ICON;
public static ItemOverlayFormat from(int overlay) {
return overlay == 2 ? ItemOverlayFormat.BACKGROUND : ItemOverlayFormat.ICON;
}
}
public static class ItemOverlayState {
protected PositionedStack slot;
protected boolean isPresent;
public ItemOverlayState(PositionedStack slot, boolean isPresent) {
this.slot = slot;
this.isPresent = isPresent;
}
public boolean isPresent() {
return this.isPresent;
}
public PositionedStack getSlot() {
return this.slot;
}
public void draw(ItemOverlayFormat format) {
LayoutManager.drawItemPresenceOverlay(
this.slot.relx,
this.slot.rely,
this.isPresent,
format == ItemOverlayFormat.BACKGROUND);
}
}
private static final int OVERLAY_BUTTON_ID_START = 4;
public final GuiContainer firstGui;
public final IRecipeHandler handler;
@@ -72,7 +108,7 @@ public class GuiOverlayButton extends GuiNEIButton {
protected ItemsTooltipLineHandler missedMaterialsTooltipLineHandler;
protected final IOverlayHandler overlayHandler;
protected final List<Boolean> itemPresenceCache = new ArrayList<>();
protected final List<ItemOverlayState> itemPresenceCache = new ArrayList<>();
protected boolean requireShiftForOverlayRecipe = true;
protected boolean useOverlayRenderer = false;
protected boolean hasOverlay = false;
@@ -114,26 +150,26 @@ public class GuiOverlayButton extends GuiNEIButton {
public Map<String, String> handleHotkeys(GuiContainer gui, int mousex, int mousey, Map<String, String> hotkeys) {
if (this.requireShiftForOverlayRecipe) {
if (this.requireShiftForOverlayRecipe && this.useOverlayRenderer) {
hotkeys.put(translate("recipe.overlay.fillCraftingGrid.key"), translate("recipe.overlay.fillCraftingGrid"));
}
String keyName = NEIClientConfig.getKeyName(NEIClientConfig.getKeyBinding("gui.bookmark"), true);
String keyName = NEIClientConfig.getKeyName("gui.bookmark");
if (keyName != null) {
hotkeys.put(keyName, translate("recipe.overlay.bookmark"));
}
keyName = NEIClientConfig.getKeyName(NEIClientConfig.getKeyBinding("gui.bookmark_recipe"), true);
keyName = NEIClientConfig.getKeyName("gui.bookmark_recipe");
if (keyName != null) {
hotkeys.put(keyName, translate("recipe.overlay.bookmarkRecipe"));
}
keyName = NEIClientConfig.getKeyName(NEIClientConfig.getKeyBinding("gui.bookmark_count"), true);
keyName = NEIClientConfig.getKeyName("gui.bookmark_count");
if (keyName != null) {
hotkeys.put(keyName, translate("recipe.overlay.bookmarkAmount"));
}
keyName = NEIClientConfig.getKeyName(NEIClientConfig.getKeyBinding("gui.bookmark_recipe_count"), true);
keyName = NEIClientConfig.getKeyName("gui.bookmark_recipe_count");
if (keyName != null) {
hotkeys.put(keyName, translate("recipe.overlay.bookmarkRecipeAndAmount"));
}
@@ -152,20 +188,16 @@ public class GuiOverlayButton extends GuiNEIButton {
public void drawItemPresenceOverlay() {
final int presenceOverlay = NEIClientConfig.itemPresenceOverlay();
final boolean highlightPresentItem = NEIClientConfig.isSlotHighlightPresent();
final List<PositionedStack> ingredients = this.handler.getIngredientStacks(recipeIndex);
final List<Boolean> itemPresenceCache = ingredientsOverlay();
final ItemOverlayFormat format = ItemOverlayFormat.from(presenceOverlay);
for (int j = 0; j < ingredients.size(); j++) {
PositionedStack stack = ingredients.get(j);
Boolean isPresent = j < itemPresenceCache.size() ? itemPresenceCache.get(j) : null;
if (isPresent != null && (highlightPresentItem || !isPresent)) {
LayoutManager.drawItemPresenceOverlay(stack.relx, stack.rely, isPresent, presenceOverlay == 2);
for (ItemOverlayState overlay : ingredientsOverlay()) {
if (highlightPresentItem || !overlay.isPresent()) {
overlay.draw(format);
}
}
}
protected List<Boolean> ingredientsOverlay() {
protected List<ItemOverlayState> ingredientsOverlay() {
List<PositionedStack> ingredients = this.handler.getIngredientStacks(recipeIndex);
if (this.itemPresenceCache.size() != ingredients.size()) {
@@ -178,13 +210,8 @@ public class GuiOverlayButton extends GuiNEIButton {
this.itemPresenceCache.addAll(presenceOverlay(ingredients));
}
List<ItemStack> items = new ArrayList<>();
for (int j = 0; j < ingredients.size(); j++) {
if (j >= this.itemPresenceCache.size() || !this.itemPresenceCache.get(j)) {
items.add(ingredients.get(j).item);
}
}
List<ItemStack> items = this.itemPresenceCache.stream().filter(state -> !state.isPresent())
.map(state -> state.getSlot().item).collect(Collectors.toCollection(ArrayList::new));
if (!items.isEmpty()) {
this.missedMaterialsTooltipLineHandler = new ItemsTooltipLineHandler(
@@ -221,10 +248,9 @@ public class GuiOverlayButton extends GuiNEIButton {
return this.hasOverlay;
}
private List<Boolean> presenceOverlay(List<PositionedStack> ingredients) {
final List<Boolean> itemPresenceSlots = new ArrayList<>();
@SuppressWarnings("unchecked")
final List<ItemStack> invStacks = ((List<Slot>) this.firstGui.inventorySlots.inventorySlots).stream()
private List<ItemOverlayState> presenceOverlay(List<PositionedStack> ingredients) {
final List<ItemOverlayState> itemPresenceSlots = new ArrayList<>();
final List<ItemStack> invStacks = this.firstGui.inventorySlots.inventorySlots.stream()
.filter(
s -> s != null && s.getStack() != null
&& s.getStack().stackSize > 0
@@ -234,9 +260,9 @@ public class GuiOverlayButton extends GuiNEIButton {
for (PositionedStack stack : ingredients) {
Optional<ItemStack> used = invStacks.stream().filter(is -> is.stackSize > 0 && stack.contains(is))
.findFirst();
.findAny();
itemPresenceSlots.add(used.isPresent());
itemPresenceSlots.add(new ItemOverlayState(stack, used.isPresent()));
if (used.isPresent()) {
ItemStack is = used.get();
@@ -10,7 +10,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.stream.Collectors;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
@@ -127,15 +126,27 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
}
public static PermutationTooltipLineHandler getInstance(PositionedStack pStack) {
final ItemFilter filter = TemplateRecipeHandler.getItemFilter();
List<ItemStack> items = Arrays.asList(pStack.items).stream().filter(filter::matches)
.collect(Collectors.toCollection(ArrayList::new));
final List<ItemStack> items = pStack.getFilteredPermutations();
if (items.isEmpty()) {
items = Arrays.asList(pStack.items);
if (items.size() > 1) {
return new PermutationTooltipLineHandler(pStack, items);
}
return new PermutationTooltipLineHandler(pStack, items);
return null;
}
@Override
protected void drawItem(int x, int y, ItemStack drawStack, String stackSize) {
if (StackInfo.equalItemAndNBT(drawStack, this.pStack.item, true)) {
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
GL11.glDisable(GL11.GL_LIGHTING);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GuiDraw.drawRect(x - 1, y - 1, 18, 18, 0x66555555);
GL11.glPopAttrib();
}
super.drawItem(x, y, drawStack, stackSize);
}
}
@@ -237,7 +248,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
guiRecipe.changePage(0);
} else {
final IRecipeFilter filter = new ItemRecipeFilter(GuiRecipe.searchField.getFilter());
ArrayList<Integer> filtered = searchHandler.getSearchResult(filter);
List<Integer> filtered = searchHandler.getSearchResult(filter);
if (filtered == null) {
stop();
@@ -402,7 +413,6 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
}
}
@SuppressWarnings("unchecked")
public void initGui() {
xSize = 176;
ySize = Math.min(Math.max(height - 68, 166), 370);
@@ -478,7 +488,6 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
refreshPage();
}
@SuppressWarnings("unchecked")
private void updateOverlayButtons() {
final List<Integer> indices = getRecipeIndices();
@@ -565,6 +574,10 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
return recipeFilter.filters.size() == 1 ? recipeFilter.filters.get(0) : recipeFilter;
}
public static ItemFilter getSearchItemFilter() {
return searchField.getFilter();
}
private void checkYShift() {
yShift = handlerInfo == null ? 0 : handlerInfo.getYShift();
}
@@ -871,41 +884,40 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
public List<String> handleItemTooltip(GuiContainer gui, ItemStack itemstack, int mousex, int mousey,
List<String> currenttip) {
try (CompatibilityHacks compatibilityHacks = new CompatibilityHacks()) {
List<Integer> indices = getRecipeIndices();
List<Integer> indices = getRecipeIndices();
try (CompatibilityHacks compatibilityHacks = new CompatibilityHacks()) {
for (int recipeIndex : indices) {
currenttip = handler.original.handleItemTooltip(this, itemstack, currenttip, recipeIndex);
}
}
if (NEIClientConfig.showCycledIngredientsTooltip()) {
PositionedStack focused = null;
if (NEIClientConfig.showCycledIngredientsTooltip()) {
PositionedStack focused = null;
for (int refIndex = 0; refIndex < indices.size(); refIndex++) {
final int recipeIndex = indices.get(refIndex);
for (int refIndex = 0; refIndex < indices.size(); refIndex++) {
final int recipeIndex = indices.get(refIndex);
if (itemstack != null && focused == null) {
final List<PositionedStack> stacks = handler.original.getIngredientStacks(recipeIndex);
if (itemstack != null && focused == null) {
final List<PositionedStack> stacks = handler.original.getIngredientStacks(recipeIndex);
for (PositionedStack pStack : stacks) {
if (isMouseOver(pStack, refIndex)) {
focused = pStack;
break;
}
for (PositionedStack pStack : stacks) {
if (isMouseOver(pStack, refIndex)) {
focused = pStack;
break;
}
}
}
if (focused == null || focused.items.length <= 1) {
this.permutationTooltipLineHandler = null;
} else if (this.permutationTooltipLineHandler == null
|| this.permutationTooltipLineHandler.pStack != focused) {
this.permutationTooltipLineHandler = PermutationTooltipLineHandler.getInstance(focused);
}
} else if (this.permutationTooltipLineHandler != null) {
this.permutationTooltipLineHandler = null;
}
if (focused == null || focused.items.length <= 1) {
this.permutationTooltipLineHandler = null;
} else if (this.permutationTooltipLineHandler == null
|| this.permutationTooltipLineHandler.pStack != focused) {
this.permutationTooltipLineHandler = PermutationTooltipLineHandler.getInstance(focused);
}
} else if (this.permutationTooltipLineHandler != null) {
this.permutationTooltipLineHandler = null;
}
if (this.permutationTooltipLineHandler != null) {
@@ -984,7 +996,6 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
}
public void refreshPage() {
RecipeCatalysts.updatePosition(ySize - BG_TOP_HEIGHT - (GuiRecipeCatalyst.fullBorder * 2));
changePage(0);
refreshSlots();
final int recipesPerPage = getRecipesPerPage();
@@ -998,6 +1009,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
checkYShift();
if (!limitToOneRecipe) {
RecipeCatalysts.updatePosition(ySize - BG_TOP_HEIGHT - (GuiRecipeCatalyst.fullBorder * 2));
toggleSearch.w = toggleSearch.h = 12;
toggleSearch.x = borderPadding + buttonWidth;
toggleSearch.y = 17;
@@ -1100,8 +1112,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
.filter(b -> b.recipeIndex == recipeIndex).findAny().orElse(null);
if (overlayButton != null && overlayButton.enabled) {
final String overlayKeyName = NEIClientConfig
.getKeyName(NEIClientConfig.getKeyBinding("gui.overlay_use"), true);
final String overlayKeyName = NEIClientConfig.getKeyName("gui.overlay_use");
if (overlayKeyName != null) {
fontRendererObj.drawStringWithShadow(
@@ -1110,6 +1121,8 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
handlerInfo.getHeight() - fontRendererObj.FONT_HEIGHT,
0xffffff);
}
overlayButton.drawItemPresenceOverlay();
}
}
@@ -213,10 +213,9 @@ public abstract class GuiRecipeTab extends Widget {
File handlerFile = NEIClientConfig.handlerFile;
if (!handlerFile.exists()) {
NEIClientConfig.logger.info("Config file doesn't exist, creating");
try {
try (FileOutputStream fileOutputStream = new FileOutputStream(handlerFile.getAbsoluteFile())) {
assert handlerUrl != null;
ReadableByteChannel readableByteChannel = Channels.newChannel(handlerUrl.openStream());
FileOutputStream fileOutputStream = new FileOutputStream(handlerFile.getAbsoluteFile());
FileChannel fileChannel = fileOutputStream.getChannel();
fileChannel.transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
} catch (IOException e) {
@@ -233,7 +232,7 @@ public abstract class GuiRecipeTab extends Widget {
}
}
try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()))) {
CSVParser csvParser = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(reader);
CSVParser csvParser = CSVFormat.EXCEL.builder().setHeader().setSkipHeaderRecord(true).build().parse(reader);
for (CSVRecord record : csvParser) {
final String handler = record.get("handler");
final String modName = record.get("modName");
@@ -2,6 +2,8 @@ package codechicken.nei.recipe;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import net.minecraft.client.Minecraft;
import net.minecraft.item.ItemStack;
@@ -14,6 +16,7 @@ public class GuiUsageRecipe extends GuiRecipe<IUsageHandler> {
public static ArrayList<IUsageHandler> usagehandlers = new ArrayList<>();
public static ArrayList<IUsageHandler> serialUsageHandlers = new ArrayList<>();
private static Set<String> existingHandlers = new HashSet<>();
public static boolean openRecipeGui(String inputId, Object... ingredients) {
@@ -65,12 +68,25 @@ public class GuiUsageRecipe extends GuiRecipe<IUsageHandler> {
public static void registerUsageHandler(IUsageHandler handler) {
final String handlerId = handler.getHandlerId();
if (usagehandlers.stream().anyMatch(h -> h.getHandlerId().equals(handlerId))
|| serialUsageHandlers.stream().anyMatch(h -> h.getHandlerId().equals(handlerId)))
return;
if (NEIClientConfig.serialHandlers.contains(handlerId)) serialUsageHandlers.add(handler);
else usagehandlers.add(handler);
if (existingHandlers.contains(handlerId)) {
return;
}
synchronized (existingHandlers) {
existingHandlers.add(handlerId);
}
if (NEIClientConfig.serialHandlers.contains(handlerId)) {
synchronized (serialUsageHandlers) {
serialUsageHandlers.add(handler);
}
} else {
synchronized (usagehandlers) {
usagehandlers.add(handler);
}
}
}
private static IUsageHandler getUsageOrCatalystHandler(IUsageHandler handler, String inputId,
@@ -17,8 +17,9 @@ class ItemsHistoryHandler implements ICraftingHandler, IUsageHandler {
@Override
public ICraftingHandler getRecipeHandler(String outputId, Object... results) {
if (NEIClientConfig.showHistoryPanelWidget() && "item".equals(outputId) && results[0] instanceof ItemStack) {
ItemPanels.itemPanel.historyPanel.addItem((ItemStack) results[0]);
if (NEIClientConfig.showHistoryPanelWidget() && "item".equals(outputId)
&& results[0] instanceof ItemStack stack) {
ItemPanels.itemPanel.historyPanel.addItem(stack);
}
return null;
@@ -27,8 +28,9 @@ class ItemsHistoryHandler implements ICraftingHandler, IUsageHandler {
@Override
public IUsageHandler getUsageHandler(String inputId, Object... ingredients) {
if (NEIClientConfig.showHistoryPanelWidget() && "item".equals(inputId) && ingredients[0] instanceof ItemStack) {
ItemPanels.itemPanel.historyPanel.addItem((ItemStack) ingredients[0]);
if (NEIClientConfig.showHistoryPanelWidget() && "item".equals(inputId)
&& ingredients[0] instanceof ItemStack stack) {
ItemPanels.itemPanel.historyPanel.addItem(stack);
}
return null;
@@ -70,12 +72,12 @@ class ItemsHistoryHandler implements ICraftingHandler, IUsageHandler {
}
@Override
public boolean keyTyped(GuiRecipe gui, char keyChar, int keyCode, int recipe) {
public boolean keyTyped(GuiRecipe<?> gui, char keyChar, int keyCode, int recipe) {
return false;
}
@Override
public boolean mouseClicked(GuiRecipe gui, int button, int recipe) {
public boolean mouseClicked(GuiRecipe<?> gui, int button, int recipe) {
return true;
}
@@ -145,10 +145,9 @@ public class RecipeCatalysts {
File catalystFile = NEIClientConfig.catalystFile;
if (!catalystFile.exists()) {
NEIClientConfig.logger.info("Config file doesn't exist, creating");
try {
try (FileOutputStream fileOutputStream = new FileOutputStream(catalystFile.getAbsoluteFile())) {
assert handlerUrl != null;
ReadableByteChannel readableByteChannel = Channels.newChannel(handlerUrl.openStream());
FileOutputStream fileOutputStream = new FileOutputStream(catalystFile.getAbsoluteFile());
FileChannel fileChannel = fileOutputStream.getChannel();
fileChannel.transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
} catch (IOException e) {
@@ -165,7 +164,7 @@ public class RecipeCatalysts {
}
}
try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()))) {
CSVParser csvParser = CSVFormat.EXCEL.withFirstRecordAsHeader().parse(reader);
CSVParser csvParser = CSVFormat.EXCEL.builder().setHeader().setSkipHeaderRecord(true).build().parse(reader);
for (CSVRecord record : csvParser) {
final String handler = record.get("handler");
final String modId = record.get("modId");
@@ -194,7 +193,7 @@ public class RecipeCatalysts {
try {
// gently handling copy&paste from handlers.csv
Class<?> clazz = Class.forName(handler);
Object object = clazz.newInstance();
Object object = clazz.getConstructor().newInstance();
if (object instanceof IRecipeHandler) {
if (forceClassName) {
forceClassNameList.add(handler);
@@ -29,9 +29,10 @@ public class RecipeInfo {
@Override
public boolean equals(Object obj) {
if (!(obj instanceof OverlayKey)) return false;
OverlayKey key = (OverlayKey) obj;
return Objects.equal(ident, key.ident) && guiClass == key.guiClass;
if (obj instanceof OverlayKey item) {
return Objects.equal(ident, item.ident) && guiClass == item.guiClass;
}
return false;
}
@Override
@@ -1,14 +1,22 @@
package codechicken.nei.recipe;
import java.util.Map;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.ItemStack;
import codechicken.nei.ItemPanels;
import codechicken.nei.api.ShortcutInputHandler;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.guihook.IContainerInputHandler;
import codechicken.nei.guihook.IContainerTooltipHandler;
public class RecipeItemInputHandler implements IContainerInputHandler {
public class RecipeItemInputHandler implements IContainerInputHandler, IContainerTooltipHandler {
public static void load() {
RecipeItemInputHandler recipeHandler = new RecipeItemInputHandler();
GuiContainerManager.addInputHandler(recipeHandler);
GuiContainerManager.addTooltipHandler(recipeHandler);
}
@Override
public boolean lastKeyTyped(GuiContainer gui, char keyChar, int keyCode) {
@@ -21,9 +29,21 @@ public class RecipeItemInputHandler implements IContainerInputHandler {
|| ItemPanels.bookmarkPanel.contains(mousex, mousey))
return false;
ItemStack stackover = GuiContainerManager.getStackMouseOver(gui);
return ShortcutInputHandler.handleMouseClick(GuiContainerManager.getStackMouseOver(gui));
}
return ShortcutInputHandler.handleMouseClick(stackover);
@Override
public Map<String, String> handleHotkeys(GuiContainer gui, int mousex, int mousey, Map<String, String> hotkeys) {
if ((gui instanceof GuiRecipe) || ItemPanels.itemPanel.contains(mousex, mousey)
|| ItemPanels.bookmarkPanel.contains(mousex, mousey)
|| ItemPanels.itemPanel.historyPanel.contains(mousex, mousey)) {
hotkeys.putAll(
ShortcutInputHandler
.handleHotkeys(gui, mousex, mousey, GuiContainerManager.getStackMouseOver(gui)));
}
return hotkeys;
}
@Override
@@ -1,8 +1,9 @@
package codechicken.nei.recipe;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.function.Predicate;
import java.util.function.IntPredicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
@@ -14,9 +15,9 @@ class SearchRecipeHandler<H extends IRecipeHandler> {
public H original;
private ArrayList<Integer> filteredRecipes;
private List<Integer> filteredRecipes;
private ArrayList<Integer> searchRecipes;
private List<Integer> searchRecipes;
public SearchRecipeHandler(H handler) {
this.original = handler;
@@ -52,7 +53,7 @@ class SearchRecipeHandler<H extends IRecipeHandler> {
return handler instanceof TemplateRecipeHandler;
}
public static int findFirst(IRecipeHandler handler, Predicate<Integer> predicate) {
public static int findFirst(IRecipeHandler handler, IntPredicate predicate) {
final IRecipeFilter filter = searchingAvailable(handler) ? GuiRecipe.getRecipeListFilter() : null;
int refIndex = -1;
@@ -69,14 +70,14 @@ class SearchRecipeHandler<H extends IRecipeHandler> {
return -1;
}
public ArrayList<Integer> getSearchResult(IRecipeFilter filter) {
public List<Integer> getSearchResult(IRecipeFilter filter) {
if (filteredRecipes.isEmpty() || !this.searchingAvailable()) {
return null;
}
ArrayList<Integer> filtered = null;
final ArrayList<Integer> recipes = IntStream.range(0, filteredRecipes.size()).boxed()
List<Integer> filtered = null;
final List<Integer> recipes = IntStream.range(0, filteredRecipes.size()).boxed()
.collect(Collectors.toCollection(ArrayList::new));
try {
@@ -95,7 +96,7 @@ class SearchRecipeHandler<H extends IRecipeHandler> {
return filtered;
}
public void setSearchIndices(ArrayList<Integer> searchRecipes) {
public void setSearchIndices(List<Integer> searchRecipes) {
this.searchRecipes = searchRecipes;
}
@@ -1,14 +1,7 @@
package codechicken.nei.recipe;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -17,29 +10,26 @@ import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidContainerItem;
import org.apache.commons.io.IOUtils;
import codechicken.nei.ClientHandler;
import codechicken.nei.ItemStackMap;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.LRUCache;
import codechicken.nei.api.IStackStringifyHandler;
import codechicken.nei.api.ItemInfo;
import codechicken.nei.recipe.stackinfo.DefaultStackStringifyHandler;
import codechicken.nei.recipe.stackinfo.GTFluidStackStringifyHandler;
import codechicken.nei.util.ItemStackKey;
public class StackInfo {
public static final ArrayList<IStackStringifyHandler> stackStringifyHandlers = new ArrayList<>();
private static final HashMap<String, HashMap<String, String[]>> guidfilters = new HashMap<>();
private static final FluidStack NULL_FLUID = new FluidStack(FluidRegistry.WATER, 0);
public static final List<IStackStringifyHandler> stackStringifyHandlers = new ArrayList<>();
private static final Map<String, HashMap<String, String[]>> guidfilters = new HashMap<>();
private static final ItemStackMap<String> guidcache = new ItemStackMap<>();
private static final LinkedHashMap<ItemStack, FluidStack> fluidcache = new LinkedHashMap<ItemStack, FluidStack>() {
@Override
protected boolean removeEldestEntry(Map.Entry<ItemStack, FluidStack> eldest) {
return size() > 20;
}
};
private static final LRUCache<ItemStackKey, FluidStack> fluidcache = new LRUCache<>(200);
static {
stackStringifyHandlers.add(new DefaultStackStringifyHandler());
@@ -83,8 +73,20 @@ public class StackInfo {
return stack;
}
public static ItemStack withAmount(ItemStack stack, long customCount) {
if (stack == null) return null;
final NBTTagCompound nbTag = StackInfo.itemStackToNBT(stack);
return nbTag != null ? loadFromNBT(nbTag, customCount) : null;
}
public static int getAmount(ItemStack stack) {
if (stack == null) return 0;
final NBTTagCompound nbTag = StackInfo.itemStackToNBT(stack);
return nbTag != null ? nbTag.getInteger("Count") : 0;
}
public static boolean equalItemAndNBT(ItemStack stackA, ItemStack stackB, boolean useNBT) {
if (!stackA.isItemEqual(stackB)) {
if (stackA == null || stackB == null || !stackA.isItemEqual(stackB)) {
return false;
}
@@ -99,19 +101,20 @@ public class StackInfo {
return true;
}
public static FluidStack getFluid(ItemStack stack) {
FluidStack fluid = fluidcache.get(stack);
public static synchronized FluidStack getFluid(ItemStack stack) {
ItemStackKey key = new ItemStackKey(stack);
FluidStack fluid = fluidcache.get(key);
if (fluid == null && !fluidcache.containsKey(stack)) {
if (fluid == null) {
for (int i = stackStringifyHandlers.size() - 1; i >= 0 && fluid == null; i--) {
fluid = stackStringifyHandlers.get(i).getFluid(stack);
}
fluidcache.put(stack, fluid);
fluidcache.put(key, fluid == null ? NULL_FLUID : fluid);
}
return fluid;
return fluid == NULL_FLUID ? null : fluid;
}
public static boolean isFluidContainer(ItemStack stack) {
@@ -154,10 +157,10 @@ public class StackInfo {
try {
if (local instanceof NBTTagCompound) {
local = ((NBTTagCompound) local).getTag(rule[i]);
} else if (local instanceof NBTTagList) {
local = ((NBTTagList) local).tagList.get(Integer.parseInt(rule[i]));
if (local instanceof NBTTagCompound item) {
local = item.getTag(rule[i]);
} else if (local instanceof NBTTagList item) {
local = item.tagList.get(Integer.parseInt(rule[i]));
} else {
break;
}
@@ -167,8 +170,8 @@ public class StackInfo {
}
}
if (local instanceof NBTBase) {
keys.add(((NBTBase) local).toString());
if (local instanceof NBTBase item) {
keys.add(item.toString());
} else if (local != null) {
keys.add(String.valueOf(local));
}
@@ -187,37 +190,9 @@ public class StackInfo {
}
public static void loadGuidFilters() {
guidfilters.clear();
final File guidFlitersFile = new File(NEIClientConfig.configDir, "guidfilters.cfg");
List<String> itemStrings = new ArrayList<>();
if (guidFlitersFile.exists()) {
try (FileReader reader = new FileReader(guidFlitersFile)) {
NEIClientConfig.logger.info("Loading guid filters from file {}", guidFlitersFile);
itemStrings = IOUtils.readLines(reader);
} catch (IOException e) {
NEIClientConfig.logger.error("Failed to load bookmarks from file {}", guidFlitersFile, e);
e.printStackTrace();
}
} else {
final URL filterUrl = StackInfo.class.getResource("/assets/nei/guidfilters.cfg");
try (BufferedReader reader = new BufferedReader(new InputStreamReader(filterUrl.openStream()))) {
itemStrings = IOUtils.readLines(reader);
} catch (IOException e) {
NEIClientConfig.logger.info("Error parsing guid filters");
e.printStackTrace();
} catch (Exception e) {
NEIClientConfig.logger.info("Error parsing guid filters");
e.printStackTrace();
}
}
for (String guidStr : itemStrings) {
ClientHandler.loadSettingsFile("guidfilters.cfg", lines -> lines.forEach(guidStr -> {
final String[] parts = guidStr.split(",");
final HashMap<String, String[]> rules = new HashMap<>();
@@ -226,7 +201,7 @@ public class StackInfo {
}
guidfilters.put(parts[0], rules);
}
}));
}
public static ItemStack getItemStackWithMinimumDamage(ItemStack[] stacks) {
@@ -235,7 +210,7 @@ public class StackInfo {
if (stacks.length > 1) {
for (ItemStack stack : stacks) {
if (stack.getItem() != null && stack.getItemDamage() < damage) {
if (stack.getItem() != null && !ItemInfo.isHidden(stack) && stack.getItemDamage() < damage) {
damage = stack.getItemDamage();
result = stack;
}
@@ -1,20 +1,17 @@
package codechicken.nei.recipe;
import static codechicken.lib.gui.GuiDraw.changeTexture;
import static codechicken.lib.gui.GuiDraw.drawTexturedModalRect;
import static codechicken.lib.gui.GuiDraw.getMousePosition;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;
@@ -32,20 +29,17 @@ import org.lwjgl.opengl.GL11;
import com.google.common.base.Stopwatch;
import codechicken.lib.gui.GuiDraw;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.ItemList;
import codechicken.nei.ItemList.AllMultiItemFilter;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.NEIServerUtils;
import codechicken.nei.PositionedStack;
import codechicken.nei.PresetsList;
import codechicken.nei.api.DefaultOverlayRenderer;
import codechicken.nei.api.IOverlayHandler;
import codechicken.nei.api.IRecipeOverlayRenderer;
import codechicken.nei.api.IStackPositioner;
import codechicken.nei.api.ItemFilter;
import codechicken.nei.api.ItemInfo;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.guihook.IContainerInputHandler;
import codechicken.nei.guihook.IContainerTooltipHandler;
@@ -187,50 +181,31 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
public List<PositionedStack> getCycledIngredients(int cycle, List<PositionedStack> ingredients) {
if (!NEIClientUtils.shiftKey() && !disableCycledIngredients) {
if (NEIClientConfig.useJEIStyledCycledIngredients()) {
jeiStyledRenderPermutation(ingredients, cycle);
} else {
randomRenderPermutation(ingredients, cycle);
}
randomRenderPermutation(ingredients, cycle);
}
return ingredients;
}
public void randomRenderPermutation(List<PositionedStack> stacks, long cycle) {
final ItemFilter filter = getItemFilter();
final int randCycle = Math.abs(new Random(cycle + offset).nextInt());
cycle = NEIClientConfig.useJEIStyledCycledIngredients() ? cycle
: Math.abs(new Random(cycle + offset).nextInt());
for (PositionedStack stack : stacks) {
if (stack.items.length <= 1) continue;
ArrayList<Integer> filtered = getFilteredIngredientAlternatives(stack, filter);
if (filtered.isEmpty()) {
stack.setPermutationToRender((int) (randCycle % stack.items.length));
} else {
stack.setPermutationToRender(filtered.get((int) (randCycle % filtered.size())));
}
}
}
protected void jeiStyledRenderPermutation(List<PositionedStack> stacks, long cycle) {
final ItemFilter filter = getItemFilter();
for (PositionedStack stack : stacks) {
if (stack.items.length <= 1) continue;
ArrayList<Integer> filtered = getFilteredIngredientAlternatives(stack, filter);
if (filtered.isEmpty()) {
stack.setPermutationToRender((int) (cycle % stack.items.length));
} else {
stack.setPermutationToRender(filtered.get((int) (cycle % filtered.size())));
}
for (PositionedStack pStack : stacks) {
if (pStack.items.length <= 1) continue;
final List<ItemStack> items = pStack.getFilteredPermutations();
pStack.setPermutationToRender(items.get((int) (cycle % items.size())));
}
}
@Deprecated
public void randomRenderPermutation(PositionedStack stack, long cycle) {
Random rand = new Random(cycle + offset);
stack.setPermutationToRender((int) (Math.abs(rand.nextInt()) % stack.items.length));
cycle = NEIClientConfig.useJEIStyledCycledIngredients() ? cycle
: Math.abs(new Random(cycle + offset).nextInt());
if (stack.items.length <= 1) return;
final List<ItemStack> items = stack.getFilteredPermutations();
stack.setPermutationToRender(items.get((int) (cycle % items.size())));
}
public void setIngredientPermutation(Collection<PositionedStack> ingredients, ItemStack ingredient) {
@@ -311,7 +286,7 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
public static class RecipeTransferRectHandler implements IContainerInputHandler, IContainerTooltipHandler {
private static final HashMap<Class<? extends GuiContainer>, HashSet<RecipeTransferRect>> guiMap = new HashMap<>();
private static final Map<Class<? extends GuiContainer>, HashSet<RecipeTransferRect>> guiMap = new ConcurrentHashMap<>();
public static void registerRectsToGuis(List<Class<? extends GuiContainer>> classes,
List<RecipeTransferRect> rects) {
@@ -430,25 +405,6 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
RecipeTransferRectHandler.registerRectsToGuis(getRecipeTransferRectGuis(), transferRects);
}
public static ItemFilter getItemFilter() {
return new AllMultiItemFilter(
item -> !ItemInfo.hiddenItems.contains(item),
PresetsList.getItemFilter(),
GuiRecipe.searchField != null ? GuiRecipe.searchField.getFilter() : null);
}
protected static ArrayList<Integer> getFilteredIngredientAlternatives(PositionedStack stack, ItemFilter filter) {
final ArrayList<Integer> filtered = new ArrayList<>();
for (int i = 0; i < stack.items.length; i++) {
if (filter.matches(stack.items[i])) {
filtered.add(i);
}
}
return filtered;
}
/**
* Add all RecipeTransferRects to the transferRects list during this call. Afterward they may be added to the input
* handler for the corresponding guis from getRecipeTransferRectGuis
@@ -552,16 +508,16 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
switch (direction) {
case 0: // right
drawTexturedModalRect(x, y, tx, ty, var, h);
GuiDraw.drawTexturedModalRect(x, y, tx, ty, var, h);
break;
case 1: // down
drawTexturedModalRect(x, y, tx, ty, w, var);
GuiDraw.drawTexturedModalRect(x, y, tx, ty, w, var);
break;
case 2: // left
drawTexturedModalRect(x + w - var, y, tx + w - var, ty, var, h);
GuiDraw.drawTexturedModalRect(x + w - var, y, tx + w - var, ty, var, h);
break;
case 3: // up
drawTexturedModalRect(x, y + h - var, tx, ty + h - var, w, var);
GuiDraw.drawTexturedModalRect(x, y + h - var, tx, ty + h - var, w, var);
break;
}
}
@@ -594,7 +550,7 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
// available
// This will ideally have been pre-cached elsewhere and will be a NOOP
findFuelsOnce();
return getClass().newInstance();
return getClass().getConstructor().newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -649,14 +605,14 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
public void drawBackground(int recipe) {
GL11.glColor4f(1, 1, 1, 1);
changeTexture(getGuiTexture());
drawTexturedModalRect(0, 0, 5, 11, 166, 65);
GuiDraw.changeTexture(getGuiTexture());
GuiDraw.drawTexturedModalRect(0, 0, 5, 11, 166, 65);
}
public void drawForeground(int recipe) {
GL11.glColor4f(1, 1, 1, 1);
GL11.glDisable(GL11.GL_LIGHTING);
changeTexture(getGuiTexture());
GuiDraw.changeTexture(getGuiTexture());
drawExtras(recipe);
}
@@ -703,7 +659,7 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
@Override
public List<String> handleTooltip(GuiRecipe<?> gui, List<String> currenttip, int recipe) {
if (GuiContainerManager.shouldShowTooltip(gui) && currenttip.size() == 0) {
if (GuiContainerManager.shouldShowTooltip(gui) && currenttip.isEmpty()) {
Point offset = gui.getRecipePosition(recipe);
currenttip = transferRectTooltip(gui, transferRects, offset.x, offset.y, currenttip);
}
@@ -743,21 +699,32 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
public boolean mouseScrolled(GuiRecipe<?> gui, int scroll, int recipe) {
if (!NEIClientUtils.shiftKey()) return false;
final Point pos = getMousePosition();
final Point pos = GuiDraw.getMousePosition();
final Point offset = gui.getRecipePosition(recipe);
final Point relMouse = new Point(pos.x - gui.guiLeft - offset.x, pos.y - gui.guiTop - offset.y);
final PositionedStack overStack = getIngredientMouseOver(relMouse.x, relMouse.y, recipe);
if (overStack != null && overStack.items.length > 1) {
final ItemFilter filter = getItemFilter();
final List<ItemStack> items = overStack.getFilteredPermutations();
int stackIndex = 0;
for (int index = 0; index < items.size(); index++) {
if (NEIServerUtils.areStacksSameTypeCraftingWithNBT(items.get(index), overStack.item)) {
stackIndex = index;
break;
}
}
final ItemStack stack = items.get((items.size() - scroll + stackIndex) % items.size());
if (NEIClientConfig.useJEIStyledCycledIngredients()) {
ItemStack stack = overStack.item;
for (PositionedStack pStack : getIngredientStacks(recipe)) {
shiftPermutationToRender(pStack, stack, scroll, filter);
if (pStack.containsWithNBT(stack)) {
pStack.setPermutationToRender(stack);
}
}
} else {
shiftPermutationToRender(overStack, overStack.item, scroll, filter);
overStack.setPermutationToRender(stack);
}
return true;
@@ -766,35 +733,6 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
return false;
}
private void shiftPermutationToRender(PositionedStack pStack, ItemStack stack, int scroll, ItemFilter filter) {
if (!pStack.containsWithNBT(stack)) return;
final List<Integer> filtered = getFilteredIngredientAlternatives(pStack, filter);
int index = 0;
if (filtered.isEmpty()) {
for (int i = 0; i < pStack.items.length; i++) {
if (NEIServerUtils.areStacksSameTypeCraftingWithNBT(pStack.items[i], stack)) {
index = i;
break;
}
}
pStack.setPermutationToRender((int) ((pStack.items.length - scroll + index) % pStack.items.length));
} else {
for (int i = 0; i < filtered.size(); i++) {
if (NEIServerUtils.areStacksSameTypeCraftingWithNBT(pStack.items[filtered.get(i)], stack)) {
index = i;
break;
}
}
pStack.setPermutationToRender(filtered.get((int) ((filtered.size() - scroll + index) % filtered.size())));
}
}
private PositionedStack getIngredientMouseOver(int mousex, int mousey, int recipe) {
for (PositionedStack pStack : getIngredientStacks(recipe)) {
@@ -813,7 +751,7 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
private static boolean transferRect(GuiContainer gui, Collection<RecipeTransferRect> transferRects, int offsetx,
int offsety, boolean usage) {
Point pos = getMousePosition();
Point pos = GuiDraw.getMousePosition();
Point relMouse = new Point(pos.x - gui.guiLeft - offsetx, pos.y - gui.guiTop - offsety);
for (RecipeTransferRect rect : transferRects) {
if (rect.rect.contains(relMouse) && (usage ? GuiUsageRecipe.openRecipeGui(rect.outputId, rect.results)
@@ -826,7 +764,7 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
private static List<String> transferRectTooltip(GuiContainer gui, Collection<RecipeTransferRect> transferRects,
int offsetx, int offsety, List<String> currenttip) {
Point pos = getMousePosition();
Point pos = GuiDraw.getMousePosition();
Point relMouse = new Point(pos.x - gui.guiLeft - offsetx, pos.y - gui.guiTop - offsety);
for (RecipeTransferRect rect : transferRects) {
if (rect.rect.contains(relMouse)) {
@@ -11,22 +11,27 @@ import net.minecraftforge.fluids.FluidStack;
import codechicken.nei.api.IStackStringifyHandler;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.relauncher.ReflectionHelper;
public class GTFluidStackStringifyHandler implements IStackStringifyHandler {
protected static Class<?> GTDisplayFluid = null;
protected static Class<?> itemFluidDisplay = null;
protected static Method getFluidDisplayStack = null;
protected static Method getFluidFromDisplayStack = null;
public static boolean replaceAE2FCFluidDrop = false;
static {
try {
final Class<?> gtUtility = Class.forName("gregtech.api.util.GT_Utility");
final ClassLoader loader = GTFluidStackStringifyHandler.class.getClassLoader();
final Class<?> gtUtility = ReflectionHelper
.getClass(loader, "gregtech.api.util.GTUtility", "gregtech.api.util.GT_Utility");
GTDisplayFluid = Class.forName("gregtech.common.items.GT_FluidDisplayItem");
itemFluidDisplay = ReflectionHelper.getClass(
loader,
"gregtech.common.items.ItemFluidDisplay",
"gregtech.common.items.GT_FluidDisplayItem");
getFluidFromDisplayStack = gtUtility.getMethod("getFluidFromDisplayStack", ItemStack.class);
getFluidDisplayStack = gtUtility.getMethod("getFluidDisplayStack", FluidStack.class, boolean.class);
} catch (Exception ignored) {
/* Do nothing */
}
@@ -72,7 +77,7 @@ public class GTFluidStackStringifyHandler implements IStackStringifyHandler {
final Item item = stack.getItem();
try {
if (getFluidFromDisplayStack != null && GTDisplayFluid != null && GTDisplayFluid.isInstance(item)) {
if (getFluidFromDisplayStack != null && itemFluidDisplay != null && itemFluidDisplay.isInstance(item)) {
final Object obj = getFluidFromDisplayStack.invoke(null, stack);
if (obj != null) {
@@ -1,50 +1,18 @@
package codechicken.nei.search;
import java.util.HashSet;
import java.util.List;
import java.util.StringJoiner;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import codechicken.nei.ItemList;
import codechicken.nei.ItemStackMap;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.api.ItemFilter;
import codechicken.nei.guihook.GuiContainerManager;
public class TooltipFilter implements ItemFilter {
// lookup optimisation
private static final ConcurrentHashMap<ItemStackKey, String> itemSearchNames = new ConcurrentHashMap<>();
private static class ItemStackKey {
public final ItemStack stack;
public ItemStackKey(ItemStack stack) {
this.stack = stack;
}
@Override
public int hashCode() {
if (this.stack == null) return 1;
int hashCode = 1;
hashCode = 31 * hashCode + stack.stackSize;
hashCode = 31 * hashCode + Item.getIdFromItem(stack.getItem());
hashCode = 31 * hashCode + stack.getItemDamage();
hashCode = 31 * hashCode + (!stack.hasTagCompound() ? 0 : stack.getTagCompound().hashCode());
return hashCode;
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof ItemStackKey)) return false;
return ItemStack.areItemStacksEqual(this.stack, ((ItemStackKey) o).stack);
}
}
private static final ItemStackMap<String> itemSearchNames = new ItemStackMap<>();
private final Pattern pattern;
@@ -57,31 +25,44 @@ public class TooltipFilter implements ItemFilter {
return pattern.matcher(getSearchTooltip(itemStack)).find();
}
public static void populateSearchMap() {
/* Create a snapshot of the current keys in the cache */
HashSet<ItemStackKey> oldItems = new HashSet<>(itemSearchNames.keySet());
for (ItemStack stack : ItemList.items) {
oldItems.remove(new ItemStackKey(stack));
}
itemSearchNames.keySet().removeAll(oldItems);
public static void clearCache() {
itemSearchNames.clear();
}
protected static String getSearchTooltip(ItemStack stack) {
return itemSearchNames.computeIfAbsent(new ItemStackKey(stack), key -> getTooltip(key.stack));
public static void putItem(ItemStack stack) {
String tooltip = getTooltip(stack.copy());
synchronized (itemSearchNames) {
itemSearchNames.put(stack, tooltip);
}
}
public static String getSearchTooltip(ItemStack stack) {
String tooltip = itemSearchNames.get(stack);
if (tooltip == null) {
tooltip = getTooltip(stack.copy());
synchronized (itemSearchNames) {
itemSearchNames.put(stack, tooltip);
}
}
return tooltip;
}
private static String getTooltip(ItemStack itemstack) {
final List<String> list = GuiContainerManager.itemDisplayNameMultiline(itemstack, null, true);
final StringJoiner sb = new StringJoiner("\n");
final int size = list.size();
for (int i = 1; i < size; i++) {
sb.add(list.get(i));
}
try {
List<String> namelist = itemstack.getTooltip(NEIClientUtils.mc().thePlayer, false);
return EnumChatFormatting.getTextWithoutFormattingCodes(sb.toString());
if (namelist.size() > 1) {
return EnumChatFormatting
.getTextWithoutFormattingCodes(String.join("\n", namelist.subList(1, namelist.size())));
}
} catch (Throwable ignored) {}
return "";
}
}
@@ -0,0 +1,203 @@
package codechicken.nei.util;
import java.util.ArrayList;
import java.util.List;
import java.util.function.IntPredicate;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import java.util.stream.IntStream;
import net.minecraft.item.Item;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.oredict.OreDictionary;
import codechicken.nei.ItemList.AllMultiItemFilter;
import codechicken.nei.ItemList.AnyMultiItemFilter;
import codechicken.nei.ItemList.NegatedItemFilter;
import codechicken.nei.api.ItemFilter;
import cpw.mods.fml.common.registry.FMLControlledNamespacedRegistry;
import cpw.mods.fml.common.registry.GameData;
/**
* @formatter:off
*
* parts:
* modname:itemid - identify
* $orename - ore dictionary
* tag.color=red - tag
* 0 or 0-12 - damage
*
* modifiers:
* ! - logical not. exclude items that match the following expression (!minecraft:portal)
* r/.../ - standard java regex (r/^m\w{6}ft$/ = minecraft)
* , - logical or in token (minecraft:potion 16384-16462,!16386)
* | - logical or multi-item search (wrench|hammer)
*
*
* example: minecraft:potion 16384-16462,!16386 | $oreiron | tag.color=red
*/
public class ItemStackFilterParser {
private ItemStackFilterParser() {}
public static ItemFilter parse(String filterText) {
final List<ItemFilter> searchTokens = new ArrayList<>();
filterText = filterText.trim();
if (!filterText.isEmpty()) {
for (String part : filterText.split("\\s*\\|\\s*")) {
AllMultiItemFilter filter = parsePart(part);
if (!filter.filters.isEmpty()) {
searchTokens.add(filter);
}
}
}
if (searchTokens.isEmpty()) {
return null;
} else if (searchTokens.size() == 1) {
return searchTokens.get(0);
} else {
return new AnyMultiItemFilter(searchTokens);
}
}
private static AllMultiItemFilter parsePart(String part) {
final AllMultiItemFilter searchTokens = new AllMultiItemFilter();
for (String token : part.split("\\s+")) {
ItemFilter ruleFilter = parseRules(token);
if (ruleFilter != null) {
searchTokens.filters.add(ruleFilter);
}
}
return searchTokens;
}
protected static ItemFilter parseRules(String token) {
final AnyMultiItemFilter orFilter = new AnyMultiItemFilter();
final AnyMultiItemFilter orNotFilter = new AnyMultiItemFilter();
final AllMultiItemFilter ruleFilter = new AllMultiItemFilter();
for (String rule : token.split(",")) {
boolean ignore = rule.startsWith("!");
ItemFilter filter = null;
if (ignore) {
rule = rule.substring(1);
}
if (rule.startsWith("$")) {
filter = getOreDictFilter(rule.substring(1));
} else if (rule.startsWith("tag.")) {
filter = getTagFilter(rule.substring(4));
} else if (Pattern.matches("^\\d+(-\\d+)?$", rule)) {
filter = getDamageFilter(rule);
} else {
filter = getStringIdentifierFilter(rule);
}
if (filter == null) {
continue;
}
if (ignore) {
orNotFilter.filters.add(filter);
} else {
orFilter.filters.add(filter);
}
}
if (!orFilter.filters.isEmpty()) {
ruleFilter.filters.add(orFilter);
}
if (!orNotFilter.filters.isEmpty()) {
ruleFilter.filters.add(new NegatedItemFilter(orNotFilter));
}
return ruleFilter.filters.isEmpty() ? null : ruleFilter;
}
protected static Predicate<String> getMatcher(String searchText) {
if (searchText.length() >= 3 && searchText.startsWith("r/") && searchText.endsWith("/")) {
try {
Pattern pattern = Pattern.compile(
searchText.substring(2, searchText.length() - 1),
Pattern.MULTILINE | Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
return value -> pattern.matcher(value).find();
} catch (PatternSyntaxException ignored) {}
} else if (!searchText.isEmpty()) {
final String lowerCase = searchText.toLowerCase();
return value -> value.toLowerCase().contains(lowerCase);
}
return null;
}
protected static ItemFilter getOreDictFilter(String rule) {
final Predicate<String> matcher = getMatcher(rule);
if (matcher == null) {
return null;
}
return stack -> IntStream.of(OreDictionary.getOreIDs(stack))
.anyMatch(id -> matcher.test(OreDictionary.getOreName(id)));
}
protected static ItemFilter getTagFilter(String rule) {
final String[] parts = rule.split("=", 2);
final String[] path = parts[0].split("\\.");
final Predicate<String> value = getMatcher(parts[1]);
return stack -> {
Object tag = stack.getTagCompound();
for (int i = 0; i < path.length && tag != null; i++) {
if (tag instanceof NBTTagCompound) {
tag = ((NBTTagCompound) tag).getTag(path[i]);
} else if (tag instanceof NBTTagList) {
tag = ((NBTTagList) tag).tagList.get(Integer.parseInt(path[i]));
} else {
tag = null;
}
}
return tag == null ? value == null : value != null && value.test(tag.toString());
};
}
protected static ItemFilter getDamageFilter(String rule) {
final String[] range = rule.split("-");
final IntPredicate matcher;
if (range.length == 1) {
final int damage = Integer.parseInt(range[0]);
matcher = dmg -> dmg == damage;
} else {
final int damageStart = Integer.parseInt(range[0]);
final int damageEnd = Integer.parseInt(range[1]);
matcher = dmg -> dmg >= damageStart && dmg <= damageEnd;
}
return stack -> matcher.test(stack.getItemDamage());
}
protected static ItemFilter getStringIdentifierFilter(String rule) {
final FMLControlledNamespacedRegistry<Item> iItemRegistry = GameData.getItemRegistry();
final Predicate<String> matcher = getMatcher(rule);
return stack -> {
String name = iItemRegistry.getNameForObject(stack.getItem());
return name != null && !name.isEmpty() && matcher.test(name);
};
}
}
@@ -0,0 +1,33 @@
package codechicken.nei.util;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
public class ItemStackKey {
public final ItemStack stack;
private int hashCode = 1;
public ItemStackKey(ItemStack stack) {
this.stack = stack;
if (this.stack != null) {
this.hashCode = 31 * this.hashCode + stack.stackSize;
this.hashCode = 31 * this.hashCode + Item.getIdFromItem(stack.getItem());
this.hashCode = 31 * this.hashCode + stack.getItemDamage();
this.hashCode = 31 * this.hashCode + (!stack.hasTagCompound() ? 0 : stack.getTagCompound().hashCode());
}
}
@Override
public int hashCode() {
return this.hashCode;
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof ItemStackKey)) return false;
return ItemStack.areItemStacksEqual(this.stack, ((ItemStackKey) o).stack);
}
}
@@ -1,7 +1,5 @@
package codechicken.nei.util;
import java.util.Set;
import javax.annotation.Nullable;
import net.minecraft.nbt.NBTBase;
@@ -34,8 +32,7 @@ public class NBTHelper {
private static boolean matchTagCompound(NBTTagCompound template, NBTTagCompound target) {
if (template.tagMap.size() > target.tagMap.size()) return false;
// noinspection unchecked
for (String key : (Set<String>) template.func_150296_c()) {
for (String key : template.func_150296_c()) {
if (!matchTag(template.getTag(key), target.getTag(key))) return false;
}
@@ -1,5 +1,6 @@
package codechicken.nei.util;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -216,8 +217,9 @@ public class NBTJson {
if (obj.has("__custom_type")) {
try {
final String className = obj.get("__custom_type").getAsString();
return (NBTBase) Class.forName(className).newInstance();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException th) {}
return (NBTBase) Class.forName(className).getConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException
| SecurityException | ClassNotFoundException th) {}
}
return null;
@@ -0,0 +1,78 @@
package codechicken.nei.util;
import static com.gtnewhorizon.gtnhlib.client.event.RenderTooltipEvent.*;
import java.util.List;
import java.util.function.Consumer;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.MinecraftForge;
import com.gtnewhorizon.gtnhlib.client.event.RenderTooltipEvent;
public class RenderTooltipEventHelper {
private static RenderTooltipEvent event;
/**
* @return {@code true} if the event has been canceled
*/
public static boolean post(ItemStack stack, GuiScreen gui, int x, int y, FontRenderer font) {
event = new RenderTooltipEvent(
stack,
gui,
ORIGINAL_BG_START,
ORIGINAL_BG_END,
ORIGINAL_BORDER_START,
ORIGINAL_BORDER_END,
x,
y,
font);
if (stack != null) {
MinecraftForge.EVENT_BUS.post(event);
if (event.isCanceled()) {
flush();
return true;
}
}
return false;
}
public static void flush() {
event = null;
}
public static int getBackgroundStart() {
return event == null ? ORIGINAL_BG_START : event.backgroundStart;
}
public static int getBackgroundEnd() {
return event == null ? ORIGINAL_BG_END : event.backgroundEnd;
}
public static int getBorderStart() {
return event == null ? ORIGINAL_BORDER_START : event.borderStart;
}
public static int getBorderEnd() {
return event == null ? ORIGINAL_BORDER_END : event.borderEnd;
}
public static int getX() {
return event.x;
}
public static int getY() {
return event.y;
}
public static FontRenderer getFont() {
return event.font;
}
public static Consumer<List<String>> getAlternativeRenderer() {
return event.alternativeRenderer;
}
}
@@ -31,7 +31,7 @@ public class TextHistory {
}
public Optional<String> get(Direction direction, String currentText) {
if (direction == direction.NEXT) {
if (direction == Direction.NEXT) {
return getNext(currentText);
} else {
return getPrevious(currentText);
@@ -7,13 +7,6 @@ ILOAD 4
PUTSTATIC codechicken/nei/ItemMobSpawner.placedZ:I
RETURN
list d_spawnerWorld
ACONST_NULL
list spawnerWorld
ALOAD 0
INVOKEVIRTUAL net/minecraft/tileentity/MobSpawnerBaseLogic.func_98271_a()Lnet/minecraft/world/World;
list n_commaFix
LDC *
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
@@ -2,19 +2,26 @@
#
# One line - one group
# Item added in first valid group
# | - logical or. multi-item search (wrench|hammer)
# $ - search by ore dictionary ($ore)
# ! - logical not. exclude items that match the following expression (-@minecraft)
# r/.../ - standard java regex (@r/m\w{6}ft/ = @minecraft)
# 0 - damage filter
# 0-12 - damage range filter
# , - logical or in token
#
#
# parts:
# modname:itemid - identify
# $orename - ore dictionary
# tag.color=red - tag
# 0 or 0-12 - damage
#
# modifiers:
# ! - logical not. exclude items that match the following expression (!minecraft:portal)
# r/.../ - standard java regex (r/^m\w{6}ft$/ = minecraft)
# , - logical or in token (minecraft:potion 16384-16462,!16386)
# | - logical or multi-item search (wrench|hammer)
#
# example: minecraft:potion 16384-16462,!16386 | $oreiron | tag.color=red
#
minecraft:spawn_egg
minecraft:mob_spawner
minecraft:record_
#splash
minecraft:potion >16000
#lingering
minecraft:potion >8000 <9000
#splash potion
minecraft:potion 16000-17000
#lingering potion
minecraft:potion 8000-9000
@@ -1,5 +1,5 @@
# Each line in this file should either be a comment (line starts with '#'), or a prefix of a fully-qualified class name
# (that includes the package name) for a Minecraft GUI Container screen.
# If you delete this file, it will be regenerated with the default enable autofocus list.
net.minecraft.client.gui.inventory.GuiInventory
net.minecraft.client.gui.
makamys.satchels.gui.GuiSatchelsInventory
@@ -53,4 +53,5 @@ miscutils:particleIon,Damage
miscutils:personalHealingDevice
tectech:item.em.debugContainer,tag.symbols
tinkersdefense:Heater Shield,tag.InfiTool
tinkersdefense:Round Shield,tag.InfiTool
tinkersdefense:Round Shield,tag.InfiTool
miscutils:itemCustomMetaCover.miscutils.GtMachineCasings,Damage
@@ -0,0 +1,2 @@
# Each line in this file should either be a comment (line starts with '#'), handler name or handler id.
# If you delete this file, it will be regenerated with the default handlers list.
@@ -0,0 +1,24 @@
# Hidden Items Filters
#
# parts:
# modname:itemid - identify
# $orename - ore dictionary
# tag.color=red - tag
# 0 or 0-12 - damage
#
# modifiers:
# ! - logical not. exclude items that match the following expression (!minecraft:portal)
# r/.../ - standard java regex (r/^m\w{6}ft$/ = minecraft)
# , - logical or in token (minecraft:potion 16384-16462,!16386)
# | - logical or multi-item search (wrench|hammer)
#
# example: minecraft:potion 16384-16462,!16386 | $oreiron | tag.color=red
#
minecraft:portal
minecraft:end_portal
minecraft:fire
minecraft:lava
minecraft:mob_spawner
minecraft:anvil !0
minecraft:flowing_water
minecraft:flowing_lava
@@ -822,6 +822,7 @@ gt.recipe.largeboilerfakefuels,gregtech:gt.blockmachines:1022,,gregtech,TRUE,gre
gt.recipe.largeboilerfakefuels,gregtech:gt.blockmachines:1023,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.vacuumfreezer,gregtech:gt.blockmachines:1002,,gregtech,TRUE,gregapi_post,,,,,
smelting,gregtech:gt.blockmachines:1003,,gregtech,TRUE,gregapi_post,,,,,
smelting,gregtech:gt.blockmachines:15412,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.dieselgeneratorfuel,gregtech:gt.blockmachines:1110,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.dieselgeneratorfuel,gregtech:gt.blockmachines:1111,,gregtech,TRUE,gregapi_post,,,,,
gt.recipe.dieselgeneratorfuel,gregtech:gt.blockmachines:1112,,gregtech,TRUE,gregapi_post,,,,,
@@ -1420,3 +1421,79 @@ techguns.nei.TechgunsChemLabNEIRecipeHandler,Techguns:basicMachine:4,,Techguns,T
techguns.nei.TechgunsAmmoPressNEIRecipeHandler,Techguns:basicMachine:0,,Techguns,TRUE,,,,,,
techguns.nei.TechgunsMetalPressNEIRecipeHandler,Techguns:basicMachine:1,,Techguns,TRUE,,,,,,
techguns.nei.TechgunsChargingStationNEIRecipeHandler,Techguns:basicMachine:9,,Techguns,TRUE,,,,,,
ihl.nei_integration.EvaporatorRecipeHandler,ihl:evaporatorBlock,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.ElectricEvaporatorRecipeHandler,ihl:electricEvaporatorBlock,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.AchesonFurnaceRecipeHandler,ihl:achesonFurnance,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.MuffleFurnaceRecipeHandler,ihl:muffleFurnance,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.DetonationSprayingMachineRecipeHandler,ihl:cannonBronze,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.ExtruderRecipeHandler,ihl:extruder,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.ImpregnatingMachineRecipeHandler,ihl:tubBronze,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.LeadOvenRecipeHandler,ihl:leadOven,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.LoomRecipeHandler,ihl:loom,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.GasWeldingStationGasRecipeHandler,ihl:gasWeldingStation,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.WoodenRollingMachineRecipeHandler,ihl:woodenRollingMachinePart1,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.CryogenicDistillerRecipeHandler,ihl:cryogenicDistiller,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.ChemicalReactorRecipeHandler,ihl:chemicalReactor,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.FluidizedBedReactorRecipeHandler,ihl:fluidizedBedReactor,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.LabElectrolyzerRecipeHandler,ihl:labElectrolyzer,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.RollingMachineRecipeHandler,ihl:rollingMachinePart1,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.PaperMachineRecipeHandler,ihl:paperMachine,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.ElectrolysisBathRecipeHandler,ihl:electrolysisBath,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.WireMillRecipeHandler,ihl:wireMill,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.InjectionMoldRecipeHandler,ihl:injectionMold,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.VulcanizationExtrudingMoldRecipeHandler,ihl:vulcanizationExtrudingMold,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.CrucibleRecipeHandler,ihl:crucible,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.FractionationColumnRecipeHandler,ihl:fractionatorCover,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.IronWorkbenchRecipeHandler,ihl:ironWorkbench,,ihl,TRUE,,,,,,,,,,,
com.cout970.magneticraft.compat.nei.CraftingCrusher,Magneticraft:crusher_control,,Magneticraft,TRUE,,,,,,,,,,,
com.cout970.magneticraft.compat.nei.CraftingGrinder,Magneticraft:grinder_control,,Magneticraft,TRUE,,,,,,,,,,,
com.cout970.magneticraft.compat.nei.CraftingPolymerizer,Magneticraft:polimerizer_control,,Magneticraft,TRUE,,,,,,,,,,,
com.cout970.magneticraft.compat.nei.CraftingBiomassBurner,Magneticraft:biomassburner,,Magneticraft,TRUE,,,,,,,,,,,
com.cout970.magneticraft.compat.nei.CraftingSifter,Magneticraft:sifter_control,,Magneticraft,TRUE,,,,,,,,,,,
pneumaticCraft.common.thirdparty.nei.NEIRefineryManager,PneumaticCraft:refinery,,PneumaticCraft,TRUE,,,,,,,,,,,
pneumaticCraft.common.thirdparty.nei.NEIPlasticMixerManager,PneumaticCraft:plasticMixer,,PneumaticCraft,TRUE,,,,,,,,,,,
pneumaticCraft.common.thirdparty.nei.NEIAmadronTradeManager,PneumaticCraft:amadronTablet,,PneumaticCraft,TRUE,,,,,,,,,,,
pneumaticCraft.common.thirdparty.nei.NEIUVLightBoxManager,PneumaticCraft:uvLightBox,,PneumaticCraft,TRUE,,,,,,,,,,,
pneumaticCraft.common.thirdparty.nei.NEIEtchingAcidManager,PneumaticCraft:etchingAcid,,PneumaticCraft,TRUE,,,,,,,,,,,
pneumaticCraft.common.thirdparty.nei.NEIThermopneumaticProcessingPlantManager,PneumaticCraft:thermopneumaticProcessingPlant,,PneumaticCraft,TRUE,,,,,,,,,,,
pneumaticCraft.common.thirdparty.nei.NEIAssemblyControllerRecipeManager,PneumaticCraft:assemblyController,,PneumaticCraft,TRUE,,,,,,,,,,,
pneumaticCraft.common.thirdparty.nei.NEIPressureChamberRecipeManager,PneumaticCraft:pressureChamberInterface,,PneumaticCraft,TRUE,,,,,,,,,,,
exter.foundry.integration.nei.InductionCrucibleFurnaceRecipeHandler,foundry:foundryMachine:0,,foundry,TRUE,,,,,,,,,,,
exter.foundry.integration.nei.AlloyMixerRecipeHandler,foundry:foundryMachine:2,,foundry,TRUE,,,,,,,,,,,
exter.foundry.integration.nei.MetalCasterRecipeHandler,foundry:foundryMachine:1,,foundry,TRUE,,,,,,,,,,,
exter.foundry.integration.nei.InfuserRecipeHandler,foundry:foundryMachine:3,,foundry,TRUE,,,,,,,,,,,
exter.foundry.integration.nei.InfuserSubstanceRecipeHandler,foundry:foundryMachine:3,,foundry,TRUE,,,,,,,,,,,
exter.foundry.integration.nei.AlloyFurnaceRecipeHandler,foundry:alloyFurnace,,foundry,TRUE,,,,,,,,,,,
exter.foundry.integration.nei.MetalAtomizerRecipeHandler,foundry:foundryMachine:5,,foundry,TRUE,,,,,,,,,,,
net.dries007.tfcnei.recipeHandlers.AnvilRecipeHandler,terrafirmacraft:Anvil,,terrafirmacraft,TRUE,,,,,,,,,,,
net.dries007.tfcnei.recipeHandlers.QuernRecipeHandler,terrafirmacraft:item.Quern,,terrafirmacraft,TRUE,,,,,,,,,,,
net.dries007.tfcnei.recipeHandlers.KilnRecipeHandler,,,terrafirmacraft,TRUE,,,,,,,,,,,
net.dries007.tfcnei.recipeHandlers.LoomRecipeHandler,terrafirmacraft:Loom,,terrafirmacraft,TRUE,,,,,,,,,,,
net.dries007.tfcnei.recipeHandlers.KnappingRecipeHandler,terrafirmacraft:item.LooseRock,,terrafirmacraft,TRUE,,,,,,,,,,,
net.dries007.tfcnei.recipeHandlers.BarrelRecipeHandler,terrafirmacraft:Barrel,,terrafirmacraft,TRUE,,,,,,,,,,,
net.dries007.tfcnei.recipeHandlers.AlloyRecipeHandler,terrafirmacraft:Crucible,,terrafirmacraft,TRUE,,,,,,,,,,,
net.dries007.tfcnei.recipeHandlers.HeatRecipeHandler,terrafirmacraft:Firepit,,terrafirmacraft,TRUE,,,,,,,,,,,
techreborn.compat.nei.FustionReacorRecipeHandler,techreborn:fusioncontrolcomputer,,techreborn,TRUE,,,,,,,,,,,
techreborn.compat.nei.recipes.VacuumFreezerRecipeHandler,techreborn:vacuumfreezer,,techreborn,TRUE,,,,,,,,,,,
techreborn.compat.nei.recipes.ImplosionCompressorRecipeHandler,techreborn:implosioncompressor,,techreborn,TRUE,,,,,,,,,,,
techreborn.compat.nei.recipes.AlloySmelterRecipeHandler,techreborn:alloySmelter,,techreborn,TRUE,,,,,,,,,,,
techreborn.compat.nei.recipes.IronAlloySmelterRecipeHandler,techreborn:alloyfurnace,,techreborn,TRUE,,,,,,,,,,,
techreborn.compat.nei.recipes.IndustrialSawmillRecipeHandler,techreborn:industrialSawmill,,techreborn,TRUE,,,,,,,,,,,
techreborn.compat.nei.recipes.ChemicalReactorRecipeHandler,techreborn:chemicalreactor,,techreborn,TRUE,,,,,,,,,,,
techreborn.compat.nei.recipes.CentrifugeRecipeHandler,techreborn:techreborn.centrifuge,,techreborn,TRUE,,,,,,,,,,,
techreborn.compat.nei.recipes.GrinderRecipeHandler,techreborn:grinder,,techreborn,TRUE,,,,,,,,,,,
techreborn.compat.nei.recipes.IndustrialElectrolyzerRecipeHandler,techreborn:industrialelectrolyzer,,techreborn,TRUE,,,,,,,,,,,
techreborn.compat.nei.recipes.BlastFurnaceRecipeHandler,techreborn:blastFurnace,,techreborn,TRUE,,,,,,,,,,,
techreborn.compat.nei.ShapedRollingMachineHandler,techreborn:rollingmachine,,techreborn,TRUE,,,,,,,,,,,
techreborn.compat.nei.ShapelessRollingMachineHandler,techreborn:rollingmachine,,techreborn,TRUE,,,,,,,,,,,
techreborn.compat.nei.recipes.AssemblingMachineRecipeHandler,techreborn:assemblymachine,,techreborn,TRUE,,,,,,,,,,,
com.fiskmods.lightsabers.nei.LightsaberForgeRecipeHandler,lightsabers:lightsaber_forge_light,,lightsabers,TRUE,,,,,,,,,,,
com.fiskmods.lightsabers.nei.DoubleLightsaberRecipeHandler,lightsabers:lightsaber_forge_dark,,lightsabers,TRUE,,,,,,,,,,,
com.fiskmods.lightsabers.nei.DisassemblyRecipeHandler,lightsabers:disassembly_station,,lightsabers,TRUE,,,,,,,,,,,
matteroverdrive.compat.modules.nei.CraftingHandlerInscriber,mo:inscriber,,mo,TRUE,,,,,,,,,,,
straywolfe.cookingwithtfc.client.nei.CookingPotRecipeHandler,cookingwithtfc:item.clayCookingPot:1,,cookingwithtfc,TRUE,,,,,,,,,,,
straywolfe.cookingwithtfc.client.nei.ClayOvenRecipeHandler,cookingwithtfc:item.clayOvenWall,,cookingwithtfc,TRUE,,,,,,,,,,,
factorization.nei.RecipeGrinder,factorization:diamond_cutting_head,,factorization,TRUE,,,,,,,,,,,
factorization.nei.RecipeMixer,factorization:FzBlock:18,,factorization,TRUE,,,,,,,,,,,
ua.pp.shurgent.tfctech.nei.WireDrawBenchRecipeHandler,tfctech:item.Wire Draw Bench,,tfctech,TRUE,,,,,,,,,,,
mekanism.client.nei.ElectrolyticSeparatorRecipeHandler,Mekanism:MachineBlock2:4,,Mekanism,TRUE,,,,,,,,,,,
1 handler itemName nbtInfo modId modRequired excludedModId priority minVersion maxVersion forceClassName itemNotes
822 gt.recipe.largeboilerfakefuels gregtech:gt.blockmachines:1023 gregtech TRUE gregapi_post
823 gt.recipe.vacuumfreezer gregtech:gt.blockmachines:1002 gregtech TRUE gregapi_post
824 smelting gregtech:gt.blockmachines:1003 gregtech TRUE gregapi_post
825 smelting gregtech:gt.blockmachines:15412 gregtech TRUE gregapi_post
826 gt.recipe.dieselgeneratorfuel gregtech:gt.blockmachines:1110 gregtech TRUE gregapi_post
827 gt.recipe.dieselgeneratorfuel gregtech:gt.blockmachines:1111 gregtech TRUE gregapi_post
828 gt.recipe.dieselgeneratorfuel gregtech:gt.blockmachines:1112 gregtech TRUE gregapi_post
1421 techguns.nei.TechgunsAmmoPressNEIRecipeHandler Techguns:basicMachine:0 Techguns TRUE
1422 techguns.nei.TechgunsMetalPressNEIRecipeHandler Techguns:basicMachine:1 Techguns TRUE
1423 techguns.nei.TechgunsChargingStationNEIRecipeHandler Techguns:basicMachine:9 Techguns TRUE
1424 ihl.nei_integration.EvaporatorRecipeHandler ihl:evaporatorBlock ihl TRUE
1425 ihl.nei_integration.ElectricEvaporatorRecipeHandler ihl:electricEvaporatorBlock ihl TRUE
1426 ihl.nei_integration.AchesonFurnaceRecipeHandler ihl:achesonFurnance ihl TRUE
1427 ihl.nei_integration.MuffleFurnaceRecipeHandler ihl:muffleFurnance ihl TRUE
1428 ihl.nei_integration.DetonationSprayingMachineRecipeHandler ihl:cannonBronze ihl TRUE
1429 ihl.nei_integration.ExtruderRecipeHandler ihl:extruder ihl TRUE
1430 ihl.nei_integration.ImpregnatingMachineRecipeHandler ihl:tubBronze ihl TRUE
1431 ihl.nei_integration.LeadOvenRecipeHandler ihl:leadOven ihl TRUE
1432 ihl.nei_integration.LoomRecipeHandler ihl:loom ihl TRUE
1433 ihl.nei_integration.GasWeldingStationGasRecipeHandler ihl:gasWeldingStation ihl TRUE
1434 ihl.nei_integration.WoodenRollingMachineRecipeHandler ihl:woodenRollingMachinePart1 ihl TRUE
1435 ihl.nei_integration.CryogenicDistillerRecipeHandler ihl:cryogenicDistiller ihl TRUE
1436 ihl.nei_integration.ChemicalReactorRecipeHandler ihl:chemicalReactor ihl TRUE
1437 ihl.nei_integration.FluidizedBedReactorRecipeHandler ihl:fluidizedBedReactor ihl TRUE
1438 ihl.nei_integration.LabElectrolyzerRecipeHandler ihl:labElectrolyzer ihl TRUE
1439 ihl.nei_integration.RollingMachineRecipeHandler ihl:rollingMachinePart1 ihl TRUE
1440 ihl.nei_integration.PaperMachineRecipeHandler ihl:paperMachine ihl TRUE
1441 ihl.nei_integration.ElectrolysisBathRecipeHandler ihl:electrolysisBath ihl TRUE
1442 ihl.nei_integration.WireMillRecipeHandler ihl:wireMill ihl TRUE
1443 ihl.nei_integration.InjectionMoldRecipeHandler ihl:injectionMold ihl TRUE
1444 ihl.nei_integration.VulcanizationExtrudingMoldRecipeHandler ihl:vulcanizationExtrudingMold ihl TRUE
1445 ihl.nei_integration.CrucibleRecipeHandler ihl:crucible ihl TRUE
1446 ihl.nei_integration.FractionationColumnRecipeHandler ihl:fractionatorCover ihl TRUE
1447 ihl.nei_integration.IronWorkbenchRecipeHandler ihl:ironWorkbench ihl TRUE
1448 com.cout970.magneticraft.compat.nei.CraftingCrusher Magneticraft:crusher_control Magneticraft TRUE
1449 com.cout970.magneticraft.compat.nei.CraftingGrinder Magneticraft:grinder_control Magneticraft TRUE
1450 com.cout970.magneticraft.compat.nei.CraftingPolymerizer Magneticraft:polimerizer_control Magneticraft TRUE
1451 com.cout970.magneticraft.compat.nei.CraftingBiomassBurner Magneticraft:biomassburner Magneticraft TRUE
1452 com.cout970.magneticraft.compat.nei.CraftingSifter Magneticraft:sifter_control Magneticraft TRUE
1453 pneumaticCraft.common.thirdparty.nei.NEIRefineryManager PneumaticCraft:refinery PneumaticCraft TRUE
1454 pneumaticCraft.common.thirdparty.nei.NEIPlasticMixerManager PneumaticCraft:plasticMixer PneumaticCraft TRUE
1455 pneumaticCraft.common.thirdparty.nei.NEIAmadronTradeManager PneumaticCraft:amadronTablet PneumaticCraft TRUE
1456 pneumaticCraft.common.thirdparty.nei.NEIUVLightBoxManager PneumaticCraft:uvLightBox PneumaticCraft TRUE
1457 pneumaticCraft.common.thirdparty.nei.NEIEtchingAcidManager PneumaticCraft:etchingAcid PneumaticCraft TRUE
1458 pneumaticCraft.common.thirdparty.nei.NEIThermopneumaticProcessingPlantManager PneumaticCraft:thermopneumaticProcessingPlant PneumaticCraft TRUE
1459 pneumaticCraft.common.thirdparty.nei.NEIAssemblyControllerRecipeManager PneumaticCraft:assemblyController PneumaticCraft TRUE
1460 pneumaticCraft.common.thirdparty.nei.NEIPressureChamberRecipeManager PneumaticCraft:pressureChamberInterface PneumaticCraft TRUE
1461 exter.foundry.integration.nei.InductionCrucibleFurnaceRecipeHandler foundry:foundryMachine:0 foundry TRUE
1462 exter.foundry.integration.nei.AlloyMixerRecipeHandler foundry:foundryMachine:2 foundry TRUE
1463 exter.foundry.integration.nei.MetalCasterRecipeHandler foundry:foundryMachine:1 foundry TRUE
1464 exter.foundry.integration.nei.InfuserRecipeHandler foundry:foundryMachine:3 foundry TRUE
1465 exter.foundry.integration.nei.InfuserSubstanceRecipeHandler foundry:foundryMachine:3 foundry TRUE
1466 exter.foundry.integration.nei.AlloyFurnaceRecipeHandler foundry:alloyFurnace foundry TRUE
1467 exter.foundry.integration.nei.MetalAtomizerRecipeHandler foundry:foundryMachine:5 foundry TRUE
1468 net.dries007.tfcnei.recipeHandlers.AnvilRecipeHandler terrafirmacraft:Anvil terrafirmacraft TRUE
1469 net.dries007.tfcnei.recipeHandlers.QuernRecipeHandler terrafirmacraft:item.Quern terrafirmacraft TRUE
1470 net.dries007.tfcnei.recipeHandlers.KilnRecipeHandler terrafirmacraft TRUE
1471 net.dries007.tfcnei.recipeHandlers.LoomRecipeHandler terrafirmacraft:Loom terrafirmacraft TRUE
1472 net.dries007.tfcnei.recipeHandlers.KnappingRecipeHandler terrafirmacraft:item.LooseRock terrafirmacraft TRUE
1473 net.dries007.tfcnei.recipeHandlers.BarrelRecipeHandler terrafirmacraft:Barrel terrafirmacraft TRUE
1474 net.dries007.tfcnei.recipeHandlers.AlloyRecipeHandler terrafirmacraft:Crucible terrafirmacraft TRUE
1475 net.dries007.tfcnei.recipeHandlers.HeatRecipeHandler terrafirmacraft:Firepit terrafirmacraft TRUE
1476 techreborn.compat.nei.FustionReacorRecipeHandler techreborn:fusioncontrolcomputer techreborn TRUE
1477 techreborn.compat.nei.recipes.VacuumFreezerRecipeHandler techreborn:vacuumfreezer techreborn TRUE
1478 techreborn.compat.nei.recipes.ImplosionCompressorRecipeHandler techreborn:implosioncompressor techreborn TRUE
1479 techreborn.compat.nei.recipes.AlloySmelterRecipeHandler techreborn:alloySmelter techreborn TRUE
1480 techreborn.compat.nei.recipes.IronAlloySmelterRecipeHandler techreborn:alloyfurnace techreborn TRUE
1481 techreborn.compat.nei.recipes.IndustrialSawmillRecipeHandler techreborn:industrialSawmill techreborn TRUE
1482 techreborn.compat.nei.recipes.ChemicalReactorRecipeHandler techreborn:chemicalreactor techreborn TRUE
1483 techreborn.compat.nei.recipes.CentrifugeRecipeHandler techreborn:techreborn.centrifuge techreborn TRUE
1484 techreborn.compat.nei.recipes.GrinderRecipeHandler techreborn:grinder techreborn TRUE
1485 techreborn.compat.nei.recipes.IndustrialElectrolyzerRecipeHandler techreborn:industrialelectrolyzer techreborn TRUE
1486 techreborn.compat.nei.recipes.BlastFurnaceRecipeHandler techreborn:blastFurnace techreborn TRUE
1487 techreborn.compat.nei.ShapedRollingMachineHandler techreborn:rollingmachine techreborn TRUE
1488 techreborn.compat.nei.ShapelessRollingMachineHandler techreborn:rollingmachine techreborn TRUE
1489 techreborn.compat.nei.recipes.AssemblingMachineRecipeHandler techreborn:assemblymachine techreborn TRUE
1490 com.fiskmods.lightsabers.nei.LightsaberForgeRecipeHandler lightsabers:lightsaber_forge_light lightsabers TRUE
1491 com.fiskmods.lightsabers.nei.DoubleLightsaberRecipeHandler lightsabers:lightsaber_forge_dark lightsabers TRUE
1492 com.fiskmods.lightsabers.nei.DisassemblyRecipeHandler lightsabers:disassembly_station lightsabers TRUE
1493 matteroverdrive.compat.modules.nei.CraftingHandlerInscriber mo:inscriber mo TRUE
1494 straywolfe.cookingwithtfc.client.nei.CookingPotRecipeHandler cookingwithtfc:item.clayCookingPot:1 cookingwithtfc TRUE
1495 straywolfe.cookingwithtfc.client.nei.ClayOvenRecipeHandler cookingwithtfc:item.clayOvenWall cookingwithtfc TRUE
1496 factorization.nei.RecipeGrinder factorization:diamond_cutting_head factorization TRUE
1497 factorization.nei.RecipeMixer factorization:FzBlock:18 factorization TRUE
1498 ua.pp.shurgent.tfctech.nei.WireDrawBenchRecipeHandler tfctech:item.Wire Draw Bench tfctech TRUE
1499 mekanism.client.nei.ElectrolyticSeparatorRecipeHandler Mekanism:MachineBlock2:4 Mekanism TRUE
@@ -579,3 +579,78 @@ techguns.nei.TechgunsChemLabNEIRecipeHandler,Techguns,Techguns:basicMachine:4,,T
techguns.nei.TechgunsAmmoPressNEIRecipeHandler,Techguns,Techguns:basicMachine:0,,Techguns,TRUE,,,75,,3,,,,,,
techguns.nei.TechgunsMetalPressNEIRecipeHandler,Techguns,Techguns:basicMachine:1,,Techguns,TRUE,,,75,,3,,,,,,
techguns.nei.TechgunsChargingStationNEIRecipeHandler,Techguns,Techguns:basicMachine:9,,Techguns,TRUE,,,65,,3,,,,,,
ihl.nei_integration.FluidizedBedReactorRecipeHandler,IHL Tools & Machines for IC2V2,ihl:fluidizedBedReactor,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.EvaporatorRecipeHandler,IHL Tools & Machines for IC2V2,ihl:evaporatorBlock,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.ElectricEvaporatorRecipeHandler,IHL Tools & Machines for IC2V2,ihl:electricEvaporatorBlock,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.AchesonFurnaceRecipeHandler,IHL Tools & Machines for IC2V2,ihl:achesonFurnance,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.MuffleFurnaceRecipeHandler,IHL Tools & Machines for IC2V2,ihl:muffleFurnance,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.DetonationSprayingMachineRecipeHandler,IHL Tools & Machines for IC2V2,ihl:cannonBronze,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.ExtruderRecipeHandler,IHL Tools & Machines for IC2V2,ihl:extruder,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.ImpregnatingMachineRecipeHandler,IHL Tools & Machines for IC2V2,ihl:tubBronze,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.LeadOvenRecipeHandler,IHL Tools & Machines for IC2V2,ihl:leadOven,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.LoomRecipeHandler,IHL Tools & Machines for IC2V2,ihl:loom,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.GasWeldingStationGasRecipeHandler,IHL Tools & Machines for IC2V2,ihl:gasWeldingStation,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.WoodenRollingMachineRecipeHandler,IHL Tools & Machines for IC2V2,ihl:woodenRollingMachinePart1,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.CryogenicDistillerRecipeHandler,IHL Tools & Machines for IC2V2,ihl:cryogenicDistiller,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.ChemicalReactorRecipeHandler,IHL Tools & Machines for IC2V2,ihl:chemicalReactor,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.LabElectrolyzerRecipeHandler,IHL Tools & Machines for IC2V2,ihl:labElectrolyzer,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.RollingMachineRecipeHandler,IHL Tools & Machines for IC2V2,ihl:rollingMachinePart1,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.PaperMachineRecipeHandler,IHL Tools & Machines for IC2V2,ihl:paperMachine,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.ElectrolysisBathRecipeHandler,IHL Tools & Machines for IC2V2,ihl:electrolysisBath,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.WireMillRecipeHandler,IHL Tools & Machines for IC2V2,ihl:wireMill,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.InjectionMoldRecipeHandler,IHL Tools & Machines for IC2V2,ihl:injectionMold,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.VulcanizationExtrudingMoldRecipeHandler,IHL Tools & Machines for IC2V2,ihl:vulcanizationExtrudingMold,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.CrucibleRecipeHandler,IHL Tools & Machines for IC2V2,ihl:crucible,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.FractionationColumnRecipeHandler,IHL Tools & Machines for IC2V2,ihl:fractionatorCover,,ihl,TRUE,,,,,,,,,,,
ihl.nei_integration.IronWorkbenchRecipeHandler,IHL Tools & Machines for IC2V2,ihl:ironWorkbench,,ihl,TRUE,,,,,,,,,,,
com.cout970.magneticraft.compat.nei.CraftingCrusher,Magneticraft,Magneticraft:crusher_control,,Magneticraft,TRUE,,,,,,,,,,,
com.cout970.magneticraft.compat.nei.CraftingGrinder,Magneticraft,Magneticraft:grinder_control,,Magneticraft,TRUE,,,,,,,,,,,
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.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,,,,,,,,,,,
pneumaticCraft.common.thirdparty.nei.NEIEtchingAcidManager,PneumaticCraft,PneumaticCraft:etchingAcid,,PneumaticCraft,TRUE,,,,,,,,,,,
pneumaticCraft.common.thirdparty.nei.NEIThermopneumaticProcessingPlantManager,PneumaticCraft,PneumaticCraft:thermopneumaticProcessingPlant,,PneumaticCraft,TRUE,,,,,,,,,,,
pneumaticCraft.common.thirdparty.nei.NEIAssemblyControllerRecipeManager,PneumaticCraft,PneumaticCraft:assemblyController,,PneumaticCraft,TRUE,,,115,,2,,,,,,
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.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,,,,,,,,,,,
exter.foundry.integration.nei.MetalAtomizerRecipeHandler,Foundry,foundry:foundryMachine:5,,foundry,TRUE,,,,,,,,,,,
net.dries007.tfcnei.recipeHandlers.AnvilRecipeHandler,TerraFirmaCraft,terrafirmacraft:Anvil,,terrafirmacraft,TRUE,,10,138,208,2,,,,,,
net.dries007.tfcnei.recipeHandlers.QuernRecipeHandler,TerraFirmaCraft,terrafirmacraft:item.Quern,,terrafirmacraft,TRUE,,,65,166,5,,,,,,
net.dries007.tfcnei.recipeHandlers.KilnRecipeHandler,TerraFirmaCraft,,,terrafirmacraft,TRUE,,,65,166,5,terrafirmacraftneiplugin:textures/gui/pitkiln.png,47,38,14,14,
net.dries007.tfcnei.recipeHandlers.LoomRecipeHandler,TerraFirmaCraft,terrafirmacraft:Loom,,terrafirmacraft,TRUE,,,65,166,5,,,,,,
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,"",,,,,
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,,,,,,,,,,,
techreborn.compat.nei.recipes.AlloySmelterRecipeHandler,TechReborn,techreborn:alloySmelter,,techreborn,TRUE,,,,,,,,,,,
techreborn.compat.nei.recipes.IronAlloySmelterRecipeHandler,TechReborn,techreborn:alloyfurnace,,techreborn,TRUE,,,,,,,,,,,
techreborn.compat.nei.recipes.IndustrialSawmillRecipeHandler,TechReborn,techreborn:industrialSawmill,,techreborn,TRUE,,,,,,,,,,,
techreborn.compat.nei.recipes.ChemicalReactorRecipeHandler,TechReborn,techreborn:chemicalreactor,,techreborn,TRUE,,,,,,,,,,,
techreborn.compat.nei.recipes.CentrifugeRecipeHandler,TechReborn,techreborn:techreborn.centrifuge,,techreborn,TRUE,,,,,,,,,,,
techreborn.compat.nei.recipes.GrinderRecipeHandler,TechReborn,techreborn:grinder,,techreborn,TRUE,,,,,,,,,,,
techreborn.compat.nei.recipes.IndustrialElectrolyzerRecipeHandler,TechReborn,techreborn:industrialelectrolyzer,,techreborn,TRUE,,,,,,,,,,,
techreborn.compat.nei.recipes.BlastFurnaceRecipeHandler,TechReborn,techreborn:blastFurnace,,techreborn,TRUE,,,,,,,,,,,
techreborn.compat.nei.ShapedRollingMachineHandler,TechReborn,techreborn:rollingmachine,,techreborn,TRUE,,,,,,,,,,,
techreborn.compat.nei.ShapelessRollingMachineHandler,TechReborn,techreborn:rollingmachine,,techreborn,TRUE,,,,,,,,,,,
techreborn.compat.nei.recipes.AssemblingMachineRecipeHandler,TechReborn,techreborn:assemblymachine,,techreborn,TRUE,,,,,,,,,,,
com.fiskmods.lightsabers.nei.LightsaberForgeRecipeHandler,Advanced Lightsabers Mod,lightsabers:lightsaber_forge_light,,lightsabers,TRUE,,,,,,,,,,,
com.fiskmods.lightsabers.nei.DoubleLightsaberRecipeHandler,Advanced Lightsabers Mod,lightsabers:lightsaber_forge_dark,,lightsabers,TRUE,,,,,,,,,,,
com.fiskmods.lightsabers.nei.DisassemblyRecipeHandler,Advanced Lightsabers Mod,lightsabers:disassembly_station,,lightsabers,TRUE,,,,,,,,,,,
matteroverdrive.compat.modules.nei.CraftingHandlerInscriber,Matter Overdrive,mo:inscriber,,mo,TRUE,,,,,,,,,,,
straywolfe.cookingwithtfc.client.nei.CookingPotRecipeHandler,Cooking with TFC,cookingwithtfc:item.clayCookingPot:1,,cookingwithtfc,TRUE,,,,,,,,,,,
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,,,,,,,,,,,
1 handler modName itemName nbtInfo modId modRequired excludedModId yShift handlerHeight handlerWidth maxRecipesPerPage imageResource imageX imageY imageWidth imageHeight itemNotes
579 techguns.nei.TechgunsAmmoPressNEIRecipeHandler Techguns Techguns:basicMachine:0 Techguns TRUE 75 3
580 techguns.nei.TechgunsMetalPressNEIRecipeHandler Techguns Techguns:basicMachine:1 Techguns TRUE 75 3
581 techguns.nei.TechgunsChargingStationNEIRecipeHandler Techguns Techguns:basicMachine:9 Techguns TRUE 65 3
582 ihl.nei_integration.FluidizedBedReactorRecipeHandler IHL Tools & Machines for IC2V2 ihl:fluidizedBedReactor ihl TRUE
583 ihl.nei_integration.EvaporatorRecipeHandler IHL Tools & Machines for IC2V2 ihl:evaporatorBlock ihl TRUE
584 ihl.nei_integration.ElectricEvaporatorRecipeHandler IHL Tools & Machines for IC2V2 ihl:electricEvaporatorBlock ihl TRUE
585 ihl.nei_integration.AchesonFurnaceRecipeHandler IHL Tools & Machines for IC2V2 ihl:achesonFurnance ihl TRUE
586 ihl.nei_integration.MuffleFurnaceRecipeHandler IHL Tools & Machines for IC2V2 ihl:muffleFurnance ihl TRUE
587 ihl.nei_integration.DetonationSprayingMachineRecipeHandler IHL Tools & Machines for IC2V2 ihl:cannonBronze ihl TRUE
588 ihl.nei_integration.ExtruderRecipeHandler IHL Tools & Machines for IC2V2 ihl:extruder ihl TRUE
589 ihl.nei_integration.ImpregnatingMachineRecipeHandler IHL Tools & Machines for IC2V2 ihl:tubBronze ihl TRUE
590 ihl.nei_integration.LeadOvenRecipeHandler IHL Tools & Machines for IC2V2 ihl:leadOven ihl TRUE
591 ihl.nei_integration.LoomRecipeHandler IHL Tools & Machines for IC2V2 ihl:loom ihl TRUE
592 ihl.nei_integration.GasWeldingStationGasRecipeHandler IHL Tools & Machines for IC2V2 ihl:gasWeldingStation ihl TRUE
593 ihl.nei_integration.WoodenRollingMachineRecipeHandler IHL Tools & Machines for IC2V2 ihl:woodenRollingMachinePart1 ihl TRUE
594 ihl.nei_integration.CryogenicDistillerRecipeHandler IHL Tools & Machines for IC2V2 ihl:cryogenicDistiller ihl TRUE
595 ihl.nei_integration.ChemicalReactorRecipeHandler IHL Tools & Machines for IC2V2 ihl:chemicalReactor ihl TRUE
596 ihl.nei_integration.LabElectrolyzerRecipeHandler IHL Tools & Machines for IC2V2 ihl:labElectrolyzer ihl TRUE
597 ihl.nei_integration.RollingMachineRecipeHandler IHL Tools & Machines for IC2V2 ihl:rollingMachinePart1 ihl TRUE
598 ihl.nei_integration.PaperMachineRecipeHandler IHL Tools & Machines for IC2V2 ihl:paperMachine ihl TRUE
599 ihl.nei_integration.ElectrolysisBathRecipeHandler IHL Tools & Machines for IC2V2 ihl:electrolysisBath ihl TRUE
600 ihl.nei_integration.WireMillRecipeHandler IHL Tools & Machines for IC2V2 ihl:wireMill ihl TRUE
601 ihl.nei_integration.InjectionMoldRecipeHandler IHL Tools & Machines for IC2V2 ihl:injectionMold ihl TRUE
602 ihl.nei_integration.VulcanizationExtrudingMoldRecipeHandler IHL Tools & Machines for IC2V2 ihl:vulcanizationExtrudingMold ihl TRUE
603 ihl.nei_integration.CrucibleRecipeHandler IHL Tools & Machines for IC2V2 ihl:crucible ihl TRUE
604 ihl.nei_integration.FractionationColumnRecipeHandler IHL Tools & Machines for IC2V2 ihl:fractionatorCover ihl TRUE
605 ihl.nei_integration.IronWorkbenchRecipeHandler IHL Tools & Machines for IC2V2 ihl:ironWorkbench ihl TRUE
606 com.cout970.magneticraft.compat.nei.CraftingCrusher Magneticraft Magneticraft:crusher_control Magneticraft TRUE
607 com.cout970.magneticraft.compat.nei.CraftingGrinder Magneticraft Magneticraft:grinder_control Magneticraft TRUE
608 com.cout970.magneticraft.compat.nei.CraftingPolymerizer Magneticraft Magneticraft:polimerizer_control Magneticraft TRUE
609 com.cout970.magneticraft.compat.nei.CraftingBiomassBurner Magneticraft Magneticraft:biomassburner Magneticraft TRUE
610 com.cout970.magneticraft.compat.nei.CraftingSifter Magneticraft Magneticraft:sifter_control Magneticraft TRUE
611 pneumaticCraft.common.thirdparty.nei.NEIRefineryManager PneumaticCraft PneumaticCraft:refinery PneumaticCraft TRUE 80 4
612 pneumaticCraft.common.thirdparty.nei.NEIPlasticMixerManager PneumaticCraft PneumaticCraft:plasticMixer PneumaticCraft TRUE
613 pneumaticCraft.common.thirdparty.nei.NEIAmadronTradeManager PneumaticCraft PneumaticCraft:amadronTablet PneumaticCraft TRUE
614 pneumaticCraft.common.thirdparty.nei.NEIUVLightBoxManager PneumaticCraft PneumaticCraft:uvLightBox PneumaticCraft TRUE
615 pneumaticCraft.common.thirdparty.nei.NEIEtchingAcidManager PneumaticCraft PneumaticCraft:etchingAcid PneumaticCraft TRUE
616 pneumaticCraft.common.thirdparty.nei.NEIThermopneumaticProcessingPlantManager PneumaticCraft PneumaticCraft:thermopneumaticProcessingPlant PneumaticCraft TRUE
617 pneumaticCraft.common.thirdparty.nei.NEIAssemblyControllerRecipeManager PneumaticCraft PneumaticCraft:assemblyController PneumaticCraft TRUE 115 2
618 pneumaticCraft.common.thirdparty.nei.NEIPressureChamberRecipeManager PneumaticCraft PneumaticCraft:pressureChamberInterface PneumaticCraft TRUE 130 2
619 exter.foundry.integration.nei.InductionCrucibleFurnaceRecipeHandler Foundry foundry:foundryMachine:0 foundry TRUE
620 exter.foundry.integration.nei.AlloyMixerRecipeHandler Foundry foundry:foundryMachine:2 foundry TRUE
621 exter.foundry.integration.nei.MetalCasterRecipeHandler Foundry foundry:foundryMachine:1 foundry TRUE
622 exter.foundry.integration.nei.InfuserRecipeHandler Foundry foundry:foundryMachine:3 foundry TRUE
623 exter.foundry.integration.nei.InfuserSubstanceRecipeHandler Foundry foundry:foundryMachine:3 foundry TRUE
624 exter.foundry.integration.nei.AlloyFurnaceRecipeHandler Foundry foundry:alloyFurnace foundry TRUE
625 exter.foundry.integration.nei.MetalAtomizerRecipeHandler Foundry foundry:foundryMachine:5 foundry TRUE
626 net.dries007.tfcnei.recipeHandlers.AnvilRecipeHandler TerraFirmaCraft terrafirmacraft:Anvil terrafirmacraft TRUE 10 138 208 2
627 net.dries007.tfcnei.recipeHandlers.QuernRecipeHandler TerraFirmaCraft terrafirmacraft:item.Quern terrafirmacraft TRUE 65 166 5
628 net.dries007.tfcnei.recipeHandlers.KilnRecipeHandler TerraFirmaCraft terrafirmacraft TRUE 65 166 5 terrafirmacraftneiplugin:textures/gui/pitkiln.png 47 38 14 14
629 net.dries007.tfcnei.recipeHandlers.LoomRecipeHandler TerraFirmaCraft terrafirmacraft:Loom terrafirmacraft TRUE 65 166 5
630 net.dries007.tfcnei.recipeHandlers.KnappingRecipeHandler TerraFirmaCraft terrafirmacraft:item.LooseRock terrafirmacraft TRUE 96 166 3
631 net.dries007.tfcnei.recipeHandlers.BarrelRecipeHandler TerraFirmaCraft terrafirmacraft:Barrel terrafirmacraft TRUE 65 166 5
632 net.dries007.tfcnei.recipeHandlers.AlloyRecipeHandler TerraFirmaCraft terrafirmacraft:Crucible terrafirmacraft TRUE 65 166 5
633 net.dries007.tfcnei.recipeHandlers.HeatRecipeHandler TerraFirmaCraft terrafirmacraft:Firepit terrafirmacraft TRUE 65 166 5
634 techreborn.compat.nei.FustionReacorRecipeHandler TechReborn techreborn:fusioncontrolcomputer techreborn TRUE
635 techreborn.compat.nei.recipes.VacuumFreezerRecipeHandler TechReborn techreborn:vacuumfreezer techreborn TRUE
636 techreborn.compat.nei.recipes.ImplosionCompressorRecipeHandler TechReborn techreborn:implosioncompressor techreborn TRUE
637 techreborn.compat.nei.recipes.AlloySmelterRecipeHandler TechReborn techreborn:alloySmelter techreborn TRUE
638 techreborn.compat.nei.recipes.IronAlloySmelterRecipeHandler TechReborn techreborn:alloyfurnace techreborn TRUE
639 techreborn.compat.nei.recipes.IndustrialSawmillRecipeHandler TechReborn techreborn:industrialSawmill techreborn TRUE
640 techreborn.compat.nei.recipes.ChemicalReactorRecipeHandler TechReborn techreborn:chemicalreactor techreborn TRUE
641 techreborn.compat.nei.recipes.CentrifugeRecipeHandler TechReborn techreborn:techreborn.centrifuge techreborn TRUE
642 techreborn.compat.nei.recipes.GrinderRecipeHandler TechReborn techreborn:grinder techreborn TRUE
643 techreborn.compat.nei.recipes.IndustrialElectrolyzerRecipeHandler TechReborn techreborn:industrialelectrolyzer techreborn TRUE
644 techreborn.compat.nei.recipes.BlastFurnaceRecipeHandler TechReborn techreborn:blastFurnace techreborn TRUE
645 techreborn.compat.nei.ShapedRollingMachineHandler TechReborn techreborn:rollingmachine techreborn TRUE
646 techreborn.compat.nei.ShapelessRollingMachineHandler TechReborn techreborn:rollingmachine techreborn TRUE
647 techreborn.compat.nei.recipes.AssemblingMachineRecipeHandler TechReborn techreborn:assemblymachine techreborn TRUE
648 com.fiskmods.lightsabers.nei.LightsaberForgeRecipeHandler Advanced Lightsabers Mod lightsabers:lightsaber_forge_light lightsabers TRUE
649 com.fiskmods.lightsabers.nei.DoubleLightsaberRecipeHandler Advanced Lightsabers Mod lightsabers:lightsaber_forge_dark lightsabers TRUE
650 com.fiskmods.lightsabers.nei.DisassemblyRecipeHandler Advanced Lightsabers Mod lightsabers:disassembly_station lightsabers TRUE
651 matteroverdrive.compat.modules.nei.CraftingHandlerInscriber Matter Overdrive mo:inscriber mo TRUE
652 straywolfe.cookingwithtfc.client.nei.CookingPotRecipeHandler Cooking with TFC cookingwithtfc:item.clayCookingPot:1 cookingwithtfc TRUE
653 straywolfe.cookingwithtfc.client.nei.ClayOvenRecipeHandler Cooking with TFC cookingwithtfc:item.clayOvenWall cookingwithtfc TRUE
654 factorization.nei.RecipeMixer Factorization factorization:FzBlock:18 factorization TRUE
655 ua.pp.shurgent.tfctech.nei.WireDrawBenchRecipeHandler Shurgent's TFCTech Addon tfctech:item.Wire Draw Bench tfctech TRUE
656 mekanism.client.nei.ElectrolyticSeparatorRecipeHandler Mekanism Mekanism:MachineBlock2:4 Mekanism TRUE
@@ -104,6 +104,26 @@ nei.options.inventory.search.patternMode=Suchmodus
nei.options.inventory.search.patternMode.0=Gewöhnlich
nei.options.inventory.search.patternMode.1=Erweitert
nei.options.inventory.search.patternMode.2=Regex
nei.options.inventory.search.modNameSearchMode=Modname Suchmodus
nei.options.inventory.search.modNameSearchMode.0=Immer
nei.options.inventory.search.modNameSearchMode.1=Präfix: %s
nei.options.inventory.search.modNameSearchMode.2=Nie
nei.options.inventory.search.tooltipSearchMode=Tooltip Suchmodus
nei.options.inventory.search.tooltipSearchMode.0=Immer
nei.options.inventory.search.tooltipSearchMode.1=Präfix: %s
nei.options.inventory.search.tooltipSearchMode.2=Nie
nei.options.inventory.search.identifierSearchMode=Identifikator Suchmodus
nei.options.inventory.search.identifierSearchMode.0=Immer
nei.options.inventory.search.identifierSearchMode.1=Präfix: %s
nei.options.inventory.search.identifierSearchMode.2=Nie
nei.options.inventory.search.oreDictSearchMode=OreDict Suchmodus
nei.options.inventory.search.oreDictSearchMode.0=Immer
nei.options.inventory.search.oreDictSearchMode.1=Präfix: %s
nei.options.inventory.search.oreDictSearchMode.2=Nie
nei.options.inventory.search.subsetsSearchMode=Item-SubSet Suchmodus
nei.options.inventory.search.subsetsSearchMode.0=Immer
nei.options.inventory.search.subsetsSearchMode.1=Präfix: %s
nei.options.inventory.search.subsetsSearchMode.2=Nie
nei.options.inventory.utilities=Nützliches
nei.options.inventory.utilities.tip=Wähle Inhalte für den Mehrzweckmodus
nei.options.inventory.utilities.time=Zeit
+45 -8
View File
@@ -3,6 +3,8 @@ nei.save=Save
# PC/Linux Control Key
nei.key.ctrl=CTRL
nei.key.shift=SHIFT
nei.key.alt=ALT
# Mac Command Key
nei.key.ctrl.mac=CMD
nei.showHotkeys=Hold %s for hotkeys
@@ -190,9 +192,6 @@ nei.options.inventory.bookmarks.ignorePotionOverlap.false=No
nei.options.inventory.bookmarks.worldSpecific=World Specific Bookmarks
nei.options.inventory.bookmarks.worldSpecific.true=Yes
nei.options.inventory.bookmarks.worldSpecific.false=No
nei.options.inventory.worldSpecificPresets=World Specific Presets
nei.options.inventory.worldSpecificPresets.true=Yes
nei.options.inventory.worldSpecificPresets.false=No
nei.options.inventory.guirecipe=Recipes GUI
nei.options.inventory.guirecipe.jeiStyleTabs=JEI Style Tabs
nei.options.inventory.guirecipe.jeiStyleTabs.true=Yes
@@ -209,7 +208,7 @@ nei.options.inventory.guirecipe.jeiStyleRecipeCatalyst.true=Yes
nei.options.inventory.guirecipe.jeiStyleRecipeCatalyst.false=No
nei.options.inventory.guirecipe.cycledIngredientsTooltip=Cycled Ingredients Tooltip
nei.options.inventory.guirecipe.cycledIngredientsTooltip.true=Show
nei.options.inventory.guirecipe.cycledIngredientsTooltip.false=Nide
nei.options.inventory.guirecipe.cycledIngredientsTooltip.false=Hide
nei.options.inventory.showItemQuantityWidget=Show Item Quantity Widget
nei.options.inventory.showItemQuantityWidget.true=Yes
nei.options.inventory.showItemQuantityWidget.false=No
@@ -217,6 +216,9 @@ nei.options.inventory.search=Search Widget
nei.options.inventory.search.widgetPosition=Widget Position
nei.options.inventory.search.widgetPosition.true=Center
nei.options.inventory.search.widgetPosition.false=Right
nei.options.inventory.search.hideUntilSearching=Hide Until Searching
nei.options.inventory.search.hideUntilSearching.true=Yes
nei.options.inventory.search.hideUntilSearching.false=No
nei.options.inventory.search.widgetAutofocus=Autofocus
nei.options.inventory.search.widgetAutofocus.0=No
nei.options.inventory.search.widgetAutofocus.1=Yes
@@ -225,9 +227,19 @@ nei.options.inventory.search.patternMode=Search Mode
nei.options.inventory.search.patternMode.0=Plain
nei.options.inventory.search.patternMode.1=Extended
nei.options.inventory.search.patternMode.2=Regex
nei.options.inventory.search.spaceMode=Space Works like
nei.options.inventory.search.spaceMode.0=AND
nei.options.inventory.search.spaceMode.0.tip=Space between non-prefixed tokens works like "AND"
nei.options.inventory.search.spaceMode.1=Space
nei.options.inventory.search.spaceMode.1.tip=Space between non-prefixed tokens works like "space"
nei.options.inventory.search.spaceMode.2=AND-X
nei.options.inventory.search.spaceMode.2.tip=Space between non-prefixed tokens works like "AND" but all tokens must be within the same category
nei.options.inventory.search.quoteDropItemName=Quote Drop Item Name
nei.options.inventory.search.quoteDropItemName.true=Yes
nei.options.inventory.search.quoteDropItemName.false=No
nei.options.inventory.search.format=Search Format
nei.options.inventory.search.format.true=Old Format
nei.options.inventory.search.format.false=Extended
nei.options.inventory.search.modNameSearchMode=Mod Name Search
nei.options.inventory.search.modNameSearchMode.0=Always
nei.options.inventory.search.modNameSearchMode.1=Prefix: %s
@@ -295,9 +307,10 @@ nei.options.inventory.disableMouseScrollTransfer.false=False
nei.options.inventory.invertMouseScrollTransfer=Invert Mouse Wheel Transfer Direction
nei.options.inventory.invertMouseScrollTransfer.true=True
nei.options.inventory.invertMouseScrollTransfer.false=False
nei.options.inventory.cacheItemRendering=Cache Item Rendering
nei.options.inventory.cacheItemRendering.true=True
nei.options.inventory.cacheItemRendering.false=False
nei.options.inventory.gridRenderingCacheMode=Grid Rendering Cache Mode
nei.options.inventory.gridRenderingCacheMode.0=Off
nei.options.inventory.gridRenderingCacheMode.1=Low FPS
nei.options.inventory.gridRenderingCacheMode.2=Freeze
nei.options.inventory.collapsibleItems=Collapsible Items
nei.options.inventory.collapsibleItems.enabled=Collapsible Items
nei.options.inventory.collapsibleItems.enabled.true=Enabled
@@ -318,6 +331,13 @@ nei.options.inventory.history.useRows=Rows
nei.options.inventory.history.splittingMode=Splitting Mode
nei.options.inventory.history.splittingMode.0=Background
nei.options.inventory.history.splittingMode.1=Dotted Line
nei.options.inventory.subsets=Subsets Widget
nei.options.inventory.subsets.enabled=Subsets Visibility
nei.options.inventory.subsets.enabled.true=Enabled
nei.options.inventory.subsets.enabled.false=Disabled
nei.options.inventory.subsets.widgetPosition=Widget Position
nei.options.inventory.subsets.widgetPosition.true=Top
nei.options.inventory.subsets.widgetPosition.false=Bottom
nei.options.inventory.itemzoom=Item Zoom Panel
nei.options.inventory.itemzoom.enabled=Item Zoom Panel Visibility
nei.options.inventory.itemzoom.enabled.true=Enabled
@@ -440,6 +460,23 @@ nei.itemsort.default.tip=Leave the natural ordering of each item unchanged
nei.itemsort.damage=Item Damage
nei.itemsort.name=Display Name
nei.subsets.item.cheat=Give out an Item
nei.subsets.item.cheat.key=Ctrl + LMB
nei.subsets.item.search=Search by Item
nei.subsets.item.search.key=Shift + LMB
nei.subsets.item.show=Show Item
nei.subsets.item.show.key=LMB
nei.subsets.item.hide=Hide Item
nei.subsets.item.hide.key=RMB
nei.subsets.tag.search=Search by Subset
nei.subsets.tag.search.key=Shift + LMB
nei.subsets.tag.onlythis=Show only this Subset
nei.subsets.tag.onlythis.key=Double LMB
nei.subsets.tag.show=Show Subset
nei.subsets.tag.show.key=LMB
nei.subsets.tag.hide=Hide Subset
nei.subsets.tag.hide.key=RMB
nei.subsets.Blocks=Blocks
nei.subsets.Blocks.MobSpawners=Mob Spawners
nei.subsets.CreativeTabs=Creative Tabs
@@ -480,7 +517,7 @@ nei.presets.mode.hide=Hide
nei.presets.mode.hide.char=H
nei.presets.mode.hide.tip=Hide items in panel
nei.presets.mode.remove=Remove
nei.presets.mode.remove.tip=Hide items in panel and it recipes
nei.presets.mode.remove.tip=Hide items in panel and their recipes
nei.presets.mode.remove.char=R
nei.presets.mode.group=Group
nei.presets.mode.group.tip=Create custom collapsible items group
Loaded 100 of 102 files, more files were not shown because too many files have changed in this diff. Show more