Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4058f23490 | ||
|
|
0ba14091fb | ||
|
|
6ed0be7961 | ||
|
|
d40b951cce | ||
|
|
ecdf7892ce | ||
|
|
1eaaac94bc | ||
|
|
e99167dddb | ||
|
|
34cb0dc43f | ||
|
|
acaad4bf91 | ||
|
|
3de75f4e26 | ||
|
|
47497090ea | ||
|
|
8b45a1757f | ||
|
|
2782f8252e | ||
|
|
a5538b2566 | ||
|
|
a1f324b796 | ||
|
|
f3b6be26df | ||
|
|
9c764e3682 | ||
|
|
08605c3d73 | ||
|
|
9ec1e0f0cd | ||
|
|
e61151186c | ||
|
|
f7787a9a22 | ||
|
|
a91083bb5a | ||
|
|
51f830bdf6 | ||
|
|
9326ac48ad | ||
|
|
c125b71ae0 | ||
|
|
805b90d6f8 | ||
|
|
900b9f90e7 | ||
|
|
06d4a96c3a | ||
|
|
9a5a4a77ef | ||
|
|
4d874ec910 | ||
|
|
7f0f2466a5 | ||
|
|
83e1966ff2 | ||
|
|
548f754823 | ||
|
|
e036fd14a8 | ||
|
|
463f4c9b60 | ||
|
|
5070fde640 | ||
|
|
454b4f7e1d | ||
|
|
7b83456f01 | ||
|
|
4b7b84b031 | ||
|
|
75309b81ec | ||
|
|
24e46bb43e | ||
|
|
2ba0773401 | ||
|
|
eac913c80c | ||
|
|
126f0ea73c | ||
|
|
cd4668ec84 | ||
|
|
7c247dd0d2 | ||
|
|
87b549fab5 |
No files matched your search
@@ -0,0 +1,17 @@
|
||||
name: Optimize images
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ master, main, release/** ]
|
||||
paths:
|
||||
- "**/*.png"
|
||||
|
||||
push:
|
||||
branches: [ master, main, release/** ]
|
||||
paths:
|
||||
- "**/*.png"
|
||||
|
||||
jobs:
|
||||
optimize-images:
|
||||
uses: GTNewHorizons/GTNH-Actions-Workflows/.github/workflows/optimize-images.yml@master
|
||||
secrets: inherit
|
||||
@@ -2,7 +2,6 @@ compileJava {
|
||||
options.encoding = "UTF-8"
|
||||
}
|
||||
|
||||
|
||||
generateGrammarSource {
|
||||
maxHeapSize = "128m"
|
||||
arguments += ['-package', 'codechicken.nei.search', '-visitor', '-no-listener']
|
||||
@@ -12,6 +11,10 @@ generateGrammarSource {
|
||||
compileJava.dependsOn generateGrammarSource
|
||||
sourcesJar.dependsOn generateGrammarSource
|
||||
|
||||
sourcesJar {
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
java.srcDirs += ["build/generated/sources/search/antlr/"]
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Add your dependencies here
|
||||
|
||||
dependencies {
|
||||
api('com.github.GTNewHorizons:CodeChickenCore:1.4.7:dev')
|
||||
implementation('com.github.GTNewHorizons:GTNHLib:0.8.0:dev')
|
||||
api('com.github.GTNewHorizons:CodeChickenCore:1.4.10:dev')
|
||||
devOnlyNonPublishable('com.github.GTNewHorizons:GTNHLib:0.9.13:dev')
|
||||
|
||||
shadowImplementation('org.apache.commons:commons-csv:1.10.0')
|
||||
|
||||
|
||||
@@ -39,9 +39,33 @@ remoteMappings = https\://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/co
|
||||
# `./gradlew runClient --username=AnotherPlayer`, or configuring this command in your IDE.
|
||||
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 = true
|
||||
# Enables modern Java syntax support. Valid values:
|
||||
# - false: No modern syntax, Java 8 only
|
||||
# - jabel: Jabel syntax-only support, compiles to J8 bytecode
|
||||
# - jvmDowngrader: Full modern Java via JVM Downgrader (syntax + stdlib APIs)
|
||||
# - modern: Native modern Java bytecode, no downgrading
|
||||
enableModernJavaSyntax = jabel
|
||||
|
||||
# If set, ignores the above setting and compiles with the given toolchain. This may cause unexpected issues,
|
||||
# and should *not* be used in most situations. -1 disables this.
|
||||
# forceToolchainVersion = -1
|
||||
|
||||
# Target JVM version for JVM Downgrader bytecode downgrading.
|
||||
# Only used when enableModernJavaSyntax = jvmDowngrader
|
||||
# downgradeTargetVersion = 8
|
||||
|
||||
# Comma-separated list of Java versions for multi-release jar support (JVM Downgrader only).
|
||||
# Classes will be available in META-INF/versions/N/ for each version N in this list.
|
||||
# Default: "21,25" (J25+ gets native classes, J21-24 gets partial downgrade, J8-20 gets full downgrade).
|
||||
# jvmDowngraderMultiReleaseVersions = 21,25
|
||||
|
||||
# Specifies how JVM Downgrader API stubs are provided. Options:
|
||||
# - shade: Shade minimized stubs into the jar
|
||||
# - gtnhlib: GTNHLib provides stubs at runtime (adds version constraint)
|
||||
# - external: Another dependency provides stubs (no constraint, no warning)
|
||||
# - (empty): Warning reminding you to configure stubs
|
||||
# Note: 'shade' option requires you to verify license compliance, see: https://github.com/unimined/JvmDowngrader/blob/main/LICENSE.md
|
||||
# jvmDowngraderStubsProvider =
|
||||
|
||||
# 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.
|
||||
@@ -209,3 +233,6 @@ curseForgeRelations = requiredDependency\:codechickencore-unofficial
|
||||
# This is meant to be set in $HOME/.gradle/gradle.properties.
|
||||
# ideaCheckSpotlessOnBuild = true
|
||||
|
||||
# Non-GTNH properties
|
||||
org.gradle.configuration-cache = true
|
||||
org.gradle.parallel = true
|
||||
@@ -0,0 +1,12 @@
|
||||
#This file is generated by updateDaemonJvm
|
||||
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/c5ee947fbfb70bc347d8d531e3a578c4/redirect
|
||||
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/5ee463876563a46fff651cce1bc53a4c/redirect
|
||||
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/c5ee947fbfb70bc347d8d531e3a578c4/redirect
|
||||
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/5ee463876563a46fff651cce1bc53a4c/redirect
|
||||
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/e1118b4c7c2858d28154d086dbff010e/redirect
|
||||
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/faa12903720d410b387cc69ccafb1a74/redirect
|
||||
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/c5ee947fbfb70bc347d8d531e3a578c4/redirect
|
||||
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/5ee463876563a46fff651cce1bc53a4c/redirect
|
||||
toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/a4c09dd2e2d7079373d30e524bbc2829/redirect
|
||||
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/b96cb7670c095245220e7d01d5927b58/redirect
|
||||
toolchainVersion=25
|
||||
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
# Copyright © 2015 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -57,7 +57,7 @@
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# https://github.com/gradle/gradle/blob/b631911858264c0b6e4d6603d677ff5218766cee/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
@@ -114,7 +114,6 @@ case "$( uname )" in #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH="\\\"\\\""
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
@@ -172,7 +171,6 @@ fi
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
@@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||
"$@"
|
||||
|
||||
|
||||
@@ -70,11 +70,10 @@ goto fail
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
|
||||
@@ -17,7 +17,7 @@ pluginManagement {
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.48'
|
||||
id 'com.gtnewhorizons.gtnhsettingsconvention' version '2.0.24'
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -509,31 +509,31 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
}
|
||||
}
|
||||
|
||||
public Rectangle4i calculateBounds() {
|
||||
final GuiContainer gui = NEIClientUtils.getGuiContainer();
|
||||
final int width = (gui.width - gui.xSize) / 2 - PADDING * 2;
|
||||
final Rectangle4i bounds = new Rectangle4i(
|
||||
PADDING,
|
||||
PADDING,
|
||||
(gui.width - 176) / 2 - PADDING * 2,
|
||||
gui.height - PADDING * 2);
|
||||
@Override
|
||||
public Rectangle4i calculateBounds(GuiContainer gui) {
|
||||
final int maxWidth = (gui.width - 176) / 2 - PADDING * 2;
|
||||
final int maxHeight = gui.height - PADDING * 2;
|
||||
final int freeSpace = (gui.width - gui.xSize) / 2 - PADDING * 2;
|
||||
|
||||
int paddingLeft = (int) Math
|
||||
.ceil(bounds.w * NEIClientConfig.getSetting("world.panels.bookmarks.left").getIntValue() / 100000.0);
|
||||
int paddingTop = (int) Math
|
||||
.ceil(bounds.h * NEIClientConfig.getSetting("world.panels.bookmarks.top").getIntValue() / 100000.0);
|
||||
int paddingRight = (int) Math
|
||||
.ceil(bounds.w * NEIClientConfig.getSetting("world.panels.bookmarks.right").getIntValue() / 100000.0);
|
||||
int paddingBottom = (int) Math
|
||||
.ceil(bounds.h * NEIClientConfig.getSetting("world.panels.bookmarks.bottom").getIntValue() / 100000.0);
|
||||
final int paddingLeft = (int) Math
|
||||
.ceil(maxWidth * NEIClientConfig.getSetting("world.panels.bookmarks.left").getIntValue() / 100000.0);
|
||||
final int paddingTop = (int) Math
|
||||
.ceil(maxHeight * NEIClientConfig.getSetting("world.panels.bookmarks.top").getIntValue() / 100000.0);
|
||||
final int paddingRight = (int) Math
|
||||
.ceil(maxWidth * NEIClientConfig.getSetting("world.panels.bookmarks.right").getIntValue() / 100000.0);
|
||||
final int paddingBottom = (int) Math
|
||||
.ceil(maxHeight * NEIClientConfig.getSetting("world.panels.bookmarks.bottom").getIntValue() / 100000.0);
|
||||
|
||||
bounds.h = Math.max(ItemsGrid.SLOT_SIZE, bounds.h - paddingTop - paddingBottom);
|
||||
bounds.y = bounds.y + Math.min(paddingTop, bounds.h - ItemsGrid.SLOT_SIZE);
|
||||
final int width = Math.max(
|
||||
ItemsGrid.SLOT_SIZE,
|
||||
snapDownToMultiple(
|
||||
Math.min(freeSpace - paddingLeft, maxWidth - paddingLeft - paddingRight)
|
||||
- BookmarkGrid.GROUP_PANEL_WIDTH,
|
||||
ItemsGrid.SLOT_SIZE))
|
||||
+ BookmarkGrid.GROUP_PANEL_WIDTH;
|
||||
final int height = Math.max(ItemsGrid.SLOT_SIZE, maxHeight - paddingTop - paddingBottom);
|
||||
|
||||
bounds.w = Math.max(ItemsGrid.SLOT_SIZE, Math.min(bounds.w - paddingLeft - paddingRight, width - paddingLeft));
|
||||
bounds.x = bounds.x + Math.min(paddingLeft, bounds.w - ItemsGrid.SLOT_SIZE);
|
||||
|
||||
return bounds;
|
||||
return new Rectangle4i(paddingLeft + PADDING, paddingTop + PADDING, width, height);
|
||||
}
|
||||
|
||||
protected ItemStack getDraggedStackWithQuantity(ItemStack itemStack) {
|
||||
@@ -996,7 +996,7 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
@Override
|
||||
public boolean onMouseWheel(int shift, int mousex, int mousey) {
|
||||
|
||||
if (!inEditingState() && new Rectangle4i(
|
||||
if ((!inEditingState() || this.sortableGroup != null) && new Rectangle4i(
|
||||
namespacePrev.x,
|
||||
namespacePrev.y,
|
||||
namespaceNext.x + namespaceNext.w - namespacePrev.x,
|
||||
|
||||
@@ -43,7 +43,6 @@ 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;
|
||||
@@ -276,7 +275,6 @@ public class ClientHandler {
|
||||
public static void load() {
|
||||
instance = new ClientHandler();
|
||||
|
||||
GuiModListScroll.register("NotEnoughItems");
|
||||
PacketCustom.assignHandler(NEICPH.channel, new NEICPH());
|
||||
FMLCommonHandler.instance().bus().register(instance);
|
||||
MinecraftForge.EVENT_BUS.register(instance);
|
||||
|
||||
@@ -4,6 +4,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import codechicken.nei.api.IBookmarkContainerHandler;
|
||||
@@ -12,15 +13,14 @@ public class DefaultBookmarkContainerHandler implements IBookmarkContainerHandle
|
||||
|
||||
@Override
|
||||
public void pullBookmarkItemsFromContainer(GuiContainer guiContainer, ArrayList<ItemStack> bookmarkItems) {
|
||||
final List<Slot> slots = guiContainer.inventorySlots.inventorySlots;
|
||||
final FastTransferManager manager = new FastTransferManager();
|
||||
final List<ItemStack> containerStacks = getStorageStacks(guiContainer);
|
||||
|
||||
for (ItemStack bookmarkItem : bookmarkItems) {
|
||||
for (int i = 0; i < containerStacks.size() && bookmarkItem.stackSize > 0; i++) {
|
||||
final ItemStack containerItem = containerStacks.get(i);
|
||||
|
||||
if (bookmarkItem.isItemEqual(containerItem)) {
|
||||
final int transferAmount = Math.min(bookmarkItem.stackSize, containerItem.stackSize);
|
||||
for (int i = 0; i < slots.size() - 4 * 9; i++) {
|
||||
final Slot slot = slots.get(i);
|
||||
if (slot.getHasStack() && bookmarkItem.isItemEqual(slot.getStack())) {
|
||||
final int transferAmount = Math.min(bookmarkItem.stackSize, slot.getStack().stackSize);
|
||||
manager.transferItems(guiContainer, i, transferAmount);
|
||||
bookmarkItem.stackSize -= transferAmount;
|
||||
}
|
||||
|
||||
@@ -8,39 +8,142 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.fluids.FluidRegistry;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import codechicken.core.CommonUtils;
|
||||
import codechicken.nei.api.API;
|
||||
import codechicken.nei.recipe.GuiCraftingRecipe;
|
||||
import codechicken.nei.recipe.GuiRecipeTab;
|
||||
import codechicken.nei.recipe.ICraftingHandler;
|
||||
import codechicken.nei.recipe.IRecipeHandler;
|
||||
import codechicken.nei.recipe.Recipe.RecipeId;
|
||||
import codechicken.nei.recipe.RecipeHandlerRef;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
import codechicken.nei.util.FavoriteStorage;
|
||||
import codechicken.nei.util.NBTJson;
|
||||
|
||||
public class FavoriteRecipes {
|
||||
|
||||
private static final Set<NBTTagCompound> tools = new HashSet<>();
|
||||
private static final Map<NBTTagCompound, RecipeId> items = new HashMap<>();
|
||||
private static final Map<String, RecipeId> fluids = new HashMap<>();
|
||||
protected static final class FastKey {
|
||||
|
||||
public final ItemStack stack;
|
||||
private int hash;
|
||||
|
||||
public FastKey(ItemStack stack) {
|
||||
this.stack = stack;
|
||||
|
||||
this.hash = 31 + Item.getIdFromItem(stack.getItem());
|
||||
this.hash = 31 * this.hash + stack.getItemDamage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
|
||||
if (o instanceof FastKey k && this.stack.getItem() == k.stack.getItem()
|
||||
&& this.stack.getItemDamage() == k.stack.getItemDamage()) {
|
||||
return this.stack == k.stack || Objects.equals(this.stack.stackTagCompound, k.stack.stackTagCompound);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static final RestartableTask singleRecipeFavoritesTask = new RestartableTask(
|
||||
"Generate Single-Recipe Favorites") {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
final List<ICraftingHandler> handlers = GuiCraftingRecipe.getCraftingHandlers("all");
|
||||
final Map<FastKey, RecipeHandlerRef> autogeneratedRecipes = new HashMap<>();
|
||||
final Set<FastKey> whitelistItems = new HashSet<>(ItemList.items.size());
|
||||
final FavoriteStorage storage = new FavoriteStorage();
|
||||
|
||||
for (ItemStack stack : ItemList.items) {
|
||||
whitelistItems.add(new FastKey(stack));
|
||||
}
|
||||
|
||||
if (interrupted()) return;
|
||||
|
||||
for (ICraftingHandler handler : handlers) {
|
||||
if (!GuiRecipeTab.getHandlerInfo(handler).getShowFavoritesButton()) continue;
|
||||
|
||||
for (int i = 0; i < handler.numRecipes(); i++) {
|
||||
RecipeHandlerRef ref = null;
|
||||
|
||||
for (PositionedStack result : getOutputs(handler, i)) {
|
||||
ItemStack stack = StackInfo.getItemStackWithMinimumDamage(result.items);
|
||||
final FastKey key = new FastKey(stack);
|
||||
|
||||
if (!whitelistItems.contains(key)) continue;
|
||||
|
||||
if (autogeneratedRecipes.get(key) == null) {
|
||||
|
||||
if (ref == null) {
|
||||
ref = RecipeHandlerRef.of(handler, i);
|
||||
}
|
||||
|
||||
autogeneratedRecipes.put(key, ref);
|
||||
} else {
|
||||
autogeneratedRecipes.remove(key);
|
||||
whitelistItems.remove(key);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (interrupted()) return;
|
||||
}
|
||||
|
||||
final Map<RecipeHandlerRef, RecipeId> recipesCache = new HashMap<>();
|
||||
|
||||
for (Map.Entry<FastKey, RecipeHandlerRef> entry : autogeneratedRecipes.entrySet()) {
|
||||
final RecipeId recipeId = recipesCache
|
||||
.computeIfAbsent(entry.getValue(), r -> RecipeId.of(r.handler, r.recipeIndex));
|
||||
storage.add(entry.getKey().stack, recipeId);
|
||||
}
|
||||
|
||||
FavoriteRecipes.autoFavorites = storage;
|
||||
updateSubsetVisibility();
|
||||
}
|
||||
|
||||
protected List<PositionedStack> getOutputs(IRecipeHandler handler, int recipeIndex) {
|
||||
final PositionedStack pStackResult = handler.getResultStack(recipeIndex);
|
||||
return pStackResult != null ? Collections.singletonList(pStackResult) : handler.getOtherStacks(recipeIndex);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public static final String FAVORITE_ITEM = "FavoriteItem";
|
||||
private static final FavoriteStorage manualFavorites = new FavoriteStorage();
|
||||
private static FavoriteStorage autoFavorites = new FavoriteStorage();
|
||||
private static File favoriteFile;
|
||||
private static int revision = 0;
|
||||
|
||||
static {
|
||||
API.addSubset("Favorites", FavoriteRecipes::contains);
|
||||
API.addSubset("Favorites.Manual", manualFavorites::contains);
|
||||
API.addSubset("Favorites.Generated", stack -> FavoriteRecipes.autoFavorites.contains(stack));
|
||||
}
|
||||
|
||||
private FavoriteRecipes() {}
|
||||
@@ -66,7 +169,6 @@ public class FavoriteRecipes {
|
||||
final File defaultFavorites = configFavorites.exists() ? configFavorites : globalFavorites;
|
||||
|
||||
if (defaultFavorites.exists()) {
|
||||
|
||||
try {
|
||||
if (favoriteFile.createNewFile()) {
|
||||
InputStream src = new FileInputStream(defaultFavorites);
|
||||
@@ -101,7 +203,9 @@ public class FavoriteRecipes {
|
||||
}
|
||||
|
||||
final JsonParser parser = new JsonParser();
|
||||
items.clear();
|
||||
boolean hasErrors = false;
|
||||
|
||||
manualFavorites.clear();
|
||||
|
||||
for (String itemStr : itemStrings) {
|
||||
|
||||
@@ -121,70 +225,97 @@ public class FavoriteRecipes {
|
||||
continue;
|
||||
}
|
||||
|
||||
final String fluidKey = getFluidKey(stack);
|
||||
|
||||
if (fluidKey != null) {
|
||||
fluids.put(fluidKey, recipeId);
|
||||
if (FAVORITE_ITEM.equals(recipeId.getHandleName()) || RecipeHandlerRef.of(recipeId) != null) {
|
||||
manualFavorites.add(stack, recipeId);
|
||||
} else {
|
||||
hasErrors = true;
|
||||
}
|
||||
|
||||
items.put(itemStackNBT, recipeId);
|
||||
|
||||
if (NEIServerUtils.isItemTool(stack)) {
|
||||
tools.add(itemStackNBT);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
NEIClientConfig.logger.error("Failed to load favorite from json string: {}", itemStr);
|
||||
hasErrors = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
SubsetWidget.updateHiddenItems();
|
||||
if (hasErrors) {
|
||||
|
||||
try {
|
||||
Files.copy(
|
||||
favoriteFile,
|
||||
new File(favoriteFile.getAbsolutePath() + ".backup-" + System.currentTimeMillis()));
|
||||
NEIClientConfig.logger.info("Backed up invalid favorite file to {}", favoriteFile);
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to backup invalid favorite file to {}", favoriteFile, e);
|
||||
}
|
||||
|
||||
save();
|
||||
}
|
||||
|
||||
loadAutoGeneratedRecipes();
|
||||
}
|
||||
|
||||
public static RecipeId getGeneratedFavorite(ItemStack stack) {
|
||||
if (NEIClientConfig.favoritesEnabled() && stack != null) {
|
||||
return autoFavorites.getRecipeId(stack);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ItemStack getGeneratedFavorite(RecipeId recipeId) {
|
||||
if (NEIClientConfig.favoritesEnabled() && recipeId != null) {
|
||||
return autoFavorites.getItemStack(recipeId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static RecipeId getManualFavorite(ItemStack stack) {
|
||||
if (NEIClientConfig.favoritesEnabled() && stack != null) {
|
||||
return manualFavorites.getRecipeId(stack);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ItemStack getManualFavorite(RecipeId recipeId) {
|
||||
if (NEIClientConfig.favoritesEnabled() && recipeId != null) {
|
||||
return manualFavorites.getItemStack(recipeId);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static RecipeId getFavorite(ItemStack stack) {
|
||||
|
||||
if (NEIClientConfig.favoritesEnabled() && stack != null) {
|
||||
RecipeId recipeId = items.get(StackInfo.itemStackToNBT(stack, false));
|
||||
|
||||
if (recipeId == null) {
|
||||
recipeId = fluids.get(getFluidKey(stack));
|
||||
}
|
||||
|
||||
if (recipeId != null) {
|
||||
return recipeId;
|
||||
}
|
||||
|
||||
if (NEIServerUtils.isItemTool(stack)
|
||||
&& (stack.stackTagCompound == null || !stack.stackTagCompound.hasKey("GT.ToolStats"))) {
|
||||
for (NBTTagCompound nbt : tools) {
|
||||
if (NEIServerUtils.areStacksSameTypeCraftingWithNBT(stack, StackInfo.loadFromNBT(nbt))) {
|
||||
return items.get(nbt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final RecipeId recipeId = manualFavorites.getRecipeId(stack);
|
||||
return recipeId != null ? recipeId : autoFavorites.getRecipeId(stack);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ItemStack getFavorite(RecipeId recipeId) {
|
||||
if (NEIClientConfig.favoritesEnabled()) {
|
||||
final Optional<Map.Entry<NBTTagCompound, RecipeId>> result = items.entrySet().stream()
|
||||
.filter(entry -> entry.getValue().equals(recipeId)).findAny();
|
||||
|
||||
if (result.isPresent()) {
|
||||
return StackInfo.loadFromNBT(result.get().getKey());
|
||||
}
|
||||
if (NEIClientConfig.favoritesEnabled() && recipeId != null) {
|
||||
final ItemStack stack = manualFavorites.getItemStack(recipeId);
|
||||
return stack != null ? stack : autoFavorites.getItemStack(recipeId);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int size() {
|
||||
return items.size() + fluids.size();
|
||||
return manualFavorites.size() + autoFavorites.size();
|
||||
}
|
||||
|
||||
public static void reload() {
|
||||
save();
|
||||
load();
|
||||
}
|
||||
|
||||
public static boolean containsManual(ItemStack stack) {
|
||||
return getManualFavorite(stack) != null;
|
||||
}
|
||||
|
||||
public static boolean contains(ItemStack stack) {
|
||||
@@ -192,36 +323,37 @@ public class FavoriteRecipes {
|
||||
}
|
||||
|
||||
public static void setFavorite(ItemStack stack, RecipeId recipeId) {
|
||||
final NBTTagCompound itemStackNBT = StackInfo.itemStackToNBT(stack, false);
|
||||
final String fluidKey = getFluidKey(stack);
|
||||
if (stack == null) return;
|
||||
|
||||
items.entrySet().removeIf(entry -> entry.getKey().equals(itemStackNBT) || entry.getValue().equals(recipeId));
|
||||
fluids.entrySet().removeIf(entry -> entry.getKey().equals(fluidKey) || entry.getValue().equals(recipeId));
|
||||
manualFavorites.removeItemStack(stack);
|
||||
|
||||
if (recipeId != null) {
|
||||
items.put(itemStackNBT, recipeId);
|
||||
|
||||
if (NEIServerUtils.isItemTool(stack)) {
|
||||
tools.add(itemStackNBT);
|
||||
}
|
||||
|
||||
if (fluidKey != null) {
|
||||
fluids.put(fluidKey, recipeId);
|
||||
}
|
||||
manualFavorites.removeRecipeId(recipeId);
|
||||
manualFavorites.add(stack, recipeId);
|
||||
}
|
||||
|
||||
SubsetWidget.updateHiddenItems();
|
||||
ItemList.updateFilter.restart();
|
||||
updateSubsetVisibility();
|
||||
}
|
||||
|
||||
private static String getFluidKey(ItemStack stack) {
|
||||
final FluidStack fluid = StackInfo.getFluid(stack);
|
||||
public static void loadAutoGeneratedRecipes() {
|
||||
if (ItemList.loadFinished
|
||||
&& NEIClientConfig.getBooleanSetting("inventory.favorites.generateSingleRecipeFavorites")) {
|
||||
singleRecipeFavoritesTask.restart();
|
||||
} else {
|
||||
singleRecipeFavoritesTask.stop();
|
||||
autoFavorites.clear();
|
||||
|
||||
if (fluid != null) {
|
||||
return FluidRegistry.getFluidName(fluid);
|
||||
updateSubsetVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
protected static void updateSubsetVisibility() {
|
||||
SubsetWidget.updateHiddenItems();
|
||||
FavoriteRecipes.revision++;
|
||||
}
|
||||
|
||||
public static int getRevision() {
|
||||
return revision;
|
||||
}
|
||||
|
||||
public static void save() {
|
||||
@@ -232,7 +364,7 @@ public class FavoriteRecipes {
|
||||
|
||||
final List<String> strings = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<NBTTagCompound, RecipeId> entry : items.entrySet()) {
|
||||
for (Map.Entry<NBTTagCompound, RecipeId> entry : manualFavorites.getAllFavorites()) {
|
||||
|
||||
try {
|
||||
final JsonObject line = new JsonObject();
|
||||
|
||||
@@ -278,7 +278,7 @@ public class FormattedTextField extends GuiTextField {
|
||||
}
|
||||
|
||||
Tessellator tessellator = Tessellator.instance;
|
||||
GL11.glColor4f(0.0F, 0.0F, 255.0F, 255.0F);
|
||||
GL11.glColor4f(0.0F, 0.0F, 1.0F, 1.0F);
|
||||
GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
GL11.glEnable(GL11.GL_COLOR_LOGIC_OP);
|
||||
GL11.glLogicOp(GL11.GL_OR_REVERSE);
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
package codechicken.nei;
|
||||
|
||||
import net.minecraft.client.gui.GuiRepair;
|
||||
import net.minecraft.client.gui.inventory.GuiBrewingStand;
|
||||
import net.minecraft.client.gui.inventory.GuiCrafting;
|
||||
import net.minecraft.client.gui.inventory.GuiFurnace;
|
||||
import net.minecraft.client.gui.inventory.GuiInventory;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
import codechicken.nei.api.API;
|
||||
import codechicken.nei.recipe.BrewingOverlayHandler;
|
||||
import codechicken.nei.recipe.BrewingRecipeHandler;
|
||||
import codechicken.nei.recipe.DefaultOverlayHandler;
|
||||
import codechicken.nei.recipe.FireworkRecipeHandler;
|
||||
import codechicken.nei.recipe.FuelRecipeHandler;
|
||||
import codechicken.nei.recipe.FurnaceRecipeHandler;
|
||||
import codechicken.nei.recipe.InformationHandler;
|
||||
import codechicken.nei.recipe.ProfilerRecipeHandler;
|
||||
import codechicken.nei.recipe.RepairOverlayHandler;
|
||||
import codechicken.nei.recipe.RepairRecipeHandler;
|
||||
import codechicken.nei.recipe.ShapedRecipeHandler;
|
||||
import codechicken.nei.recipe.ShapelessRecipeHandler;
|
||||
import cpw.mods.fml.common.event.FMLInterModComms;
|
||||
|
||||
public class IMCForNEI {
|
||||
|
||||
public static void IMCSender() {
|
||||
|
||||
API.registerRecipeHandler(new ShapedRecipeHandler());
|
||||
API.registerUsageHandler(new ShapedRecipeHandler());
|
||||
sendHandler("codechicken.nei.recipe.ShapedRecipeHandler", "minecraft:crafting_table");
|
||||
|
||||
API.registerRecipeHandler(new ShapelessRecipeHandler());
|
||||
API.registerUsageHandler(new ShapelessRecipeHandler());
|
||||
sendHandler("codechicken.nei.recipe.ShapelessRecipeHandler", "minecraft:crafting_table");
|
||||
|
||||
API.registerRecipeHandler(new FireworkRecipeHandler());
|
||||
API.registerUsageHandler(new FireworkRecipeHandler());
|
||||
sendHandler("codechicken.nei.recipe.FireworkRecipeHandler", "minecraft:fireworks");
|
||||
|
||||
API.registerRecipeHandler(new FurnaceRecipeHandler());
|
||||
API.registerUsageHandler(new FurnaceRecipeHandler());
|
||||
sendHandler("codechicken.nei.recipe.FurnaceRecipeHandler", "minecraft:furnace");
|
||||
|
||||
API.registerRecipeHandler(new BrewingRecipeHandler());
|
||||
API.registerUsageHandler(new BrewingRecipeHandler());
|
||||
sendHandler("codechicken.nei.recipe.BrewingRecipeHandler", "minecraft:brewing_stand");
|
||||
|
||||
API.registerRecipeHandler(new FuelRecipeHandler());
|
||||
API.registerUsageHandler(new FuelRecipeHandler());
|
||||
sendFuelRecipeHandler();
|
||||
|
||||
API.registerRecipeHandler(new InformationHandler());
|
||||
API.registerUsageHandler(new InformationHandler());
|
||||
sendInformationHandler();
|
||||
|
||||
API.registerRecipeHandler(new RepairRecipeHandler());
|
||||
API.registerUsageHandler(new RepairRecipeHandler());
|
||||
sendRepairHandler();
|
||||
sendCatalyst("repair", "minecraft:anvil");
|
||||
|
||||
API.registerGuiOverlay(GuiCrafting.class, "crafting");
|
||||
API.registerGuiOverlay(GuiInventory.class, "crafting2x2", 63, 20);
|
||||
API.registerGuiOverlay(GuiFurnace.class, "smelting");
|
||||
API.registerGuiOverlay(GuiFurnace.class, "fuel");
|
||||
API.registerGuiOverlay(GuiBrewingStand.class, "brewing");
|
||||
API.registerGuiOverlay(GuiRepair.class, "repair", 2, 37);
|
||||
|
||||
API.registerGuiOverlayHandler(GuiCrafting.class, new DefaultOverlayHandler(), "crafting");
|
||||
API.registerGuiOverlayHandler(GuiInventory.class, new DefaultOverlayHandler(63, 20), "crafting2x2");
|
||||
API.registerGuiOverlayHandler(GuiBrewingStand.class, new BrewingOverlayHandler(), "brewing");
|
||||
API.registerGuiOverlayHandler(GuiRepair.class, new RepairOverlayHandler(), "repair");
|
||||
|
||||
API.registerRecipeHandler(new ProfilerRecipeHandler(true));
|
||||
API.registerUsageHandler(new ProfilerRecipeHandler(false));
|
||||
}
|
||||
|
||||
private static void sendHandler(String aName, String aBlock) {
|
||||
NBTTagCompound aNBT = new NBTTagCompound();
|
||||
aNBT.setString("handler", aName);
|
||||
aNBT.setString("modName", "Minecraft");
|
||||
aNBT.setString("modId", "minecraft");
|
||||
aNBT.setString("itemName", aBlock);
|
||||
aNBT.setInteger("handlerWidth", 166);
|
||||
aNBT.setInteger("handlerHeight", 65);
|
||||
aNBT.setBoolean("multipleWidgetsAllowed", true);
|
||||
aNBT.setInteger("yShift", 0);
|
||||
FMLInterModComms.sendMessage("NotEnoughItems", "registerHandlerInfo", aNBT);
|
||||
}
|
||||
|
||||
private static void sendRepairHandler() {
|
||||
NBTTagCompound aNBT = new NBTTagCompound();
|
||||
aNBT.setString("handler", "codechicken.nei.recipe.RepairRecipeHandler");
|
||||
aNBT.setString("modName", "Minecraft");
|
||||
aNBT.setString("modId", "minecraft");
|
||||
aNBT.setString("itemName", "minecraft:anvil");
|
||||
aNBT.setInteger("handlerHeight", 39);
|
||||
aNBT.setInteger("handlerWidth", 166);
|
||||
aNBT.setBoolean("multipleWidgetsAllowed", true);
|
||||
aNBT.setBoolean("showFavoritesButton", false);
|
||||
aNBT.setInteger("yShift", 0);
|
||||
FMLInterModComms.sendMessage("NotEnoughItems", "registerHandlerInfo", aNBT);
|
||||
}
|
||||
|
||||
private static void sendFuelRecipeHandler() {
|
||||
NBTTagCompound aNBT = new NBTTagCompound();
|
||||
aNBT.setString("handler", "codechicken.nei.recipe.FuelRecipeHandler");
|
||||
aNBT.setString("modName", "Minecraft");
|
||||
aNBT.setString("modId", "minecraft");
|
||||
aNBT.setString("imageResource", "nei:textures/nei_tabbed_sprites.png");
|
||||
aNBT.setInteger("imageX", 80);
|
||||
aNBT.setInteger("imageY", 0);
|
||||
aNBT.setInteger("imageWidth", 14);
|
||||
aNBT.setInteger("imageHeight", 14);
|
||||
aNBT.setInteger("handlerHeight", 65);
|
||||
aNBT.setInteger("handlerWidth", 166);
|
||||
aNBT.setBoolean("multipleWidgetsAllowed", true);
|
||||
aNBT.setInteger("yShift", 0);
|
||||
FMLInterModComms.sendMessage("NotEnoughItems", "registerHandlerInfo", aNBT);
|
||||
}
|
||||
|
||||
private static void sendInformationHandler() {
|
||||
NBTTagCompound aNBT = new NBTTagCompound();
|
||||
aNBT.setString("handler", "codechicken.nei.recipe.InformationHandler");
|
||||
aNBT.setString("modName", "Not Enough Items");
|
||||
aNBT.setString("modId", "nei");
|
||||
aNBT.setString("imageResource", "nei:textures/nei_tabbed_sprites.png");
|
||||
aNBT.setInteger("imageX", 96);
|
||||
aNBT.setInteger("imageY", 0);
|
||||
aNBT.setInteger("imageWidth", 16);
|
||||
aNBT.setInteger("imageHeight", 16);
|
||||
aNBT.setInteger("handlerHeight", 65);
|
||||
aNBT.setInteger("handlerWidth", 166);
|
||||
aNBT.setBoolean("multipleWidgetsAllowed", true);
|
||||
aNBT.setInteger("yShift", 0);
|
||||
FMLInterModComms.sendMessage("NotEnoughItems", "registerHandlerInfo", aNBT);
|
||||
}
|
||||
|
||||
private static void sendCatalyst(String aName, String aStack) {
|
||||
NBTTagCompound aNBT = new NBTTagCompound();
|
||||
aNBT.setString("handlerID", aName);
|
||||
aNBT.setString("itemName", aStack);
|
||||
aNBT.setInteger("priority", 0);
|
||||
FMLInterModComms.sendMessage("NotEnoughItems", "registerCatalystInfo", aNBT);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -117,7 +117,8 @@ public class ItemCraftablesPanel
|
||||
.entrySet().stream()
|
||||
.sorted(
|
||||
Map.Entry.comparingByKey(
|
||||
Comparator.comparing(FavoriteRecipes::contains).reversed()
|
||||
Comparator.comparing(FavoriteRecipes::containsManual)
|
||||
.thenComparing(FavoriteRecipes::contains).reversed()
|
||||
.thenComparing(ItemSorter.instance)))
|
||||
.limit(maxSlotIndex).collect(Collectors.toList());
|
||||
int slotIndex = 0;
|
||||
|
||||
@@ -31,6 +31,8 @@ import codechicken.nei.api.ItemFilter;
|
||||
import codechicken.nei.api.ItemFilter.ItemFilterProvider;
|
||||
import codechicken.nei.api.ItemInfo;
|
||||
import codechicken.nei.recipe.InformationHandler;
|
||||
import codechicken.nei.recipe.RecipeHandlerRef;
|
||||
import codechicken.nei.recipe.RepairRecipeHandler;
|
||||
import codechicken.nei.search.TooltipFilter;
|
||||
import codechicken.nei.util.ItemUntranslator;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
@@ -432,6 +434,9 @@ public class ItemList {
|
||||
|
||||
loadFinished = true;
|
||||
|
||||
RepairRecipeHandler.findRepairRecipesOnceParallel();
|
||||
RecipeHandlerRef.clearCache();
|
||||
FavoriteRecipes.reload();
|
||||
SubsetWidget.updateHiddenItems();
|
||||
ItemPanels.bookmarkPanel.load();
|
||||
updateFilter.restart();
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package codechicken.nei;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import net.minecraft.creativetab.CreativeTabs;
|
||||
import net.minecraft.entity.Entity;
|
||||
@@ -15,6 +17,7 @@ import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemBlock;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityMobSpawner;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
import net.minecraft.util.IIcon;
|
||||
@@ -26,10 +29,27 @@ import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
public class ItemMobSpawner extends ItemBlock {
|
||||
|
||||
private static final Map<Integer, EntityLiving> entityHashMap = new HashMap<>();
|
||||
private static final Map<Integer, String> IDtoNameMap = new HashMap<>();
|
||||
public static int idPig;
|
||||
private static boolean loaded;
|
||||
private static final Map<Integer, EntityLiving> entityHashMap = new ConcurrentHashMap<>();
|
||||
private static final Map<Integer, String> IDtoNameMap = new ConcurrentHashMap<>();
|
||||
private static final Map<Class<? extends Entity>, String> ENTITY_CLASS_TO_NAME_CACHE = new ConcurrentHashMap<>();
|
||||
|
||||
public static int idPig = 90;
|
||||
private static volatile boolean loaded = false;
|
||||
|
||||
// For asm
|
||||
public static int placedX;
|
||||
public static int placedY;
|
||||
public static int placedZ;
|
||||
|
||||
public static void setLastPlacedPosition(int x, int y, int z) {
|
||||
placedX = x;
|
||||
placedY = y;
|
||||
placedZ = z;
|
||||
}
|
||||
|
||||
public static int[] getLastPlacedPosition() {
|
||||
return new int[] { placedX, placedY, placedZ };
|
||||
}
|
||||
|
||||
public ItemMobSpawner() {
|
||||
super(Blocks.mob_spawner);
|
||||
@@ -37,99 +57,260 @@ public class ItemMobSpawner extends ItemBlock {
|
||||
MinecraftForgeClient.registerItemRenderer(this, new SpawnerRenderer());
|
||||
}
|
||||
|
||||
/**
|
||||
* These are ASM translated from BlockMobSpawner
|
||||
*/
|
||||
public static int placedX;
|
||||
public static int placedY;
|
||||
public static int placedZ;
|
||||
|
||||
@Override
|
||||
public IIcon getIconFromDamage(int par1) {
|
||||
public IIcon getIconFromDamage(int meta) {
|
||||
return Blocks.mob_spawner.getBlockTextureFromSide(0);
|
||||
}
|
||||
|
||||
public boolean onItemUse(ItemStack itemstack, EntityPlayer entityplayer, World world, int x, int y, int z, int par7,
|
||||
float par8, float par9, float par10) {
|
||||
if (super.onItemUse(itemstack, entityplayer, world, x, y, z, par7, par8, par9, par10) && world.isRemote) {
|
||||
TileEntityMobSpawner tileentitymobspawner = (TileEntityMobSpawner) world
|
||||
.getTileEntity(placedX, placedY, placedZ);
|
||||
if (tileentitymobspawner != null) {
|
||||
setDefaultTag(itemstack);
|
||||
String mobtype = IDtoNameMap.get(itemstack.getItemDamage());
|
||||
if (mobtype != null) {
|
||||
NEICPH.sendMobSpawnerID(placedX, placedY, placedZ, mobtype);
|
||||
tileentitymobspawner.func_145881_a().setEntityName(mobtype);
|
||||
@Override
|
||||
public boolean onItemUse(ItemStack itemstack, EntityPlayer entityplayer, World world, int x, int y, int z, int side,
|
||||
float hitX, float hitY, float hitZ) {
|
||||
|
||||
placedX = x;
|
||||
placedY = y;
|
||||
placedZ = z;
|
||||
|
||||
boolean placed = super.onItemUse(itemstack, entityplayer, world, x, y, z, side, hitX, hitY, hitZ);
|
||||
|
||||
if (placed && !world.isRemote) {
|
||||
TileEntity tileEntity = world.getTileEntity(x, y, z);
|
||||
if (tileEntity instanceof TileEntityMobSpawner) {
|
||||
TileEntityMobSpawner spawner = (TileEntityMobSpawner) tileEntity;
|
||||
String mobType = getMobTypeFromItemStack(itemstack);
|
||||
if (mobType != null) {
|
||||
spawner.func_145881_a().setEntityName(mobType);
|
||||
world.markBlockForUpdate(x, y, z);
|
||||
NEICPH.sendMobSpawnerID(x, y, z, mobType);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return placed;
|
||||
}
|
||||
|
||||
private String getMobTypeFromItemStack(ItemStack stack) {
|
||||
int meta = getValidMetaData(stack);
|
||||
return IDtoNameMap.get(meta);
|
||||
}
|
||||
|
||||
private int getValidMetaData(ItemStack stack) {
|
||||
int meta = stack.getItemDamage();
|
||||
if (meta == 0 || !IDtoNameMap.containsKey(meta)) {
|
||||
return idPig;
|
||||
}
|
||||
return meta;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public void addInformation(ItemStack itemstack, EntityPlayer par2EntityPlayer, List<String> list, boolean par4) {
|
||||
setDefaultTag(itemstack);
|
||||
int meta = itemstack.getItemDamage();
|
||||
if (meta == 0) {
|
||||
meta = idPig;
|
||||
public void addInformation(ItemStack itemstack, EntityPlayer player, List<String> tooltip, boolean advanced) {
|
||||
int meta = getValidMetaData(itemstack);
|
||||
EntityLiving entity = getEntity(meta);
|
||||
String mobName = IDtoNameMap.get(meta);
|
||||
|
||||
if (entity != null && mobName != null) {
|
||||
EnumChatFormatting color = (entity instanceof IMob) ? EnumChatFormatting.DARK_RED
|
||||
: EnumChatFormatting.DARK_AQUA;
|
||||
tooltip.add(color + mobName);
|
||||
}
|
||||
Entity e = getEntity(meta);
|
||||
list.add(
|
||||
(e instanceof IMob ? EnumChatFormatting.DARK_RED : EnumChatFormatting.DARK_AQUA)
|
||||
+ IDtoNameMap.get(meta));
|
||||
}
|
||||
|
||||
public static EntityLiving getEntity(int ID) {
|
||||
EntityLiving e = entityHashMap.get(ID);
|
||||
if (e == null) {
|
||||
loadSpawners();
|
||||
Class<?> clazz = EntityList.IDtoClassMapping.get(ID);
|
||||
World world = NEIClientUtils.mc().theWorld;
|
||||
try {
|
||||
e = (EntityLiving) clazz.getConstructor(new Class[] { World.class }).newInstance(world);
|
||||
} catch (Throwable t) {
|
||||
if (clazz == null)
|
||||
NEIClientConfig.logger.error("Null class for entity (" + ID + ", " + IDtoNameMap.get(ID));
|
||||
else NEIClientConfig.logger.error("Error creating instance of entity: " + clazz.getName(), t);
|
||||
e = getEntity(idPig);
|
||||
}
|
||||
entityHashMap.put(ID, e);
|
||||
public static EntityLiving getEntity(int id) {
|
||||
EntityLiving cached = entityHashMap.get(id);
|
||||
if (cached != null) {
|
||||
return cached;
|
||||
}
|
||||
return e;
|
||||
|
||||
loadSpawners();
|
||||
|
||||
Class<?> entityClass = EntityList.IDtoClassMapping.get(id);
|
||||
World world = NEIClientUtils.mc() != null ? NEIClientUtils.mc().theWorld : null;
|
||||
|
||||
if (isInvalidEntityClass(entityClass)) {
|
||||
return cacheFallback(id);
|
||||
}
|
||||
|
||||
EntityLiving entity = createEntityInstance(entityClass, world, id);
|
||||
if (entity != null) {
|
||||
entityHashMap.put(id, entity);
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
private static boolean isInvalidEntityClass(Class<?> entityClass) {
|
||||
if (entityClass == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int modifiers = entityClass.getModifiers();
|
||||
if (Modifier.isAbstract(modifiers) || Modifier.isInterface(modifiers)) {
|
||||
NEIClientConfig.logger.warn("Skipping abstract/interface entity class: {}", entityClass.getName());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!EntityLiving.class.isAssignableFrom(entityClass)) {
|
||||
NEIClientConfig.logger.warn("Skipping non-EntityLiving class: {}", entityClass.getName());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static EntityLiving createEntityInstance(Class<?> entityClass, World world, int id) {
|
||||
if (entityClass == null || world == null) {
|
||||
NEIClientConfig.logger.debug("World or entity class is null, using fallback for ID: {}", id);
|
||||
return getFallbackEntity(id);
|
||||
}
|
||||
|
||||
try {
|
||||
Class<? extends EntityLiving> livingClass = (Class<? extends EntityLiving>) entityClass;
|
||||
return livingClass.getConstructor(World.class).newInstance(world);
|
||||
} catch (Throwable t) {
|
||||
logEntityCreationError(entityClass, id, t);
|
||||
return getFallbackEntity(id);
|
||||
}
|
||||
}
|
||||
|
||||
private static void logEntityCreationError(Class<?> entityClass, int id, Throwable t) {
|
||||
String entityName = IDtoNameMap.getOrDefault(id, "unknown");
|
||||
if (entityClass == null) {
|
||||
NEIClientConfig.logger
|
||||
.error("Failed to create entity instance: Class is null for ID {}, Name {}", id, entityName, t);
|
||||
} else {
|
||||
NEIClientConfig.logger.error(
|
||||
"Failed to create instance of entity: Class {}, ID {}, Name {}",
|
||||
entityClass.getName(),
|
||||
id,
|
||||
entityName,
|
||||
t);
|
||||
}
|
||||
}
|
||||
|
||||
private static EntityLiving cacheFallback(int id) {
|
||||
EntityLiving fallback = getFallbackEntity(id);
|
||||
if (fallback != null) {
|
||||
entityHashMap.put(id, fallback);
|
||||
}
|
||||
return fallback;
|
||||
}
|
||||
|
||||
private static EntityLiving getFallbackEntity(int originalId) {
|
||||
EntityLiving pig = entityHashMap.get(idPig);
|
||||
if (pig == null) {
|
||||
World world = NEIClientUtils.mc() != null ? NEIClientUtils.mc().theWorld : null;
|
||||
|
||||
if (world != null) {
|
||||
try {
|
||||
pig = new EntityPig(world);
|
||||
entityHashMap.put(idPig, pig);
|
||||
NEIClientConfig.logger.debug("Created fallback pig entity for ID: {}", originalId);
|
||||
} catch (Exception e) {
|
||||
NEIClientConfig.logger
|
||||
.error("Failed to create fallback pig entity for original ID: {}", originalId, e);
|
||||
}
|
||||
} else {
|
||||
NEIClientConfig.logger.warn("World is null, cannot create fallback entity for ID: {}", originalId);
|
||||
}
|
||||
}
|
||||
|
||||
return pig;
|
||||
}
|
||||
|
||||
public static void clearEntityReferences() {
|
||||
entityHashMap.clear();
|
||||
NEIClientConfig.logger.debug("Cleared all entity references from cache");
|
||||
}
|
||||
|
||||
private void setDefaultTag(ItemStack itemstack) {
|
||||
if (!IDtoNameMap.containsKey(itemstack.getItemDamage())) itemstack.setItemDamage(idPig);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static void loadSpawners() {
|
||||
if (loaded) return;
|
||||
loaded = true;
|
||||
for (Map.Entry<Class<? extends Entity>, String> entry : EntityList.classToStringMapping.entrySet()) {
|
||||
final Class<? extends Entity> clazz = entry.getKey();
|
||||
if (EntityLiving.class.isAssignableFrom(clazz)) {
|
||||
Integer id = (Integer) EntityList.classToIDMapping.get(clazz);
|
||||
if (id == null) continue;
|
||||
String name = entry.getValue();
|
||||
if (name == null) continue;
|
||||
if (name.equals("EnderDragon")) continue;
|
||||
if (name.equals("Pig")) idPig = id;
|
||||
if (clazz != EntityPig.class || name.equals("Pig")) {
|
||||
IDtoNameMap.put(id, name);
|
||||
if (loaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (ItemMobSpawner.class) {
|
||||
try {
|
||||
for (Map.Entry<Class<? extends Entity>, String> entry : ((Map<Class<? extends Entity>, String>) EntityList.classToStringMapping)
|
||||
.entrySet()) {
|
||||
|
||||
Class<? extends Entity> clazz = entry.getKey();
|
||||
String name = entry.getValue();
|
||||
|
||||
if (shouldRegisterEntity(clazz, name)) {
|
||||
Integer id = (Integer) EntityList.classToIDMapping.get(clazz);
|
||||
if (id != null) {
|
||||
IDtoNameMap.put(id, name);
|
||||
ENTITY_CLASS_TO_NAME_CACHE.put(clazz, name);
|
||||
|
||||
if ("Pig".equals(name)) {
|
||||
idPig = id;
|
||||
NEIClientConfig.logger.debug("Set pig entity ID to: {}", id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
loaded = true;
|
||||
NEIClientConfig.logger.info("Loaded {} spawner entity mappings", IDtoNameMap.size());
|
||||
|
||||
} catch (Exception e) {
|
||||
NEIClientConfig.logger.error("Error loading spawners from entity list", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean shouldRegisterEntity(Class<? extends Entity> clazz, String name) {
|
||||
if (clazz == null || name == null || name.trim().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!EntityLiving.class.isAssignableFrom(clazz)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ("EnderDragon".equals(name) || "Giant".equals(name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
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));
|
||||
if (!NEIClientConfig.hasSMPCounterPart()) {
|
||||
list.add(new ItemStack(item));
|
||||
} else {
|
||||
loadSpawners();
|
||||
for (int id : IDtoNameMap.keySet()) {
|
||||
ItemStack stack = new ItemStack(item, 1, id);
|
||||
list.add(stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static String getEntityNameForMeta(int meta) {
|
||||
loadSpawners();
|
||||
return IDtoNameMap.getOrDefault(meta, IDtoNameMap.getOrDefault(idPig, "Pig"));
|
||||
}
|
||||
|
||||
public static boolean isValidEntityMeta(int meta) {
|
||||
loadSpawners();
|
||||
return IDtoNameMap.containsKey(meta) || meta == 0;
|
||||
}
|
||||
|
||||
public static Map<Integer, String> getRegisteredSpawnerEntities() {
|
||||
loadSpawners();
|
||||
return Collections.unmodifiableMap(IDtoNameMap);
|
||||
}
|
||||
|
||||
public static boolean isEntityValidForSpawner(Class<? extends Entity> entityClass) {
|
||||
if (entityClass == null) return false;
|
||||
|
||||
String name = ENTITY_CLASS_TO_NAME_CACHE.get(entityClass);
|
||||
if (name == null) {
|
||||
name = (String) EntityList.classToStringMapping.get(entityClass);
|
||||
}
|
||||
|
||||
return name != null && shouldRegisterEntity(entityClass, name);
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,13 @@ public class ItemPanel extends PanelWidget<ItemsPanelGrid> {
|
||||
}
|
||||
|
||||
public static void updateItemList(ArrayList<ItemStack> newItems) {
|
||||
ItemPanels.itemPanel.getGrid().setItems(newItems);
|
||||
final ItemsPanelGrid grid = ItemPanels.itemPanel.getGrid();
|
||||
|
||||
if (grid.rawItems.size() != newItems.size()) {
|
||||
grid.setPage(0);
|
||||
}
|
||||
|
||||
grid.setItems(newItems);
|
||||
ItemPanels.itemPanel.realItems = newItems;
|
||||
}
|
||||
|
||||
@@ -115,31 +121,29 @@ public class ItemPanel extends PanelWidget<ItemsPanelGrid> {
|
||||
return String.format("%d/%d", getPage(), Math.max(1, getNumPages()));
|
||||
}
|
||||
|
||||
public Rectangle4i calculateBounds() {
|
||||
final GuiContainer gui = NEIClientUtils.getGuiContainer();
|
||||
final int width = (gui.width - gui.xSize) / 2 - PADDING * 2;
|
||||
final Rectangle4i bounds = new Rectangle4i(
|
||||
(gui.width + gui.xSize) / 2 + PADDING,
|
||||
PADDING,
|
||||
(gui.width - 176) / 2 - PADDING * 2,
|
||||
gui.height - PADDING * 2);
|
||||
@Override
|
||||
public Rectangle4i calculateBounds(GuiContainer gui) {
|
||||
final int maxWidth = (gui.width - 176) / 2 - PADDING * 2;
|
||||
final int maxHeight = gui.height - PADDING * 2;
|
||||
final int freeSpace = (gui.width - gui.xSize) / 2 - PADDING * 2;
|
||||
|
||||
int paddingLeft = (int) Math
|
||||
.ceil(bounds.w * NEIClientConfig.getSetting("world.panels.items.left").getIntValue() / 100000.0);
|
||||
int paddingTop = (int) Math
|
||||
.ceil(bounds.h * NEIClientConfig.getSetting("world.panels.items.top").getIntValue() / 100000.0);
|
||||
int paddingRight = (int) Math
|
||||
.ceil(bounds.w * NEIClientConfig.getSetting("world.panels.items.right").getIntValue() / 100000.0);
|
||||
int paddingBottom = (int) Math
|
||||
.ceil(bounds.h * NEIClientConfig.getSetting("world.panels.items.bottom").getIntValue() / 100000.0);
|
||||
final int paddingLeft = (int) Math
|
||||
.ceil(maxWidth * NEIClientConfig.getSetting("world.panels.items.left").getIntValue() / 100000.0);
|
||||
final int paddingTop = (int) Math
|
||||
.ceil(maxHeight * NEIClientConfig.getSetting("world.panels.items.top").getIntValue() / 100000.0);
|
||||
final int paddingRight = (int) Math
|
||||
.ceil(maxWidth * NEIClientConfig.getSetting("world.panels.items.right").getIntValue() / 100000.0);
|
||||
final int paddingBottom = (int) Math
|
||||
.ceil(maxHeight * NEIClientConfig.getSetting("world.panels.items.bottom").getIntValue() / 100000.0);
|
||||
|
||||
bounds.h = Math.max(ItemsGrid.SLOT_SIZE, bounds.h - paddingTop - paddingBottom);
|
||||
bounds.y = bounds.y + Math.min(paddingTop, bounds.h - ItemsGrid.SLOT_SIZE);
|
||||
final int width = Math.max(
|
||||
ItemsGrid.SLOT_SIZE,
|
||||
snapDownToMultiple(
|
||||
Math.min(freeSpace - paddingRight, maxWidth - paddingLeft - paddingRight),
|
||||
ItemsGrid.SLOT_SIZE));
|
||||
final int height = Math.max(ItemsGrid.SLOT_SIZE, maxHeight - paddingTop - paddingBottom);
|
||||
|
||||
bounds.w = Math.max(ItemsGrid.SLOT_SIZE, Math.min(bounds.w - paddingLeft - paddingRight, width - paddingRight));
|
||||
bounds.x = bounds.x + Math.max(0, width - bounds.w - paddingRight);
|
||||
|
||||
return bounds;
|
||||
return new Rectangle4i(gui.width - width - PADDING - paddingRight, paddingTop + PADDING, width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -70,7 +70,7 @@ public class ItemsPanelGrid extends ItemsGrid<ItemsPanelGrid.ItemsPanelGridSlot,
|
||||
}
|
||||
|
||||
public ArrayList<ItemStack> newItems;
|
||||
public ArrayList<ItemStack> rawItems;
|
||||
public ArrayList<ItemStack> rawItems = new ArrayList<>();
|
||||
protected List<ItemsPanelGridSlot> gridMask;
|
||||
|
||||
protected final Map<Integer, Integer> itemToGroup = new HashMap<>();
|
||||
|
||||
@@ -66,9 +66,9 @@ import codechicken.nei.guihook.IContainerInputHandler;
|
||||
import codechicken.nei.guihook.IContainerObjectHandler;
|
||||
import codechicken.nei.guihook.IContainerTooltipHandler;
|
||||
import codechicken.nei.recipe.AutoCraftingManager;
|
||||
import codechicken.nei.recipe.DebugHandlerWidget;
|
||||
import codechicken.nei.recipe.GuiRecipeTab;
|
||||
import codechicken.nei.recipe.RecipeCatalysts;
|
||||
import codechicken.nei.recipe.debug.DebugHandlerWidget;
|
||||
|
||||
public class LayoutManager implements IContainerInputHandler, IContainerTooltipHandler, IContainerDrawHandler,
|
||||
IContainerObjectHandler, IKeyStateTracker {
|
||||
@@ -92,7 +92,6 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
public static SubsetWidget dropDown;
|
||||
public static SearchField searchField;
|
||||
public static ItemZoom itemZoom;
|
||||
public static DebugHandlerWidget recipeHandlerWidget;
|
||||
|
||||
public static ButtonCycled options;
|
||||
public static ButtonCycled bookmarksButton;
|
||||
@@ -104,7 +103,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
public static Button delete;
|
||||
public static ButtonCycled gamemode;
|
||||
public static Button rain;
|
||||
public static Button magnet;
|
||||
public static ButtonCycled magnet;
|
||||
public static Button[] timeButtons = new Button[4];
|
||||
public static Button heal;
|
||||
|
||||
@@ -406,8 +405,6 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
|
||||
itemZoom = new ItemZoom();
|
||||
|
||||
recipeHandlerWidget = new DebugHandlerWidget();
|
||||
|
||||
dropDown = new SubsetWidget();
|
||||
searchField = new SearchField("search");
|
||||
API.addItemFilter(searchField);
|
||||
@@ -600,7 +597,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
return getStateTip("rain", state);
|
||||
}
|
||||
};
|
||||
magnet = new Button() {
|
||||
magnet = new ButtonCycled(2) {
|
||||
|
||||
@Override
|
||||
public boolean onButtonPress(boolean rightclick) {
|
||||
@@ -786,8 +783,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
addWidget(dropDown);
|
||||
}
|
||||
|
||||
addWidget(recipeHandlerWidget);
|
||||
recipeHandlerWidget.setVisible();
|
||||
addWidget(DebugHandlerWidget.instance);
|
||||
}
|
||||
|
||||
public static LayoutStyle getLayoutStyle(int id) {
|
||||
|
||||
@@ -31,7 +31,8 @@ public class LayoutStyleMinecraft extends LayoutStyle {
|
||||
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.magnet.icons[0] = new Image(180, 24, 12, 12);
|
||||
LayoutManager.magnet.icons[1] = new Image(180, 36, 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);
|
||||
@@ -86,6 +87,7 @@ public class LayoutStyleMinecraft extends LayoutStyle {
|
||||
LayoutManager.options.index = NEIClientConfig.getCheatMode();
|
||||
|
||||
LayoutManager.magnet.state = 0x4 | (NEIClientConfig.getMagnetMode() ? 1 : 0);
|
||||
LayoutManager.magnet.index = (LayoutManager.magnet.state & 0x1) != 0 ? 1 : 0;
|
||||
|
||||
if (NEIClientConfig.canPerformAction("delete")) {
|
||||
layoutButton(LayoutManager.delete);
|
||||
|
||||
@@ -56,12 +56,10 @@ import codechicken.nei.config.OptionToggleButtonBoubs;
|
||||
import codechicken.nei.config.OptionUtilities;
|
||||
import codechicken.nei.config.preset.GuiPresetList;
|
||||
import codechicken.nei.event.NEIConfigsLoadedEvent;
|
||||
import codechicken.nei.recipe.DebugHandlerWidget;
|
||||
import codechicken.nei.recipe.GuiRecipeTab;
|
||||
import codechicken.nei.recipe.IRecipeHandler;
|
||||
import codechicken.nei.recipe.InformationHandler;
|
||||
import codechicken.nei.recipe.RecipeCatalysts;
|
||||
import codechicken.nei.recipe.RecipeInfo;
|
||||
import codechicken.nei.util.ItemUntranslator;
|
||||
import codechicken.nei.util.NEIKeyboardUtils;
|
||||
import codechicken.obfuscator.ObfuscationRun;
|
||||
@@ -149,6 +147,7 @@ public class NEIClientConfig {
|
||||
API.addOption(new OptionToggleButton("inventory.widgetsenabled"));
|
||||
|
||||
tag.getTag("findFuelsParallel").getBooleanValue(true);
|
||||
tag.getTag("showRepairOnlyForDamageableItems").getBooleanValue(true);
|
||||
|
||||
tag.getTag("inventory.autocrafting").getBooleanValue(true);
|
||||
tag.getTag("inventory.dynamicFontSize").getBooleanValue(true);
|
||||
@@ -782,8 +781,7 @@ public class NEIClientConfig {
|
||||
@Override
|
||||
public boolean onClick(int button) {
|
||||
super.onClick(button);
|
||||
FavoriteRecipes.save();
|
||||
FavoriteRecipes.load();
|
||||
FavoriteRecipes.reload();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@@ -796,7 +794,19 @@ public class NEIClientConfig {
|
||||
.getBooleanValue(false);
|
||||
API.addOption(new OptionToggleButton("inventory.favorites.showRecipeTooltipInGui", true));
|
||||
|
||||
tag.getTag("inventory.favorites.depth").setComment("Bookmark creation depth").getIntValue(3);
|
||||
tag.getTag("inventory.favorites.generateSingleRecipeFavorites")
|
||||
.setComment("Automatically generate favorites for items with only one recipe").getBooleanValue(false);
|
||||
API.addOption(new OptionToggleButton("inventory.favorites.generateSingleRecipeFavorites", true) {
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button) {
|
||||
super.onClick(button);
|
||||
FavoriteRecipes.loadAutoGeneratedRecipes();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
tag.getTag("inventory.favorites.depth").setComment("Bookmark creation depth").getIntValue(9);
|
||||
API.addOption(new OptionIntegerField("inventory.favorites.depth", 0, 100));
|
||||
}
|
||||
|
||||
@@ -816,6 +826,7 @@ public class NEIClientConfig {
|
||||
API.addHashBind("gui.search", Keyboard.KEY_F);
|
||||
API.addKeyBind("gui.bookmark", Keyboard.KEY_A);
|
||||
API.addHashBind("gui.favorite", Keyboard.KEY_F + NEIClientUtils.SHIFT_HASH);
|
||||
API.addKeyBind("gui.favorite_item", Keyboard.KEY_F);
|
||||
API.addHashBind("gui.remove_recipe", Keyboard.KEY_A + NEIClientUtils.SHIFT_HASH);
|
||||
API.addKeyBind("gui.bookmark_pull_items", Keyboard.KEY_V);
|
||||
API.addKeyBind("gui.overlay", Keyboard.KEY_S);
|
||||
@@ -966,7 +977,6 @@ public class NEIClientConfig {
|
||||
// main NEI config loading
|
||||
ItemInfo.load();
|
||||
GuiInfo.load();
|
||||
RecipeInfo.load();
|
||||
HeldItemHandler.load();
|
||||
LayoutManager.load();
|
||||
NEIController.load();
|
||||
@@ -998,7 +1008,6 @@ public class NEIClientConfig {
|
||||
SubsetWidget.loadHidden();
|
||||
CollapsibleItems.load();
|
||||
ItemSorter.loadConfig();
|
||||
FavoriteRecipes.load();
|
||||
|
||||
// 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
|
||||
@@ -1007,8 +1016,6 @@ public class NEIClientConfig {
|
||||
// API. I don't expect any handler to do this, but who knows what modders have come up with...
|
||||
pluginNEIConfigLoaded = true;
|
||||
MinecraftForge.EVENT_BUS.post(new NEIConfigsLoadedEvent());
|
||||
|
||||
DebugHandlerWidget.loadHandlerInfoPatch();
|
||||
ItemList.loadItems.restart();
|
||||
}
|
||||
}.start();
|
||||
|
||||
@@ -11,7 +11,6 @@ import static codechicken.nei.NEIClientConfig.world;
|
||||
import java.awt.Color;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.math.BigInteger;
|
||||
import java.math.RoundingMode;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
@@ -47,6 +46,7 @@ import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.gtnewhorizon.gtnhlib.util.numberformatting.NumberFormatUtil;
|
||||
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.lib.inventory.InventoryRange;
|
||||
@@ -126,16 +126,22 @@ public class NEIClientUtils extends NEIServerUtils {
|
||||
});
|
||||
}
|
||||
|
||||
public static String formatNumbers(BigInteger aNumber) {
|
||||
public static String formatNumber(long aNumber) {
|
||||
|
||||
if (NEIModContainer.isGTNHLibLoaded()) {
|
||||
return NumberFormatUtil.formatNumber(aNumber);
|
||||
}
|
||||
|
||||
return getDecimalFormat().format(aNumber);
|
||||
}
|
||||
|
||||
public static String formatNumbers(long aNumber) {
|
||||
return getDecimalFormat().format(aNumber);
|
||||
}
|
||||
public static String formatFluid(long aNumber) {
|
||||
|
||||
public static String formatNumbers(double aNumber) {
|
||||
return getDecimalFormat().format(aNumber);
|
||||
if (NEIModContainer.isGTNHLibLoaded()) {
|
||||
return NumberFormatUtil.formatFluid(aNumber);
|
||||
}
|
||||
|
||||
return getDecimalFormat().format(aNumber) + " L";
|
||||
}
|
||||
|
||||
public static void deleteHeldItem() {
|
||||
@@ -198,7 +204,7 @@ public class NEIClientUtils extends NEIServerUtils {
|
||||
public static void cheatItem(ItemStack stack, int button, int mode) {
|
||||
if (!canCheatItem(stack)) return;
|
||||
|
||||
if (mode == -1 && button == 0 && shiftKey() && NEIClientConfig.hasSMPCounterPart()) {
|
||||
if (mode == -1 && button == 0 && controlKey() && NEIClientConfig.hasSMPCounterPart()) {
|
||||
for (IInfiniteItemHandler handler : ItemInfo.infiniteHandlers) {
|
||||
if (!handler.canHandleItem(stack)) continue;
|
||||
|
||||
@@ -413,18 +419,11 @@ public class NEIClientUtils extends NEIServerUtils {
|
||||
if (textWidth > containerWidth) {
|
||||
int dots = fontRenderer.getStringWidth("...");
|
||||
|
||||
if (containerWidth > dots) {
|
||||
textWidth += dots;
|
||||
|
||||
while (textWidth > containerWidth) {
|
||||
textWidth -= fontRenderer.getCharWidth(text.charAt(text.length() - 1));
|
||||
text = text.substring(0, text.length() - 1);
|
||||
}
|
||||
|
||||
return text + "...";
|
||||
if (containerWidth <= dots) {
|
||||
return "...";
|
||||
}
|
||||
|
||||
return "...";
|
||||
return fontRenderer.trimStringToWidth(text, containerWidth - dots) + "...";
|
||||
}
|
||||
|
||||
return text;
|
||||
|
||||
@@ -7,8 +7,7 @@ import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
@@ -18,6 +17,7 @@ import codechicken.core.launch.CodeChickenCorePlugin;
|
||||
import codechicken.nei.api.IConfigureNEI;
|
||||
import codechicken.nei.asm.NEICorePlugin;
|
||||
import codechicken.nei.config.IMCHandler;
|
||||
import codechicken.nei.guihook.HideousLinkedList;
|
||||
import codechicken.nei.recipe.GuiRecipeTab;
|
||||
import cpw.mods.fml.client.FMLFileResourcePack;
|
||||
import cpw.mods.fml.client.FMLFolderResourcePack;
|
||||
@@ -31,13 +31,15 @@ import cpw.mods.fml.common.event.FMLInterModComms;
|
||||
import cpw.mods.fml.common.event.FMLLoadCompleteEvent;
|
||||
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLServerAboutToStartEvent;
|
||||
import cpw.mods.fml.common.versioning.ArtifactVersion;
|
||||
import cpw.mods.fml.common.versioning.VersionParser;
|
||||
import cpw.mods.fml.common.versioning.VersionRange;
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
public class NEIModContainer extends DummyModContainer {
|
||||
|
||||
public static LinkedList<IConfigureNEI> plugins = new LinkedList<>();
|
||||
public static final LinkedList<IConfigureNEI> plugins = new HideousLinkedList<>(new CopyOnWriteArrayList<>());
|
||||
|
||||
private static boolean gregTech5Loaded;
|
||||
private static boolean gtnhLibLoaded;
|
||||
@@ -46,7 +48,6 @@ public class NEIModContainer extends DummyModContainer {
|
||||
|
||||
public NEIModContainer() {
|
||||
super(getModMetadata());
|
||||
loadMetadata();
|
||||
}
|
||||
|
||||
private static ModMetadata getModMetadata() {
|
||||
@@ -54,7 +55,7 @@ public class NEIModContainer extends DummyModContainer {
|
||||
modMetadata.name = "NotEnoughItems";
|
||||
modMetadata.modId = "NotEnoughItems";
|
||||
modMetadata.version = Tags.VERSION;
|
||||
modMetadata.authorList = Arrays.asList("ChickenBones", "mitchej123");
|
||||
modMetadata.authorList = Arrays.asList("ChickenBones", "mitchej123", "SLPrime");
|
||||
modMetadata.url = "https://github.com/GTNewHorizons/NotEnoughItems";
|
||||
modMetadata.description = "Recipe Viewer, Inventory Manager, Item Spawner, Cheats and more; GTNH Version includes many enhancements.";
|
||||
return modMetadata;
|
||||
@@ -79,36 +80,12 @@ public class NEIModContainer extends DummyModContainer {
|
||||
public List<ArtifactVersion> getDependencies() {
|
||||
List<ArtifactVersion> deps = new ArrayList<>();
|
||||
deps.add(VersionParser.parseVersionReference("CodeChickenCore@[" + codechicken.core.asm.Tags.VERSION + ",)"));
|
||||
deps.add(VersionParser.parseVersionReference("gtnhlib@[0.6.0,)"));
|
||||
deps.add(VersionParser.parseVersionReference("gtnhlib@[0.9.6,)"));
|
||||
return deps;
|
||||
}
|
||||
|
||||
private String description;
|
||||
|
||||
private void loadMetadata() {
|
||||
description = super.getMetadata().description.replace("Supporters:", EnumChatFormatting.AQUA + "Supporters:");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModMetadata getMetadata() {
|
||||
StringBuilder s_plugins = new StringBuilder();
|
||||
if (plugins.size() == 0) {
|
||||
s_plugins.append(EnumChatFormatting.RED).append("No installed plugins.");
|
||||
} else {
|
||||
s_plugins.append(EnumChatFormatting.GREEN).append("Installed plugins: ");
|
||||
for (int i = 0; i < plugins.size(); i++) {
|
||||
if (i > 0) s_plugins.append(", ");
|
||||
IConfigureNEI plugin = plugins.get(i);
|
||||
s_plugins.append(plugin.getName()).append(" ").append(plugin.getVersion());
|
||||
}
|
||||
s_plugins.append(".");
|
||||
}
|
||||
|
||||
ModMetadata meta = super.getMetadata();
|
||||
meta.description = description.replace("<plugins>", s_plugins.toString());
|
||||
return meta;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean registerBus(EventBus bus, LoadController controller) {
|
||||
bus.register(this);
|
||||
@@ -125,8 +102,10 @@ public class NEIModContainer extends DummyModContainer {
|
||||
|
||||
@Subscribe
|
||||
public void init(FMLInitializationEvent event) {
|
||||
if (CommonUtils.isClient()) ClientHandler.load();
|
||||
|
||||
if (CommonUtils.isClient()) {
|
||||
ClientHandler.load();
|
||||
IMCForNEI.IMCSender();
|
||||
}
|
||||
ServerHandler.load();
|
||||
}
|
||||
|
||||
@@ -147,6 +126,11 @@ public class NEIModContainer extends DummyModContainer {
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onServerAboutToStart(FMLServerAboutToStartEvent event) {
|
||||
NEIServerConfig.resetFirstLoad();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void handleIMCMessages(FMLInterModComms.IMCEvent event) {
|
||||
IMCHandler.processIMC(event.getMessages());
|
||||
|
||||
@@ -18,7 +18,6 @@ import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.JsonToNBT;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
import net.minecraftforge.permission.PermissionLevel;
|
||||
@@ -37,21 +36,23 @@ import codechicken.lib.packet.PacketCustom;
|
||||
|
||||
public class NEIServerConfig {
|
||||
|
||||
private static MinecraftServer server;
|
||||
|
||||
private static boolean firstLoad;
|
||||
public static Logger logger = LogManager.getLogger("NotEnoughItems");
|
||||
public static File saveDir;
|
||||
public static ConfigFile serverConfig;
|
||||
public static Map<Integer, NBTTagCompound> dimTags = new HashMap<>();
|
||||
public static HashMap<String, PlayerSave> playerSaves = new HashMap<>();
|
||||
public static ItemStackMap<Set<String>> bannedItems = new ItemStackMap<>();
|
||||
|
||||
private static boolean doesPermAPIExist = false;
|
||||
|
||||
public static void resetFirstLoad() {
|
||||
firstLoad = true;
|
||||
}
|
||||
|
||||
public static void load(World world) {
|
||||
if (MinecraftServer.getServer() != server) {
|
||||
if (firstLoad) {
|
||||
firstLoad = false;
|
||||
logger.debug("Loading NEI Server");
|
||||
server = MinecraftServer.getServer();
|
||||
saveDir = new File(DimensionManager.getCurrentSaveRootDirectory(), "NEI");
|
||||
|
||||
dimTags.clear();
|
||||
|
||||
@@ -183,7 +183,7 @@ public class NEIServerUtils {
|
||||
public static boolean areStacksSameTypeWithNBT(ItemStack stack1, ItemStack stack2) {
|
||||
return stack1 != null && stack2 != null
|
||||
&& stack1.getItem() == stack2.getItem()
|
||||
&& (!stack2.getHasSubtypes() || stack2.getItemDamage() == stack1.getItemDamage())
|
||||
&& (stack2.isItemStackDamageable() || stack2.getItemDamage() == stack1.getItemDamage())
|
||||
&& NBTHelper.matchTag(stack1.getTagCompound(), stack2.getTagCompound());
|
||||
}
|
||||
|
||||
|
||||
@@ -82,10 +82,14 @@ public abstract class PanelWidget<T extends ItemsGrid<? extends ItemsGridSlot, ?
|
||||
|
||||
public abstract String getLabelText();
|
||||
|
||||
public abstract Rectangle4i calculateBounds();
|
||||
public abstract Rectangle4i calculateBounds(GuiContainer gui);
|
||||
|
||||
protected static int snapDownToMultiple(int value, int multiple) {
|
||||
return (value / multiple) * multiple;
|
||||
}
|
||||
|
||||
public void resize(GuiContainer gui) {
|
||||
final Rectangle4i bounds = calculateBounds();
|
||||
final Rectangle4i bounds = calculateBounds(gui);
|
||||
|
||||
x = bounds.x;
|
||||
y = bounds.y;
|
||||
|
||||
@@ -104,7 +104,7 @@ public class PositionedStack {
|
||||
items = filteringPermutations(items, GuiRecipe.getSearchItemFilter());
|
||||
items = filteringPermutations(items, additionalFilter);
|
||||
|
||||
items.sort(Comparator.comparing(FavoriteRecipes::contains).reversed());
|
||||
items.sort(Comparator.comparing(FavoriteRecipes::containsManual).reversed());
|
||||
return items;
|
||||
}
|
||||
|
||||
|
||||
@@ -222,7 +222,6 @@ public class SearchField extends TextField implements ItemFilterProvider {
|
||||
public void onTextChange(String oldText) {
|
||||
final String newText = text();
|
||||
if (!newText.equals(oldText)) {
|
||||
if (newText.length() > 0) NEIClientConfig.logger.debug("Searching for " + newText);
|
||||
NEIClientConfig.setSearchExpression(newText);
|
||||
ItemList.updateFilter.restart();
|
||||
}
|
||||
@@ -315,6 +314,9 @@ public class SearchField extends TextField implements ItemFilterProvider {
|
||||
public static String getEscapedSearchText(String text) {
|
||||
text = EnumChatFormatting.getTextWithoutFormattingCodes(text);
|
||||
|
||||
boolean addQuotes = text.contains(" ")
|
||||
&& NEIClientConfig.getBooleanSetting("inventory.search.quoteDropItemName");
|
||||
|
||||
switch (NEIClientConfig.getIntSetting("inventory.search.patternMode")) {
|
||||
case 1:
|
||||
text = text.replaceAll("[\\?|\\*]", "\\\\$0");
|
||||
@@ -323,14 +325,19 @@ public class SearchField extends TextField implements ItemFilterProvider {
|
||||
text = text.replaceAll("[{}()\\[\\].+*?^$\\\\|]", "\\\\$0");
|
||||
break;
|
||||
case 3:
|
||||
text = text.replaceAll("\"", "\\\\$0");
|
||||
text = "\"" + text + "\"";
|
||||
return text;
|
||||
// In extended+ quotes require only quotes to be escaped
|
||||
if (addQuotes) {
|
||||
text = text.replaceAll("\"", "\\\\$0");
|
||||
} else {
|
||||
String prefixes = searchParser.getPrefixes();
|
||||
text = text.replaceAll("[-<>^{}|/\\\\\"" + Pattern.quote(prefixes) + "]", "\\\\$0");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (text.contains(" ") && NEIClientConfig.getBooleanSetting("inventory.search.quoteDropItemName")) {
|
||||
if (addQuotes) {
|
||||
text = "\"" + text + "\"";
|
||||
}
|
||||
|
||||
|
||||
@@ -468,7 +468,7 @@ public class SearchTokenParser {
|
||||
return tokens;
|
||||
}
|
||||
|
||||
private String getPrefixes() {
|
||||
public String getPrefixes() {
|
||||
if (this.prefixes == null) {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
|
||||
|
||||
@@ -21,10 +21,8 @@ import cpw.mods.fml.common.gameevent.TickEvent.Phase;
|
||||
|
||||
public class ServerHandler {
|
||||
|
||||
private static ServerHandler instance;
|
||||
|
||||
public static void load() {
|
||||
instance = new ServerHandler();
|
||||
ServerHandler instance = new ServerHandler();
|
||||
|
||||
PacketCustom.assignHandler(NEICPH.channel, new NEISPH());
|
||||
FMLCommonHandler.instance().bus().register(instance);
|
||||
|
||||
@@ -10,9 +10,6 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
@@ -53,9 +50,7 @@ public class SubsetWidget extends Button implements ItemFilterProvider {
|
||||
protected static final int MARGIN = 2;
|
||||
protected static final char PREFIX = '%';
|
||||
|
||||
protected static ReentrantReadWriteLock hiddenItemLock = new ReentrantReadWriteLock();
|
||||
protected static Lock hiddenWriteLock = hiddenItemLock.writeLock();
|
||||
protected static Lock hiddenReadLock = hiddenItemLock.readLock();
|
||||
private static final Object hiddenLock = new Object();
|
||||
|
||||
public static class SubsetTag {
|
||||
|
||||
@@ -377,11 +372,18 @@ public class SubsetWidget extends Button implements ItemFilterProvider {
|
||||
}
|
||||
final AnyMultiItemFilter filter = new AnyMultiItemFilter();
|
||||
final Set<ItemStack> filteredItems = new HashSet<>();
|
||||
final List<SubsetTag> snapshot;
|
||||
|
||||
for (SubsetTag tag : tags.values()) {
|
||||
synchronized (tags) {
|
||||
snapshot = new ArrayList<>(tags.values());
|
||||
}
|
||||
|
||||
for (SubsetTag tag : snapshot) {
|
||||
if (tag.filter != null && matches(tag.path, searchText, pattern)) {
|
||||
filteredItems.addAll(tag.items);
|
||||
filter.filters.add(tag.filter);
|
||||
synchronized (tag.items) {
|
||||
filteredItems.addAll(tag.items);
|
||||
filter.filters.add(tag.filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -414,6 +416,7 @@ public class SubsetWidget extends Button implements ItemFilterProvider {
|
||||
* All operations on this variable should be synchronised.
|
||||
*/
|
||||
private static final ItemStackSet hiddenItems = new ItemStackSet();
|
||||
|
||||
private static final Map<String, SubsetTag> tags = new HashMap<>();
|
||||
private static final SubsetTag root = new SubsetTag("");
|
||||
protected static boolean enableSearchBySubsets = false;
|
||||
@@ -436,6 +439,7 @@ public class SubsetWidget extends Button implements ItemFilterProvider {
|
||||
}
|
||||
|
||||
updateHiddenItems();
|
||||
SearchField.searchParser.clearCache();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -447,24 +451,14 @@ public class SubsetWidget extends Button implements ItemFilterProvider {
|
||||
parentpath -> parentpath.equals(path.toLowerCase())
|
||||
|| parentpath.startsWith(path.toLowerCase() + "."));
|
||||
updateHiddenItems();
|
||||
SearchField.searchParser.clearCache();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isHidden(ItemStack item) {
|
||||
try {
|
||||
if (hiddenReadLock.tryLock(5, TimeUnit.SECONDS)) {
|
||||
try {
|
||||
return hiddenItems.contains(item);
|
||||
} finally {
|
||||
hiddenReadLock.unlock();
|
||||
}
|
||||
} else {
|
||||
NEIClientConfig.logger.error("Unable to obtain read lock in 'isHidden'");
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
synchronized (hiddenLock) {
|
||||
return hiddenItems.contains(item);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static List<ItemStack> getItems(SubsetTag tag, List<ItemStack> items) {
|
||||
@@ -478,90 +472,45 @@ public class SubsetWidget extends Button implements ItemFilterProvider {
|
||||
}
|
||||
|
||||
public static void showOnly(SubsetTag tag) {
|
||||
try {
|
||||
if (hiddenWriteLock.tryLock(5, TimeUnit.SECONDS)) {
|
||||
try {
|
||||
hiddenItems.clear();
|
||||
hiddenItems.addAll(getItems(root, new ArrayList<>()));
|
||||
hiddenItems.removeAll(getItems(tag, new ArrayList<>()));
|
||||
} finally {
|
||||
hiddenWriteLock.unlock();
|
||||
}
|
||||
} else {
|
||||
NEIClientConfig.logger.error("Unable to obtain write lock in 'showOnly'");
|
||||
}
|
||||
|
||||
calculateVisibility();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
synchronized (hiddenLock) {
|
||||
hiddenItems.clear();
|
||||
hiddenItems.addAll(getItems(root, new ArrayList<>()));
|
||||
hiddenItems.removeAll(getItems(tag, new ArrayList<>()));
|
||||
}
|
||||
|
||||
calculateVisibility();
|
||||
}
|
||||
|
||||
public static void setHidden(SubsetTag tag, boolean hidden) {
|
||||
try {
|
||||
if (hiddenWriteLock.tryLock(5, TimeUnit.SECONDS)) {
|
||||
try {
|
||||
List<ItemStack> tagItems = getItems(tag, new ArrayList<>());
|
||||
synchronized (hiddenLock) {
|
||||
final List<ItemStack> tagItems = getItems(tag, new ArrayList<>());
|
||||
|
||||
if (hidden) {
|
||||
hiddenItems.addAll(tagItems);
|
||||
} else {
|
||||
hiddenItems.removeAll(tagItems);
|
||||
}
|
||||
|
||||
} finally {
|
||||
hiddenWriteLock.unlock();
|
||||
}
|
||||
if (hidden) {
|
||||
hiddenItems.addAll(tagItems);
|
||||
} else {
|
||||
NEIClientConfig.logger.error("Unable to obtain write lock in 'setHidden'");
|
||||
hiddenItems.removeAll(tagItems);
|
||||
}
|
||||
|
||||
calculateVisibility();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
calculateVisibility();
|
||||
}
|
||||
|
||||
public static void setHidden(ItemStack item, boolean hidden) {
|
||||
try {
|
||||
if (hiddenWriteLock.tryLock(5, TimeUnit.SECONDS)) {
|
||||
try {
|
||||
|
||||
if (hidden) {
|
||||
hiddenItems.add(item);
|
||||
} else {
|
||||
hiddenItems.remove(item);
|
||||
}
|
||||
|
||||
} finally {
|
||||
hiddenWriteLock.unlock();
|
||||
}
|
||||
synchronized (hiddenLock) {
|
||||
if (hidden) {
|
||||
hiddenItems.add(item);
|
||||
} else {
|
||||
NEIClientConfig.logger.error("Unable to obtain write lock in 'setHidden'");
|
||||
hiddenItems.remove(item);
|
||||
}
|
||||
|
||||
calculateVisibility();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
calculateVisibility();
|
||||
}
|
||||
|
||||
public static void unhideAll() {
|
||||
try {
|
||||
if (hiddenWriteLock.tryLock(5, TimeUnit.SECONDS)) {
|
||||
try {
|
||||
hiddenItems.clear();
|
||||
} finally {
|
||||
hiddenWriteLock.unlock();
|
||||
}
|
||||
} else {
|
||||
NEIClientConfig.logger.error("Unable to obtain write lock in 'unhideAll'");
|
||||
}
|
||||
|
||||
calculateVisibility();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
synchronized (hiddenLock) {
|
||||
hiddenItems.clear();
|
||||
}
|
||||
calculateVisibility();
|
||||
}
|
||||
|
||||
public static void updateHiddenItems() {
|
||||
@@ -646,29 +595,20 @@ public class SubsetWidget extends Button implements ItemFilterProvider {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (hiddenWriteLock.tryLock(5, TimeUnit.SECONDS)) {
|
||||
try {
|
||||
hiddenItems.clear();
|
||||
hiddenItems.addAll(itemList);
|
||||
} finally {
|
||||
hiddenWriteLock.unlock();
|
||||
}
|
||||
} else {
|
||||
NEIClientConfig.logger.error("Unable to obtain second write lock in 'loadHidden'");
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
synchronized (hiddenLock) {
|
||||
hiddenItems.clear();
|
||||
hiddenItems.addAll(itemList);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void saveHidden() {
|
||||
if (NEIClientConfig.world == null) return;
|
||||
|
||||
final NBTTagList list = new NBTTagList();
|
||||
for (ItemStack stack : hiddenItems.values()) {
|
||||
list.appendTag(stack.writeToNBT(new NBTTagCompound()));
|
||||
synchronized (hiddenLock) {
|
||||
for (ItemStack stack : hiddenItems.values()) {
|
||||
list.appendTag(stack.writeToNBT(new NBTTagCompound()));
|
||||
}
|
||||
}
|
||||
|
||||
NEIClientConfig.world.nbt.setTag("hiddenItems", list);
|
||||
@@ -686,14 +626,22 @@ public class SubsetWidget extends Button implements ItemFilterProvider {
|
||||
public void execute() {
|
||||
|
||||
try {
|
||||
final List<SubsetTag> list = new ArrayList<>(tags.values());
|
||||
final List<SubsetTag> list;
|
||||
|
||||
synchronized (tags) {
|
||||
list = new ArrayList<>(tags.values());
|
||||
}
|
||||
|
||||
root.clearCache();
|
||||
|
||||
list.parallelStream().forEach(tag -> {
|
||||
tag.clearCache();
|
||||
ItemList.items.stream().filter(tag.filter::matches)
|
||||
.collect(Collectors.toCollection(() -> tag.items));
|
||||
|
||||
if (!(tag.filter instanceof NothingItemFilter)) {
|
||||
ItemList.items.stream().filter(tag.filter::matches)
|
||||
.collect(Collectors.toCollection(() -> tag.items));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
for (SubsetTag tag : list) {
|
||||
@@ -729,6 +677,7 @@ public class SubsetWidget extends Button implements ItemFilterProvider {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
SearchField.searchParser.clearCache();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -745,6 +694,11 @@ public class SubsetWidget extends Button implements ItemFilterProvider {
|
||||
if (NEIClientConfig.subsetWidgetOnTop()) {
|
||||
return NEIClientUtils.translate("inventory.item_subsets");
|
||||
} else {
|
||||
final String translated = NEIClientUtils.translate("gui.button.label.subset");
|
||||
if (!translated.startsWith("nei.")) { // Optional localization string for resource packs
|
||||
return translated;
|
||||
}
|
||||
|
||||
return EnumChatFormatting.DARK_PURPLE + String.valueOf(SearchField.searchParser.getRedefinedPrefix(PREFIX))
|
||||
+ EnumChatFormatting.RESET;
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ public abstract class TextField extends Widget {
|
||||
onTextChange(oldText);
|
||||
}
|
||||
|
||||
return handled;
|
||||
return handled || keyID == Keyboard.KEY_SPACE;
|
||||
}
|
||||
|
||||
public abstract void onTextChange(String oldText);
|
||||
|
||||
@@ -234,12 +234,12 @@ public abstract class ShortcutInputHandler {
|
||||
if (recipe != null) {
|
||||
math = RecipeChainMath.of(recipe, 1);
|
||||
}
|
||||
} else if (slot.getRecipeId() != null && slot.getType() == BookmarkItemType.RESULT) {
|
||||
} else if (slot.getRecipeId() != null && slot.getType() != BookmarkItemType.INGREDIENT) {
|
||||
|
||||
if (slot.getGroup().crafting == null) {
|
||||
final Recipe recipe = Recipe.of(slot.getRecipeId());
|
||||
if (recipe != null) {
|
||||
math = RecipeChainMath.of(recipe, slot != null ? slot.getMultiplier() : 1);
|
||||
math = RecipeChainMath.of(recipe, Math.max(1, slot != null ? slot.getMultiplier() : 1));
|
||||
}
|
||||
} else {
|
||||
math = ItemPanels.bookmarkPanel.getGrid()
|
||||
@@ -585,6 +585,9 @@ public abstract class ShortcutInputHandler {
|
||||
hotkeys.put(
|
||||
NEIClientUtils.getKeyName(NEIClientUtils.SHIFT_HASH, NEIMouseUtils.MOUSE_BTN_RMB),
|
||||
NEIClientUtils.translate("itempanel.open_usage"));
|
||||
hotkeys.put(
|
||||
NEIClientUtils.getKeyName(NEIClientUtils.CTRL_HASH, NEIMouseUtils.MOUSE_BTN_LMB),
|
||||
NEIClientUtils.translate("itempanel.infinite_item"));
|
||||
} else {
|
||||
hotkeys.put(
|
||||
NEIMouseUtils.getKeyName(NEIMouseUtils.MOUSE_BTN_LMB),
|
||||
|
||||
@@ -89,7 +89,7 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
public static final Color PLACEHOLDER_COLOR = new Color(0x66222222, true);
|
||||
|
||||
public static final int DEFAULT_GROUP_ID = 0;
|
||||
protected static final int GROUP_PANEL_WIDTH = 7;
|
||||
public static final int GROUP_PANEL_WIDTH = 7;
|
||||
protected static final float SCALE_SPEED = 0.1f;
|
||||
|
||||
protected List<BookmarkItem> bookmarkItems = new ArrayList<>();
|
||||
@@ -771,6 +771,25 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
int absoluteSlotIndex = absoluteRowIndex * this.columns;
|
||||
int overGroupId = getRowGroupId(overRowIndex);
|
||||
|
||||
// move group to same grid
|
||||
if (this != sortableGroup.grid) {
|
||||
final BookmarkGroup sourceGroup = sortableGroup.grid.getGroup(sortableGroup.groupId);
|
||||
final List<BookmarkItem> itemsToMove = sortableGroup.getBookmarkItems();
|
||||
|
||||
sortableGroup.grid.removeGroup(sortableGroup.groupId);
|
||||
|
||||
final int groupId = this.addGroup(sourceGroup);
|
||||
for (BookmarkItem item : itemsToMove) {
|
||||
item.groupId = groupId;
|
||||
this.bookmarkItems.add(item);
|
||||
}
|
||||
|
||||
sortableGroup.grid = this;
|
||||
sortableGroup.groupId = groupId;
|
||||
this.onItemsChanged();
|
||||
this.getMask();// force generate grid
|
||||
}
|
||||
|
||||
if (sortableGroup.groupId == overGroupId) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@ public class BookmarkGridGenerator {
|
||||
index = Math.max(0, index);
|
||||
|
||||
while (j++ < maxIndex) {
|
||||
boolean isFirstColumn = (index % gridColumns) == 0;
|
||||
final boolean isFirstColumn = (index % gridColumns) == 0;
|
||||
|
||||
if (this.grid.isInvalidSlot(index % maxIndex)) {
|
||||
index++;
|
||||
@@ -239,7 +239,7 @@ public class BookmarkGridGenerator {
|
||||
return index;
|
||||
} else if (isFirstColumn && (meta.recipeId == null || previousMeta == null
|
||||
|| previousMeta.groupId != meta.groupId
|
||||
|| meta.type == BookmarkItemType.ITEM
|
||||
|| meta.type != BookmarkItemType.INGREDIENT
|
||||
|| !meta.recipeId.equals(previousMeta.recipeId)
|
||||
|| index + 1 < maxIndex && this.grid.isInvalidSlot((index + 1) % maxIndex))) {
|
||||
// In first column must be an item without recipe, a recipe result, or an ingredient
|
||||
@@ -248,6 +248,7 @@ public class BookmarkGridGenerator {
|
||||
} else
|
||||
if (!isFirstColumn && meta.type != BookmarkItemType.ITEM
|
||||
&& previousMeta.type != BookmarkItemType.ITEM
|
||||
&& meta.groupId == previousMeta.groupId
|
||||
&& meta.recipeId != null
|
||||
&& meta.recipeId.equals(previousMeta.recipeId)) {
|
||||
return index;
|
||||
|
||||
@@ -7,7 +7,6 @@ import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -16,6 +15,7 @@ import net.minecraft.nbt.NBTTagCompound;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import com.google.common.io.Files;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
@@ -137,6 +137,7 @@ public class BookmarkStorage {
|
||||
NBTTagCompound navigation = new NBTTagCompound();
|
||||
namespaces.add(new BookmarkGrid());
|
||||
BookmarkGrid grid = namespaces.get(0);
|
||||
boolean wasError = false;
|
||||
|
||||
if (NEIClientConfig.world.nbt.hasKey("bookmark")) {
|
||||
navigation = NEIClientConfig.world.nbt.getCompoundTag("bookmark");
|
||||
@@ -151,17 +152,19 @@ public class BookmarkStorage {
|
||||
}
|
||||
|
||||
if (itemStr.startsWith("; ")) {
|
||||
JsonObject settings = parser.parse(itemStr.substring(2)).getAsJsonObject();
|
||||
|
||||
if (grid.size() > 0) {
|
||||
// do not create empty namespaces
|
||||
grid = new BookmarkGrid();
|
||||
|
||||
if (navigation.hasKey("namespacePage." + namespaces.size())) {
|
||||
grid.setPage(navigation.getInteger("namespacePage." + namespaces.size()));
|
||||
}
|
||||
|
||||
namespaces.add(grid);
|
||||
}
|
||||
|
||||
if (navigation.hasKey("namespacePage." + (namespaces.size() - 1))) {
|
||||
grid.setPage(navigation.getInteger("namespacePage." + (namespaces.size() - 1)));;
|
||||
}
|
||||
final JsonObject settings = parser.parse(itemStr.substring(2)).getAsJsonObject();
|
||||
|
||||
if (settings.get("viewmode") != null) {
|
||||
grid.groups.get(BookmarkGrid.DEFAULT_GROUP_ID).viewMode = BookmarkViewMode
|
||||
@@ -196,17 +199,28 @@ public class BookmarkStorage {
|
||||
}
|
||||
|
||||
if (!addItemToGrid(grid, parser.parse(itemStr).getAsJsonObject())) {
|
||||
wasError = true;
|
||||
NEIClientConfig.logger.warn(
|
||||
"Failed to load bookmarked ItemStack from json string, the item no longer exists:\n{}",
|
||||
itemStr);
|
||||
}
|
||||
|
||||
} catch (IllegalArgumentException | JsonSyntaxException | IllegalStateException e) {
|
||||
} catch (Exception e) {
|
||||
wasError = true;
|
||||
NEIClientConfig.logger.error("Failed to load bookmarked ItemStack from json string:\n{}", itemStr);
|
||||
}
|
||||
}
|
||||
|
||||
prepareOldRecipeFormat(namespaces);
|
||||
if (wasError) {
|
||||
try {
|
||||
Files.copy(
|
||||
bookmarkFile,
|
||||
new File(bookmarkFile.getAbsolutePath() + ".backup-" + System.currentTimeMillis()));
|
||||
NEIClientConfig.logger.info("Backed up invalid bookmark file to {}", bookmarkFile);
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to backup invalid bookmark file to {}", bookmarkFile, e);
|
||||
}
|
||||
}
|
||||
|
||||
for (BookmarkGrid gr : namespaces) {
|
||||
gr.onItemsChanged();
|
||||
@@ -264,48 +278,6 @@ public class BookmarkStorage {
|
||||
return itemStack != null;
|
||||
}
|
||||
|
||||
private void prepareOldRecipeFormat(List<BookmarkGrid> namespaces) {
|
||||
|
||||
for (BookmarkGrid grid : namespaces) {
|
||||
if (grid.bookmarkItems.stream()
|
||||
.noneMatch(item -> item.recipeId != null && item.recipeId.getResult() == null)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final Map<String, RecipeId> recipes = new HashMap<>();
|
||||
|
||||
for (BookmarkItem item : grid.bookmarkItems) {
|
||||
if (item.recipeId != null && item.type != BookmarkItemType.INGREDIENT
|
||||
&& item.recipeId.getResult() == null) {
|
||||
final JsonObject recipeJson = item.recipeId.toJsonObject();
|
||||
final String recipeGUID = item.groupId + ":" + NBTJson.toJson(recipeJson);
|
||||
|
||||
if (!recipes.containsKey(recipeGUID)) {
|
||||
recipeJson.add("result", NBTJson.toJsonObject(StackInfo.itemStackToNBT(item.itemStack)));
|
||||
recipes.put(recipeGUID, item.recipeId = RecipeId.of(recipeJson));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (BookmarkItem item : grid.bookmarkItems) {
|
||||
if (item.recipeId != null && item.recipeId.getResult() == null) {
|
||||
final JsonObject recipeJson = item.recipeId.toJsonObject();
|
||||
final String recipeGUID = item.groupId + ":" + NBTJson.toJson(recipeJson);
|
||||
|
||||
if (recipes.containsKey(recipeGUID)) {
|
||||
item.recipeId = recipes.get(recipeGUID).copy();
|
||||
item.permutations = BookmarkItem.generatePermutations(
|
||||
item.itemStack,
|
||||
item.recipeId,
|
||||
item.type == BookmarkItemType.INGREDIENT);
|
||||
} else {
|
||||
item.recipeId = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void save() {
|
||||
|
||||
if (this.bookmarkFile == null) {
|
||||
|
||||
@@ -93,7 +93,8 @@ public class IMCHandler {
|
||||
final boolean multipleWidgetsAllowed = tag.hasKey("multipleWidgetsAllowed")
|
||||
? tag.getBoolean("multipleWidgetsAllowed")
|
||||
: tag.hasKey("maxRecipesPerPage") && tag.getInteger("maxRecipesPerPage") > 1;
|
||||
info.setHandlerDimensions(handlerWidth, handlerHeight, multipleWidgetsAllowed);
|
||||
info.setHandlerDimensions(handlerWidth, handlerHeight);
|
||||
info.setMultipleWidgetsAllowed(multipleWidgetsAllowed);
|
||||
} catch (NumberFormatException ignored) {
|
||||
NEIClientConfig.logger.info("Error setting handler dimensions for {}", handler);
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import java.util.Map;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.IntFunction;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -164,7 +165,7 @@ public class GuiContainerManager {
|
||||
* @return A list of Strings representing the text to be displayed on each line of the tool tip.
|
||||
*/
|
||||
public static List<String> itemDisplayNameMultiline(ItemStack stack, GuiContainer gui, boolean includeHandlers) {
|
||||
List<String> namelist = null;
|
||||
List<String> namelist;
|
||||
try {
|
||||
namelist = stack.getTooltip(
|
||||
Minecraft.getMinecraft().thePlayer,
|
||||
@@ -199,26 +200,27 @@ public class GuiContainerManager {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String countDetails(int stackSize, int maxStackSize, String fullPattern, String shortPattern) {
|
||||
public static String countDetails(int stackSize, int maxStackSize, String fullPattern, String shortPattern,
|
||||
IntFunction<String> valueFormatter) {
|
||||
if (maxStackSize > 1 && stackSize > maxStackSize) {
|
||||
final int remainder = stackSize % maxStackSize;
|
||||
final int units = stackSize / maxStackSize;
|
||||
|
||||
if (remainder > 0) {
|
||||
return String.format(
|
||||
fullPattern,
|
||||
NEIClientUtils.formatNumbers(stackSize),
|
||||
NEIClientUtils.formatNumbers(stackSize / maxStackSize),
|
||||
NEIClientUtils.formatNumbers(maxStackSize),
|
||||
NEIClientUtils.formatNumbers(remainder));
|
||||
valueFormatter.apply(stackSize),
|
||||
NEIClientUtils.formatNumber(units),
|
||||
valueFormatter.apply(maxStackSize),
|
||||
valueFormatter.apply(remainder));
|
||||
} else {
|
||||
return String.format(
|
||||
shortPattern,
|
||||
NEIClientUtils.formatNumbers(stackSize),
|
||||
NEIClientUtils.formatNumbers(stackSize / maxStackSize),
|
||||
NEIClientUtils.formatNumbers(maxStackSize));
|
||||
valueFormatter.apply(stackSize),
|
||||
NEIClientUtils.formatNumber(units),
|
||||
valueFormatter.apply(maxStackSize));
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -232,7 +234,8 @@ public class GuiContainerManager {
|
||||
stack.stackSize,
|
||||
stack.getMaxStackSize(),
|
||||
translate("inventory.tooltip.count.item", "%s = %s * %s + %s"),
|
||||
translate("inventory.tooltip.count.item", "%s = %s * %s"));
|
||||
translate("inventory.tooltip.count.item", "%s = %s * %s"),
|
||||
NEIClientUtils::formatNumber);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,8 +250,9 @@ public class GuiContainerManager {
|
||||
return countDetails(
|
||||
amount,
|
||||
144,
|
||||
translate("inventory.tooltip.count.fluid", "%s L = %s * %s L + %s L"),
|
||||
translate("inventory.tooltip.count.fluid", "%s L = %s * %s L"));
|
||||
translate("inventory.tooltip.count.fluid", "%s = %s * %s + %s"),
|
||||
translate("inventory.tooltip.count.fluid", "%s = %s * %s"),
|
||||
NEIClientUtils::formatFluid);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,12 +19,12 @@ import java.util.stream.Stream;
|
||||
*
|
||||
* @param <E>
|
||||
*/
|
||||
final class HideousLinkedList<E> extends LinkedList<E> {
|
||||
public final class HideousLinkedList<E> extends LinkedList<E> {
|
||||
|
||||
private static final long serialVersionUID = -8504433551965776915L;
|
||||
private final List<E> backing;
|
||||
|
||||
HideousLinkedList(List<E> backing) {
|
||||
public HideousLinkedList(List<E> backing) {
|
||||
this.backing = backing;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ public class AcceptsFollowingTooltipLineHandler extends ItemsTooltipLineHandler
|
||||
ItemStack activeStack, int maxRows) {
|
||||
|
||||
if (items.size() > 1) {
|
||||
items.sort(Comparator.comparing(FavoriteRecipes::contains).reversed());
|
||||
items.sort(Comparator.comparing(FavoriteRecipes::containsManual).reversed());
|
||||
return new AcceptsFollowingTooltipLineHandler(tooltipGUID, items, activeStack, maxRows);
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public class AcceptsFollowingTooltipLineHandler extends ItemsTooltipLineHandler
|
||||
protected void drawItem(int x, int y, ItemStack drawStack, String stackSize) {
|
||||
super.drawItem(x, y, drawStack, stackSize);
|
||||
|
||||
if (FavoriteRecipes.contains(drawStack)) {
|
||||
if (FavoriteRecipes.containsManual(drawStack)) {
|
||||
NEIClientUtils.drawNEIOverlayText("F", x, y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,662 +0,0 @@
|
||||
package codechicken.nei.recipe;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
import codechicken.nei.Button;
|
||||
import codechicken.nei.ClientHandler;
|
||||
import codechicken.nei.FormattedTextField;
|
||||
import codechicken.nei.LayoutManager;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.TextField;
|
||||
import codechicken.nei.Widget;
|
||||
import codechicken.nei.drawable.DrawableBuilder;
|
||||
import codechicken.nei.drawable.DrawableResource;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.guihook.IContainerInputHandler;
|
||||
import codechicken.nei.recipe.TemplateRecipeHandler.RecipeTransferRect;
|
||||
|
||||
public class DebugHandlerWidget extends Widget implements IContainerInputHandler {
|
||||
|
||||
private static abstract class IntegerField extends TextField {
|
||||
|
||||
protected int defaultValue = 0;
|
||||
|
||||
public IntegerField(String ident, int defaultValue) {
|
||||
super(ident);
|
||||
this.defaultValue = defaultValue;
|
||||
this.h = LINE_HEIGHT;
|
||||
this.z = 2;
|
||||
((FormattedTextField) field).setPlaceholder(Integer.toString(this.defaultValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initInternalTextField() {
|
||||
field = new FormattedTextField(Minecraft.getMinecraft().fontRenderer, 0, 0, 0, 0) {
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
String text = super.getText();
|
||||
return !isFocused() && this.placeholder.equals(text) ? "" : text;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean beforeWrite(String text) {
|
||||
if (text == null || text.isEmpty()) return true;
|
||||
try {
|
||||
return Integer.parseInt(text) >= 0;
|
||||
} catch (NumberFormatException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean textboxKeyTyped(char keyChar, int keyID) {
|
||||
if (!isFocused()) return false;
|
||||
|
||||
if (super.textboxKeyTyped(keyChar, keyID)) {
|
||||
return true;
|
||||
} else if (keyID == Keyboard.KEY_DOWN) {
|
||||
setText(Integer.toString(getInteger() - 1));
|
||||
return true;
|
||||
} else if (keyID == Keyboard.KEY_UP) {
|
||||
setText(Integer.toString(getInteger() + 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
field.setMaxStringLength(maxSearchLength);
|
||||
field.setCursorPositionZero();
|
||||
}
|
||||
|
||||
protected int getInteger() {
|
||||
try {
|
||||
return Integer.parseInt(text());
|
||||
} catch (NumberFormatException nfe) {
|
||||
return this.defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMouseWheel(int i, int mx, int my) {
|
||||
if (!contains(mx, my)) return false;
|
||||
setText(Integer.toString(getInteger() + i));
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final int[] COLORS = new int[] { 0x2200FF00, 0x22FF0000, 0x220000FF, 0x2200FFFF, 0x22FF00FF, 0x22FFFF00 };
|
||||
|
||||
private IRecipeHandler handler;
|
||||
private HandlerInfo handlerInfo;
|
||||
|
||||
private static final int WINDOW_WIDTH = 176;
|
||||
private static final int LINE_HEIGHT = 16;
|
||||
private static final int INLINE_PADDING = 6;
|
||||
private static final int LABEL_WIDTH = 50;
|
||||
|
||||
private IntegerField order;
|
||||
private IntegerField yShift;
|
||||
private IntegerField handlerHeight;
|
||||
private IntegerField handlerWidth;
|
||||
private Button multipleWidgetsAllowed;
|
||||
private Button useCustomScroll;
|
||||
|
||||
private Point dragPoint = null;
|
||||
public boolean showWidget = false;
|
||||
|
||||
private static final int BORDER_PADDING = 6;
|
||||
private final DrawableResource BG_TEXTURE = new DrawableBuilder("nei:textures/gui/recipebg.png", 0, 0, 176, 166)
|
||||
.build();
|
||||
|
||||
public DebugHandlerWidget() {
|
||||
GuiContainerManager.addInputHandler(this);
|
||||
|
||||
this.order = new IntegerField("order", 0) {
|
||||
|
||||
@Override
|
||||
public void onTextChange(String oldText) {
|
||||
|
||||
if (NEIClientConfig.handlerOrdering.get(handler.getOverlayIdentifier()) != null) {
|
||||
if (getInteger() != NEIClientConfig.handlerOrdering.get(handler.getOverlayIdentifier())) {
|
||||
updatePatch(5, getInteger(), this.defaultValue);
|
||||
}
|
||||
} else if (NEIClientConfig.handlerOrdering.get(handler.getHandlerId()) != null) {
|
||||
if (getInteger() != NEIClientConfig.handlerOrdering.get(handler.getHandlerId())) {
|
||||
updatePatch(5, getInteger(), this.defaultValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.yShift = new IntegerField("yShift", 0) {
|
||||
|
||||
@Override
|
||||
public void onTextChange(String oldText) {
|
||||
if (getInteger() != handlerInfo.getYShift()) {
|
||||
handlerInfo.setYShift(getInteger());
|
||||
updatePatch(1, getInteger(), this.defaultValue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.multipleWidgetsAllowed = new Button() {
|
||||
|
||||
{
|
||||
this.h = LINE_HEIGHT;
|
||||
this.z = 2;
|
||||
}
|
||||
|
||||
public String getRenderLabel() {
|
||||
return handlerInfo.isMultipleWidgetsAllowed() ? "On" : "Off";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onButtonPress(boolean rightclick) {
|
||||
handlerInfo.setHandlerDimensions(
|
||||
handlerInfo.getWidth(),
|
||||
handlerInfo.getHeight(),
|
||||
!handlerInfo.isMultipleWidgetsAllowed());
|
||||
updatePatch(4, handlerInfo.isMultipleWidgetsAllowed() ? 1 : 0, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.handlerHeight = new IntegerField("handlerHeight", HandlerInfo.DEFAULT_HEIGHT) {
|
||||
|
||||
@Override
|
||||
public void draw(int mx, int my) {
|
||||
this.field.setEnabled(handler.getRecipeHeight(0) <= 0);
|
||||
super.draw(mx, my);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChange(String oldText) {
|
||||
if (getInteger() != handlerInfo.getHeight()) {
|
||||
handlerInfo.setHandlerDimensions(
|
||||
handlerInfo.getWidth(),
|
||||
getInteger(),
|
||||
handlerInfo.isMultipleWidgetsAllowed());
|
||||
updatePatch(2, getInteger(), this.defaultValue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.handlerWidth = new IntegerField("handlerWidth", HandlerInfo.DEFAULT_WIDTH) {
|
||||
|
||||
@Override
|
||||
public void onTextChange(String oldText) {
|
||||
if (getInteger() != handlerInfo.getWidth()) {
|
||||
handlerInfo.setHandlerDimensions(
|
||||
getInteger(),
|
||||
handlerInfo.getHeight(),
|
||||
handlerInfo.isMultipleWidgetsAllowed());
|
||||
updatePatch(3, getInteger(), this.defaultValue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.useCustomScroll = new Button() {
|
||||
|
||||
{
|
||||
this.h = LINE_HEIGHT;
|
||||
this.z = 2;
|
||||
}
|
||||
|
||||
public String getRenderLabel() {
|
||||
return handlerInfo.getUseCustomScroll() ? "On" : "Off";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onButtonPress(boolean rightclick) {
|
||||
handlerInfo.setUseCustomScroll(!handlerInfo.getUseCustomScroll());
|
||||
updatePatch(6, handlerInfo.getUseCustomScroll() ? 1 : 0, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
this.w = WINDOW_WIDTH;
|
||||
this.h = 10 + 13 * LINE_HEIGHT;
|
||||
this.x = 10;
|
||||
this.y = 50;
|
||||
this.z = 1;
|
||||
}
|
||||
|
||||
private void updatePatch(int key, int value, int defaultValue) {
|
||||
final String handlerKey = getHandlerID(handler);
|
||||
|
||||
if (!patches.containsKey(handlerKey)) {
|
||||
patches.put(handlerKey, new String[] { handlerKey, null, null, null, null, null, null });
|
||||
}
|
||||
|
||||
if (value == defaultValue) {
|
||||
patches.get(handlerKey)[key] = null;
|
||||
} else {
|
||||
patches.get(handlerKey)[key] = String.valueOf(value);
|
||||
}
|
||||
|
||||
saveHandlerInfoPatch();
|
||||
|
||||
if (NEIClientUtils.getGuiContainer() instanceof GuiRecipe<?>recipe) {
|
||||
recipe.forceRefreshPage();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void drawKeyLabel(String keyLabel, int topShift) {
|
||||
GuiDraw.drawString(
|
||||
NEIClientUtils.cropText(GuiDraw.fontRenderer, keyLabel, LABEL_WIDTH),
|
||||
this.x + INLINE_PADDING,
|
||||
topShift,
|
||||
0x66555555,
|
||||
false);
|
||||
GuiDraw.drawString(":", this.x + INLINE_PADDING + LABEL_WIDTH, topShift, 0x66555555, false);
|
||||
}
|
||||
|
||||
private void drawDetail(String keyLabel, String valueLabel, int topShift, int spaceWidth) {
|
||||
drawKeyLabel(keyLabel, topShift);
|
||||
GuiDraw.drawString(
|
||||
NEIClientUtils.cropText(
|
||||
GuiDraw.fontRenderer,
|
||||
valueLabel,
|
||||
this.w - INLINE_PADDING * 2 - LABEL_WIDTH - spaceWidth),
|
||||
this.x + INLINE_PADDING + LABEL_WIDTH + spaceWidth,
|
||||
topShift,
|
||||
0xffffff);
|
||||
}
|
||||
|
||||
private void drawControl(String keyLabel, Widget field, int topShift, int spaceWidth) {
|
||||
drawKeyLabel(keyLabel, topShift);
|
||||
|
||||
field.x = this.x + INLINE_PADDING + LABEL_WIDTH + spaceWidth;
|
||||
field.y = topShift - 4;
|
||||
field.w = this.w - INLINE_PADDING * 2 - LABEL_WIDTH - spaceWidth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int mx, int my) {
|
||||
|
||||
if (this.handler != null) {
|
||||
final int spaceWidth = GuiDraw.fontRenderer.getStringWidth(": ");
|
||||
int topShift = this.y + BORDER_PADDING + 12 + 6;
|
||||
|
||||
GL11.glColor4f(1F, 1F, 1F, 1F);
|
||||
GL11.glScaled(1, 1, 2f);
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST);
|
||||
BG_TEXTURE.draw(
|
||||
this.x,
|
||||
this.y,
|
||||
this.w,
|
||||
this.h,
|
||||
BORDER_PADDING,
|
||||
BORDER_PADDING,
|
||||
BORDER_PADDING,
|
||||
BORDER_PADDING);
|
||||
GuiDraw.drawRect(
|
||||
this.x + INLINE_PADDING,
|
||||
this.y + BORDER_PADDING,
|
||||
this.w - INLINE_PADDING * 2,
|
||||
12,
|
||||
0x30000000);
|
||||
GuiDraw.drawStringC("Debug Recipe Handler", this.x + this.w / 2, this.y + BORDER_PADDING + 2, 0xffffff);
|
||||
|
||||
for (Map.Entry<String, String> entry : getDetailsInfo().entrySet()) {
|
||||
drawDetail(entry.getKey(), entry.getValue(), topShift, spaceWidth);
|
||||
topShift += LINE_HEIGHT;
|
||||
}
|
||||
|
||||
drawControl("Order", this.order, topShift, spaceWidth);
|
||||
topShift += LINE_HEIGHT;
|
||||
|
||||
drawControl("yShift", this.yShift, topShift, spaceWidth);
|
||||
topShift += LINE_HEIGHT;
|
||||
|
||||
drawControl("Multi Widgets", this.multipleWidgetsAllowed, topShift, spaceWidth);
|
||||
topShift += LINE_HEIGHT;
|
||||
|
||||
drawControl("Height", this.handlerHeight, topShift, spaceWidth);
|
||||
topShift += LINE_HEIGHT;
|
||||
|
||||
drawControl("Width", this.handlerWidth, topShift, spaceWidth);
|
||||
topShift += LINE_HEIGHT;
|
||||
|
||||
drawControl("Use Custom Scroll", this.useCustomScroll, topShift, spaceWidth);
|
||||
topShift += LINE_HEIGHT;
|
||||
|
||||
GL11.glScaled(1, 1, 1 / 2f);
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, String> getDetailsInfo() {
|
||||
final Map<String, String> lines = new LinkedHashMap<>();
|
||||
final boolean isHeightHackApplied = NEIClientConfig.heightHackHandlerRegex.stream()
|
||||
.map(pattern -> pattern.matcher(this.handler.getHandlerId())).anyMatch(Matcher::matches);
|
||||
|
||||
lines.put("Name", this.handler.getRecipeName());
|
||||
lines.put("ID", this.handler.getOverlayIdentifier());
|
||||
lines.put("Key", this.handler.getHandlerId());
|
||||
lines.put("H.Hack", String.valueOf(isHeightHackApplied));
|
||||
lines.put("Mod Name", this.handlerInfo.getModName());
|
||||
lines.put("Mod ID", this.handlerInfo.getModId());
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
public void setVisible() {
|
||||
if (showWidget && this.handler != null) {
|
||||
LayoutManager.addWidget(this.order);
|
||||
LayoutManager.addWidget(this.yShift);
|
||||
LayoutManager.addWidget(this.handlerHeight);
|
||||
LayoutManager.addWidget(this.handlerWidth);
|
||||
LayoutManager.addWidget(this.multipleWidgetsAllowed);
|
||||
LayoutManager.addWidget(this.useCustomScroll);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
final GuiContainer gui = NEIClientUtils.getGuiContainer();
|
||||
|
||||
if (showWidget && gui instanceof GuiRecipe recipe) {
|
||||
|
||||
if (this.handler != recipe.getHandler()) {
|
||||
this.handler = recipe.getHandler();
|
||||
this.handlerInfo = GuiRecipeTab.getHandlerInfo(handler);
|
||||
|
||||
this.order.setText(String.valueOf(NEIClientConfig.getHandlerOrder(this.handler)));
|
||||
this.yShift.setText(String.valueOf(this.handlerInfo.getYShift()));
|
||||
this.handlerHeight.setText(String.valueOf(this.handlerInfo.getHeight()));
|
||||
this.handlerWidth.setText(String.valueOf(this.handlerInfo.getWidth()));
|
||||
}
|
||||
|
||||
} else {
|
||||
this.handler = null;
|
||||
this.handlerInfo = null;
|
||||
showWidget = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> handleTooltip(int mx, int my, List<String> tooltip) {
|
||||
|
||||
if (this.handler != null) {
|
||||
final int spaceWidth = GuiDraw.fontRenderer.getStringWidth(": ");
|
||||
final int leftShift = this.x + INLINE_PADDING;
|
||||
|
||||
if (mx >= leftShift && mx < this.x + WINDOW_WIDTH - INLINE_PADDING) {
|
||||
int topShift = this.y + BORDER_PADDING + 12 + 6;
|
||||
|
||||
for (Map.Entry<String, String> entry : getDetailsInfo().entrySet()) {
|
||||
if (my >= topShift && my < topShift + LINE_HEIGHT) {
|
||||
|
||||
if (mx < leftShift + LABEL_WIDTH + spaceWidth) {
|
||||
tooltip.add(String.valueOf(entry.getKey()));
|
||||
} else {
|
||||
tooltip.add(String.valueOf(entry.getValue()));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
topShift += LINE_HEIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyTyped(GuiContainer gui, char keyChar, int keyCode) {
|
||||
|
||||
if (NEIClientConfig.getBooleanSetting("inventory.guirecipe.handlerInfo") && showWidget
|
||||
&& keyCode == Keyboard.KEY_C
|
||||
&& NEIClientUtils.controlKey()) {
|
||||
final int spaceWidth = GuiDraw.fontRenderer.getStringWidth(": ");
|
||||
final Point mouse = GuiDraw.getMousePosition();
|
||||
|
||||
if (mouse.x >= this.x + INLINE_PADDING + LABEL_WIDTH + spaceWidth
|
||||
&& mouse.x < this.x + WINDOW_WIDTH - INLINE_PADDING) {
|
||||
int topShift = this.y + BORDER_PADDING + 12 + 6;
|
||||
|
||||
for (Map.Entry<String, String> entry : getDetailsInfo().entrySet()) {
|
||||
if (mouse.y >= topShift && mouse.y < topShift + LINE_HEIGHT) {
|
||||
GuiScreen.setClipboardString(entry.getValue());
|
||||
return true;
|
||||
}
|
||||
topShift += LINE_HEIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(GuiContainer gui, int mousex, int mousey, int button) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyTyped(GuiContainer gui, char keyChar, int keyID) {}
|
||||
|
||||
@Override
|
||||
public boolean lastKeyTyped(GuiContainer gui, char keyChar, int keyID) {
|
||||
|
||||
if (NEIClientConfig.getBooleanSetting("inventory.guirecipe.handlerInfo") && keyID == Keyboard.KEY_D
|
||||
&& NEIClientUtils.shiftKey()) {
|
||||
showWidget = !showWidget;
|
||||
return true;
|
||||
} else if (this.handler != null) {
|
||||
return this.order.focused() || this.yShift.focused()
|
||||
|| this.handlerHeight.focused()
|
||||
|| this.handlerWidth.focused();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMouseClicked(GuiContainer gui, int mousex, int mousey, int button) {
|
||||
if (this.handler != null
|
||||
&& new Rectangle4i(this.x + INLINE_PADDING, this.y + BORDER_PADDING, this.w - INLINE_PADDING * 2, 12)
|
||||
.contains(mousex, mousey)) {
|
||||
this.dragPoint = new Point(mousex, mousey);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(int px, int py) {
|
||||
return this.handler != null && super.contains(px, py);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMouseUp(GuiContainer gui, int mousex, int mousey, int button) {
|
||||
this.dragPoint = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled) {}
|
||||
|
||||
@Override
|
||||
public boolean handleClickExt(int mx, int my, int button) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMouseDragged(GuiContainer gui, int mousex, int mousey, int button, long heldTime) {
|
||||
if (this.dragPoint != null) {
|
||||
this.x -= this.dragPoint.x - mousex;
|
||||
this.y -= this.dragPoint.y - mousey;
|
||||
this.dragPoint.move(mousex, mousey);
|
||||
}
|
||||
}
|
||||
|
||||
public void drawGuiPlaceholder(NEIRecipeWidget widget) {
|
||||
if (!showWidget) return;
|
||||
|
||||
NEIClientUtils.gl2DRenderContext(() -> {
|
||||
|
||||
// background
|
||||
GuiDraw.drawRect(
|
||||
widget.x,
|
||||
widget.y,
|
||||
widget.w,
|
||||
widget.h,
|
||||
COLORS[widget.handlerRef.recipeIndex % COLORS.length]);
|
||||
|
||||
// center cross
|
||||
GuiDraw.drawRect(widget.x + widget.w / 2 - 1, widget.y, 1, widget.h, 0x88ffffff);
|
||||
GuiDraw.drawRect(widget.x, widget.y + widget.h / 2 - 1, widget.w, 1, 0x88ffffff);
|
||||
|
||||
// blue-line-top (grid-top)
|
||||
GuiDraw.drawRect(widget.x + 14, widget.y + 5, widget.w - 38, 1, 0xff0000aa);
|
||||
|
||||
// blue-line-bottom {grid-bottom}
|
||||
GuiDraw.drawRect(widget.x + 14, widget.y + widget.h - 7, widget.w - 38, 1, 0xff0000aa);
|
||||
|
||||
// blue-left (grid start)
|
||||
GuiDraw.drawRect(widget.x + 24, widget.y + (widget.h - 16) / 2, 1, 16, 0xffaa00aa);
|
||||
|
||||
// purple (before favorite)
|
||||
GuiDraw.drawRect(
|
||||
widget.x + Math.min(168, widget.w) - 27,
|
||||
widget.y + widget.h - 6 - GuiRecipeButton.BUTTON_HEIGHT * 2 - 4,
|
||||
GuiRecipeButton.BUTTON_WIDTH,
|
||||
1,
|
||||
0xffaa00aa);
|
||||
|
||||
// green ()
|
||||
GuiDraw.drawRect(
|
||||
widget.x + Math.min(168, widget.w) - 35,
|
||||
widget.y + widget.h - 6 - GuiRecipeButton.BUTTON_HEIGHT - 3,
|
||||
20,
|
||||
1,
|
||||
0xff00aa00);
|
||||
|
||||
// purple space before bottom grid
|
||||
GuiDraw.drawRect(
|
||||
widget.x + 14,
|
||||
widget.y + widget.h - 7 - GuiRecipeButton.BUTTON_WIDTH / 2,
|
||||
38,
|
||||
1,
|
||||
0xffaa00aa);
|
||||
|
||||
if (widget.handlerRef.handler instanceof TemplateRecipeHandler handler) {
|
||||
int yShift = widget.getHandlerInfo().getYShift();
|
||||
|
||||
for (RecipeTransferRect rect : handler.transferRects) {
|
||||
GuiDraw.drawRect(
|
||||
widget.x + rect.rect.x,
|
||||
widget.y + yShift + rect.rect.y,
|
||||
rect.rect.width,
|
||||
rect.rect.height,
|
||||
0x40ff0000);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private static Map<String, String[]> patches = new HashMap<>();
|
||||
|
||||
public static void loadHandlerInfoPatch() {
|
||||
|
||||
ClientHandler.loadSettingsFile("handlers.patch", lines -> {
|
||||
|
||||
for (String line : lines.collect(Collectors.toCollection(HashSet::new))) {
|
||||
final String[] parts = line.split(",");
|
||||
final String handler = parts[0];
|
||||
|
||||
if (GuiRecipeTab.handlerMap.containsKey(handler)) {
|
||||
final HandlerInfo info = GuiRecipeTab.handlerMap.get(handler);
|
||||
final int yShift = intOrDefault(parts[1], info.getYShift());
|
||||
final int height = intOrDefault(parts[2], info.getHeight());
|
||||
final int width = intOrDefault(parts[3], info.getWidth());
|
||||
final boolean isMultipleWidgetsAllowed = intOrDefault(
|
||||
parts[4],
|
||||
info.isMultipleWidgetsAllowed() ? 1 : 0) == 1;
|
||||
final int order = intOrDefault(parts[5], NEIClientConfig.handlerOrdering.getOrDefault(handler, 0));
|
||||
final boolean useCustomScroll = intOrDefault(parts[6], info.getUseCustomScroll() ? 1 : 0) == 1;
|
||||
|
||||
info.setYShift(yShift);
|
||||
info.setHandlerDimensions(width, height, isMultipleWidgetsAllowed);
|
||||
info.setUseCustomScroll(useCustomScroll);
|
||||
NEIClientConfig.handlerOrdering.put(handler, order);
|
||||
}
|
||||
|
||||
patches.put(handler, parts);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private static void saveHandlerInfoPatch() {
|
||||
final List<String> lines = new ArrayList<>();
|
||||
|
||||
for (String[] line : patches.values()) {
|
||||
lines.add(String.join(",", line));
|
||||
}
|
||||
|
||||
final File path = new File(NEIClientConfig.configDir, "handlers.patch");
|
||||
|
||||
try (FileOutputStream output = new FileOutputStream(path)) {
|
||||
IOUtils.writeLines(lines, "\n", output, StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
|
||||
private static int intOrDefault(String str, int defaultValue) {
|
||||
if (str == null || str.equals("")) return defaultValue;
|
||||
try {
|
||||
return Integer.parseInt(str);
|
||||
} catch (NumberFormatException e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getHandlerID(IRecipeHandler handler) {
|
||||
|
||||
if (GuiRecipeTab.handlerMap.containsKey(handler.getHandlerId())) {
|
||||
return handler.getHandlerId();
|
||||
} else if (handler instanceof TemplateRecipeHandler) {
|
||||
return handler.getOverlayIdentifier();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -98,10 +98,14 @@ public class DefaultOverlayHandler implements IOverlayHandler {
|
||||
&& presenceOverlay(firstGui, handler, recipeIndex).stream().allMatch(state -> state.isPresent());
|
||||
}
|
||||
|
||||
protected Slot getCraftingResultSlot(GuiContainer gui) {
|
||||
return gui.inventorySlots.inventorySlots.stream().filter(slot -> slot instanceof SlotCrafting).findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean craft(GuiContainer firstGui, IRecipeHandler handler, int recipeIndex, int multiplier) {
|
||||
final Slot craftingSlot = firstGui.inventorySlots.inventorySlots.stream()
|
||||
.filter(slot -> slot instanceof SlotCrafting).findFirst().orElse(null);
|
||||
final Slot craftingSlot = getCraftingResultSlot(firstGui);
|
||||
|
||||
if (craftingSlot == null) {
|
||||
return false;
|
||||
@@ -145,7 +149,7 @@ public class DefaultOverlayHandler implements IOverlayHandler {
|
||||
|
||||
/**
|
||||
* Gets the slots in the crafting matrix for the given GUI and recipe handler.
|
||||
*
|
||||
*
|
||||
* @param gui
|
||||
* @param handler
|
||||
* @return
|
||||
@@ -194,9 +198,10 @@ public class DefaultOverlayHandler implements IOverlayHandler {
|
||||
}
|
||||
|
||||
private void moveIngredients(GuiContainer gui, List<IngredientDistribution> assignedIngredients, int multiplier) {
|
||||
final Slot craftingSlot = getCraftingResultSlot(gui);
|
||||
|
||||
for (Slot slot : gui.inventorySlots.inventorySlots) {
|
||||
if (slot instanceof SlotCrafting || !slot.getHasStack()
|
||||
if (slot == craftingSlot || !slot.getHasStack()
|
||||
|| !canMoveFrom(slot, gui)
|
||||
|| !slot.canTakeStack(gui.mc.thePlayer))
|
||||
continue;
|
||||
@@ -422,8 +427,8 @@ public class DefaultOverlayHandler implements IOverlayHandler {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected boolean canStack(ItemStack stack1, ItemStack stack2) {
|
||||
if (stack1 == null || stack2 == null) return true;
|
||||
return NEIClientUtils.areStacksSameTypeCraftingWithNBT(stack1, stack2);
|
||||
protected boolean canStack(ItemStack dst, ItemStack src) {
|
||||
if (dst == null || src == null) return true;
|
||||
return NEIClientUtils.areStacksSameTypeCraftingWithNBT(dst, src);
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.bookmark.BookmarkItem.BookmarkItemType;
|
||||
import codechicken.nei.bookmark.BookmarksGridSlot;
|
||||
import codechicken.nei.recipe.Recipe.RecipeId;
|
||||
import codechicken.nei.recipe.TemplateRecipeHandler.RecipeTransferRect;
|
||||
|
||||
public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
|
||||
|
||||
@@ -77,7 +78,9 @@ public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
|
||||
ArrayList<ICraftingHandler> serialCraftingHandlers = GuiCraftingRecipe.serialCraftingHandlers;
|
||||
UnaryOperator<ICraftingHandler> recipeHandlerFunction;
|
||||
|
||||
if ("recipeId".equals(outputId)) {
|
||||
if ("all".equals(outputId)) {
|
||||
recipeHandlerFunction = GuiCraftingRecipe::buildAllRecipesHandler;
|
||||
} else if ("recipeId".equals(outputId)) {
|
||||
ItemStack stack = (ItemStack) results[0];
|
||||
RecipeId recipeId = (RecipeId) results[1];
|
||||
craftinghandlers = filterByHandlerName(craftinghandlers, recipeId.getHandleName());
|
||||
@@ -98,6 +101,24 @@ public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
|
||||
return recipeQuery.runWithProfiling(NEIClientUtils.translate("recipe.concurrent.crafting"));
|
||||
}
|
||||
|
||||
private static ICraftingHandler buildAllRecipesHandler(ICraftingHandler handler) {
|
||||
if (handler instanceof TemplateRecipeHandler templateHandler) {
|
||||
TemplateRecipeHandler allHandler = templateHandler.newInstance();
|
||||
if (allHandler.transferRects.isEmpty()) {
|
||||
allHandler.loadCraftingRecipes("all");
|
||||
return allHandler;
|
||||
}
|
||||
for (RecipeTransferRect rect : allHandler.transferRects) {
|
||||
if (allHandler.specifyTransferRect() == null
|
||||
|| allHandler.specifyTransferRect().equals(rect.outputId)) {
|
||||
allHandler.loadCraftingRecipes(rect.outputId, rect.results);
|
||||
return allHandler;
|
||||
}
|
||||
}
|
||||
}
|
||||
return handler.getRecipeHandler("all");
|
||||
}
|
||||
|
||||
private static ArrayList<ICraftingHandler> filterByHandlerName(ArrayList<ICraftingHandler> craftinghandlers,
|
||||
String handlerName) {
|
||||
return craftinghandlers.stream().filter(h -> getHandlerName(h).equals(handlerName))
|
||||
|
||||
@@ -54,7 +54,7 @@ public class GuiFavoriteButton extends GuiRecipeButton {
|
||||
super(handlerRef, x, y, BUTTON_ID_START + handlerRef.recipeIndex, "❤");
|
||||
this.recipe = Recipe.of(this.handlerRef);
|
||||
|
||||
ItemStack stack = FavoriteRecipes.getFavorite(this.recipe.getRecipeId());
|
||||
ItemStack stack = FavoriteRecipes.getManualFavorite(this.recipe.getRecipeId());
|
||||
this.favorite = stack != null;
|
||||
|
||||
if (stack == null) {
|
||||
@@ -88,7 +88,7 @@ public class GuiFavoriteButton extends GuiRecipeButton {
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
this.favorite = this.favorite && FavoriteRecipes.getFavorite(this.recipe.getRecipeId()) != null;
|
||||
this.favorite = this.favorite && FavoriteRecipes.getManualFavorite(this.recipe.getRecipeId()) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -146,7 +146,6 @@ public class GuiFavoriteButton extends GuiRecipeButton {
|
||||
@Override
|
||||
public List<String> handleTooltip(List<String> currenttip) {
|
||||
currenttip.add(translate("recipe.favorite"));
|
||||
|
||||
return currenttip;
|
||||
}
|
||||
|
||||
@@ -178,7 +177,7 @@ public class GuiFavoriteButton extends GuiRecipeButton {
|
||||
this.selectedResult = results.get(nextIndex);
|
||||
this.favorite = StackInfo.equalItemAndNBT(
|
||||
results.get(nextIndex).getItemStack(),
|
||||
FavoriteRecipes.getFavorite(this.recipe.getRecipeId()),
|
||||
FavoriteRecipes.getManualFavorite(this.recipe.getRecipeId()),
|
||||
true);
|
||||
|
||||
return true;
|
||||
@@ -206,29 +205,47 @@ public class GuiFavoriteButton extends GuiRecipeButton {
|
||||
|
||||
if (stack == null) {
|
||||
stack = ingr.getItemStack();
|
||||
RecipeId recipeId = FavoriteRecipes.getFavorite(stack);
|
||||
RecipeId recipeId = FavoriteRecipes.getManualFavorite(stack);
|
||||
|
||||
if (recipeId == null) {
|
||||
for (ItemStack permStack : permutations) {
|
||||
if ((recipeId = FavoriteRecipes.getFavorite(permStack)) != null) {
|
||||
if ((recipeId = FavoriteRecipes.getManualFavorite(permStack)) != null) {
|
||||
stack = permStack;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Recipe recipe = Recipe.of(recipeId);
|
||||
if (recipeId == null) {
|
||||
recipeId = FavoriteRecipes.getGeneratedFavorite(stack);
|
||||
}
|
||||
|
||||
if (recipe == null) {
|
||||
stack = null;
|
||||
} else {
|
||||
items.add(stack);
|
||||
|
||||
if (depth >= 0) {
|
||||
result.add(recipe);
|
||||
localLoop.add(recipe);
|
||||
if (recipeId == null) {
|
||||
for (ItemStack permStack : permutations) {
|
||||
if ((recipeId = FavoriteRecipes.getGeneratedFavorite(permStack)) != null) {
|
||||
stack = permStack;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (recipeId != null && FavoriteRecipes.FAVORITE_ITEM.contains(recipeId.getHandleName())) {
|
||||
items.add(stack);
|
||||
} else {
|
||||
Recipe recipe = Recipe.of(recipeId);
|
||||
|
||||
if (recipe == null) {
|
||||
stack = null;
|
||||
} else {
|
||||
items.add(stack);
|
||||
|
||||
if (depth >= 0) {
|
||||
result.add(recipe);
|
||||
localLoop.add(recipe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (stack != null) {
|
||||
|
||||
@@ -3,7 +3,6 @@ package codechicken.nei.recipe;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
@@ -97,9 +96,11 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
super(handlerRef, x, y, handlerRef.recipeIndex + BUTTON_ID_SHIFT, "+");
|
||||
this.firstGui = firstGui != null && firstGui.inventorySlots != null ? firstGui : null;
|
||||
|
||||
this.canUseOverlayRenderer = this.firstGui != null && handlerRef.getRecipeOverlayRenderer(firstGui) != null;
|
||||
this.canFillCraftingGrid = this.firstGui != null && handlerRef.getOverlayHandler(firstGui) != null;
|
||||
this.hasOverlay = this.canUseOverlayRenderer || this.canFillCraftingGrid;
|
||||
if (this.firstGui != null) {
|
||||
this.canUseOverlayRenderer = this.handlerRef.getRecipeOverlayRenderer(this.firstGui) != null;
|
||||
this.canFillCraftingGrid = this.handlerRef.canFillCraftingGrid(this.firstGui);
|
||||
this.hasOverlay = this.canUseOverlayRenderer || this.handlerRef.getOverlayHandler(this.firstGui) != null;
|
||||
}
|
||||
|
||||
setRequireShiftForOverlayRecipe(NEIClientConfig.requireShiftForOverlayRecipe());
|
||||
ingredientsOverlay();
|
||||
@@ -107,16 +108,20 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
|
||||
@Override
|
||||
public List<String> handleTooltip(List<String> currenttip) {
|
||||
currenttip.add(NEIClientUtils.translate("recipe.overlay"));
|
||||
|
||||
if (!this.enabled && requireShiftForOverlayRecipe() && canFillCraftingGrid()) {
|
||||
currenttip.set(currenttip.size() - 1, currenttip.get(currenttip.size() - 1) + GuiDraw.TOOLTIP_LINESPACE);
|
||||
currenttip.add(
|
||||
EnumChatFormatting.RED + NEIClientUtils.translate("recipe.overlay.mismatch")
|
||||
+ EnumChatFormatting.RESET);
|
||||
} else if (this.missedMaterialsTooltipLineHandler != null) {
|
||||
if (!this.enabled || this.missedMaterialsTooltipLineHandler != null && this.canFillCraftingGrid) {
|
||||
currenttip.add(NEIClientUtils.translate("recipe.overlay") + GuiDraw.TOOLTIP_LINESPACE);
|
||||
} else {
|
||||
currenttip.add(NEIClientUtils.translate("recipe.overlay"));
|
||||
}
|
||||
|
||||
if ((!requireShiftForOverlayRecipe() || NEIClientUtils.shiftKey()) && canFillCraftingGrid()) {
|
||||
if (!this.enabled) {
|
||||
currenttip.add(EnumChatFormatting.RED + NEIClientUtils.translate("recipe.overlay.mismatch"));
|
||||
}
|
||||
|
||||
if (this.missedMaterialsTooltipLineHandler != null && this.canFillCraftingGrid) {
|
||||
|
||||
if (!requireShiftForOverlayRecipe() || NEIClientUtils.shiftKey()) {
|
||||
this.missedMaterialsTooltipLineHandler.setLabelColor(EnumChatFormatting.RED);
|
||||
} else {
|
||||
this.missedMaterialsTooltipLineHandler.setLabelColor(EnumChatFormatting.GRAY);
|
||||
@@ -174,7 +179,7 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
protected void drawContent(Minecraft minecraft, int y, int x, boolean mouseOver) {
|
||||
DrawableResource icon = ICON_OVERLAY;
|
||||
|
||||
if (hasOverlay() && (!requireShiftForOverlayRecipe() || NEIClientUtils.shiftKey())) {
|
||||
if (this.canFillCraftingGrid && (!requireShiftForOverlayRecipe() || NEIClientUtils.shiftKey())) {
|
||||
icon = this.missedMaterialsTooltipLineHandler == null ? ICON_FILL : ICON_FILL_ERROR;
|
||||
}
|
||||
|
||||
@@ -212,10 +217,12 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
if (this.itemPresenceCache.size() != ingredients.size()) {
|
||||
this.itemPresenceCache.clear();
|
||||
|
||||
if (canFillCraftingGrid()) {
|
||||
if (this.firstGui != null) {
|
||||
this.itemPresenceCache.addAll(this.handlerRef.getPresenceOverlay(this.firstGui));
|
||||
} else if (this.firstGui != null) {
|
||||
this.itemPresenceCache.addAll(presenceOverlay(ingredients));
|
||||
|
||||
if (this.itemPresenceCache.isEmpty()) {
|
||||
this.itemPresenceCache.addAll(presenceOverlay(ingredients));
|
||||
}
|
||||
}
|
||||
|
||||
final List<ItemStack> items = this.itemPresenceCache.stream().filter(state -> !state.isPresent())
|
||||
@@ -230,6 +237,8 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
} else {
|
||||
this.missedMaterialsTooltipLineHandler = null;
|
||||
}
|
||||
|
||||
updateEnabled();
|
||||
}
|
||||
|
||||
return this.itemPresenceCache;
|
||||
@@ -237,7 +246,12 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
|
||||
public void setRequireShiftForOverlayRecipe(boolean require) {
|
||||
this.requireShiftForOverlayRecipe = require;
|
||||
this.enabled = hasOverlay() && (this.requireShiftForOverlayRecipe || canFillCraftingGrid());
|
||||
updateEnabled();
|
||||
}
|
||||
|
||||
private void updateEnabled() {
|
||||
this.enabled = hasOverlay() || this.canFillCraftingGrid
|
||||
&& (this.requireShiftForOverlayRecipe || this.missedMaterialsTooltipLineHandler == null);
|
||||
}
|
||||
|
||||
public void setCanUseOverlayRenderer(boolean use) {
|
||||
@@ -253,7 +267,7 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
}
|
||||
|
||||
public boolean canFillCraftingGrid() {
|
||||
return this.missedMaterialsTooltipLineHandler == null || this.handlerRef.canFillCraftingGrid(this.firstGui);
|
||||
return this.canFillCraftingGrid && this.missedMaterialsTooltipLineHandler == null;
|
||||
}
|
||||
|
||||
public boolean hasOverlay() {
|
||||
@@ -265,7 +279,7 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
}
|
||||
|
||||
protected List<ItemOverlayState> presenceOverlay(List<PositionedStack> ingredients) {
|
||||
final List<ItemOverlayState> itemPresenceSlots = new ArrayList<>();
|
||||
final List<ItemOverlayState> states = new ArrayList<>();
|
||||
final List<ItemStack> invStacks = this.firstGui.inventorySlots.inventorySlots.stream()
|
||||
.filter(
|
||||
s -> s != null && s.getStack() != null
|
||||
@@ -275,28 +289,29 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
.map(s -> s.getStack().copy()).collect(Collectors.toCollection(ArrayList::new));
|
||||
|
||||
for (PositionedStack stack : ingredients) {
|
||||
Optional<ItemStack> used = invStacks.stream().filter(is -> is.stackSize > 0 && stack.contains(is))
|
||||
.findAny();
|
||||
boolean found = false;
|
||||
|
||||
itemPresenceSlots.add(new ItemOverlayState(stack, used.isPresent()));
|
||||
|
||||
if (used.isPresent()) {
|
||||
ItemStack is = used.get();
|
||||
is.stackSize -= 1;
|
||||
for (ItemStack is : invStacks) {
|
||||
if (is.stackSize > 0 && stack.contains(is)) {
|
||||
is.stackSize--;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
states.add(new ItemOverlayState(stack, found));
|
||||
}
|
||||
|
||||
return itemPresenceSlots;
|
||||
return states;
|
||||
}
|
||||
|
||||
public void overlayRecipe(boolean shift) {
|
||||
if (!hasOverlay()) return;
|
||||
|
||||
if (!requireShiftForOverlayRecipe() || shift) {
|
||||
if (canFillCraftingGrid()) {
|
||||
if (this.canFillCraftingGrid) {
|
||||
this.handlerRef.fillCraftingGrid(this.firstGui, 0);
|
||||
}
|
||||
} else if (useOverlayRenderer()) {
|
||||
} else if (hasOverlay() && useOverlayRenderer()) {
|
||||
this.handlerRef.useOverlayRenderer(this.firstGui);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
@@ -58,8 +59,13 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
IGuiClientSide, IGuiHandleMouseWheel, IContainerTooltipHandler, INEIGuiHandler {
|
||||
|
||||
private static final int BORDER_PADDING = 5;
|
||||
private final DrawableResource BG_TEXTURE = new DrawableBuilder("nei:textures/gui/recipebg.png", 0, 0, 176, 166)
|
||||
.build();
|
||||
private static final int TRANSPARENCY_BORDER = 4;
|
||||
private final DrawableResource BG_TEXTURE = new DrawableBuilder(
|
||||
"nei:textures/gui/recipebg.png",
|
||||
0,
|
||||
0,
|
||||
176 + TRANSPARENCY_BORDER * 2,
|
||||
166 + TRANSPARENCY_BORDER * 2).build();
|
||||
|
||||
private static final int BUTTON_WIDTH = 13;
|
||||
private static final int BUTTON_HEIGHT = 12;
|
||||
@@ -598,6 +604,15 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
return;
|
||||
}
|
||||
|
||||
if (button == 0 && isHandlerTitleHovered(mousex, mousey)) {
|
||||
if (this instanceof GuiCraftingRecipe) {
|
||||
GuiCraftingRecipe.openRecipeGui("all");
|
||||
} else if (this instanceof GuiUsageRecipe) {
|
||||
GuiUsageRecipe.openRecipeGui("all");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
super.mouseClicked(mousex, mousey, button);
|
||||
}
|
||||
|
||||
@@ -703,6 +718,10 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
|
||||
this.recipeTabs.handleTooltip(mousex, mousey, currenttip);
|
||||
|
||||
if (currenttip.isEmpty() && isHandlerTitleHovered(mousex, mousey)) {
|
||||
currenttip.add(NEIClientUtils.translate("recipe.tab.view_all.tooltip"));
|
||||
}
|
||||
|
||||
if (currenttip.isEmpty() && GuiRecipe.searchField.isVisible()
|
||||
&& new Rectangle(GuiRecipe.searchField.x + GuiRecipe.searchField.w, 15, 44, 16)
|
||||
.contains(mousex - this.guiLeft, mousey - this.guiTop)) {
|
||||
@@ -764,7 +783,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
return this.recipeCatalyst;
|
||||
}
|
||||
|
||||
protected void forceRefreshPage() {
|
||||
public void forceRefreshPage() {
|
||||
this.currenthandlers.sort(NEIClientConfig.HANDLER_COMPARATOR);
|
||||
|
||||
final int currentPage = this.handlerPages.getCurrentPageIndex();
|
||||
@@ -789,14 +808,14 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
@Override
|
||||
public void drawGuiContainerBackgroundLayer(float f, int mouseX, int mouseY) {
|
||||
BG_TEXTURE.draw(
|
||||
this.guiLeft,
|
||||
this.guiTop,
|
||||
this.xSize,
|
||||
this.ySize,
|
||||
BORDER_PADDING,
|
||||
BORDER_PADDING,
|
||||
BORDER_PADDING,
|
||||
BORDER_PADDING);
|
||||
this.guiLeft - TRANSPARENCY_BORDER,
|
||||
this.guiTop - TRANSPARENCY_BORDER,
|
||||
this.xSize + TRANSPARENCY_BORDER * 2,
|
||||
this.ySize + TRANSPARENCY_BORDER * 2,
|
||||
BORDER_PADDING + TRANSPARENCY_BORDER,
|
||||
BORDER_PADDING + TRANSPARENCY_BORDER,
|
||||
BORDER_PADDING + TRANSPARENCY_BORDER,
|
||||
BORDER_PADDING + TRANSPARENCY_BORDER);
|
||||
|
||||
drawJEITabs(mouseX, mouseY);
|
||||
}
|
||||
@@ -817,9 +836,11 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
this.prevpage.yPosition + BUTTON_HEIGHT,
|
||||
0x30000000);
|
||||
|
||||
final String handlerTitle = this.handler.original.getRecipeName().trim();
|
||||
final String titleColorCode = getHandlerTitleColorCode(isHandlerTitleHovered(mouseX, mouseY));
|
||||
drawCenteredString(
|
||||
this.fontRendererObj,
|
||||
this.handler.original.getRecipeName().trim(),
|
||||
titleColorCode + handlerTitle + EnumChatFormatting.RESET,
|
||||
this.guiLeft + this.xSize / 2,
|
||||
this.prevtype.yPosition + textMiddle,
|
||||
0xffffff);
|
||||
@@ -867,6 +888,24 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isHandlerTitleHovered(int mousex, int mousey) {
|
||||
final String handlerTitle = this.handler.original.getRecipeName().trim();
|
||||
final int titleWidth = this.fontRendererObj.getStringWidth(handlerTitle);
|
||||
final int textMiddle = (BUTTON_WIDTH - this.fontRendererObj.FONT_HEIGHT) / 2;
|
||||
final int titleX = this.guiLeft + (this.xSize - titleWidth) / 2;
|
||||
final int titleY = this.prevtype.yPosition + textMiddle;
|
||||
return new Rectangle(titleX, titleY, titleWidth, this.fontRendererObj.FONT_HEIGHT).contains(mousex, mousey);
|
||||
}
|
||||
|
||||
private String getHandlerTitleColorCode(boolean hovered) {
|
||||
final String key = hovered ? "recipe.title.color.hover" : "recipe.title.color.normal";
|
||||
final String translated = NEIClientUtils.translate(key);
|
||||
if (!translated.startsWith("nei.")) { // Optional localization string for resource packs
|
||||
return translated;
|
||||
}
|
||||
return hovered ? EnumChatFormatting.YELLOW.toString() : EnumChatFormatting.WHITE.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuiContainer getFirstScreen() {
|
||||
return this.firstGui;
|
||||
|
||||
@@ -49,12 +49,14 @@ public class GuiRecipeCatalyst extends ScrollContainer {
|
||||
|
||||
private static final int SLOT_SIZE = 16;
|
||||
private static final int BORDER_PADDING = 6;
|
||||
private static final int TRANSPARENCY_BORDER = 4;
|
||||
private static final DrawableResource BG_TEXTURE = new DrawableBuilder(
|
||||
"nei:textures/catalyst_tab.png",
|
||||
0,
|
||||
0,
|
||||
28,
|
||||
28).setTextureSize(28, 28).build();
|
||||
28 + TRANSPARENCY_BORDER * 2,
|
||||
28 + TRANSPARENCY_BORDER * 2).setTextureSize(28 + TRANSPARENCY_BORDER * 2, 28 + TRANSPARENCY_BORDER * 2)
|
||||
.build();
|
||||
|
||||
private static final DrawableResource FG_TEXTURE = new DrawableBuilder("nei:textures/slot.png", 0, 0, 18, 18)
|
||||
.setTextureSize(18, 18).build();
|
||||
@@ -149,7 +151,15 @@ public class GuiRecipeCatalyst extends ScrollContainer {
|
||||
if (!this.showWidget) return;
|
||||
|
||||
GL11.glColor4f(1, 1, 1, 1);
|
||||
BG_TEXTURE.draw(this.x, this.y, this.w, this.h, BORDER_PADDING, BORDER_PADDING, BORDER_PADDING, BORDER_PADDING);
|
||||
BG_TEXTURE.draw(
|
||||
this.x - TRANSPARENCY_BORDER,
|
||||
this.y - TRANSPARENCY_BORDER,
|
||||
this.w + TRANSPARENCY_BORDER * 2,
|
||||
this.h + TRANSPARENCY_BORDER * 2,
|
||||
BORDER_PADDING + TRANSPARENCY_BORDER,
|
||||
BORDER_PADDING + TRANSPARENCY_BORDER,
|
||||
BORDER_PADDING + TRANSPARENCY_BORDER,
|
||||
BORDER_PADDING + TRANSPARENCY_BORDER);
|
||||
FG_TEXTURE.draw(
|
||||
this.x + this.paddingInlineStart - 1,
|
||||
this.y + this.paddingBlockStart - 1,
|
||||
|
||||
@@ -33,6 +33,7 @@ import codechicken.nei.Widget;
|
||||
import codechicken.nei.drawable.DrawableResource;
|
||||
import codechicken.nei.event.NEIRegisterHandlerInfosEvent;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.recipe.debug.DebugHandlerWidget;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
|
||||
public abstract class GuiRecipeTab extends Widget {
|
||||
@@ -258,7 +259,8 @@ public abstract class GuiRecipeTab extends Widget {
|
||||
final int handlerHeight = intOrDefault(record.get("handlerHeight"), HandlerInfo.DEFAULT_HEIGHT);
|
||||
final int handlerWidth = intOrDefault(record.get("handlerWidth"), HandlerInfo.DEFAULT_WIDTH);
|
||||
final boolean multipleWidgetsAllowed = intOrDefault(record.get("maxRecipesPerPage"), 1) > 1;
|
||||
info.setHandlerDimensions(handlerWidth, handlerHeight, multipleWidgetsAllowed);
|
||||
info.setHandlerDimensions(handlerWidth, handlerHeight);
|
||||
info.setMultipleWidgetsAllowed(multipleWidgetsAllowed);
|
||||
} catch (NumberFormatException ignored) {
|
||||
NEIClientConfig.logger.info("Error setting handler dimensions for " + handler);
|
||||
}
|
||||
@@ -292,11 +294,12 @@ public abstract class GuiRecipeTab extends Widget {
|
||||
}
|
||||
NEIClientConfig.logger.info("Sending {}", NEIRegisterHandlerInfosEvent.class.getSimpleName());
|
||||
MinecraftForge.EVENT_BUS.post(new NEIRegisterHandlerInfosEvent());
|
||||
DebugHandlerWidget.instance.loadHandlerInfoPatch();
|
||||
}
|
||||
|
||||
private static HandlerInfo getDefaultHandlerInfo() {
|
||||
final HandlerInfo info = new HandlerInfo("Unknown", "Unknown", "Unknown", false, "");
|
||||
info.setHandlerDimensions(HandlerInfo.DEFAULT_WIDTH, HandlerInfo.DEFAULT_HEIGHT, false);
|
||||
info.setHandlerDimensions(HandlerInfo.DEFAULT_WIDTH, HandlerInfo.DEFAULT_HEIGHT);
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import codechicken.nei.ItemPanels;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.recipe.Recipe.RecipeId;
|
||||
import codechicken.nei.recipe.TemplateRecipeHandler.RecipeTransferRect;
|
||||
|
||||
public class GuiUsageRecipe extends GuiRecipe<IUsageHandler> {
|
||||
|
||||
@@ -38,12 +39,10 @@ public class GuiUsageRecipe extends GuiRecipe<IUsageHandler> {
|
||||
&& ingredients[0] instanceof ItemStack stack) {
|
||||
ItemPanels.itemPanel.historyPanel.addItem(stack);
|
||||
}
|
||||
|
||||
mc.displayGuiScreen(gui);
|
||||
gui.openTargetRecipe(recipeId);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -55,14 +54,36 @@ public class GuiUsageRecipe extends GuiRecipe<IUsageHandler> {
|
||||
public static ArrayList<IUsageHandler> getUsageHandlers(String inputId, Object... ingredients) {
|
||||
|
||||
final RecipeHandlerQuery<IUsageHandler> recipeQuery = new RecipeHandlerQuery<>(
|
||||
h -> getUsageOrCatalystHandler(h, inputId, ingredients),
|
||||
"all".equals(inputId) ? GuiUsageRecipe::buildAllRecipesHandler
|
||||
: h -> getUsageOrCatalystHandler(h, inputId, ingredients),
|
||||
GuiUsageRecipe.usagehandlers,
|
||||
GuiUsageRecipe.serialUsageHandlers,
|
||||
"Error while looking up usage recipe",
|
||||
"inputId: " + inputId,
|
||||
"ingredients: " + Arrays.toString(ingredients));
|
||||
|
||||
return recipeQuery.runWithProfiling(NEIClientUtils.translate("recipe.concurrent.usage"));
|
||||
ArrayList<IUsageHandler> handlers = recipeQuery
|
||||
.runWithProfiling(NEIClientUtils.translate("recipe.concurrent.usage"));
|
||||
return handlers;
|
||||
}
|
||||
|
||||
private static IUsageHandler buildAllRecipesHandler(IUsageHandler handler) {
|
||||
if (handler instanceof TemplateRecipeHandler templateHandler) {
|
||||
TemplateRecipeHandler allHandler = templateHandler.newInstance();
|
||||
if (allHandler.transferRects.isEmpty()) {
|
||||
allHandler.loadCraftingRecipes("all");
|
||||
return allHandler;
|
||||
}
|
||||
for (RecipeTransferRect rect : allHandler.transferRects) {
|
||||
if (allHandler.specifyTransferRect() == null
|
||||
|| allHandler.specifyTransferRect().equals(rect.outputId)) {
|
||||
allHandler.loadCraftingRecipes(rect.outputId, rect.results);
|
||||
return allHandler;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return handler.getUsageHandler("all");
|
||||
}
|
||||
|
||||
public static void registerUsageHandler(IUsageHandler handler) {
|
||||
|
||||
@@ -45,13 +45,13 @@ public class HandlerInfo {
|
||||
|
||||
@Deprecated
|
||||
public void setHandlerDimensions(int height, int width, int maxRecipesPerPage) {
|
||||
setHandlerDimensions(width, height, maxRecipesPerPage > 1);
|
||||
setHandlerDimensions(width, height);
|
||||
setMultipleWidgetsAllowed(maxRecipesPerPage > 1);
|
||||
}
|
||||
|
||||
public void setHandlerDimensions(int width, int height, boolean multipleWidgetsAllowed) {
|
||||
public void setHandlerDimensions(int width, int height) {
|
||||
this.height = height;
|
||||
this.width = width;
|
||||
this.multipleWidgetsAllowed = multipleWidgetsAllowed;
|
||||
}
|
||||
|
||||
public boolean setItem(String itemId, String nbtString) {
|
||||
@@ -102,6 +102,10 @@ public class HandlerInfo {
|
||||
return this.multipleWidgetsAllowed ? Integer.MAX_VALUE : 1;
|
||||
}
|
||||
|
||||
public void setMultipleWidgetsAllowed(boolean multipleWidgetsAllowed) {
|
||||
this.multipleWidgetsAllowed = multipleWidgetsAllowed;
|
||||
}
|
||||
|
||||
public boolean isMultipleWidgetsAllowed() {
|
||||
return this.multipleWidgetsAllowed;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,9 @@ import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.StatCollector;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.nei.ClientHandler;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
@@ -81,6 +84,13 @@ public class InformationHandler extends TemplateRecipeHandler {
|
||||
return "nei:textures/gui/recipebg.png";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawBackground(int recipe) {
|
||||
GL11.glColor4f(1, 1, 1, 1);
|
||||
GuiDraw.changeTexture(getGuiTexture());
|
||||
GuiDraw.drawTexturedModalRect(0, 0, 7, 13, 166, 65);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRecipeHeight(int recipe) {
|
||||
final CachedInfoPage page = (CachedInfoPage) this.arecipes.get(recipe);
|
||||
|
||||
@@ -13,6 +13,7 @@ import java.util.stream.Stream;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
|
||||
@@ -21,7 +22,6 @@ import org.lwjgl.opengl.GL12;
|
||||
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.nei.FavoriteRecipes;
|
||||
import codechicken.nei.LayoutManager;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.NEIServerUtils;
|
||||
@@ -31,12 +31,16 @@ import codechicken.nei.api.IGuiContainerOverlay;
|
||||
import codechicken.nei.api.ShortcutInputHandler;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.recipe.GuiRecipeButton.UpdateRecipeButtonsEvent;
|
||||
import codechicken.nei.recipe.Recipe.RecipeId;
|
||||
import codechicken.nei.recipe.debug.DebugHandlerWidget;
|
||||
import codechicken.nei.util.NEIMouseUtils;
|
||||
|
||||
public class NEIRecipeWidget extends Widget {
|
||||
|
||||
protected AcceptsFollowingTooltipLineHandler acceptsFollowingTooltipLineHandler;
|
||||
protected final WeakHashMap<PositionedStack, List<ItemStack>> permutations = new WeakHashMap<>();
|
||||
protected final Map<PositionedStack, Integer> favoriteIndexes = new WeakHashMap<>();
|
||||
protected final Map<PositionedStack, List<ItemStack>> permutations = new WeakHashMap<>();
|
||||
protected int favoriteRevision = -1;
|
||||
protected boolean update = true;
|
||||
protected int cycleticks = 0;
|
||||
protected int lastcycle = -1;
|
||||
@@ -123,18 +127,18 @@ public class NEIRecipeWidget extends Widget {
|
||||
final UpdateRecipeButtonsEvent.Post postEvent = new UpdateRecipeButtonsEvent.Post(
|
||||
guiRecipe,
|
||||
this,
|
||||
getDefatulButtons());
|
||||
getDefaultButtons());
|
||||
MinecraftForge.EVENT_BUS.post(postEvent);
|
||||
return postEvent.buttonList;
|
||||
}
|
||||
|
||||
} else {
|
||||
return getDefatulButtons();
|
||||
return getDefaultButtons();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected List<GuiRecipeButton> getDefatulButtons() {
|
||||
protected List<GuiRecipeButton> getDefaultButtons() {
|
||||
GuiContainer guiContainer = NEIClientUtils.getGuiContainer();
|
||||
final List<GuiRecipeButton> buttons = new ArrayList<>();
|
||||
final boolean showFavorites = NEIClientConfig.favoritesEnabled() && handlerInfo.getShowFavoritesButton();
|
||||
@@ -165,7 +169,7 @@ public class NEIRecipeWidget extends Widget {
|
||||
if (this.update) {
|
||||
this.update = false;
|
||||
|
||||
if (!NEIClientUtils.shiftKey() && (this.cycleticks++) / 20 != this.lastcycle || this.lastcycle == -1) {
|
||||
if (!NEIClientUtils.shiftKey() && ((this.cycleticks++) / 20) != this.lastcycle || this.lastcycle == -1) {
|
||||
this.lastcycle = this.cycleticks / 20;
|
||||
updatePermutations();
|
||||
}
|
||||
@@ -187,6 +191,11 @@ public class NEIRecipeWidget extends Widget {
|
||||
GuiContainerManager.enableMatrixStackLogging();
|
||||
|
||||
for (PositionedStack pStack : getInputs()) {
|
||||
|
||||
if (!this.permutations.containsKey(pStack)) {
|
||||
updatePermutationsFor(pStack);
|
||||
}
|
||||
|
||||
GuiContainerManager.drawItem(pStack.relx, pStack.rely, pStack.item);
|
||||
|
||||
if (pStack.contains(mouseX - this.x, mouseY - this.y - yShift)) {
|
||||
@@ -195,6 +204,11 @@ public class NEIRecipeWidget extends Widget {
|
||||
}
|
||||
|
||||
for (PositionedStack pStack : getCatalysts()) {
|
||||
|
||||
if (!this.permutations.containsKey(pStack)) {
|
||||
updatePermutationsFor(pStack);
|
||||
}
|
||||
|
||||
GuiContainerManager.drawItem(pStack.relx, pStack.rely, pStack.item);
|
||||
|
||||
if (pStack.contains(mouseX - this.x, mouseY - this.y - yShift)) {
|
||||
@@ -214,13 +228,13 @@ public class NEIRecipeWidget extends Widget {
|
||||
|
||||
this.handlerRef.handler.drawForeground(this.handlerRef.recipeIndex);
|
||||
|
||||
final GuiRecipeButton overlayButton = getRecipeButtons().stream()
|
||||
.filter(
|
||||
b -> this.showAsWidget ? b instanceof GuiOverlayButton
|
||||
: b.contains(mouseX - this.x, mouseY - this.y - yShift))
|
||||
.findAny().orElse(null);
|
||||
final GuiRecipeButton overlayButton = forEachButtons(
|
||||
button -> (this.showAsWidget ? button instanceof GuiOverlayButton : button.contains(mouseX, mouseY))
|
||||
? button
|
||||
: null,
|
||||
(GuiRecipeButton) null);
|
||||
|
||||
if (overlayButton != null && overlayButton.enabled) {
|
||||
if (overlayButton != null) {
|
||||
NEIClientUtils.gl2DRenderContext(() -> overlayButton.drawItemOverlay());
|
||||
}
|
||||
|
||||
@@ -238,11 +252,43 @@ public class NEIRecipeWidget extends Widget {
|
||||
}
|
||||
}
|
||||
|
||||
LayoutManager.recipeHandlerWidget.drawGuiPlaceholder(this);
|
||||
DebugHandlerWidget.instance.drawGuiPlaceholder(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleKeyPress(int keyID, char keyChar) {
|
||||
|
||||
if (NEIClientConfig.favoritesEnabled() && NEIClientUtils.shiftKey()
|
||||
&& NEIClientConfig.isKeyHashDown("gui.favorite_item")) {
|
||||
final Point mouse = GuiDraw.getMousePosition();
|
||||
final int yShift = this.handlerInfo.getYShift();
|
||||
PositionedStack pStackOver = null;
|
||||
|
||||
for (PositionedStack pStack : getInputs()) {
|
||||
if (pStack.contains(mouse.x - this.x, mouse.y - this.y - yShift)) {
|
||||
pStackOver = pStack;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pStackOver != null) {
|
||||
|
||||
if (FavoriteRecipes.containsManual(pStackOver.item)) {
|
||||
FavoriteRecipes.setFavorite(pStackOver.item, null);
|
||||
} else {
|
||||
FavoriteRecipes.setFavorite(
|
||||
pStackOver.item,
|
||||
RecipeId.of(
|
||||
pStackOver.item,
|
||||
FavoriteRecipes.FAVORITE_ITEM,
|
||||
Arrays.asList(new ItemStack(Blocks.fire, 1), pStackOver.item)));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -335,16 +381,17 @@ public class NEIRecipeWidget extends Widget {
|
||||
for (PositionedStack pStack : getCatalysts()) {
|
||||
if (pStack.contains(mousex - this.x, mousey - this.y - yShift)) {
|
||||
hovered = pStack;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hovered == null || hovered.items.length <= 1) {
|
||||
if (hovered == null || this.permutations.getOrDefault(hovered, Collections.emptyList()).size() <= 1) {
|
||||
this.acceptsFollowingTooltipLineHandler = null;
|
||||
} else if (this.acceptsFollowingTooltipLineHandler == null
|
||||
|| this.acceptsFollowingTooltipLineHandler.tooltipGUID != hovered) {
|
||||
this.acceptsFollowingTooltipLineHandler = AcceptsFollowingTooltipLineHandler
|
||||
.of(hovered, hovered.getFilteredPermutations(), hovered.item);
|
||||
.of(hovered, this.permutations.get(hovered), hovered.item);
|
||||
}
|
||||
} else if (this.acceptsFollowingTooltipLineHandler != null) {
|
||||
this.acceptsFollowingTooltipLineHandler = null;
|
||||
@@ -359,6 +406,7 @@ public class NEIRecipeWidget extends Widget {
|
||||
|
||||
@Override
|
||||
public Map<String, String> handleHotkeys(int mouseX, int mouseY, Map<String, String> hotkeys) {
|
||||
final int yShift = this.handlerInfo.getYShift();
|
||||
final Map<String, String> buttonHotkeys = forEachButtons(
|
||||
button -> button.contains(mouseX, mouseY) ? button.handleHotkeys(mouseX, mouseY, hotkeys) : null,
|
||||
hotkeys);
|
||||
@@ -371,6 +419,14 @@ public class NEIRecipeWidget extends Widget {
|
||||
NEIClientUtils.translate("recipe.accepts.scroll"));
|
||||
}
|
||||
|
||||
if (getInputs().stream().anyMatch(
|
||||
pStack -> this.permutations.getOrDefault(pStack, Collections.emptyList()).size() > 1
|
||||
&& pStack.contains(mouseX - this.x, mouseY - this.y - yShift))) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.favorite_item", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("recipe.favorite.toggle"));
|
||||
}
|
||||
|
||||
return buttonHotkeys;
|
||||
}
|
||||
|
||||
@@ -395,8 +451,8 @@ public class NEIRecipeWidget extends Widget {
|
||||
if (!NEIClientUtils.shiftKey()) return false;
|
||||
final PositionedStack overStack = getPositionedStackMouseOver(mx, my);
|
||||
|
||||
if (overStack != null && overStack.items.length > 1) {
|
||||
final List<ItemStack> items = overStack.getFilteredPermutations();
|
||||
if (overStack != null && this.permutations.getOrDefault(overStack, Collections.emptyList()).size() > 1) {
|
||||
final List<ItemStack> items = this.permutations.get(overStack);
|
||||
final int stackIndex = indexOf(items, overStack.item);
|
||||
final ItemStack stack = items.get((items.size() - scroll + stackIndex) % items.size());
|
||||
|
||||
@@ -505,21 +561,21 @@ public class NEIRecipeWidget extends Widget {
|
||||
}
|
||||
|
||||
protected void updatePermutations() {
|
||||
final int rev = FavoriteRecipes.getRevision();
|
||||
|
||||
if (this.favoriteRevision != rev) {
|
||||
this.favoriteRevision = rev;
|
||||
this.acceptsFollowingTooltipLineHandler = null;
|
||||
this.favoriteIndexes.clear();
|
||||
this.permutations.clear();
|
||||
}
|
||||
|
||||
for (PositionedStack pStack : getInputs()) {
|
||||
if (pStack.items.length > 1) {
|
||||
final List<ItemStack> permutations = this.permutations
|
||||
.computeIfAbsent(pStack, stack -> stack.getFilteredPermutations(FavoriteRecipes::contains));
|
||||
pStack.setPermutationToRender(permutations.get(this.lastcycle % permutations.size()));
|
||||
}
|
||||
updatePermutationsFor(pStack);
|
||||
}
|
||||
|
||||
for (PositionedStack pStack : getCatalysts()) {
|
||||
if (pStack.items.length > 1) {
|
||||
final List<ItemStack> permutations = this.permutations
|
||||
.computeIfAbsent(pStack, stack -> stack.getFilteredPermutations(FavoriteRecipes::contains));
|
||||
pStack.setPermutationToRender(permutations.get(this.lastcycle % permutations.size()));
|
||||
}
|
||||
updatePermutationsFor(pStack);
|
||||
}
|
||||
|
||||
if (this.acceptsFollowingTooltipLineHandler != null) {
|
||||
@@ -529,6 +585,36 @@ public class NEIRecipeWidget extends Widget {
|
||||
|
||||
}
|
||||
|
||||
private void updatePermutationsFor(PositionedStack pStack) {
|
||||
List<ItemStack> perms = this.permutations.get(pStack);
|
||||
int favoriteIndex = this.favoriteIndexes.getOrDefault(pStack, -1);
|
||||
boolean needsUpdate = false;
|
||||
|
||||
if (perms == null) {
|
||||
perms = pStack.getFilteredPermutations();
|
||||
favoriteIndex = -1;
|
||||
|
||||
if (perms.size() > 1) {
|
||||
for (ItemStack item : perms) {
|
||||
if (!FavoriteRecipes.containsManual(item)) break;
|
||||
favoriteIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
this.permutations.put(pStack, perms);
|
||||
this.favoriteIndexes.put(pStack, favoriteIndex);
|
||||
needsUpdate = true;
|
||||
}
|
||||
|
||||
if (perms.size() > 1 || needsUpdate) {
|
||||
final int size = favoriteIndex != -1 ? favoriteIndex + 1 : perms.size();
|
||||
|
||||
if (size > 0) {
|
||||
pStack.setPermutationToRender(perms.get(this.lastcycle % size));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected List<PositionedStack> getInputs() {
|
||||
return this.handlerRef.handler.getIngredientStacks(this.handlerRef.recipeIndex);
|
||||
}
|
||||
|
||||
@@ -51,6 +51,24 @@ public class Recipe {
|
||||
return new RecipeId(extractItem(result), handlerName, extractIngredients(ingredients));
|
||||
}
|
||||
|
||||
public static RecipeId of(IRecipeHandler handler, int recipeIndex) {
|
||||
final List<PositionedStack> ingredients = handler.getIngredientStacks(recipeIndex);
|
||||
final String handlerName = GuiRecipeTab.getHandlerInfo(handler).getHandlerName();
|
||||
PositionedStack pStackResult = handler.getResultStack(recipeIndex);
|
||||
|
||||
if (pStackResult == null) {
|
||||
for (PositionedStack otherStack : handler.getOtherStacks(recipeIndex)) {
|
||||
if (!FluidContainerRegistry.isContainer(otherStack.items[0])
|
||||
|| StackInfo.getFluid(otherStack.items[0]) != null) {
|
||||
pStackResult = otherStack;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new RecipeId(extractItem(pStackResult), handlerName, extractIngredients(ingredients));
|
||||
}
|
||||
|
||||
public static RecipeId of(JsonObject json) {
|
||||
String handlerName = null;
|
||||
List<ItemStack> ingredients = new ArrayList<>();
|
||||
@@ -236,6 +254,12 @@ public class Recipe {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isShapedRecipe() && this.result != null
|
||||
&& anRecipeId.result != null
|
||||
&& !StackInfo.equalItemAndNBT(this.result, anRecipeId.result, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int idx = 0; idx < this.ingredients.size(); idx++) {
|
||||
if (!StackInfo.equalItemAndNBT(this.ingredients.get(idx), anRecipeId.ingredients.get(idx), true)) {
|
||||
return false;
|
||||
|
||||
@@ -52,6 +52,11 @@ public class RecipeHandlerRef {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void clearCache() {
|
||||
recipeRefCache.clear();
|
||||
transferAlghoritmCache.clear();
|
||||
}
|
||||
|
||||
private GuiContainer prepareGui(GuiContainer firstGui) {
|
||||
|
||||
if (firstGui instanceof GuiRecipe gui) {
|
||||
|
||||
@@ -4,16 +4,11 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.client.gui.inventory.GuiBrewingStand;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.client.gui.inventory.GuiCrafting;
|
||||
import net.minecraft.client.gui.inventory.GuiFurnace;
|
||||
import net.minecraft.client.gui.inventory.GuiInventory;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
import codechicken.nei.OffsetPositioner;
|
||||
import codechicken.nei.api.API;
|
||||
import codechicken.nei.api.IOverlayHandler;
|
||||
import codechicken.nei.api.IStackPositioner;
|
||||
|
||||
@@ -96,33 +91,4 @@ public class RecipeInfo {
|
||||
return offset == null ? new int[] { 5, 11 } : offset;
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
API.registerRecipeHandler(new ShapedRecipeHandler());
|
||||
API.registerUsageHandler(new ShapedRecipeHandler());
|
||||
API.registerRecipeHandler(new ShapelessRecipeHandler());
|
||||
API.registerUsageHandler(new ShapelessRecipeHandler());
|
||||
API.registerRecipeHandler(new FireworkRecipeHandler());
|
||||
API.registerUsageHandler(new FireworkRecipeHandler());
|
||||
API.registerRecipeHandler(new FurnaceRecipeHandler());
|
||||
API.registerUsageHandler(new FurnaceRecipeHandler());
|
||||
API.registerRecipeHandler(new BrewingRecipeHandler());
|
||||
API.registerUsageHandler(new BrewingRecipeHandler());
|
||||
API.registerRecipeHandler(new FuelRecipeHandler());
|
||||
API.registerUsageHandler(new FuelRecipeHandler());
|
||||
API.registerRecipeHandler(new InformationHandler());
|
||||
API.registerUsageHandler(new InformationHandler());
|
||||
|
||||
API.registerGuiOverlay(GuiCrafting.class, "crafting");
|
||||
API.registerGuiOverlay(GuiInventory.class, "crafting2x2", 63, 20);
|
||||
API.registerGuiOverlay(GuiFurnace.class, "smelting");
|
||||
API.registerGuiOverlay(GuiFurnace.class, "fuel");
|
||||
API.registerGuiOverlay(GuiBrewingStand.class, "brewing");
|
||||
|
||||
API.registerGuiOverlayHandler(GuiCrafting.class, new DefaultOverlayHandler(), "crafting");
|
||||
API.registerGuiOverlayHandler(GuiInventory.class, new DefaultOverlayHandler(63, 20), "crafting2x2");
|
||||
API.registerGuiOverlayHandler(GuiBrewingStand.class, new BrewingOverlayHandler(), "brewing");
|
||||
|
||||
API.registerRecipeHandler(new ProfilerRecipeHandler(true));
|
||||
API.registerUsageHandler(new ProfilerRecipeHandler(false));
|
||||
}
|
||||
}
|
||||
@@ -143,7 +143,7 @@ public class RecipePageManager {
|
||||
|
||||
for (Widget widget : currentWidgets) {
|
||||
if (widget instanceof NEIRecipeWidget recipeWidget) {
|
||||
recipeWidget.setLocation(0, shiftY);
|
||||
recipeWidget.setLocation(2, shiftY);
|
||||
}
|
||||
shiftY += widget.h;
|
||||
}
|
||||
|
||||
@@ -17,12 +17,13 @@ import codechicken.nei.scroll.GuiHelper;
|
||||
public class RecipeTooltipLineHandler implements ITooltipLineHandler {
|
||||
|
||||
private static final int BG_PADDING = 5;
|
||||
private static final DrawableResource BG_TEXTURE = new DrawableBuilder(
|
||||
private static final int TRANSPARENCY_BORDER = 4;
|
||||
private final DrawableResource BG_TEXTURE = new DrawableBuilder(
|
||||
"nei:textures/gui/recipebg.png",
|
||||
0,
|
||||
0,
|
||||
176,
|
||||
166).build();
|
||||
176 + TRANSPARENCY_BORDER * 2,
|
||||
166 + TRANSPARENCY_BORDER * 2).build();
|
||||
|
||||
protected long lastUpdate = System.currentTimeMillis();
|
||||
protected String recipeName = "";
|
||||
@@ -88,7 +89,15 @@ public class RecipeTooltipLineHandler implements ITooltipLineHandler {
|
||||
GuiContainerManager.enable2DRender();
|
||||
GL11.glColor4f(1, 1, 1, 1);
|
||||
|
||||
BG_TEXTURE.draw(0, 0, size.width, size.height, BG_PADDING, BG_PADDING, BG_PADDING, BG_PADDING);
|
||||
BG_TEXTURE.draw(
|
||||
-TRANSPARENCY_BORDER,
|
||||
-TRANSPARENCY_BORDER,
|
||||
size.width + TRANSPARENCY_BORDER * 2,
|
||||
size.height + TRANSPARENCY_BORDER * 2,
|
||||
BG_PADDING + TRANSPARENCY_BORDER,
|
||||
BG_PADDING + TRANSPARENCY_BORDER,
|
||||
BG_PADDING + TRANSPARENCY_BORDER,
|
||||
BG_PADDING + TRANSPARENCY_BORDER);
|
||||
|
||||
GL11.glEnable(GL11.GL_ALPHA_TEST);
|
||||
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package codechicken.nei.recipe;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.inventory.Slot;
|
||||
|
||||
import codechicken.nei.PositionedStack;
|
||||
|
||||
public class RepairOverlayHandler extends DefaultOverlayHandler {
|
||||
|
||||
@Override
|
||||
public boolean canCraft(GuiContainer firstGui, IRecipeHandler handler, int recipeIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Slot[][] mapIngredSlots(GuiContainer gui, List<PositionedStack> ingredients) {
|
||||
final List<Slot> slots = gui.inventorySlots.inventorySlots;
|
||||
|
||||
return new Slot[][] { { slots.get(0) }, { slots.get(1) } };
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
package codechicken.nei.recipe;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.client.gui.GuiRepair;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import codechicken.nei.ItemList;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.PositionedStack;
|
||||
import codechicken.nei.RestartableTask;
|
||||
import codechicken.nei.drawable.DrawableBuilder;
|
||||
import codechicken.nei.drawable.DrawableResource;
|
||||
|
||||
public class RepairRecipeHandler extends TemplateRecipeHandler {
|
||||
|
||||
private final DrawableResource BG_TEXTURE = new DrawableBuilder("nei:textures/gui/repair.png", 0, 0, 168, 36)
|
||||
.setTextureSize(168, 36).build();
|
||||
|
||||
private static final RestartableTask reloadRepairRecipesTask = new RestartableTask("NEI Repair Recipe Reloading") {
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
new RepairRecipeHandler().buildCache();
|
||||
}
|
||||
};
|
||||
|
||||
private static class ItemStackKey {
|
||||
|
||||
private final ItemStack stack;
|
||||
|
||||
public ItemStackKey(ItemStack stack) {
|
||||
this.stack = stack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return stack.getItem().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
|
||||
if (obj instanceof ItemStackKey objeKey) {
|
||||
return NEIClientUtils.areStacksSameTypeWithNBT(stack, objeKey.stack);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class DamagablePositionedStack extends PositionedStack {
|
||||
|
||||
public DamagablePositionedStack(Object item, int x, int y) {
|
||||
super(item, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(ItemStack ingredient) {
|
||||
return ingredient.getItemDamage() > 0 && NEIClientUtils.areStacksSameTypeWithNBT(this.item, ingredient);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static List<RepairPair> cachedRecipes;
|
||||
|
||||
private static final int LEFT_X = 25;
|
||||
private static final int RIGHT_X = 74;
|
||||
private static final int OUTPUT_X = 132;
|
||||
private static final int SLOT_Y = 10;
|
||||
|
||||
public class RepairPair extends CachedRecipe {
|
||||
|
||||
final List<PositionedStack> ingredients = new ArrayList<>(2);
|
||||
final PositionedStack result;
|
||||
|
||||
RepairPair(ItemStack left, Object right, ItemStack result) {
|
||||
ingredients.add(new DamagablePositionedStack(left, LEFT_X, SLOT_Y));
|
||||
ingredients.add(new PositionedStack(right, RIGHT_X, SLOT_Y));
|
||||
this.result = new PositionedStack(result, OUTPUT_X, SLOT_Y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PositionedStack> getIngredients() {
|
||||
return this.ingredients;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PositionedStack getResult() {
|
||||
return this.result;
|
||||
}
|
||||
}
|
||||
|
||||
public static void findRepairRecipesOnceParallel() {
|
||||
reloadRepairRecipesTask.restart();
|
||||
}
|
||||
|
||||
private void buildCache() {
|
||||
final Map<ItemStackKey, RepairPair> recipes = new HashMap<>();
|
||||
|
||||
for (ItemStack itemstack1 : ItemList.items) {
|
||||
recipes.computeIfAbsent(new ItemStackKey(itemstack1), key -> this.getRepairRecipe(key.stack));
|
||||
}
|
||||
|
||||
cachedRecipes = recipes.values().stream().filter(recipe -> recipe != null).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private RepairPair getRepairRecipe(ItemStack itemstack1) {
|
||||
if (!itemstack1.isItemStackDamageable()) return null;
|
||||
|
||||
final List<ItemStack> permutations = new ArrayList<>();
|
||||
|
||||
for (ItemStack itemstack2 : ItemList.items) {
|
||||
if (itemstack1.getItem().getIsRepairable(itemstack1, itemstack2)) {
|
||||
final ItemStack right = itemstack2.copy();
|
||||
right.stackSize = 4;
|
||||
permutations.add(right);
|
||||
}
|
||||
}
|
||||
|
||||
if (permutations.isEmpty()) return null;
|
||||
|
||||
final int maxDamage = itemstack1.getMaxDamage();
|
||||
final ItemStack result = itemstack1.copy();
|
||||
final ItemStack left = itemstack1.copy();
|
||||
|
||||
left.setItemDamage(maxDamage - 1);
|
||||
result.setItemDamage(left.getItemDamageForDisplay() - (maxDamage / 4) * 4);
|
||||
|
||||
return new RepairPair(left, permutations, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TemplateRecipeHandler newInstance() {
|
||||
|
||||
if (cachedRecipes == null) {
|
||||
buildCache();
|
||||
}
|
||||
|
||||
return super.newInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadCraftingRecipes(String outputId, Object... results) {
|
||||
if (outputId.equals(getOverlayIdentifier()) && getClass() == RepairRecipeHandler.class) {
|
||||
arecipes.addAll(cachedRecipes);
|
||||
} else if (!NEIClientConfig.getBooleanSetting("showRepairOnlyForDamageableItems")) {
|
||||
super.loadCraftingRecipes(outputId, results);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadCraftingRecipes(ItemStack result) {
|
||||
for (RepairPair recipe : cachedRecipes) {
|
||||
if (recipe.getResult().contains(result)) arecipes.add(recipe);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadUsageRecipes(String inputId, Object... ingredients) {
|
||||
if (inputId.equals(getOverlayIdentifier()) && getClass() == RepairRecipeHandler.class) {
|
||||
loadCraftingRecipes(getOverlayIdentifier());
|
||||
} else {
|
||||
super.loadUsageRecipes(inputId, ingredients);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadUsageRecipes(ItemStack ingredient) {
|
||||
final boolean showRepairOnlyForDamageableItems = NEIClientConfig
|
||||
.getBooleanSetting("showRepairOnlyForDamageableItems");
|
||||
|
||||
for (RepairPair recipe : cachedRecipes) {
|
||||
final List<PositionedStack> ingredients = recipe.getIngredients();
|
||||
|
||||
if (ingredients.get(0).contains(ingredient)) {
|
||||
arecipes.add(recipe);
|
||||
} else if (!showRepairOnlyForDamageableItems && ingredients.get(1).contains(ingredient)) {
|
||||
arecipes.add(new RepairPair(ingredients.get(0).item, ingredient, recipe.getResult().item));
|
||||
}
|
||||
}
|
||||
|
||||
if (arecipes.isEmpty()) {
|
||||
final RepairPair recipe = getRepairRecipe(ingredient);
|
||||
if (recipe != null) {
|
||||
arecipes.add(recipe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadTransferRects() {
|
||||
transferRects.add(new RecipeTransferRect(new Rectangle(100, 11, 22, 15), getOverlayIdentifier()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRecipeName() {
|
||||
return NEIClientUtils.translate("recipe.repair");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGuiTexture() {
|
||||
return "nei:textures/gui/repair.png";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOverlayIdentifier() {
|
||||
return "repair";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends GuiContainer> getGuiClass() {
|
||||
return GuiRepair.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawBackground(int recipe) {
|
||||
BG_TEXTURE.draw(0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawForeground(int recipe) {}
|
||||
|
||||
}
|
||||
@@ -256,6 +256,10 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
|
||||
return rect.hashCode();
|
||||
}
|
||||
|
||||
public Rectangle getRect() {
|
||||
return rect;
|
||||
}
|
||||
|
||||
Rectangle rect;
|
||||
String outputId;
|
||||
Object[] results;
|
||||
|
||||
@@ -36,6 +36,7 @@ public class RecipeChainTooltipLineHandler implements ITooltipLineHandler {
|
||||
protected ItemsTooltipLineHandler inputs;
|
||||
protected ItemsTooltipLineHandler outputs;
|
||||
protected ItemsTooltipLineHandler remainder;
|
||||
protected ItemsTooltipLineHandler craftingNeeded;
|
||||
protected boolean lastShiftKey = false;
|
||||
protected boolean lastControlKey = false;
|
||||
|
||||
@@ -54,6 +55,7 @@ public class RecipeChainTooltipLineHandler implements ITooltipLineHandler {
|
||||
final List<ItemStack> inputs = new ArrayList<>();
|
||||
final List<ItemStack> outputs = new ArrayList<>();
|
||||
final List<ItemStack> remainder = new ArrayList<>();
|
||||
final List<ItemStack> craftingNeeded = new ArrayList<>();
|
||||
final ItemStackAmount inventory = new ItemStackAmount();
|
||||
final GuiContainer currentGui = NEIClientUtils.getGuiContainer();
|
||||
|
||||
@@ -167,6 +169,12 @@ public class RecipeChainTooltipLineHandler implements ITooltipLineHandler {
|
||||
}
|
||||
|
||||
}
|
||||
if (this.lastShiftKey) {
|
||||
for (Map.Entry<BookmarkItem, Long> item : this.math.requiredAmount.entrySet()) {
|
||||
if (item.getKey().type == BookmarkItem.BookmarkItemType.RESULT && item.getValue() != 0)
|
||||
craftingNeeded.add(item.getKey().getItemStack(item.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
inputs.sort(
|
||||
Comparator.comparing((ItemStack stack) -> StackInfo.getFluid(stack) != null)
|
||||
@@ -203,9 +211,16 @@ public class RecipeChainTooltipLineHandler implements ITooltipLineHandler {
|
||||
true,
|
||||
Integer.MAX_VALUE);
|
||||
|
||||
this.craftingNeeded = new ItemsTooltipLineHandler(
|
||||
NEIClientUtils.translate("bookmark.crafting_chain.needed"),
|
||||
craftingNeeded,
|
||||
true,
|
||||
Integer.MAX_VALUE);
|
||||
|
||||
if (this.lastShiftKey) {
|
||||
this.inputs.setLabelColor(EnumChatFormatting.RED);
|
||||
this.available.setLabelColor(EnumChatFormatting.GREEN);
|
||||
this.craftingNeeded.setLabelColor(EnumChatFormatting.BLUE);
|
||||
}
|
||||
|
||||
this.size.height = this.size.width = 0;
|
||||
@@ -217,16 +232,18 @@ public class RecipeChainTooltipLineHandler implements ITooltipLineHandler {
|
||||
if (!this.math.outputRecipes.isEmpty()) {
|
||||
this.size.height = 2 + GuiDraw.fontRenderer.FONT_HEIGHT;
|
||||
}
|
||||
|
||||
this.size.width = Math.max(
|
||||
this.inputs.getSize().width,
|
||||
Math.max(
|
||||
this.outputs.getSize().width,
|
||||
Math.max(this.remainder.getSize().width, this.available.getSize().width)));
|
||||
Math.max(
|
||||
this.remainder.getSize().width,
|
||||
Math.max(this.available.getSize().width, this.craftingNeeded.getSize().width))));
|
||||
|
||||
this.size.height += this.inputs.getSize().height + this.outputs.getSize().height
|
||||
+ this.remainder.getSize().height
|
||||
+ this.available.getSize().height;
|
||||
+ this.available.getSize().height
|
||||
+ this.craftingNeeded.getSize().height;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -258,7 +275,6 @@ public class RecipeChainTooltipLineHandler implements ITooltipLineHandler {
|
||||
}
|
||||
|
||||
if (NEIClientConfig.recipeChainDir() == 0) {
|
||||
|
||||
if (!this.inputs.isEmpty()) {
|
||||
this.inputs.draw(x, y);
|
||||
y += this.inputs.getSize().height;
|
||||
@@ -269,6 +285,11 @@ public class RecipeChainTooltipLineHandler implements ITooltipLineHandler {
|
||||
y += this.available.getSize().height;
|
||||
}
|
||||
|
||||
if (!this.craftingNeeded.isEmpty()) {
|
||||
this.craftingNeeded.draw(x, y);
|
||||
y += this.craftingNeeded.getSize().height;
|
||||
}
|
||||
|
||||
if (!this.outputs.isEmpty()) {
|
||||
this.outputs.draw(x, y);
|
||||
y += this.outputs.getSize().height;
|
||||
@@ -286,6 +307,11 @@ public class RecipeChainTooltipLineHandler implements ITooltipLineHandler {
|
||||
y += this.inputs.getSize().height;
|
||||
}
|
||||
|
||||
if (!this.craftingNeeded.isEmpty()) {
|
||||
this.craftingNeeded.draw(x, y);
|
||||
y += this.craftingNeeded.getSize().height;
|
||||
}
|
||||
|
||||
if (!this.available.isEmpty()) {
|
||||
this.available.draw(x, y);
|
||||
y += this.available.getSize().height;
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package codechicken.nei.recipe.debug;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import codechicken.nei.Button;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
|
||||
public class CheckboxWidget extends Button implements IUpdatableWidget {
|
||||
|
||||
protected Consumer<CheckboxWidget> onChange;
|
||||
protected boolean value;
|
||||
|
||||
public CheckboxWidget(Consumer<CheckboxWidget> onChange) {
|
||||
super();
|
||||
this.onChange = onChange;
|
||||
this.h = 16;
|
||||
this.z = 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRenderLabel() {
|
||||
return this.value ? NEIClientUtils.translate("debug.RecipeHandler.checkbox.on")
|
||||
: NEIClientUtils.translate("debug.RecipeHandler.checkbox.off");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onButtonPress(boolean rightclick) {
|
||||
this.value = !this.value;
|
||||
onChange.accept(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void updateValue(String newValue) {
|
||||
this.value = Boolean.parseBoolean(newValue);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,618 @@
|
||||
package codechicken.nei.recipe.debug;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
import codechicken.nei.ClientHandler;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.Widget;
|
||||
import codechicken.nei.drawable.DrawableBuilder;
|
||||
import codechicken.nei.drawable.DrawableResource;
|
||||
import codechicken.nei.recipe.GuiRecipe;
|
||||
import codechicken.nei.recipe.GuiRecipeButton;
|
||||
import codechicken.nei.recipe.GuiRecipeTab;
|
||||
import codechicken.nei.recipe.HandlerInfo;
|
||||
import codechicken.nei.recipe.IRecipeHandler;
|
||||
import codechicken.nei.recipe.NEIRecipeWidget;
|
||||
import codechicken.nei.recipe.TemplateRecipeHandler;
|
||||
import codechicken.nei.recipe.TemplateRecipeHandler.RecipeTransferRect;
|
||||
import codechicken.nei.scroll.ScrollContainer;
|
||||
|
||||
public class DebugHandlerWidget extends Widget {
|
||||
|
||||
private static class HandlerInfoRecord {
|
||||
|
||||
public String handlerKey;
|
||||
public int yShift;
|
||||
public int width;
|
||||
public int height;
|
||||
public boolean multiWidgets;
|
||||
public int order;
|
||||
public boolean useCustomScroll;
|
||||
public boolean showFavorites;
|
||||
public boolean showOverlay;
|
||||
|
||||
private String csvLine;
|
||||
|
||||
public HandlerInfoRecord(String handlerKey, HandlerInfo info) {
|
||||
this.handlerKey = handlerKey;
|
||||
this.yShift = info.getYShift();
|
||||
this.width = info.getWidth();
|
||||
this.height = info.getHeight();
|
||||
this.multiWidgets = info.isMultipleWidgetsAllowed();
|
||||
this.order = NEIClientConfig.handlerOrdering.getOrDefault(handlerKey, 0);
|
||||
this.useCustomScroll = info.getUseCustomScroll();
|
||||
this.showFavorites = info.getShowFavoritesButton();
|
||||
this.showOverlay = info.getShowOverlayButton();
|
||||
this.csvLine = toCsvLine();
|
||||
}
|
||||
|
||||
public void applyTo(HandlerInfo info) {
|
||||
info.setYShift(this.yShift);
|
||||
info.setHandlerDimensions(this.width, this.height);
|
||||
info.setMultipleWidgetsAllowed(this.multiWidgets);
|
||||
info.setUseCustomScroll(this.useCustomScroll);
|
||||
info.setShowFavoritesButton(this.showFavorites);
|
||||
info.setShowOverlayButton(this.showOverlay);
|
||||
NEIClientConfig.handlerOrdering.put(this.handlerKey, this.order);
|
||||
}
|
||||
|
||||
public String toCsvLine() {
|
||||
return String.join(
|
||||
",",
|
||||
handlerKey,
|
||||
String.valueOf(yShift),
|
||||
String.valueOf(height),
|
||||
String.valueOf(width),
|
||||
String.valueOf(multiWidgets ? 1 : 0),
|
||||
String.valueOf(order),
|
||||
String.valueOf(useCustomScroll ? 1 : 0),
|
||||
String.valueOf(showFavorites ? 1 : 0),
|
||||
String.valueOf(showOverlay ? 1 : 0));
|
||||
}
|
||||
|
||||
public boolean isUnmodified() {
|
||||
return this.csvLine.equals(this.toCsvLine());
|
||||
}
|
||||
}
|
||||
|
||||
private static final int WINDOW_WIDTH = 176;
|
||||
private static final int LINE_HEIGHT = 16;
|
||||
private static final int INLINE_PADDING = 6;
|
||||
private static final int LABEL_WIDTH = 50;
|
||||
|
||||
private static final String TOOLTIP_PREFIX = "debug.RecipeHandler.";
|
||||
private static final String HEADER = "HandlerId,YShift,Height,Width,MultiWidgets,Order,UseCustomScroll,ShowFavorites,ShowOverlay";
|
||||
private final int[] COLORS = new int[] { 0x2200FF00, 0x22FF0000, 0x220000FF, 0x2200FFFF, 0x22FF00FF, 0x22FFFF00 };
|
||||
|
||||
public static DebugHandlerWidget instance = new DebugHandlerWidget();
|
||||
|
||||
private ScrollContainer container = new ScrollContainer();
|
||||
private final Map<String, IUpdatableWidget> values = new LinkedHashMap<>();
|
||||
private Map<String, HandlerInfoRecord> patches = new HashMap<>();
|
||||
|
||||
private IRecipeHandler handler;
|
||||
private HandlerInfo handlerInfo;
|
||||
private HandlerInfoRecord record;
|
||||
|
||||
private Point dragPoint = null;
|
||||
private boolean showWidget = false;
|
||||
|
||||
private final DrawableResource BG_TEXTURE = new DrawableBuilder(
|
||||
"nei:textures/gui/recipebg.png",
|
||||
0,
|
||||
0,
|
||||
176 + TRANSPARENCY_BORDER * 2,
|
||||
166 + TRANSPARENCY_BORDER * 2).build();
|
||||
private static final int BORDER_PADDING = 6;
|
||||
private static final int TRANSPARENCY_BORDER = 4;
|
||||
|
||||
public DebugHandlerWidget() {
|
||||
this.w = WINDOW_WIDTH;
|
||||
this.x = 10;
|
||||
this.y = 50;
|
||||
this.z = 4;
|
||||
|
||||
this.container.x = this.x + INLINE_PADDING;
|
||||
this.container.y = this.y + 5 + LINE_HEIGHT;
|
||||
this.container.w = this.w - INLINE_PADDING * 2;
|
||||
|
||||
int y = 0;
|
||||
y = addInfoWidget("Name", y);
|
||||
y = addInfoWidget("Id", y);
|
||||
y = addInfoWidget("Key", y);
|
||||
y = addInfoWidget("HHack", y);
|
||||
y = addInfoWidget("ModName", y);
|
||||
y = addInfoWidget("ModId", y);
|
||||
y = addInfoWidget("Override", y);
|
||||
|
||||
y = addTextFieldWidget("Order", 0, (field, oldText) -> {
|
||||
|
||||
if (field.getInteger() != record.order) {
|
||||
record.order = field.getInteger();
|
||||
saveHandlerInfoPatch();
|
||||
}
|
||||
|
||||
}, y);
|
||||
|
||||
y = addTextFieldWidget("yShift", 0, (field, oldText) -> {
|
||||
|
||||
if (field.getInteger() != handlerInfo.getYShift()) {
|
||||
handlerInfo.setYShift(field.getInteger());
|
||||
record.yShift = field.getInteger();
|
||||
saveHandlerInfoPatch();
|
||||
}
|
||||
|
||||
}, y);
|
||||
|
||||
y = addCheckboxWidget("MultiWidgets", button -> {
|
||||
handlerInfo.setMultipleWidgetsAllowed(button.value);
|
||||
record.multiWidgets = button.value;
|
||||
saveHandlerInfoPatch();
|
||||
}, y);
|
||||
|
||||
final LabelWidget readonly = new LabelWidget(0xffffff, true);
|
||||
|
||||
readonly.y = y;
|
||||
readonly.w = 57;
|
||||
readonly.x = this.w - INLINE_PADDING * 2 - readonly.w;
|
||||
this.values.put("height_readonly", readonly);
|
||||
|
||||
y = addTextFieldWidget("Height", HandlerInfo.DEFAULT_HEIGHT, (field, oldText) -> {
|
||||
|
||||
if (field.getInteger() != handlerInfo.getHeight()) {
|
||||
handlerInfo.setHandlerDimensions(handlerInfo.getWidth(), field.getInteger());
|
||||
record.height = field.getInteger();
|
||||
saveHandlerInfoPatch();
|
||||
}
|
||||
|
||||
}, y);
|
||||
|
||||
y = addTextFieldWidget("Width", HandlerInfo.DEFAULT_WIDTH, (field, oldText) -> {
|
||||
|
||||
if (field.getInteger() != handlerInfo.getWidth()) {
|
||||
handlerInfo.setHandlerDimensions(field.getInteger(), handlerInfo.getHeight());
|
||||
record.width = field.getInteger();
|
||||
saveHandlerInfoPatch();
|
||||
}
|
||||
|
||||
}, y);
|
||||
|
||||
y = addCheckboxWidget("UseCustomScroll", button -> {
|
||||
handlerInfo.setUseCustomScroll(button.value);
|
||||
record.useCustomScroll = button.value;
|
||||
saveHandlerInfoPatch();
|
||||
}, y);
|
||||
|
||||
y = addCheckboxWidget("ShowFavorites", button -> {
|
||||
handlerInfo.setShowFavoritesButton(button.value);
|
||||
record.showFavorites = button.value;
|
||||
saveHandlerInfoPatch();
|
||||
}, y);
|
||||
|
||||
y = addCheckboxWidget("ShowOverlay", button -> {
|
||||
handlerInfo.setShowOverlayButton(button.value);
|
||||
record.showOverlay = button.value;
|
||||
saveHandlerInfoPatch();
|
||||
}, y);
|
||||
|
||||
this.h = 10 + LINE_HEIGHT + y;
|
||||
this.container.h = this.h - INLINE_PADDING * 2 - LINE_HEIGHT;
|
||||
}
|
||||
|
||||
private int addInfoWidget(String key, int y) {
|
||||
final LabelWidget label = new LabelWidget(0x888888, false);
|
||||
final LabelWidget value = new LabelWidget(0xffffff, true);
|
||||
|
||||
label.y = value.y = y;
|
||||
label.w = LABEL_WIDTH;
|
||||
value.x = LABEL_WIDTH + 5;
|
||||
value.w = this.w - INLINE_PADDING * 2 - value.x;
|
||||
|
||||
label.updateValue(NEIClientUtils.translate(TOOLTIP_PREFIX + key));
|
||||
|
||||
this.container.addWidget(label);
|
||||
this.container.addWidget(value);
|
||||
this.values.put(key.toLowerCase(), value);
|
||||
|
||||
return y + value.h + 1;
|
||||
}
|
||||
|
||||
private int addTextFieldWidget(String key, int defaultValue, BiConsumer<IntegerField, String> onChange, int y) {
|
||||
final LabelWidget label = new LabelWidget(0x888888, false);
|
||||
final IntegerField value = new IntegerField(key, onChange, defaultValue);
|
||||
|
||||
label.y = value.y = y;
|
||||
value.w = 60;
|
||||
value.x = this.w - INLINE_PADDING * 2 - value.w;
|
||||
label.w = value.x;
|
||||
|
||||
label.updateValue(NEIClientUtils.translate(TOOLTIP_PREFIX + key));
|
||||
|
||||
this.container.addWidget(label);
|
||||
this.container.addWidget(value);
|
||||
|
||||
this.values.put(key.toLowerCase(), value);
|
||||
|
||||
return y + value.h + 1;
|
||||
}
|
||||
|
||||
private int addCheckboxWidget(String key, Consumer<CheckboxWidget> onChange, int y) {
|
||||
final LabelWidget label = new LabelWidget(0x888888, false);
|
||||
final CheckboxWidget value = new CheckboxWidget(onChange);
|
||||
|
||||
label.y = value.y = y;
|
||||
value.w = 58;
|
||||
value.x = this.w - INLINE_PADDING * 2 - value.w - 1;
|
||||
label.w = value.x;
|
||||
|
||||
label.updateValue(NEIClientUtils.translate(TOOLTIP_PREFIX + key));
|
||||
|
||||
this.container.addWidget(label);
|
||||
this.container.addWidget(value);
|
||||
this.values.put(key.toLowerCase(), value);
|
||||
|
||||
return y + value.h + 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int mx, int my) {
|
||||
|
||||
if (this.handler != null) {
|
||||
GL11.glColor4f(1F, 1F, 1F, 1F);
|
||||
GL11.glScaled(1, 1, 2f);
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST);
|
||||
BG_TEXTURE.draw(
|
||||
this.x - TRANSPARENCY_BORDER,
|
||||
this.y - TRANSPARENCY_BORDER,
|
||||
this.w + TRANSPARENCY_BORDER * 2,
|
||||
this.h + TRANSPARENCY_BORDER * 2,
|
||||
BORDER_PADDING + TRANSPARENCY_BORDER,
|
||||
BORDER_PADDING + TRANSPARENCY_BORDER,
|
||||
BORDER_PADDING + TRANSPARENCY_BORDER,
|
||||
BORDER_PADDING + TRANSPARENCY_BORDER);
|
||||
GuiDraw.drawRect(
|
||||
this.x + INLINE_PADDING,
|
||||
this.y + BORDER_PADDING,
|
||||
this.w - INLINE_PADDING * 2,
|
||||
12,
|
||||
0x30000000);
|
||||
GuiDraw.drawStringC(
|
||||
NEIClientUtils.translate("debug.RecipeHandler.title"),
|
||||
this.x + this.w / 2,
|
||||
this.y + BORDER_PADDING + 2,
|
||||
0xffffff);
|
||||
|
||||
this.container.draw(mx, my);
|
||||
|
||||
GL11.glScaled(1, 1, 1 / 2f);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
final GuiContainer gui = NEIClientUtils.getGuiContainer();
|
||||
|
||||
if (this.showWidget && gui instanceof GuiRecipe recipe) {
|
||||
|
||||
if (this.handler != recipe.getHandler()) {
|
||||
this.handler = recipe.getHandler();
|
||||
this.handlerInfo = GuiRecipeTab.getHandlerInfo(handler);
|
||||
this.record = this.patches.computeIfAbsent(
|
||||
getHandlerID(handler),
|
||||
handlerKey -> new HandlerInfoRecord(handlerKey, handlerInfo));
|
||||
|
||||
final boolean isHeightHackApplied = NEIClientConfig.heightHackHandlerRegex.stream()
|
||||
.map(pattern -> pattern.matcher(this.handler.getHandlerId())).anyMatch(Matcher::matches);
|
||||
|
||||
this.values.get("name").updateValue(this.handler.getRecipeName());
|
||||
this.values.get("id").updateValue(this.handler.getOverlayIdentifier());
|
||||
this.values.get("key").updateValue(this.handler.getHandlerId());
|
||||
this.values.get("hhack").updateValue(
|
||||
isHeightHackApplied ? NEIClientUtils.translate("debug.RecipeHandler.yes")
|
||||
: NEIClientUtils.translate("debug.RecipeHandler.no"));
|
||||
this.values.get("modname").updateValue(this.handlerInfo.getModName());
|
||||
this.values.get("modid").updateValue(this.handlerInfo.getModId());
|
||||
|
||||
this.values.get("order").updateValue(String.valueOf(this.record.order));
|
||||
this.values.get("yshift").updateValue(String.valueOf(this.record.yShift));
|
||||
this.values.get("height").updateValue(String.valueOf(this.record.height));
|
||||
this.values.get("height_readonly").updateValue(String.valueOf(this.record.height));
|
||||
this.values.get("width").updateValue(String.valueOf(this.record.width));
|
||||
|
||||
this.values.get("multiwidgets").updateValue(String.valueOf(this.record.multiWidgets));
|
||||
this.values.get("usecustomscroll").updateValue(String.valueOf(this.record.useCustomScroll));
|
||||
|
||||
this.values.get("showfavorites").updateValue(String.valueOf(this.record.showFavorites));
|
||||
this.values.get("showoverlay").updateValue(String.valueOf(this.record.showOverlay));
|
||||
|
||||
this.values.get("override").updateValue(
|
||||
this.record.isUnmodified() ? NEIClientUtils.translate("debug.RecipeHandler.no")
|
||||
: NEIClientUtils.translate("debug.RecipeHandler.yes"));
|
||||
|
||||
this.container.removeIf(
|
||||
widget -> this.values.get("height") == widget || this.values.get("height_readonly") == widget);
|
||||
if (handler.getRecipeHeight(0) > 0) {
|
||||
this.container.addWidget((Widget) this.values.get("height_readonly"));
|
||||
} else {
|
||||
this.container.addWidget((Widget) this.values.get("height"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
this.handler = null;
|
||||
this.record = null;
|
||||
this.handlerInfo = null;
|
||||
this.showWidget = false;
|
||||
}
|
||||
|
||||
this.container.update();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> handleTooltip(int mx, int my, List<String> tooltip) {
|
||||
return this.handler != null ? this.container.handleTooltip(mx, my, tooltip) : tooltip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> handleHotkeys(int mousex, int mousey, Map<String, String> hotkeys) {
|
||||
return this.handler != null ? this.container.handleHotkeys(mousex, mousey, hotkeys) : hotkeys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleKeyPress(int keyID, char keyChar) {
|
||||
|
||||
if (NEIClientConfig.getBooleanSetting("inventory.guirecipe.handlerInfo") && keyID == Keyboard.KEY_D
|
||||
&& NEIClientUtils.shiftKey()) {
|
||||
this.showWidget = !this.showWidget;
|
||||
return true;
|
||||
} else if (this.handler != null) {
|
||||
|
||||
if (this.container.handleKeyPress(keyID, keyChar)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
this.container.lastKeyTyped(keyID, keyChar);
|
||||
|
||||
return this.container.isFocused();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuiClick(int mx, int my) {
|
||||
if (this.handler != null) {
|
||||
this.container.onGuiClick(mx, my);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleClick(int mx, int my, int button) {
|
||||
|
||||
if (this.handler != null) {
|
||||
|
||||
if (new Rectangle4i(this.x + INLINE_PADDING, this.y + BORDER_PADDING, this.w - INLINE_PADDING * 2, 12)
|
||||
.contains(mx, my)) {
|
||||
this.dragPoint = new Point(mx, my);
|
||||
}
|
||||
|
||||
this.container.handleClick(mx, my, button);
|
||||
}
|
||||
|
||||
return this.handler != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(int px, int py) {
|
||||
return this.handler != null && super.contains(px, py);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseUp(int mx, int my, int button) {
|
||||
this.dragPoint = null;
|
||||
|
||||
if (this.handler != null) {
|
||||
this.container.mouseUp(mx, my, button);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMouseWheel(int scrolled, int mousex, int mousey) {
|
||||
|
||||
if (this.handler != null && contains(mousex, mousey)) {
|
||||
this.container.onMouseWheel(scrolled, mousex, mousey);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleClickExt(int mx, int my, int button) {
|
||||
return this.handler != null && this.container.handleClickExt(mx, my, button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(int mx, int my, int button, long heldTime) {
|
||||
if (this.dragPoint != null) {
|
||||
this.x -= this.dragPoint.x - mx;
|
||||
this.y -= this.dragPoint.y - my;
|
||||
|
||||
this.container.y = this.y + INLINE_PADDING + LINE_HEIGHT;
|
||||
this.container.x = this.x + INLINE_PADDING;
|
||||
|
||||
this.dragPoint.move(mx, my);
|
||||
}
|
||||
}
|
||||
|
||||
public void drawGuiPlaceholder(NEIRecipeWidget widget) {
|
||||
if (!this.showWidget) return;
|
||||
|
||||
NEIClientUtils.gl2DRenderContext(() -> {
|
||||
|
||||
// background
|
||||
GuiDraw.drawRect(
|
||||
widget.x,
|
||||
widget.y,
|
||||
widget.w,
|
||||
widget.h,
|
||||
COLORS[widget.getRecipeHandlerRef().recipeIndex % COLORS.length]);
|
||||
|
||||
// center cross
|
||||
GuiDraw.drawRect(widget.x + widget.w / 2 - 1, widget.y, 1, widget.h, 0x88ffffff);
|
||||
GuiDraw.drawRect(widget.x, widget.y + widget.h / 2 - 1, widget.w, 1, 0x88ffffff);
|
||||
|
||||
// blue-line-top (grid-top)
|
||||
GuiDraw.drawRect(widget.x + 14, widget.y + 5, widget.w - 38, 1, 0xff0000aa);
|
||||
|
||||
// blue-line-bottom {grid-bottom}
|
||||
GuiDraw.drawRect(widget.x + 14, widget.y + widget.h - 7, widget.w - 38, 1, 0xff0000aa);
|
||||
|
||||
// blue-left (grid start)
|
||||
GuiDraw.drawRect(widget.x + 24, widget.y + (widget.h - 16) / 2, 1, 16, 0xffaa00aa);
|
||||
|
||||
// purple (before favorite)
|
||||
GuiDraw.drawRect(
|
||||
widget.x + Math.min(168, widget.w) - 27,
|
||||
widget.y + widget.h - 6 - GuiRecipeButton.BUTTON_HEIGHT * 2 - 4,
|
||||
GuiRecipeButton.BUTTON_WIDTH,
|
||||
1,
|
||||
0xffaa00aa);
|
||||
|
||||
// green ()
|
||||
GuiDraw.drawRect(
|
||||
widget.x + Math.min(168, widget.w) - 35,
|
||||
widget.y + widget.h - 6 - GuiRecipeButton.BUTTON_HEIGHT - 3,
|
||||
20,
|
||||
1,
|
||||
0xff00aa00);
|
||||
|
||||
// purple space before bottom grid
|
||||
GuiDraw.drawRect(
|
||||
widget.x + 14,
|
||||
widget.y + widget.h - 7 - GuiRecipeButton.BUTTON_WIDTH / 2,
|
||||
38,
|
||||
1,
|
||||
0xffaa00aa);
|
||||
|
||||
if (widget.getRecipeHandlerRef().handler instanceof TemplateRecipeHandler handler) {
|
||||
int yShift = widget.getHandlerInfo().getYShift();
|
||||
|
||||
for (RecipeTransferRect rect : handler.transferRects) {
|
||||
GuiDraw.drawRect(
|
||||
widget.x + rect.getRect().x,
|
||||
widget.y + yShift + rect.getRect().y,
|
||||
rect.getRect().width,
|
||||
rect.getRect().height,
|
||||
0x40ff0000);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
public void loadHandlerInfoPatch() {
|
||||
|
||||
ClientHandler.loadSettingsFile("handlers.patch", lines -> {
|
||||
|
||||
for (String line : lines.collect(Collectors.toCollection(HashSet::new))) {
|
||||
if (HEADER.equals(line)) continue;
|
||||
final String[] parts = Arrays.copyOf((line + ",null,null,null,null,null,null,null,null").split(","), 9);
|
||||
final String handler = parts[0];
|
||||
|
||||
if (GuiRecipeTab.handlerMap.containsKey(handler)) {
|
||||
final HandlerInfo info = GuiRecipeTab.handlerMap.get(handler);
|
||||
final HandlerInfoRecord record = patches
|
||||
.computeIfAbsent(handler, handlerKey -> new HandlerInfoRecord(handler, info));
|
||||
|
||||
record.yShift = intOrDefault(parts[1], info.getYShift());
|
||||
record.height = intOrDefault(parts[2], info.getHeight());
|
||||
record.width = intOrDefault(parts[3], info.getWidth());
|
||||
record.multiWidgets = intOrDefault(parts[4], info.isMultipleWidgetsAllowed() ? 1 : 0) == 1;
|
||||
record.order = intOrDefault(parts[5], NEIClientConfig.handlerOrdering.getOrDefault(handler, 0));
|
||||
record.useCustomScroll = intOrDefault(parts[6], info.getUseCustomScroll() ? 1 : 0) == 1;
|
||||
record.showFavorites = intOrDefault(parts[7], info.getShowFavoritesButton() ? 1 : 0) == 1;
|
||||
record.showOverlay = intOrDefault(parts[8], info.getShowOverlayButton() ? 1 : 0) == 1;
|
||||
|
||||
record.applyTo(info);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void saveHandlerInfoPatch() {
|
||||
final List<String> lines = new ArrayList<>();
|
||||
lines.add(HEADER);
|
||||
|
||||
for (HandlerInfoRecord record : patches.values()) {
|
||||
if (!record.csvLine.equals(record.toCsvLine())) {
|
||||
lines.add(record.toCsvLine());
|
||||
}
|
||||
}
|
||||
|
||||
final File path = new File(NEIClientConfig.configDir, "handlers.patch");
|
||||
|
||||
try (FileOutputStream output = new FileOutputStream(path)) {
|
||||
IOUtils.writeLines(lines, "\n", output, StandardCharsets.UTF_8);
|
||||
} catch (IOException e) {}
|
||||
|
||||
if (this.record != null) {
|
||||
this.values.get("override").updateValue(
|
||||
this.record.isUnmodified() ? NEIClientUtils.translate("debug.RecipeHandler.no")
|
||||
: NEIClientUtils.translate("debug.RecipeHandler.yes"));
|
||||
}
|
||||
|
||||
if (NEIClientUtils.getGuiContainer() instanceof GuiRecipe<?>recipe) {
|
||||
recipe.forceRefreshPage();
|
||||
}
|
||||
}
|
||||
|
||||
private int intOrDefault(String str, int defaultValue) {
|
||||
if (str == null || str.isEmpty()) return defaultValue;
|
||||
try {
|
||||
return Integer.parseInt(str);
|
||||
} catch (NumberFormatException e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
private String getHandlerID(IRecipeHandler handler) {
|
||||
|
||||
if (GuiRecipeTab.handlerMap.containsKey(handler.getHandlerId())) {
|
||||
return handler.getHandlerId();
|
||||
} else if (handler instanceof TemplateRecipeHandler) {
|
||||
return handler.getOverlayIdentifier();
|
||||
}
|
||||
|
||||
return handler.getHandlerId();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package codechicken.nei.recipe.debug;
|
||||
|
||||
public interface IUpdatableWidget {
|
||||
|
||||
public void updateValue(String newValue);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package codechicken.nei.recipe.debug;
|
||||
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
import codechicken.nei.FormattedTextField;
|
||||
import codechicken.nei.TextField;
|
||||
|
||||
public class IntegerField extends TextField implements IUpdatableWidget {
|
||||
|
||||
protected int defaultValue = 0;
|
||||
protected BiConsumer<IntegerField, String> onChange;
|
||||
|
||||
public IntegerField(String ident, BiConsumer<IntegerField, String> onChange, int defaultValue) {
|
||||
super(ident);
|
||||
this.onChange = onChange;
|
||||
this.defaultValue = defaultValue;
|
||||
this.h = 16;
|
||||
this.z = 2;
|
||||
((FormattedTextField) field).setPlaceholder(Integer.toString(this.defaultValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initInternalTextField() {
|
||||
field = new FormattedTextField(Minecraft.getMinecraft().fontRenderer, 0, 0, 0, 0) {
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
final String text = super.getText();
|
||||
return !isFocused() && this.placeholder.equals(text) ? "" : text;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean beforeWrite(String text) {
|
||||
if (text == null || text.isEmpty()) return true;
|
||||
try {
|
||||
Integer.parseInt(text);
|
||||
return true;
|
||||
} catch (NumberFormatException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean textboxKeyTyped(char keyChar, int keyID) {
|
||||
|
||||
if (!isFocused()) return false;
|
||||
|
||||
if (super.textboxKeyTyped(keyChar, keyID)) {
|
||||
return true;
|
||||
} else if (keyID == Keyboard.KEY_DOWN) {
|
||||
setText(Integer.toString(getInteger() - 1));
|
||||
return true;
|
||||
} else if (keyID == Keyboard.KEY_UP) {
|
||||
setText(Integer.toString(getInteger() + 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
field.setMaxStringLength(maxSearchLength);
|
||||
field.setCursorPositionZero();
|
||||
}
|
||||
|
||||
protected int getInteger() {
|
||||
try {
|
||||
return Integer.parseInt(text());
|
||||
} catch (NumberFormatException nfe) {
|
||||
return this.defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMouseWheel(int i, int mx, int my) {
|
||||
if (!contains(mx, my)) return false;
|
||||
setText(Integer.toString(getInteger() + i));
|
||||
return true;
|
||||
}
|
||||
|
||||
public void updateValue(String newValue) {
|
||||
setText(newValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChange(String oldText) {
|
||||
onChange.accept(this, oldText);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package codechicken.nei.recipe.debug;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.Widget;
|
||||
import codechicken.nei.util.NEIMouseUtils;
|
||||
|
||||
public class LabelWidget extends Widget implements IUpdatableWidget {
|
||||
|
||||
protected int color;
|
||||
protected boolean shadow;
|
||||
protected String value = "";
|
||||
protected String croppedValue;
|
||||
|
||||
public LabelWidget(int color, boolean shadow) {
|
||||
this.color = color;
|
||||
this.shadow = shadow;
|
||||
this.h = 16;
|
||||
this.z = 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int mx, int my) {
|
||||
GuiDraw.drawString(this.croppedValue, this.x, this.y + (this.h - 8) / 2, this.color, this.shadow);
|
||||
}
|
||||
|
||||
public void updateValue(String newValue) {
|
||||
this.value = newValue;
|
||||
this.croppedValue = NEIClientUtils.cropText(GuiDraw.fontRenderer, this.value, this.w);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> handleTooltip(int mx, int my, List<String> tooltip) {
|
||||
|
||||
if (contains(mx, my)) {
|
||||
tooltip.add(this.value);
|
||||
}
|
||||
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleKeyPress(int keyID, char keyChar) {
|
||||
final Point mouse = GuiDraw.getMousePosition();
|
||||
|
||||
if (contains(mouse.x, mouse.y) && Keyboard.KEY_C == keyID && NEIClientUtils.controlKey()) {
|
||||
GuiScreen.setClipboardString(this.value);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> handleHotkeys(int mousex, int mousey, Map<String, String> hotkeys) {
|
||||
|
||||
if (contains(mousex, mousey)) {
|
||||
hotkeys.put(
|
||||
NEIClientUtils.getKeyName(NEIClientUtils.CTRL_HASH + Keyboard.KEY_C, NEIMouseUtils.MOUSE_BTN_NONE),
|
||||
NEIClientUtils.translate("debug.RecipeHandler.copy"));
|
||||
}
|
||||
|
||||
return hotkeys;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -112,7 +112,8 @@ public class GTFluidStackStringifyHandler implements IStackStringifyHandler {
|
||||
|
||||
public ItemStack normalizeRecipeQueryStack(ItemStack stack) {
|
||||
|
||||
if (stack.getItem() == GameRegistry.findItem("ae2fc", "fluid_drop")) {
|
||||
if (stack.getItem() == GameRegistry.findItem("ae2fc", "fluid_drop")
|
||||
|| stack.getItem() == GameRegistry.findItem("ae2fc", "fluid_packet")) {
|
||||
final FluidStack fluidStack = getFluid(stack);
|
||||
|
||||
if (fluidStack != null) {
|
||||
|
||||
@@ -2,6 +2,7 @@ package codechicken.nei.scroll;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
@@ -38,7 +39,7 @@ public class ScrollContainer extends WidgetContainer {
|
||||
protected int paddingBlockStart = 0;
|
||||
protected int paddingBlockEnd = 0;
|
||||
|
||||
protected final Map<Widget, Point> relativePostion = new HashMap<>();
|
||||
protected final Map<Widget, Point> relativePosition = new HashMap<>();
|
||||
protected ScrollBar horizontalScrollBar;
|
||||
protected ScrollBar verticalScrollBar;
|
||||
protected int fade = 0;
|
||||
@@ -80,23 +81,40 @@ public class ScrollContainer extends WidgetContainer {
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
|
||||
for (Map.Entry<Widget, Point> entry : this.relativePosition.entrySet()) {
|
||||
entry.getKey().x = entry.getValue().x;
|
||||
entry.getKey().y = entry.getValue().y;
|
||||
}
|
||||
|
||||
super.clear();
|
||||
this.relativePostion.clear();
|
||||
this.relativePosition.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeIf(Predicate<Widget> filter) {
|
||||
this.relativePostion.keySet().removeIf(filter);
|
||||
final Iterator<Map.Entry<Widget, Point>> it = this.relativePosition.entrySet().iterator();
|
||||
|
||||
while (it.hasNext()) {
|
||||
final Map.Entry<Widget, Point> entry = it.next();
|
||||
|
||||
if (filter.test(entry.getKey())) {
|
||||
entry.getKey().x = entry.getValue().x;
|
||||
entry.getKey().y = entry.getValue().y;
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
|
||||
return super.removeIf(filter);
|
||||
}
|
||||
|
||||
public void addWidget(Widget widget) {
|
||||
super.addWidget(widget);
|
||||
this.relativePostion.put(widget, new Point(widget.x, widget.y));
|
||||
this.relativePosition.put(widget, new Point(widget.x, widget.y));
|
||||
}
|
||||
|
||||
public Point getWidgetPosition(Widget widget) {
|
||||
return this.relativePostion.get(widget);
|
||||
return this.relativePosition.get(widget);
|
||||
}
|
||||
|
||||
public void setPaddingInline(int start, int end) {
|
||||
@@ -275,7 +293,7 @@ public class ScrollContainer extends WidgetContainer {
|
||||
this.actualHeight = 0;
|
||||
this.actualWidth = 0;
|
||||
|
||||
for (Map.Entry<Widget, Point> entry : this.relativePostion.entrySet()) {
|
||||
for (Map.Entry<Widget, Point> entry : this.relativePosition.entrySet()) {
|
||||
entry.getKey().x = entry.getValue().x;
|
||||
entry.getKey().y = entry.getValue().y;
|
||||
}
|
||||
@@ -385,6 +403,10 @@ public class ScrollContainer extends WidgetContainer {
|
||||
@Override
|
||||
public boolean handleKeyPress(int keyCode, char keyChar) {
|
||||
|
||||
if (super.handleKeyPress(keyCode, keyChar)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.isFocused()) {
|
||||
switch (keyCode) {
|
||||
case Keyboard.KEY_UP:
|
||||
@@ -402,7 +424,7 @@ public class ScrollContainer extends WidgetContainer {
|
||||
}
|
||||
}
|
||||
|
||||
return super.handleKeyPress(keyCode, keyChar);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
package codechicken.nei.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.fluids.Fluid;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
import codechicken.nei.NEIServerUtils;
|
||||
import codechicken.nei.recipe.Recipe.RecipeId;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
|
||||
public class FavoriteStorage {
|
||||
|
||||
protected final Map<NBTTagCompound, RecipeId> itemStackToRecipeId = new HashMap<>();
|
||||
protected final Map<RecipeId, NBTTagCompound> recipeIdToItemStack = new HashMap<>();
|
||||
protected final Map<Fluid, RecipeId> fluidToRecipeId = new IdentityHashMap<>();
|
||||
|
||||
protected final Map<Long, RecipeId> itemHashToRecipeId = new HashMap<>();
|
||||
protected final Map<RecipeId, Long> recipeIdToItemHash = new HashMap<>();
|
||||
protected final Map<Long, ItemStack> itemHashToItemStack = new HashMap<>();
|
||||
|
||||
public void clear() {
|
||||
this.itemStackToRecipeId.clear();
|
||||
this.fluidToRecipeId.clear();
|
||||
this.recipeIdToItemStack.clear();
|
||||
this.itemHashToRecipeId.clear();
|
||||
this.recipeIdToItemHash.clear();
|
||||
this.itemHashToItemStack.clear();
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.itemStackToRecipeId.size() + this.itemHashToRecipeId.size();
|
||||
}
|
||||
|
||||
public void removeItemStack(ItemStack stack) {
|
||||
final RecipeId recipeId = getRecipeId(stack);
|
||||
|
||||
if (recipeId != null) {
|
||||
removeRecipeId(recipeId);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeRecipeId(RecipeId recipeId) {
|
||||
this.recipeIdToItemStack.remove(recipeId);
|
||||
this.fluidToRecipeId.values().removeIf(recipeId::equals);
|
||||
this.itemStackToRecipeId.values().removeIf(recipeId::equals);
|
||||
this.itemHashToRecipeId.values().removeIf(recipeId::equals);
|
||||
this.itemHashToItemStack.remove(this.recipeIdToItemHash.get(recipeId));
|
||||
this.recipeIdToItemHash.remove(recipeId);
|
||||
}
|
||||
|
||||
public void add(ItemStack stack, RecipeId recipeId) {
|
||||
|
||||
if (!stack.hasTagCompound() || NEIServerUtils.isItemTool(stack)) {
|
||||
long key = getItemKey(stack);
|
||||
this.itemHashToRecipeId.put(key, recipeId);
|
||||
this.recipeIdToItemHash.put(recipeId, key);
|
||||
this.itemHashToItemStack.put(key, stack);
|
||||
} else {
|
||||
final NBTTagCompound itemStackNBT = StackInfo.itemStackToNBT(stack, false);
|
||||
final Fluid fluidKey = getFluidKey(stack);
|
||||
|
||||
if (fluidKey != null) {
|
||||
this.fluidToRecipeId.put(fluidKey, recipeId);
|
||||
}
|
||||
|
||||
this.itemStackToRecipeId.put(itemStackNBT, recipeId);
|
||||
this.recipeIdToItemStack.put(recipeId, itemStackNBT);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private long getItemKey(ItemStack stack) {
|
||||
return ((long) Item.getIdFromItem(stack.getItem()) << 32) | (stack.getItemDamage() & 0xFFFFFFFFL);
|
||||
}
|
||||
|
||||
private Fluid getFluidKey(ItemStack stack) {
|
||||
final FluidStack fluid = StackInfo.getFluid(stack);
|
||||
|
||||
if (fluid != null) {
|
||||
return fluid.getFluid();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public RecipeId getRecipeId(ItemStack stack) {
|
||||
RecipeId recipeId = this.itemHashToRecipeId.get(getItemKey(stack));
|
||||
|
||||
if (recipeId == null) {
|
||||
recipeId = this.itemStackToRecipeId.get(StackInfo.itemStackToNBT(stack, false));
|
||||
}
|
||||
|
||||
if (recipeId == null) {
|
||||
recipeId = this.fluidToRecipeId.get(getFluidKey(stack));
|
||||
}
|
||||
|
||||
return recipeId;
|
||||
}
|
||||
|
||||
public ItemStack getItemStack(RecipeId recipeId) {
|
||||
NBTTagCompound itemStackNBT = this.recipeIdToItemStack.get(recipeId);
|
||||
|
||||
if (itemStackNBT == null) {
|
||||
final Long key = this.recipeIdToItemHash.get(recipeId);
|
||||
if (key != null) {
|
||||
return this.itemHashToItemStack.get(key);
|
||||
}
|
||||
}
|
||||
|
||||
if (itemStackNBT != null) {
|
||||
return StackInfo.loadFromNBT(itemStackNBT);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean contains(ItemStack stack) {
|
||||
return getRecipeId(stack) != null;
|
||||
}
|
||||
|
||||
public List<Map.Entry<NBTTagCompound, RecipeId>> getAllFavorites() {
|
||||
final List<Map.Entry<NBTTagCompound, RecipeId>> entries = new ArrayList<>(this.itemStackToRecipeId.entrySet());
|
||||
|
||||
for (Map.Entry<Long, RecipeId> entry : this.itemHashToRecipeId.entrySet()) {
|
||||
final ItemStack stack = this.itemHashToItemStack.get(entry.getKey());
|
||||
if (stack != null) {
|
||||
entries.add(new HashMap.SimpleEntry<>(StackInfo.itemStackToNBT(stack, false), entry.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
}
|
||||
@@ -131,10 +131,6 @@ public class ItemUntranslator {
|
||||
private final Map<String, String> secondNames = new HashMap<>();
|
||||
private final Map<String, String> processedNames = new HashMap<>();
|
||||
|
||||
static {
|
||||
API.addSubset("Untranslated", item -> instance.getItemStackDisplayName(item).isEmpty());
|
||||
}
|
||||
|
||||
private ItemUntranslator() {}
|
||||
|
||||
public static ItemUntranslator getInstance() {
|
||||
@@ -363,12 +359,14 @@ public class ItemUntranslator {
|
||||
this.secondNames.clear();
|
||||
LanguageRegistryPatch.secondLanguageListCache = null;
|
||||
this.processedNames.clear();
|
||||
|
||||
SubsetWidget.removeTag("Untranslated");
|
||||
}
|
||||
|
||||
public void load() {
|
||||
unload();
|
||||
|
||||
this.secondNames.clear();
|
||||
LanguageRegistryPatch.secondLanguageListCache = null;
|
||||
this.processedNames.clear();
|
||||
|
||||
if (ClientHandler.loadSettingsFile(CONFIG_FILE, null, this::parseStream)
|
||||
|| ClientHandler.loadSettingsResource(CONFIG_FILE, this::parseStream)) {
|
||||
@@ -380,7 +378,7 @@ public class ItemUntranslator {
|
||||
this.secondNames.clear();
|
||||
}
|
||||
|
||||
SubsetWidget.updateHiddenItems();
|
||||
API.addSubset("Untranslated", item -> instance.getItemStackDisplayName(item).isEmpty());
|
||||
}
|
||||
|
||||
private void parseStream(Stream<String> lines) {
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
handler,modName,itemName,nbtInfo,modId,modRequired,excludedModId,yShift,handlerHeight,handlerWidth,maxRecipesPerPage,imageResource,imageX,imageY,imageWidth,imageHeight,itemNotes,useCustomScroll
|
||||
codechicken.nei.recipe.BrewingRecipeHandler,Minecraft,minecraft:brewing_stand,,minecraft,FALSE,,,65,166,5,,,,,,,
|
||||
codechicken.nei.recipe.FireworkRecipeHandler,Minecraft,minecraft:fireworks,,minecraft,FALSE,,,65,166,5,,,,,,,
|
||||
codechicken.nei.recipe.FurnaceRecipeHandler,Minecraft,minecraft:furnace,,minecraft,FALSE,,,65,166,5,,,,,,,
|
||||
codechicken.nei.recipe.ShapedRecipeHandler,Minecraft,minecraft:crafting_table,,minecraft,FALSE,,,65,166,5,,,,,,,
|
||||
codechicken.nei.recipe.ShapelessRecipeHandler,Minecraft,minecraft:crafting_table,,minecraft,FALSE,,,65,166,5,,,,,,,
|
||||
codechicken.nei.recipe.FuelRecipeHandler,Minecraft,,,minecraft,FALSE,,,65,166,5,nei:textures/nei_tabbed_sprites.png,80,0,14,14,,
|
||||
codechicken.nei.recipe.InformationHandler,Not Enough Items,,,nei,FALSE,,,65,166,1,nei:textures/nei_tabbed_sprites.png,96,0,16,16,,
|
||||
advsolar.client.nei.MTRecipeHandler,Advanced Solar Panels,AdvancedSolarPanel:BlockMolecularTransformer,,AdvancedSolarPanel,TRUE,,,68,,5,,,,,,,
|
||||
appeng.integration.modules.NEIHelpers.NEIAEShapedRecipeHandler,Applied Energistics 2,appliedenergistics2:item.ItemMultiPart:380,,appliedenergistics2,TRUE,,,65,,5,,,,,,,
|
||||
appeng.integration.modules.NEIHelpers.NEIAEShapelessRecipeHandler,Applied Energistics 2,appliedenergistics2:item.ItemMultiPart:380,,appliedenergistics2,TRUE,,,65,,5,,,,,,,
|
||||
@@ -13,8 +6,8 @@ appeng.integration.modules.NEIHelpers.NEIFacadeRecipeHandler,Applied Energistics
|
||||
appeng.integration.modules.NEIHelpers.NEIGrinderRecipeHandler,Applied Energistics 2,appliedenergistics2:tile.BlockGrinder,,appliedenergistics2,TRUE,,,,,,,,,,,,
|
||||
appeng.integration.modules.NEIHelpers.NEIInscriberRecipeHandler,Applied Energistics 2,appliedenergistics2:tile.BlockInscriber,,appliedenergistics2,TRUE,,,70,,5,,,,,,,
|
||||
appeng.integration.modules.NEIHelpers.NEIWorldCraftingHandler,Applied Energistics 2,appliedenergistics2:item.ItemMultiMaterial:9,,appliedenergistics2,TRUE,,,85,,5,,,,,,There's only some explanatory text for fluix crystals and QEDs,
|
||||
appeng.integration.modules.NEIHelpers.NEICellViewHandler,Applied Energistics 2,appliedenergistics2:item.ItemBasicStorageCell.64k,,appliedenergistics2,TRUE,,,180,,1,,,,,,,,
|
||||
com.glodblock.github.nei.NEICellViewHandler,AE2 Fluid Crafting,ae2fc:multi_fluid_storage64,,ae2fc,TRUE,,,,,1,,,,,,,,
|
||||
appeng.integration.modules.NEIHelpers.NEICellViewHandler,Applied Energistics 2,appliedenergistics2:item.ItemBasicStorageCell.64k,,appliedenergistics2,TRUE,,,180,,1,,,,,,,
|
||||
com.glodblock.github.nei.NEICellViewHandler,AE2 Fluid Crafting,ae2fc:multi_fluid_storage64,,ae2fc,TRUE,,,,,1,,,,,,,
|
||||
aroma1997.core.recipes.nei.ShapedAromicRecipeHandler,AromaBackup,minecraft:crafting_table,,AromaBackup,TRUE,,,65,,5,,,,,,,
|
||||
aroma1997.core.recipes.nei.ShapelessAromicRecipeHandler,AromaBackup,minecraft:crafting_table,,AromaBackup,TRUE,,,,,,,,,,,,
|
||||
fox.spiteful.avaritia.compat.nei.CompressionHandler,Avaritia,Avaritia:Neutronium_Compressor,,Avaritia,TRUE,,,50,,6,,,,,,,
|
||||
@@ -95,7 +88,7 @@ gt.recipe.alloysmelter,GregTech,gregtech:gt.blockmachines:201,,gregtech,TRUE,gre
|
||||
gt.recipe.arcfurnace,GregTech,gregtech:gt.blockmachines:651,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
|
||||
gt.recipe.assembler,GregTech,gregtech:gt.blockmachines:211,,gregtech,TRUE,gregapi_post,6,145,166,2,,,,,,,
|
||||
gt.recipe.autoclave,GregTech,gregtech:gt.blockmachines:571,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
|
||||
gt.recipe.blastfurnace,GregTech,gregtech:gt.blockmachines:1000,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
|
||||
gt.recipe.blastfurnace,GregTech,gregtech:gt.blockmachines:1000,,gregtech,TRUE,gregapi_post,6,135,166,2,nei:textures/multiblocks/electric_blast_furnace.png,80,0,14,18,,
|
||||
gt.recipe.brewer,GregTech,gregtech:gt.blockmachines:491,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
|
||||
gt.recipe.byproductlist,GregTech,gregtech:gt.metaitem.01:2019,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
|
||||
gt.recipe.canner,GregTech,gregtech:gt.blockmachines:231,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
|
||||
@@ -161,7 +154,7 @@ gt.recipe.thermalcentrifuge,GregTech,gregtech:gt.blockmachines:381,,gregtech,TRU
|
||||
gt.recipe.thermalgeneratorfuel,GregTech,IC2:blockGenerator:1,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
|
||||
gt.recipe.unpackager,GregTech,gregtech:gt.blockmachines:411,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
|
||||
gt.recipe.uuamplifier,GregTech,gregtech:gt.blockmachines:471,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
|
||||
gt.recipe.vacuumfreezer,GregTech,gregtech:gt.blockmachines:1002,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
|
||||
gt.recipe.vacuumfreezer,GregTech,gregtech:gt.blockmachines:1002,,gregtech,TRUE,gregapi_post,6,135,166,2,nei:textures/multiblocks/vacuum_freezer.png,80,0,12,12,,
|
||||
gt.recipe.wiremill,GregTech,gregtech:gt.blockmachines:351,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
|
||||
ic.recipe.recycler,GregTech,gregtech:gt.blockmachines:331,,gregtech,TRUE,gregapi_post,6,135,166,2,,,,,,,
|
||||
pers.gwyog.gtneioreplugin.plugin.gregtech5.PluginGT5SmallOreStat,GregTech,gregtech:gt.blockores:85,,gregtech,TRUE,,,145,,2,,,,,,,
|
||||
@@ -358,7 +351,7 @@ vazkii.botania.client.integration.nei.recipe.RecipeHandlerRunicAltar,Botania,Bot
|
||||
vazkii.botania.client.integration.nei.recipe.RecipeHandlerManaPool,Botania,Botania:pool,,Botania,TRUE,,,90,137,4,,,,,,,
|
||||
vazkii.botania.client.integration.nei.recipe.RecipeHandlerElvenTrade,Botania,Botania:alfheimPortal,,Botania,TRUE,,,90,130,4,,,,,,,
|
||||
vazkii.botania.client.integration.nei.recipe.RecipeHandlerBrewery,Botania,Botania:brewery,,Botania,TRUE,,,,,4,,,,,,,
|
||||
vazkii.botania.client.integration.nei.recipe.RecipeHandlerPureDaisy,Botania,Botania:specialFlower,"{type:puredaisy}",Botania,TRUE,,,,,4,,,,,,,
|
||||
vazkii.botania.client.integration.nei.recipe.RecipeHandlerPureDaisy,Botania,Botania:specialFlower,{type:puredaisy},Botania,TRUE,,,,,4,,,,,,,
|
||||
vazkii.botania.client.integration.nei.recipe.RecipeHandlerLexicaBotania,Botania,Botania:lexicon,,Botania,TRUE,,,,,,,,,,,,
|
||||
com.jaquadro.minecraft.storagedrawers.integration.notenoughitems.UpgradeItemRecipeHandler,Storage Drawers,minecraft:crafting_table,,StorageDrawers,TRUE,,,65,166,5,,,,,,,
|
||||
ieArcFurnace,Immersive Engineering,ImmersiveEngineering:graphiteElectrode,,ImmersiveEngineering,TRUE,,,65,166,5,,,,,,,
|
||||
@@ -535,7 +528,7 @@ vazkii.botania.client.integration.nei.RecipeHandlerRunicAltar,Botania,Botania:ru
|
||||
vazkii.botania.client.integration.nei.RecipeHandlerManaPool,Botania,Botania:pool,,Botania,TRUE,,,90,137,4,,,,,,,
|
||||
vazkii.botania.client.integration.nei.RecipeHandlerElvenTrade,Botania,Botania:alfheimPortal,,Botania,TRUE,,,90,130,4,,,,,,,
|
||||
vazkii.botania.client.integration.nei.RecipeHandlerBrewery,Botania,Botania:brewery,,Botania,TRUE,,,,,4,,,,,,,
|
||||
vazkii.botania.client.integration.nei.RecipeHandlerPureDaisy,Botania,Botania:specialFlower,"{type:puredaisy}",Botania,TRUE,,,,,4,,,,,,,
|
||||
vazkii.botania.client.integration.nei.RecipeHandlerPureDaisy,Botania,Botania:specialFlower,{type:puredaisy},Botania,TRUE,,,,,4,,,,,,,
|
||||
vazkii.botania.client.integration.nei.RecipeHandlerLexicaBotania,Botania,Botania:lexicon,,Botania,TRUE,,,,,,,,,,,,
|
||||
neiplugins.forge.OreDictionaryList,NEIPlugins,minecraft:book,,NEIPlugins,TRUE,,,,,,,,,,,,
|
||||
neiplugins.forge.FluidRegistryList,NEIPlugins,minecraft:bucket,,NEIPlugins,TRUE,,,,,,,,,,,,
|
||||
@@ -611,7 +604,7 @@ com.cout970.magneticraft.compat.nei.CraftingGrinder,Magneticraft,Magneticraft:gr
|
||||
com.cout970.magneticraft.compat.nei.CraftingPolymerizer,Magneticraft,Magneticraft:polimerizer_control,,Magneticraft,TRUE,,,,,,,,,,,,
|
||||
com.cout970.magneticraft.compat.nei.CraftingBiomassBurner,Magneticraft,Magneticraft:biomassburner,,Magneticraft,TRUE,,,,,,,,,,,,
|
||||
com.cout970.magneticraft.compat.nei.CraftingSifter,Magneticraft,Magneticraft:sifter_control,,Magneticraft,TRUE,,,,,,,,,,,,
|
||||
pneumaticCraft.common.thirdparty.nei.NEIRefineryManager,PneumaticCraft,PneumaticCraft:refinery,,PneumaticCraft,TRUE,,"",80,,4,,,,,,,
|
||||
pneumaticCraft.common.thirdparty.nei.NEIRefineryManager,PneumaticCraft,PneumaticCraft:refinery,,PneumaticCraft,TRUE,,,80,,4,,,,,,,
|
||||
pneumaticCraft.common.thirdparty.nei.NEIPlasticMixerManager,PneumaticCraft,PneumaticCraft:plasticMixer,,PneumaticCraft,TRUE,,,,,,,,,,,,
|
||||
pneumaticCraft.common.thirdparty.nei.NEIAmadronTradeManager,PneumaticCraft,PneumaticCraft:amadronTablet,,PneumaticCraft,TRUE,,,,,,,,,,,,
|
||||
pneumaticCraft.common.thirdparty.nei.NEIUVLightBoxManager,PneumaticCraft,PneumaticCraft:uvLightBox,,PneumaticCraft,TRUE,,,,,,,,,,,,
|
||||
@@ -621,7 +614,7 @@ pneumaticCraft.common.thirdparty.nei.NEIAssemblyControllerRecipeManager,Pneumati
|
||||
pneumaticCraft.common.thirdparty.nei.NEIPressureChamberRecipeManager,PneumaticCraft,PneumaticCraft:pressureChamberInterface,,PneumaticCraft,TRUE,,,130,,2,,,,,,,
|
||||
exter.foundry.integration.nei.InductionCrucibleFurnaceRecipeHandler,Foundry,foundry:foundryMachine:0,,foundry,TRUE,,,,,,,,,,,,
|
||||
exter.foundry.integration.nei.AlloyMixerRecipeHandler,Foundry,foundry:foundryMachine:2,,foundry,TRUE,,,,,,,,,,,,
|
||||
exter.foundry.integration.nei.MetalCasterRecipeHandler,Foundry,foundry:foundryMachine:1,"",foundry,TRUE,,,,,,,,,,,,
|
||||
exter.foundry.integration.nei.MetalCasterRecipeHandler,Foundry,foundry:foundryMachine:1,,foundry,TRUE,,,,,,,,,,,,
|
||||
exter.foundry.integration.nei.InfuserRecipeHandler,Foundry,foundry:foundryMachine:3,,foundry,TRUE,,,,,,,,,,,,
|
||||
exter.foundry.integration.nei.InfuserSubstanceRecipeHandler,Foundry,foundry:foundryMachine:3,,foundry,TRUE,,,,,,,,,,,,
|
||||
exter.foundry.integration.nei.AlloyFurnaceRecipeHandler,Foundry,foundry:alloyFurnace,,foundry,TRUE,,,,,,,,,,,,
|
||||
@@ -633,7 +626,7 @@ net.dries007.tfcnei.recipeHandlers.LoomRecipeHandler,TerraFirmaCraft,terrafirmac
|
||||
net.dries007.tfcnei.recipeHandlers.KnappingRecipeHandler,TerraFirmaCraft,terrafirmacraft:item.LooseRock,,terrafirmacraft,TRUE,,,96,166,3,,,,,,,
|
||||
net.dries007.tfcnei.recipeHandlers.BarrelRecipeHandler,TerraFirmaCraft,terrafirmacraft:Barrel,,terrafirmacraft,TRUE,,,65,166,5,,,,,,,
|
||||
net.dries007.tfcnei.recipeHandlers.AlloyRecipeHandler,TerraFirmaCraft,terrafirmacraft:Crucible,,terrafirmacraft,TRUE,,,65,166,5,,,,,,,
|
||||
net.dries007.tfcnei.recipeHandlers.HeatRecipeHandler,TerraFirmaCraft,terrafirmacraft:Firepit,,terrafirmacraft,TRUE,,,65,166,5,"",,,,,,
|
||||
net.dries007.tfcnei.recipeHandlers.HeatRecipeHandler,TerraFirmaCraft,terrafirmacraft:Firepit,,terrafirmacraft,TRUE,,,65,166,5,,,,,,,
|
||||
techreborn.compat.nei.FustionReacorRecipeHandler,TechReborn,techreborn:fusioncontrolcomputer,,techreborn,TRUE,,,,,,,,,,,,
|
||||
techreborn.compat.nei.recipes.VacuumFreezerRecipeHandler,TechReborn,techreborn:vacuumfreezer,,techreborn,TRUE,,,,,,,,,,,,
|
||||
techreborn.compat.nei.recipes.ImplosionCompressorRecipeHandler,TechReborn,techreborn:implosioncompressor,,techreborn,TRUE,,,,,,,,,,,,
|
||||
@@ -656,4 +649,4 @@ straywolfe.cookingwithtfc.client.nei.CookingPotRecipeHandler,Cooking with TFC,co
|
||||
straywolfe.cookingwithtfc.client.nei.ClayOvenRecipeHandler,Cooking with TFC,cookingwithtfc:item.clayOvenWall,,cookingwithtfc,TRUE,,,,,,,,,,,,
|
||||
factorization.nei.RecipeMixer,Factorization,factorization:FzBlock:18,,factorization,TRUE,,,,,,,,,,,,
|
||||
ua.pp.shurgent.tfctech.nei.WireDrawBenchRecipeHandler,Shurgent's TFCTech Addon,tfctech:item.Wire Draw Bench,,tfctech,TRUE,,,,,,,,,,,,
|
||||
mekanism.client.nei.ElectrolyticSeparatorRecipeHandler,Mekanism,Mekanism:MachineBlock2:4,,Mekanism,TRUE,,,,,,,,,,,,
|
||||
mekanism.client.nei.ElectrolyticSeparatorRecipeHandler,Mekanism,Mekanism:MachineBlock2:4,,Mekanism,TRUE,,,,,,,,,,,,
|
||||
|
@@ -47,6 +47,7 @@ nei.bookmark.crafting_chain.input=Ingredients
|
||||
nei.bookmark.crafting_chain.missing=Missing Items
|
||||
nei.bookmark.crafting_chain.output=Results
|
||||
nei.bookmark.crafting_chain.remainder=Remainders
|
||||
nei.bookmark.crafting_chain.needed=Required Crafts
|
||||
nei.bookmark.crafting_chain.available=Available Items
|
||||
nei.inventory.search.placeholder=Search...
|
||||
nei.itempanel.quantity.default=One stack
|
||||
@@ -63,6 +64,7 @@ nei.itempanel.fill_crafting_grid=Fill Crafting Grid
|
||||
nei.itempanel.fill_crafting_grid_quantity=Fill Crafting Grid With Quantity
|
||||
nei.itempanel.open_crafting=Recipe to make this item
|
||||
nei.itempanel.open_usage=Recipes that use this item
|
||||
nei.itempanel.infinite_item=Give Infinite Item
|
||||
nei.itempanel.copy_name=Copy Item Name
|
||||
nei.itempanel.copy_oredict=Copy Item OreDictionary
|
||||
nei.itempanel.copy_id=Copy Item ID
|
||||
@@ -200,6 +202,7 @@ nei.options.keys.gui.itemzoom_hold=Hold to Display Item Zoom
|
||||
nei.options.keys.gui.itemzoom_zoom_in=Item Zoom In
|
||||
nei.options.keys.gui.itemzoom_zoom_out=Item Zoom Out
|
||||
nei.options.keys.gui.favorite=Add Favorite
|
||||
nei.options.keys.gui.favorite_item=Toggle Favorite
|
||||
nei.options.keys.world=World
|
||||
nei.options.keys.world.chunkoverlay=Chunk Boundary Overlay
|
||||
nei.options.keys.world.moboverlay=Mob Spawn Overlay
|
||||
@@ -264,6 +267,9 @@ nei.options.inventory.favorites.showRecipeTooltipInGui=Show Recipe Tooltips in R
|
||||
nei.options.inventory.favorites.showRecipeTooltipInGui.true=Yes
|
||||
nei.options.inventory.favorites.showRecipeTooltipInGui.false=No
|
||||
nei.options.inventory.favorites.depth=Depth
|
||||
nei.options.inventory.favorites.generateSingleRecipeFavorites=Generate Single-Recipe Favorites
|
||||
nei.options.inventory.favorites.generateSingleRecipeFavorites.true=Yes
|
||||
nei.options.inventory.favorites.generateSingleRecipeFavorites.false=No
|
||||
nei.options.inventory.hotkeysHelpText=Show Hotkeys Help Text
|
||||
nei.options.inventory.hotkeysHelpText.true=Yes
|
||||
nei.options.inventory.hotkeysHelpText.false=No
|
||||
@@ -518,8 +524,31 @@ nei.options.tools.dump.handlers.dumped=handlers were dumped to %s
|
||||
nei.options.tools.dump.handlers.mode.0=CSV
|
||||
nei.options.tools.dump.handlers.mode.1=Json
|
||||
|
||||
nei.debug.RecipeHandler.title=Debug Recipe Handler
|
||||
nei.debug.RecipeHandler.copy=Copy
|
||||
nei.debug.RecipeHandler.Name=Name
|
||||
nei.debug.RecipeHandler.Id=ID
|
||||
nei.debug.RecipeHandler.Key=Key
|
||||
nei.debug.RecipeHandler.HHack=H.Hack
|
||||
nei.debug.RecipeHandler.ModName=Mod Name
|
||||
nei.debug.RecipeHandler.ModId=Mod ID
|
||||
nei.debug.RecipeHandler.Order=Order
|
||||
nei.debug.RecipeHandler.yShift=yShift
|
||||
nei.debug.RecipeHandler.MultiWidgets=Multi Widgets
|
||||
nei.debug.RecipeHandler.Height=Height
|
||||
nei.debug.RecipeHandler.Width=Width
|
||||
nei.debug.RecipeHandler.ShowFavorites=Show Favorites
|
||||
nei.debug.RecipeHandler.ShowOverlay=Show Overlays
|
||||
nei.debug.RecipeHandler.UseCustomScroll=Use Custom Scroll
|
||||
nei.debug.RecipeHandler.Override=Override
|
||||
nei.debug.RecipeHandler.checkbox.on=On
|
||||
nei.debug.RecipeHandler.checkbox.off=Off
|
||||
nei.debug.RecipeHandler.yes=Yes
|
||||
nei.debug.RecipeHandler.no=No
|
||||
|
||||
nei.recipe.page=Page %s/%s
|
||||
nei.recipe.tooltip=Recipes
|
||||
nei.recipe.tab.view_all.tooltip=View all categories
|
||||
nei.recipe.shaped=Shaped Crafting
|
||||
nei.recipe.shapeless=Shapeless Crafting
|
||||
nei.recipe.furnace=Smelting
|
||||
@@ -535,6 +564,7 @@ nei.recipe.firework=Fireworks
|
||||
nei.recipe.firework.tooltip0=Dyes add colours to the charges
|
||||
nei.recipe.firework.tooltip1=Recolouring adds fade colours to the charge
|
||||
nei.recipe.firework.tooltip2=Multiple charges can be spawned from one rocket
|
||||
nei.recipe.repair=Repair
|
||||
nei.recipe.brewing=Brewing
|
||||
nei.recipe.profiler.crafting=Crafting Profiling
|
||||
nei.recipe.profiler.usage=Usage Profiling
|
||||
@@ -554,6 +584,7 @@ nei.recipe.overlay.bookmarkRecipeAndCount=Save with Recipe & Count
|
||||
nei.recipe.favorite=Favorite
|
||||
nei.recipe.favorite.bookmark_recipe=Save Recipe Tree
|
||||
nei.recipe.favorite.change_result_index=Change Output
|
||||
nei.recipe.favorite.toggle=Toggle Favorite
|
||||
|
||||
nei.recipe.information=Information
|
||||
|
||||
@@ -602,6 +633,7 @@ nei.subsets.Items.Tools.Shovels=Shovels
|
||||
nei.subsets.Items.Weapons=Weapons
|
||||
nei.subsets.Items.Weapons.Ranged=Ranged
|
||||
nei.subsets.Items.Weapons.Swords=Swords
|
||||
nei.subsets.Untranslated=Untranslated
|
||||
nei.subsets.Mod=Mod
|
||||
|
||||
nei.presets.new=New Preset
|
||||
|
||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 566 B After Width: | Height: | Size: 565 B |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 726 B |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 3.9 KiB |