mirror of
https://github.com/GTNewHorizons/NotEnoughItems.git
synced 2026-11-15 17:54:50 +00:00
Compare commits
107
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 | ||
|
|
8ed1f7a043 | ||
|
|
f2efa35654 | ||
|
|
bcef287e71 | ||
|
|
7f555f7a7f | ||
|
|
9fd38da205 | ||
|
|
2fa5563408 | ||
|
|
541c0e2def | ||
|
|
ac868097e7 | ||
|
|
2f0de0b6a8 | ||
|
|
32bc29e654 | ||
|
|
ef8a7d8bd5 | ||
|
|
adc5a5df16 | ||
|
|
a828ff227a | ||
|
|
9b6f98330e | ||
|
|
667c8cb5b6 | ||
|
|
a186f69444 | ||
|
|
16f4f20239 | ||
|
|
bac207cacb | ||
|
|
630e856d83 | ||
|
|
42d96aed0c | ||
|
|
bd6384bf24 | ||
|
|
af9726d356 | ||
|
|
1e1d2f1076 | ||
|
|
7cb94fb22a | ||
|
|
87aa4f9ed5 | ||
|
|
9760fd3eaf | ||
|
|
1054871982 | ||
|
|
d90a667f68 | ||
|
|
69e6df5848 | ||
|
|
25fa7ce44e | ||
|
|
e3cd7b860d | ||
|
|
2a3aabc073 | ||
|
|
76db43c835 | ||
|
|
40e53eea7a | ||
|
|
6c4d16d6b9 | ||
|
|
4a2abe9fd7 | ||
|
|
d47417302e | ||
|
|
e13401ded8 | ||
|
|
7ada842ef3 | ||
|
|
fe0c5d4e50 | ||
|
|
2ea9ae1eb9 | ||
|
|
f7f0596fda | ||
|
|
d5e919a9cd | ||
|
|
a0ed5da699 | ||
|
|
99fb5a656e | ||
|
|
4b663222b1 | ||
|
|
3e5d0088bc | ||
|
|
948be399d2 | ||
|
|
5f6091924d | ||
|
|
c5bd1f897a | ||
|
|
61d4b6ab62 | ||
|
|
791d05d5f5 | ||
|
|
66001275c4 | ||
|
|
db6b83c906 | ||
|
|
58ef6c85e0 | ||
|
|
ab0aeef872 | ||
|
|
23b7c69e2f | ||
|
|
bb89384493 | ||
|
|
e96e4dfdde | ||
|
|
0a6a6771d8 |
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
|
||||
+4
-1
@@ -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/"]
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// Add your dependencies here
|
||||
|
||||
dependencies {
|
||||
api('com.github.GTNewHorizons:CodeChickenCore:1.4.7:dev')
|
||||
implementation('com.github.GTNewHorizons:GTNHLib:0.6.39: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
-4
@@ -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.
|
||||
@@ -96,7 +120,9 @@ usesMixinDebug = false
|
||||
# Specify the location of your implementation of IMixinConfigPlugin. Leave it empty otherwise.
|
||||
mixinPlugin =
|
||||
|
||||
# Specify the package that contains all of your Mixins. You may only place Mixins in this package or the build will fail!
|
||||
# Specify the package that contains all of your Mixins. The package must exist or
|
||||
# the build will fail. If you have a package property defined in your mixins.<modid>.json,
|
||||
# it must match with this or the build will fail.
|
||||
mixinsPackage =
|
||||
|
||||
# Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin!
|
||||
@@ -172,6 +198,12 @@ curseForgeRelations = requiredDependency\:codechickencore-unofficial
|
||||
# projects. New projects should not use this parameter.
|
||||
# customArchiveBaseName =
|
||||
|
||||
# Optional parameter to customize the default working directory used by the runClient* tasks. Relative to the project directory.
|
||||
# runClientWorkingDirectory = run/client
|
||||
|
||||
# Optional parameter to customize the default working directory used by the runServer* tasks. Relative to the project directory.
|
||||
# runServerWorkingDirectory = run/server
|
||||
|
||||
# Optional parameter to have the build automatically fail if an illegal version is used.
|
||||
# This can be useful if you e.g. only want to allow versions in the form of '1.1.xxx'.
|
||||
# The check is ONLY performed if the version is a git tag.
|
||||
@@ -201,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
|
||||
Vendored
BIN
Binary file not shown.
+1
-1
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-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=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# 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,8 +210,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
||||
"$@"
|
||||
|
||||
# Stop when "xargs" is not available.
|
||||
|
||||
Vendored
+1
-2
@@ -70,11 +70,10 @@ goto fail
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
"%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
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ pluginManagement {
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.42'
|
||||
id 'com.gtnewhorizons.gtnhsettingsconvention' version '2.0.24'
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -18,20 +18,22 @@ public SearchExpressionLexer(CharStream input, SearchTokenParser searchParser) {
|
||||
// Lexer rules
|
||||
REGEX_LEFT : 'r'? '/' -> pushMode(REGEX) ;
|
||||
QUOTE_LEFT : '"' -> pushMode(QUOTED) ;
|
||||
|
||||
DASH : '-' ;
|
||||
|
||||
RECIPE_INGREDIENTS : '<&' | '<' ;
|
||||
RECIPE_RESULT : '>&' | '>' ;
|
||||
RECIPE_OTHERS : '^&' | '^' ;
|
||||
PREFIX : CLEAN_SYMBOL {searchParser.hasRedefinedPrefix(getText().charAt(0))}? ;
|
||||
|
||||
OR : '|' ;
|
||||
LEFT_BRACKET : '{' ;
|
||||
RIGHT_BRACKET : '}' ;
|
||||
PLAIN_TEXT : (CLEAN_SYMBOL | ESCAPED_SYMBOL)+ {!searchParser.hasRedefinedPrefix(getText().charAt(0))}? ;
|
||||
NEWLINE_OR_TAB : [\t\r\n] -> skip ;
|
||||
SPACE : ' ' ;
|
||||
ESCAPED_SYMBOL : '\\' . ;
|
||||
|
||||
fragment ESCAPED_SYMBOL : '\\' . ;
|
||||
fragment CLEAN_SYMBOL : ~[-<>^{}|/\\ "] ;
|
||||
PREFIX : CLEAN_SYMBOL {searchParser.hasRedefinedPrefix(getText().charAt(0))}? ;
|
||||
CLEAN_SYMBOL : ~[-<>^{}|/\\ "] ;
|
||||
|
||||
mode REGEX;
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ prefixedExpression
|
||||
token[Character prefix]
|
||||
: regex[prefix]
|
||||
| quoted[prefix]
|
||||
| PLAIN_TEXT
|
||||
| plainText
|
||||
;
|
||||
|
||||
regex[Character prefix]
|
||||
@@ -67,4 +67,7 @@ quoted[Character prefix]
|
||||
: QUOTE_LEFT QUOTED_CONTENT QUOTE_RIGHT?
|
||||
;
|
||||
|
||||
plainText
|
||||
: (CLEAN_SYMBOL | ESCAPED_SYMBOL)+
|
||||
;
|
||||
|
||||
@@ -5,13 +5,14 @@ import net.minecraft.item.ItemStack;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
import codechicken.nei.ItemsGrid.ItemsGridSlot;
|
||||
import codechicken.nei.api.GuiInfo;
|
||||
import codechicken.nei.api.ShortcutInputHandler;
|
||||
import codechicken.nei.drawable.DrawableBuilder;
|
||||
import codechicken.nei.drawable.DrawableResource;
|
||||
import codechicken.nei.guihook.IContainerTooltipHandler;
|
||||
import codechicken.nei.recipe.GuiCraftingRecipe;
|
||||
import codechicken.nei.recipe.GuiRecipe;
|
||||
import codechicken.nei.recipe.GuiUsageRecipe;
|
||||
|
||||
public abstract class AbstractSubpanel<T extends ItemsGrid<? extends ItemsGridSlot, ? extends ItemsGrid.MouseContext>>
|
||||
extends Widget implements IContainerTooltipHandler {
|
||||
@@ -20,6 +21,7 @@ public abstract class AbstractSubpanel<T extends ItemsGrid<? extends ItemsGridSl
|
||||
|
||||
protected int mouseDownItemIndex = -1;
|
||||
protected int splittingLineColor = 0xffffffff;
|
||||
protected int linePaddingStart = 0;
|
||||
protected T grid;
|
||||
|
||||
public boolean isEmpty() {
|
||||
@@ -52,19 +54,30 @@ public abstract class AbstractSubpanel<T extends ItemsGrid<? extends ItemsGridSl
|
||||
return this.grid.getSlotMouseOver(mousex, mousey);
|
||||
}
|
||||
|
||||
protected void updateLinePadding() {
|
||||
GuiContainer guiContainer = NEIClientUtils.getGuiContainer();
|
||||
this.linePaddingStart = 0;
|
||||
|
||||
while (GuiInfo
|
||||
.hideItemPanelSlot(guiContainer, new Rectangle4i(this.x + this.linePaddingStart, this.y - 1, 10, 2))) {
|
||||
this.linePaddingStart += 10;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected void drawSplittingLine() {
|
||||
float alpha = (this.splittingLineColor >> 24 & 255) / 255.0F;
|
||||
float red = (this.splittingLineColor >> 16 & 255) / 255.0F;
|
||||
float green = (this.splittingLineColor >> 8 & 255) / 255.0F;
|
||||
float blue = (this.splittingLineColor & 255) / 255.0F;
|
||||
|
||||
int width = this.grid.columns * ItemsGrid.SLOT_SIZE;
|
||||
int width = this.grid.columns * ItemsGrid.SLOT_SIZE - this.linePaddingStart;
|
||||
int repeat = width / 6;
|
||||
int shiftX = this.x + (this.w - width) / 2;
|
||||
int shiftX = this.x + this.linePaddingStart + (this.w - width) / 2;
|
||||
|
||||
GL11.glColor4f(red, green, blue, alpha);
|
||||
for (int i = 0; i < repeat; i++) {
|
||||
DASH.draw(shiftX + i * 6, y);
|
||||
DASH.draw(shiftX + i * 6, this.y);
|
||||
}
|
||||
GL11.glColor4f(1, 1, 1, 1);
|
||||
}
|
||||
@@ -122,13 +135,7 @@ public abstract class AbstractSubpanel<T extends ItemsGrid<? extends ItemsGridSl
|
||||
|
||||
if (NEIController.manager.window instanceof GuiRecipe || NEIClientUtils.shiftKey()
|
||||
|| !NEIClientConfig.canCheatItem(hoverSlot.getItemStack())) {
|
||||
|
||||
if (button == 0) {
|
||||
GuiCraftingRecipe.openRecipeGui("item", hoverSlot.getItemStack().copy());
|
||||
} else if (button == 1) {
|
||||
GuiUsageRecipe.openRecipeGui("item", hoverSlot.getItemStack().copy());
|
||||
}
|
||||
|
||||
ShortcutInputHandler.handleMouseClick(hoverSlot.getItemStack().copy());
|
||||
} else {
|
||||
NEIClientUtils.cheatItem(getDraggedStackWithQuantity(hoverSlot.getItemStack()), button, -1);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import codechicken.nei.api.IBookmarkContainerHandler;
|
||||
import codechicken.nei.bookmark.BookmarkGrid;
|
||||
import codechicken.nei.bookmark.BookmarkGroup;
|
||||
import codechicken.nei.bookmark.BookmarkItem;
|
||||
import codechicken.nei.bookmark.BookmarkItem.BookmarkItemType;
|
||||
import codechicken.nei.bookmark.BookmarkStorage;
|
||||
import codechicken.nei.bookmark.BookmarksGridSlot;
|
||||
import codechicken.nei.bookmark.GroupingItem;
|
||||
@@ -184,23 +185,26 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
final boolean existsRecipe = recipeId != null
|
||||
&& this.grid.existsRecipe(recipeId, BookmarkGrid.DEFAULT_GROUP_ID);
|
||||
final NBTTagCompound nbTag = StackInfo.itemStackToNBT(itemStack);
|
||||
long factor = nbTag.getInteger("Count");
|
||||
long count = nbTag.getInteger("Count");
|
||||
long factor = existsRecipe ? Math.max(count, 1) : 1;
|
||||
|
||||
if (existsRecipe) {
|
||||
|
||||
for (int i = 0; i < this.grid.size(); i++) {
|
||||
if (this.grid.getBookmarkItem(i).equalsRecipe(recipeId, groupId)) {
|
||||
final long multiplier = this.grid.getBookmarkItem(i).getMultiplier();
|
||||
factor *= multiplier;
|
||||
count *= this.grid.getBookmarkItem(i).getMultiplier();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
factor = nbTag.hasKey("gtFluidName") ? Math.min(144, nbTag.getInteger("Count")) : 1;
|
||||
}
|
||||
|
||||
this.grid.addItem(BookmarkItem.of(groupId, itemStack, factor, recipeId, false), true);
|
||||
this.grid.addItem(
|
||||
BookmarkItem.of(
|
||||
groupId,
|
||||
StackInfo.withAmount(itemStack, count),
|
||||
factor,
|
||||
recipeId,
|
||||
existsRecipe ? BookmarkItemType.RESULT : BookmarkItemType.ITEM),
|
||||
true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -242,7 +246,8 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
|
||||
if (stack != null && uniqueRecipe.add(recipeId)) {
|
||||
this.grid.addItem(
|
||||
BookmarkItem.of(groupId, stack, StackInfo.getAmount(stack), recipeId, false),
|
||||
BookmarkItem
|
||||
.of(groupId, stack, StackInfo.getAmount(stack), recipeId, BookmarkItemType.ITEM),
|
||||
true);
|
||||
uniqueStack.add(stack);
|
||||
}
|
||||
@@ -302,7 +307,7 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
}
|
||||
|
||||
final int groupId = slot.getGroupId();
|
||||
final RecipeId recipeId = slot.getRecipeId();
|
||||
final RecipeId recipeId = slot.getType() == BookmarkItemType.ITEM ? null : slot.getRecipeId();
|
||||
final BookmarkGroup group = slot.getGroup();
|
||||
|
||||
if (group.crafting != null && group.collapsed) {
|
||||
@@ -366,7 +371,7 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
|
||||
public RecipeId getRecipeId(int itemIndex) {
|
||||
BookmarkItem meta = this.grid.getCalculatedItem(itemIndex);
|
||||
return meta.isIngredient ? null : meta.recipeId;
|
||||
return meta.type == BookmarkItemType.INGREDIENT ? null : meta.recipeId;
|
||||
}
|
||||
|
||||
public boolean existsRecipe(RecipeId recipeId, int groupId) {
|
||||
@@ -504,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) {
|
||||
@@ -695,7 +700,7 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> handleTooltip(GuiContainer gui, int mousex, int mousey, List<String> currenttip) {
|
||||
public List<String> handleTooltip(int mousex, int mousey, List<String> currenttip) {
|
||||
|
||||
if (this.grid.getPerPage() == 0 || this.grid.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
@@ -722,7 +727,7 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
this.recipeChainTooltipLineHandler = null;
|
||||
}
|
||||
|
||||
return super.handleTooltip(gui, mousex, mousey, currenttip);
|
||||
return super.handleTooltip(mousex, mousey, currenttip);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -748,7 +753,7 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> handleHotkeys(GuiContainer gui, int mousex, int mousey, Map<String, String> hotkeys) {
|
||||
public Map<String, String> handleHotkeys(int mousex, int mousey, Map<String, String> hotkeys) {
|
||||
final int overRowIndex = this.grid.getHoveredRowIndex(true);
|
||||
final BookmarksGridSlot slot = getSlotMouseOver(mousex, mousey);
|
||||
|
||||
@@ -781,7 +786,7 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
NEIClientConfig.getKeyName("gui.remove_recipe"),
|
||||
NEIClientUtils.translate("bookmark.group.remove_recipe"));
|
||||
|
||||
if (BookmarkContainerInfo.getBookmarkContainerHandler(gui) != null) {
|
||||
if (BookmarkContainerInfo.getBookmarkContainerHandler(NEIClientUtils.getGuiContainer()) != null) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark_pull_items"),
|
||||
NEIClientUtils.translate("bookmark.group.pull_items"));
|
||||
@@ -878,7 +883,7 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
}
|
||||
}
|
||||
|
||||
return hotkeys;
|
||||
return super.handleHotkeys(mousex, mousey, hotkeys);
|
||||
}
|
||||
|
||||
private List<String> recipeChainTooltip(int groupId, List<String> currenttip) {
|
||||
@@ -915,13 +920,13 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> handleItemTooltip(GuiContainer gui, ItemStack itemstack, int mousex, int mousey,
|
||||
List<String> currenttip) {
|
||||
public List<String> handleItemTooltip(ItemStack itemstack, int mousex, int mousey, List<String> currenttip) {
|
||||
final BookmarksGridSlot slot = this.grid.getSlotMouseOver(mousex, mousey);
|
||||
|
||||
if (slot != null) {
|
||||
|
||||
if (slot.isIngredient() && slot.getRecipeId() != null && slot.getBookmarkItem().permutations.size() > 1) {
|
||||
if (slot.getType() == BookmarkItemType.INGREDIENT && slot.getRecipeId() != null
|
||||
&& slot.getBookmarkItem().permutations.size() > 1) {
|
||||
RecipeId recipeId = slot.getRecipeId();
|
||||
|
||||
if (recipeId == null) {
|
||||
@@ -991,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,
|
||||
@@ -1019,7 +1024,8 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
if (NEIClientUtils.altKey()) {
|
||||
multiplier = NEIClientConfig.showItemQuantityWidget() ? NEIClientConfig.getItemQuantity() : 0;
|
||||
if (multiplier == 0) {
|
||||
multiplier = slot.getItemStack().getMaxStackSize();
|
||||
multiplier = StackInfo.itemStackToNBT(slot.getItemStack()).hasKey("gtFluidName") ? 144
|
||||
: slot.getItemStack().getMaxStackSize();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1181,7 +1187,15 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
}
|
||||
|
||||
if (!items.isEmpty()) {
|
||||
containerHandler.pullBookmarkItemsFromContainer(guiContainer, items);
|
||||
final int helmStackIndex = FastTransferManager.dropHeldItem(guiContainer);
|
||||
|
||||
if (guiContainer.mc.thePlayer.inventory.getItemStack() == null) {
|
||||
containerHandler.pullBookmarkItemsFromContainer(guiContainer, items);
|
||||
|
||||
if (helmStackIndex != -1) {
|
||||
FastTransferManager.clickSlot(guiContainer, helmStackIndex, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1252,7 +1266,7 @@ public class BookmarkPanel extends PanelWidget<BookmarkGrid> {
|
||||
@Deprecated
|
||||
public BookmarkRecipeId getBookmarkRecipeId(int itemIndex) {
|
||||
BookmarkItem item = this.grid.getCalculatedItem(itemIndex);
|
||||
return item == null || item.isIngredient || item.recipeId == null ? null
|
||||
return item == null || item.type == BookmarkItemType.INGREDIENT || item.recipeId == null ? null
|
||||
: new BookmarkRecipeId(item.recipeId.getHandleName(), item.recipeId.getIngredients());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package codechicken.nei;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
@@ -21,10 +24,13 @@ import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.GuiErrorScreen;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.gui.GuiSelectWorld;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.client.multiplayer.WorldClient;
|
||||
import net.minecraft.client.resources.IResource;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.EntityItem;
|
||||
import net.minecraft.launchwrapper.Launch;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.event.GuiOpenEvent;
|
||||
import net.minecraftforge.client.event.RenderWorldLastEvent;
|
||||
@@ -37,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;
|
||||
@@ -148,6 +153,7 @@ public class ClientHandler {
|
||||
loadHiddenHandlers();
|
||||
loadEnableAutoFocus();
|
||||
loadGuiCraftablesBlacklist();
|
||||
loadDefaultBookmarkContainers();
|
||||
ItemInfo.preInit();
|
||||
StackInfo.loadGuidFilters();
|
||||
}
|
||||
@@ -165,11 +171,34 @@ public class ClientHandler {
|
||||
}, callback);
|
||||
}
|
||||
|
||||
public static void loadSettingsFile(String resource, BiConsumer<File, FileWriter> createDefault,
|
||||
public static boolean loadSettingsResource(String resource, Consumer<Stream<String>> callback) {
|
||||
final ResourceLocation location = new ResourceLocation("nei", resource);
|
||||
|
||||
try {
|
||||
final IResource res = Minecraft.getMinecraft().getResourceManager().getResource(location);
|
||||
|
||||
try (BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(res.getInputStream(), StandardCharsets.UTF_8))) {
|
||||
NEIClientConfig.logger.info("Loading '{}' from jar {}", resource, location);
|
||||
callback.accept(
|
||||
IOUtils.readLines(reader).stream()
|
||||
.map(line -> line.contains("#") ? line.substring(0, line.indexOf('#')) : line)
|
||||
.map(String::trim).filter(line -> !line.isEmpty()));
|
||||
return true;
|
||||
}
|
||||
|
||||
} catch (Exception io) {
|
||||
NEIClientConfig.logger.error("Failed to load '{}' file {}", resource, location);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean loadSettingsFile(String resource, BiConsumer<File, FileWriter> createDefault,
|
||||
Consumer<Stream<String>> callback) {
|
||||
File file = new File(NEIClientConfig.configDir, resource);
|
||||
|
||||
if (!file.exists()) {
|
||||
if (!file.exists() && createDefault != null) {
|
||||
try (FileWriter writer = new FileWriter(file)) {
|
||||
NEIClientConfig.logger.info("Creating default '{}' {}", resource, file);
|
||||
createDefault.accept(file, writer);
|
||||
@@ -178,13 +207,20 @@ public class ClientHandler {
|
||||
}
|
||||
}
|
||||
|
||||
try (FileReader reader = new FileReader(file)) {
|
||||
NEIClientConfig.logger.info("Loading '{}' file {}", resource, file);
|
||||
callback.accept(
|
||||
IOUtils.readLines(reader).stream().filter(line -> !line.startsWith("#") && !line.trim().isEmpty()));
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to load '{}' file {}", resource, file, e);
|
||||
if (file.exists()) {
|
||||
try (FileReader reader = new FileReader(file)) {
|
||||
NEIClientConfig.logger.info("Loading '{}' file {}", resource, file);
|
||||
callback.accept(
|
||||
IOUtils.readLines(reader).stream()
|
||||
.map(line -> line.contains("#") ? line.substring(0, line.indexOf('#')) : line)
|
||||
.map(String::trim).filter(line -> !line.isEmpty()));
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to load '{}' file {}", resource, file, e);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void loadSerialHandlers() {
|
||||
@@ -218,6 +254,20 @@ public class ClientHandler {
|
||||
lines -> ItemCraftablesPanel.guiBlacklist = lines.collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public static void loadDefaultBookmarkContainers() {
|
||||
loadSettingsFile("defaultbookmarkcontainers.cfg", lines -> {
|
||||
for (String clazz : lines.collect(Collectors.toList())) {
|
||||
try {
|
||||
API.registerBookmarkContainerHandler(
|
||||
(Class<? extends GuiContainer>) Class.forName(clazz),
|
||||
new DefaultBookmarkContainerHandler());
|
||||
} catch (Exception e) {
|
||||
NEIClientConfig.logger.error("Failed to load class '{}' for defaultbookmarkcontainers.cfg", clazz);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void loadHiddenItems() {
|
||||
loadSettingsFile("hiddenitems.cfg", lines -> lines.forEach(API::hideItem));
|
||||
}
|
||||
@@ -225,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);
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package codechicken.nei;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
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,36 +13,18 @@ public class DefaultBookmarkContainerHandler implements IBookmarkContainerHandle
|
||||
|
||||
@Override
|
||||
public void pullBookmarkItemsFromContainer(GuiContainer guiContainer, ArrayList<ItemStack> bookmarkItems) {
|
||||
FastTransferManager manager = new FastTransferManager();
|
||||
LinkedList<ItemStack> containerStacks = manager.saveContainer(guiContainer.inventorySlots);
|
||||
final List<Slot> slots = guiContainer.inventorySlots.inventorySlots;
|
||||
final FastTransferManager manager = new FastTransferManager();
|
||||
|
||||
for (ItemStack bookmarkItem : bookmarkItems) {
|
||||
|
||||
int bookmarkSizeBackup = bookmarkItem.stackSize;
|
||||
|
||||
for (int i = 0; i < containerStacks.size() - 4 * 9; i++) { // Last 36 slots are player inventory
|
||||
ItemStack containerItem = containerStacks.get(i);
|
||||
|
||||
if (containerItem == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bookmarkItem.isItemEqual(containerItem)) {
|
||||
if (bookmarkItem.stackSize <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (bookmarkItem.stackSize == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
bookmarkItem.stackSize = bookmarkSizeBackup;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,9 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -281,6 +283,27 @@ public class FastTransferManager {
|
||||
GuiContainerManager.getManager(window).handleSlotClick(slotIndex, button, modifier);
|
||||
}
|
||||
|
||||
public static int dropHeldItem(GuiContainer window) {
|
||||
final EntityPlayerSP player = window.mc.thePlayer;
|
||||
final ItemStack held = player.inventory.getItemStack();
|
||||
|
||||
if (held == null) return -1;
|
||||
|
||||
for (int i = 0; held != null && i < window.inventorySlots.inventorySlots.size(); i++) {
|
||||
final Slot slot = window.inventorySlots.inventorySlots.get(i);
|
||||
|
||||
if (slot.inventory instanceof InventoryPlayer && !slot.getHasStack() && slot.isItemValid(held)) {
|
||||
clickSlot(window, i, 0, 0);
|
||||
|
||||
if (player.inventory.getItemStack() == null) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private boolean fillZoneWithHeldItem(GuiContainer window, int zoneIndex) {
|
||||
for (int transferTo : slotZones.get(zoneIndex)) {
|
||||
ItemStack held = NEIClientUtils.getHeldItem();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -117,105 +221,139 @@ public class FavoriteRecipes {
|
||||
final RecipeId recipeId = RecipeId.of(jsonObject.getAsJsonObject("recipeId"));
|
||||
final ItemStack stack = StackInfo.loadFromNBT(itemStackNBT);
|
||||
|
||||
if (stack != null) {
|
||||
final String fluidKey = getFluidKey(stack);
|
||||
|
||||
if (fluidKey != null) {
|
||||
fluids.put(fluidKey, recipeId);
|
||||
}
|
||||
if (recipeId == null || stack == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
items.put(itemStackNBT, recipeId);
|
||||
|
||||
if (NEIServerUtils.isItemTool(stack)) {
|
||||
tools.add(itemStackNBT);
|
||||
if (FAVORITE_ITEM.equals(recipeId.getHandleName()) || RecipeHandlerRef.of(recipeId) != null) {
|
||||
manualFavorites.add(stack, recipeId);
|
||||
} else {
|
||||
hasErrors = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} catch (IllegalArgumentException | JsonSyntaxException | IllegalStateException e) {
|
||||
NEIClientConfig.logger.error("Failed to load favorite from json string:\n{}", itemStr);
|
||||
} 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 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) {
|
||||
return getFavorite(stack) != null;
|
||||
}
|
||||
|
||||
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() {
|
||||
@@ -226,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();
|
||||
|
||||
@@ -61,6 +61,11 @@ public class FormattedTextField extends GuiTextField {
|
||||
super.setFocused(focus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(String rawText) {
|
||||
super.setText(EnumChatFormatting.getTextWithoutFormattingCodes(rawText));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelectionPos(int p_146199_1_) {
|
||||
String text = this.getText();
|
||||
@@ -273,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);
|
||||
|
||||
@@ -42,13 +42,11 @@ public class HUDRenderer implements IKeyStateTracker {
|
||||
&& mc.objectMouseOver != null
|
||||
&& mc.objectMouseOver.typeOfHit == MovingObjectType.BLOCK) {
|
||||
World world = mc.theWorld;
|
||||
ItemStack[] items = ItemInfo.getIdentifierItems(world, mc.thePlayer, mc.objectMouseOver)
|
||||
.toArray(new ItemStack[0]);
|
||||
final List<ItemStack> items = ItemInfo.getIdentifierItems(world, mc.thePlayer, mc.objectMouseOver);
|
||||
|
||||
if (items.length == 0) return;
|
||||
|
||||
ItemStack stack = StackInfo.getItemStackWithMinimumDamage(items);
|
||||
if (items.isEmpty()) return;
|
||||
|
||||
final ItemStack stack = StackInfo.getItemStackWithMinimumDamage(items.toArray(new ItemStack[0]));
|
||||
renderOverlay(stack, ItemInfo.getText(stack, world, mc.thePlayer, mc.objectMouseOver), getPositioning());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,8 +27,8 @@ public class HeldItemHandler implements IContainerInputHandler, IContainerToolti
|
||||
protected boolean contains(int mousex, int mousey) {
|
||||
return NEIClientUtils.getHeldItem() != null && !ItemPanels.bookmarkPanel.inEditingState()
|
||||
&& !AutoCraftingManager.processing()
|
||||
&& (ItemPanels.bookmarkPanel.contains(mousex, mousey) || ItemPanels.itemPanel.contains(mousex, mousey)
|
||||
|| ItemPanels.itemPanel.historyPanel.contains(mousex, mousey));
|
||||
&& (ItemPanels.bookmarkPanel.contains(mousex, mousey)
|
||||
|| ItemPanels.itemPanel.containsWithSubpanels(mousex, mousey));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -36,7 +36,8 @@ public class HeldItemHandler implements IContainerInputHandler, IContainerToolti
|
||||
|
||||
if (contains(mousex, mousey)) {
|
||||
|
||||
if (NEIClientConfig.canPerformAction("delete") && NEIClientConfig.canPerformAction("item")) {
|
||||
if (NEIClientConfig.canPerformAction("delete") && NEIClientConfig.canPerformAction("item")
|
||||
|| NEIClientUtils.mc().playerController.isInCreativeMode()) {
|
||||
if (button == 1) {
|
||||
NEIClientUtils.decreaseSlotStack(-999);
|
||||
} else {
|
||||
@@ -101,7 +102,8 @@ public class HeldItemHandler implements IContainerInputHandler, IContainerToolti
|
||||
if (contains(mousex, mousey)) {
|
||||
currenttip.clear();
|
||||
|
||||
if (NEIClientConfig.canPerformAction("delete") && NEIClientConfig.canPerformAction("item")) {
|
||||
if (NEIClientConfig.canPerformAction("delete") && NEIClientConfig.canPerformAction("item")
|
||||
|| NEIClientUtils.mc().playerController.isInCreativeMode()) {
|
||||
currenttip.add(EnumChatFormatting.RED + translate("itempanel.deleteItem"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,10 +2,11 @@ package codechicken.nei;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
@@ -90,6 +91,7 @@ public class ItemCraftablesPanel
|
||||
private GuiContainer lastGuiContainer = null;
|
||||
private ItemStackAmount lastPlayerInventory = null;
|
||||
private long lastPlayerInventorySync = 0;
|
||||
private int lastFavoritesCount = 0;
|
||||
|
||||
public ItemCraftablesPanel() {
|
||||
this.grid = new ItemsGrid<>() {
|
||||
@@ -106,28 +108,43 @@ public class ItemCraftablesPanel
|
||||
public List<CraftablesGridSlot> getMask() {
|
||||
|
||||
if (this.gridMask == null) {
|
||||
int maxSlotIndex = this.rows * this.columns;
|
||||
final AtomicInteger slotIndex = new AtomicInteger(0);
|
||||
final int maxSlotIndex = this.rows * this.columns;
|
||||
final List<CraftablesGridSlot> gridMask = new ArrayList<>();
|
||||
this.realItems.clear();
|
||||
|
||||
if (!ItemCraftablesPanel.this.availableRecipes.isEmpty()) {
|
||||
ItemCraftablesPanel.this.availableRecipes.entrySet().stream()
|
||||
.sorted(Map.Entry.comparingByKey(ItemSorter.instance)).forEach(entry -> {
|
||||
this.realItems.add(entry.getKey());
|
||||
gridMask.add(
|
||||
new CraftablesGridSlot(
|
||||
slotIndex.get(),
|
||||
slotIndex.get(),
|
||||
entry.getKey(),
|
||||
entry.getValue()));
|
||||
slotIndex.incrementAndGet();
|
||||
});
|
||||
final List<Map.Entry<ItemStack, RecipeId>> entries = ItemCraftablesPanel.this.availableRecipes
|
||||
.entrySet().stream()
|
||||
.sorted(
|
||||
Map.Entry.comparingByKey(
|
||||
Comparator.comparing(FavoriteRecipes::containsManual)
|
||||
.thenComparing(FavoriteRecipes::contains).reversed()
|
||||
.thenComparing(ItemSorter.instance)))
|
||||
.limit(maxSlotIndex).collect(Collectors.toList());
|
||||
int slotIndex = 0;
|
||||
int itemIndex = 0;
|
||||
|
||||
this.gridMask = gridMask.subList(0, Math.min(gridMask.size(), maxSlotIndex));
|
||||
for (Map.Entry<ItemStack, RecipeId> entry : entries) {
|
||||
if (!isInvalidSlot(slotIndex)) {
|
||||
this.realItems.add(entry.getKey());
|
||||
gridMask.add(
|
||||
new CraftablesGridSlot(
|
||||
slotIndex,
|
||||
itemIndex++,
|
||||
entry.getKey(),
|
||||
entry.getValue()));
|
||||
}
|
||||
if (slotIndex++ >= maxSlotIndex) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.gridMask = gridMask;
|
||||
} else {
|
||||
this.gridMask = Collections.emptyList();
|
||||
}
|
||||
|
||||
ItemCraftablesPanel.this.updateLinePadding();
|
||||
}
|
||||
|
||||
return this.gridMask;
|
||||
@@ -192,11 +209,16 @@ public class ItemCraftablesPanel
|
||||
this.lastPlayerInventorySync = System.currentTimeMillis();
|
||||
|
||||
if (firstGui != null && !ItemCraftablesPanel.guiBlacklist.contains(firstGui.getClass().getName())) {
|
||||
final boolean showOnlyFavorites = NEIClientConfig
|
||||
.getBooleanSetting("inventory.craftables.favoritesOnly");
|
||||
final ItemStackAmount inv = AutoCraftingManager.getInventoryItems(firstGui);
|
||||
|
||||
if (this.lastGuiContainer != (this.lastGuiContainer = firstGui)
|
||||
if (this.lastGuiContainer != firstGui
|
||||
|| showOnlyFavorites && this.lastFavoritesCount != FavoriteRecipes.size()
|
||||
|| !inv.equals(this.lastPlayerInventory)) {
|
||||
this.lastPlayerInventory = inv;
|
||||
this.lastGuiContainer = firstGui;
|
||||
this.lastFavoritesCount = FavoriteRecipes.size();
|
||||
this.availableRecipes = generateCraftables(firstGui);
|
||||
this.grid.onGridChanged();
|
||||
}
|
||||
@@ -251,12 +273,14 @@ public class ItemCraftablesPanel
|
||||
private Map<ItemStack, RecipeId> filterHandlerRecipes(IRecipeHandler handler, GuiContainer firstGui,
|
||||
List<ItemStack> invStacks) {
|
||||
final Map<ItemStack, RecipeId> availableRecipes = new HashMap<>();
|
||||
final boolean showOnlyFavorites = NEIClientConfig.getBooleanSetting("inventory.craftables.favoritesOnly");
|
||||
|
||||
IntStream.range(0, handler.numRecipes()).parallel().forEach(recipeIndex -> {
|
||||
if (existsIngredients(firstGui, handler.getIngredientStacks(recipeIndex), invStacks)) {
|
||||
final Recipe recipe = Recipe.of(handler, recipeIndex);
|
||||
|
||||
if (!recipe.getResults().isEmpty()) {
|
||||
if (!recipe.getResults().isEmpty()
|
||||
&& (!showOnlyFavorites || FavoriteRecipes.getFavorite(recipe.getRecipeId()) != null)) {
|
||||
synchronized (availableRecipes) {
|
||||
availableRecipes.put(recipe.getResult(), recipe.getRecipeId());
|
||||
}
|
||||
|
||||
@@ -7,14 +7,27 @@ import net.minecraft.item.ItemStack;
|
||||
|
||||
import codechicken.nei.ItemsGrid.ItemsGridSlot;
|
||||
import codechicken.nei.ItemsGrid.MouseContext;
|
||||
import codechicken.nei.recipe.Recipe.RecipeId;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
|
||||
public class ItemHistoryPanel extends AbstractSubpanel<ItemsGrid<ItemsGridSlot, MouseContext>> {
|
||||
public class ItemHistoryPanel extends AbstractSubpanel<ItemsGrid<ItemHistoryPanel.HistoryGridSlot, MouseContext>> {
|
||||
|
||||
public static class HistoryGridSlot extends ItemsGridSlot {
|
||||
|
||||
public HistoryGridSlot(int slotIndex, int itemIndex, ItemStack item) {
|
||||
super(slotIndex, itemIndex, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeId getRecipeId() {
|
||||
return FavoriteRecipes.getFavorite(this.item);
|
||||
}
|
||||
}
|
||||
|
||||
public ItemHistoryPanel() {
|
||||
this.grid = new ItemsGrid<>() {
|
||||
|
||||
protected List<ItemsGridSlot> gridMask;
|
||||
protected List<HistoryGridSlot> gridMask;
|
||||
|
||||
@Override
|
||||
protected void onGridChanged() {
|
||||
@@ -23,13 +36,19 @@ public class ItemHistoryPanel extends AbstractSubpanel<ItemsGrid<ItemsGridSlot,
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ItemsGridSlot> getMask() {
|
||||
public List<HistoryGridSlot> getMask() {
|
||||
|
||||
if (this.gridMask == null) {
|
||||
this.gridMask = new ArrayList<>();
|
||||
for (int slotIndex = 0; slotIndex < Math.min(size(), this.rows * this.columns); slotIndex++) {
|
||||
this.gridMask.add(new ItemsGridSlot(slotIndex, slotIndex, getItem(slotIndex)));
|
||||
int itemIndex = 0;
|
||||
for (int slotIndex = 0; slotIndex < this.rows * this.columns && itemIndex < size(); slotIndex++) {
|
||||
if (!isInvalidSlot(slotIndex)) {
|
||||
this.gridMask.add(new HistoryGridSlot(slotIndex, itemIndex, getItem(itemIndex)));
|
||||
itemIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
ItemHistoryPanel.this.updateLinePadding();
|
||||
}
|
||||
|
||||
return this.gridMask;
|
||||
@@ -37,7 +56,7 @@ public class ItemHistoryPanel extends AbstractSubpanel<ItemsGrid<ItemsGridSlot,
|
||||
|
||||
@Override
|
||||
protected MouseContext getMouseContext(int mousex, int mousey) {
|
||||
final ItemsGridSlot hovered = getSlotMouseOver(mousex, mousey);
|
||||
final HistoryGridSlot hovered = getSlotMouseOver(mousex, mousey);
|
||||
|
||||
if (hovered != null) {
|
||||
return new MouseContext(
|
||||
|
||||
@@ -16,10 +16,12 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
import net.minecraft.util.IIcon;
|
||||
import net.minecraftforge.fluids.IFluidContainerItem;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
@@ -29,7 +31,11 @@ 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;
|
||||
|
||||
public class ItemList {
|
||||
|
||||
@@ -101,6 +107,12 @@ public class ItemList {
|
||||
return true;
|
||||
}
|
||||
|
||||
displayName = ItemUntranslator.getInstance().getItemStackDisplayName(item);
|
||||
|
||||
if (!displayName.isEmpty() && this.pattern.matcher(displayName).find()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (item.hasDisplayName()) {
|
||||
displayName = EnumChatFormatting
|
||||
.getTextWithoutFormattingCodes(item.getItem().getItemStackDisplayName(item));
|
||||
@@ -290,6 +302,64 @@ public class ItemList {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void runChecked(ItemStack stack, Runnable action, String reason) {
|
||||
int hashOld = 0;
|
||||
if (stack.hasTagCompound()) {
|
||||
hashOld = stack.stackTagCompound.hashCode();
|
||||
}
|
||||
|
||||
action.run();
|
||||
|
||||
if (stack.hasTagCompound() && hashOld != stack.stackTagCompound.hashCode()) {
|
||||
FMLLog.warning(
|
||||
"NEI: Forced tag update with reason (" + reason
|
||||
+ ") for "
|
||||
+ stack
|
||||
+ "("
|
||||
+ stack.getItem()
|
||||
+ ")");
|
||||
}
|
||||
}
|
||||
|
||||
private void forceTagCompoundInitialization(ItemStack stack) {
|
||||
Item item = stack.getItem();
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
if (item instanceof IFluidContainerItem) {
|
||||
IFluidContainerItem fluidItem = (IFluidContainerItem) item;
|
||||
runChecked(stack, () -> fluidItem.getFluid(stack), "getFluid");
|
||||
}
|
||||
runChecked(stack, () -> item.isDamaged(stack), "isDamaged");
|
||||
runChecked(stack, () -> item.getDamage(stack), "getDamage");
|
||||
runChecked(stack, () -> item.showDurabilityBar(stack), "showDurabilityBar");
|
||||
runChecked(stack, () -> item.getAttributeModifiers(stack), "getAttributeModifiers");
|
||||
runChecked(stack, () -> item.getDurabilityForDisplay(stack), "getDurabilityForDisplay");
|
||||
runChecked(stack, () -> item.getItemStackLimit(stack), "getItemStackLimit");
|
||||
runChecked(stack, () -> item.getToolClasses(stack), "getToolClasses");
|
||||
runChecked(stack, () -> item.getUnlocalizedNameInefficiently(stack), "getUnlocalizedNameInefficiently");
|
||||
runChecked(stack, () -> item.hasEffect(stack), "hasEffect");
|
||||
runChecked(stack, () -> item.getDigSpeed(stack, Blocks.stone, 0), "getDigSpeed");
|
||||
|
||||
/*
|
||||
* unused... for now runChecked(stack, () -> GameRegistry.getFuelValue(stack), "getFuelValue");
|
||||
* runChecked(stack, () -> item.getUnlocalizedName(stack), "getUnlocalizedName"); runChecked(stack, () ->
|
||||
* item.doesContainerItemLeaveCraftingGrid(stack), "doesContainerItemLeaveCraftingGrid"); runChecked(stack,
|
||||
* () -> item.getItemUseAction(stack), "getItemUseAction"); runChecked(stack, () ->
|
||||
* item.getMaxItemUseDuration(stack), "getMaxItemUseDuration"); runChecked(stack, () ->
|
||||
* item.getPotionEffect(stack), "getPotionEffect"); runChecked(stack, () -> item.isPotionIngredient(stack),
|
||||
* "isPotionIngredient"); runChecked(stack, () -> item.getRarity(stack), "getRarity"); runChecked(stack, ()
|
||||
* -> item.hasCustomEntity(stack), "hasCustomEntity"); runChecked(stack, () ->
|
||||
* item.getSmeltingExperience(stack), "getSmeltingExperience"); runChecked(stack, () ->
|
||||
* item.getMaxDamage(stack), "getMaxDamage"); runChecked(stack, () -> item.getDamage(stack), "getDamage");
|
||||
* runChecked(stack, stack::isItemDamaged, "isItemDamaged"); runChecked(stack, () -> item.hasEffect(stack,
|
||||
* 0), "hasEffect"); runChecked(stack, () -> item.getItemEnchantability(stack), "getItemEnchantability");
|
||||
* runChecked(stack, () -> item.isBeaconPayment(stack), "isBeaconPayment"); runChecked(stack, () ->
|
||||
* item.getDamage(stack), "getDamage"); runChecked(stack, () -> item.getDamage(stack), "getDamage");
|
||||
* runChecked(stack, () -> item.getDamage(stack), "getDamage");
|
||||
*/
|
||||
}
|
||||
|
||||
// Generate itemlist, permutations, orders, collapsibleitems, and informationhandler stacks
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -329,6 +399,8 @@ public class ItemList {
|
||||
items.add(stack);
|
||||
}
|
||||
|
||||
forceTagCompoundInitialization(stack);
|
||||
|
||||
CollapsibleItems.putItem(stack);
|
||||
TooltipFilter.getSearchTooltip(stack);
|
||||
InformationHandler.populateStacks(stack);
|
||||
@@ -362,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
|
||||
@@ -222,8 +226,7 @@ public class ItemPanel extends PanelWidget<ItemsPanelGrid> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> handleItemTooltip(GuiContainer gui, ItemStack itemstack, int mousex, int mousey,
|
||||
List<String> currenttip) {
|
||||
public List<String> handleItemTooltip(ItemStack itemstack, int mousex, int mousey, List<String> currenttip) {
|
||||
|
||||
if (!this.grid.forceExpand && !currenttip.isEmpty()) {
|
||||
final ItemsPanelGridSlot hoverSlot = this.grid.getSlotMouseOver(mousex, mousey);
|
||||
@@ -237,7 +240,7 @@ public class ItemPanel extends PanelWidget<ItemsPanelGrid> {
|
||||
}
|
||||
}
|
||||
|
||||
return super.handleItemTooltip(gui, itemstack, mousex, mousey, currenttip);
|
||||
return super.handleItemTooltip(itemstack, mousex, mousey, currenttip);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -258,7 +261,7 @@ public class ItemPanel extends PanelWidget<ItemsPanelGrid> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> handleHotkeys(GuiContainer gui, int mousex, int mousey, Map<String, String> hotkeys) {
|
||||
public Map<String, String> handleHotkeys(int mousex, int mousey, Map<String, String> hotkeys) {
|
||||
final ItemsPanelGridSlot hoverSlot = this.grid.getSlotMouseOver(mousex, mousey);
|
||||
|
||||
if (!this.grid.forceExpand && hoverSlot != null && hoverSlot.groupIndex >= 0 && hoverSlot.groupSize > 1) {
|
||||
@@ -269,7 +272,12 @@ public class ItemPanel extends PanelWidget<ItemsPanelGrid> {
|
||||
NEIClientUtils.translate(message, hoverSlot.groupSize));
|
||||
}
|
||||
|
||||
return hotkeys;
|
||||
return super.handleHotkeys(mousex, mousey, hotkeys);
|
||||
}
|
||||
|
||||
public boolean containsWithSubpanels(int px, int py) {
|
||||
return contains(px, py) || NEIClientConfig.showHistoryPanelWidget() && this.historyPanel.contains(px, py)
|
||||
|| NEIClientConfig.showCraftablesPanelWidget() && this.craftablesPanel.contains(px, py);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -58,7 +58,7 @@ public class ItemZoom extends Widget implements IContainerInputHandler {
|
||||
|
||||
GL11.glPopMatrix();
|
||||
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
|
||||
GL11.glPushAttrib(GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT | GL11.GL_LIGHTING_BIT);
|
||||
GuiContainerManager.enable2DRender();
|
||||
|
||||
if (NEIClientConfig.getBooleanSetting("inventory.itemzoom.showName")) {
|
||||
|
||||
@@ -15,7 +15,6 @@ import net.minecraft.client.shader.Framebuffer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL30;
|
||||
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
import codechicken.nei.api.GuiInfo;
|
||||
@@ -52,7 +51,7 @@ public abstract class ItemsGrid<T extends ItemsGrid.ItemsGridSlot, M extends Ite
|
||||
}
|
||||
|
||||
public void captureScreen(Runnable callback, int mode) {
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
|
||||
GL11.glPushAttrib(GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT | GL11.GL_LIGHTING_BIT);
|
||||
|
||||
resetFramebuffer();
|
||||
this.framebuffer.bindFramebuffer(false);
|
||||
@@ -85,21 +84,6 @@ public abstract class ItemsGrid<T extends ItemsGrid.ItemsGridSlot, M extends Ite
|
||||
} else {
|
||||
this.framebuffer.framebufferClear();
|
||||
}
|
||||
|
||||
// copy depth buffer from MC (fix Angelica)
|
||||
OpenGlHelper.func_153171_g(GL30.GL_READ_FRAMEBUFFER, minecraft.getFramebuffer().framebufferObject);
|
||||
OpenGlHelper.func_153171_g(GL30.GL_DRAW_FRAMEBUFFER, this.framebuffer.framebufferObject);
|
||||
GL30.glBlitFramebuffer(
|
||||
0,
|
||||
0,
|
||||
minecraft.displayWidth,
|
||||
minecraft.displayHeight,
|
||||
0,
|
||||
0,
|
||||
minecraft.displayWidth,
|
||||
minecraft.displayHeight,
|
||||
GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_STENCIL_BUFFER_BIT,
|
||||
GL11.GL_NEAREST);
|
||||
}
|
||||
|
||||
public void renderCapturedScreen() {
|
||||
@@ -281,8 +265,6 @@ public abstract class ItemsGrid<T extends ItemsGrid.ItemsGridSlot, M extends Ite
|
||||
|
||||
protected boolean[] invalidSlotMap;
|
||||
|
||||
protected Label messageLabel = new Label(getMessageOnEmpty(), true);
|
||||
|
||||
protected ScreenCapture screenCapture = null;
|
||||
|
||||
public ArrayList<ItemStack> getItems() {
|
||||
@@ -360,9 +342,6 @@ public abstract class ItemsGrid<T extends ItemsGrid.ItemsGridSlot, M extends Ite
|
||||
rows = height / SLOT_SIZE;
|
||||
|
||||
paddingLeft = (width % SLOT_SIZE) / 2;
|
||||
|
||||
messageLabel.x = marginLeft + width / 2;
|
||||
messageLabel.y = marginTop + height / 2;
|
||||
}
|
||||
|
||||
public void shiftPage(int shift) {
|
||||
@@ -566,12 +545,6 @@ public abstract class ItemsGrid<T extends ItemsGrid.ItemsGridSlot, M extends Ite
|
||||
afterDrawItems(mousex, mousey, mouseContext);
|
||||
}
|
||||
|
||||
public void setVisible() {
|
||||
if (getItems().isEmpty() && getMessageOnEmpty() != null) {
|
||||
LayoutManager.addWidget(messageLabel);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean contains(int px, int py) {
|
||||
final Rectangle4i rect = new Rectangle4i(
|
||||
marginLeft + paddingLeft,
|
||||
@@ -586,7 +559,4 @@ public abstract class ItemsGrid<T extends ItemsGrid.ItemsGridSlot, M extends Ite
|
||||
return !isInvalidSlot(columns * getRowIndex(py) + getColumnIndex(px));
|
||||
}
|
||||
|
||||
public String getMessageOnEmpty() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import java.util.Set;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
import codechicken.nei.ItemsGrid.ItemsGridSlot;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
@@ -69,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<>();
|
||||
@@ -237,9 +238,18 @@ public class ItemsPanelGrid extends ItemsGrid<ItemsPanelGrid.ItemsPanelGridSlot,
|
||||
Math.min((int) (color.getAlpha() + (255f / 5) * 2), 255));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessageOnEmpty() {
|
||||
return ItemList.loadFinished ? null : NEIClientUtils.translate("itempanel.loading");
|
||||
public void draw(int mousex, int mousey) {
|
||||
if (ItemList.loadFinished) {
|
||||
super.draw(mousex, mousey);
|
||||
} else {
|
||||
GuiDraw.drawStringC(
|
||||
NEIClientUtils
|
||||
.cropText(GuiDraw.fontRenderer, NEIClientUtils.translate("itempanel.loading"), width - 10),
|
||||
marginLeft + width / 2,
|
||||
marginTop + height / 2,
|
||||
0xffffff,
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -70,7 +70,7 @@ public class ItemsTooltipLineHandler implements ITooltipLineHandler {
|
||||
}
|
||||
|
||||
public void setActiveStack(ItemStack activeStack) {
|
||||
final ItemStack realStack = items.stream().filter(stack -> StackInfo.equalItemAndNBT(stack, activeStack, true))
|
||||
final ItemStack realStack = items.stream().filter(stack -> NEIClientUtils.areStacksSameType(stack, activeStack))
|
||||
.findFirst().orElse(null);
|
||||
this.activeStackIndex = items.indexOf(realStack);
|
||||
}
|
||||
@@ -100,13 +100,15 @@ public class ItemsTooltipLineHandler implements ITooltipLineHandler {
|
||||
|
||||
fontRenderer.drawStringWithShadow(this.labelColor + this.label + ":", x, y, 0);
|
||||
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
|
||||
GL11.glPushMatrix();
|
||||
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
|
||||
|
||||
GL11.glPushAttrib(GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT | GL11.GL_LIGHTING_BIT);
|
||||
RenderHelper.enableGUIStandardItemLighting();
|
||||
|
||||
GL11.glScaled(1, 1, 3);
|
||||
GL11.glTranslatef(x, y + fontRenderer.FONT_HEIGHT + 2, 0);
|
||||
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
|
||||
final int xTranslation = x;
|
||||
final int yTranslation = y + fontRenderer.FONT_HEIGHT + 2;
|
||||
final int zTranslation = GuiContainerManager.TOOLTIP_Z_OFFSET;
|
||||
GL11.glTranslatef(xTranslation, yTranslation, zTranslation);
|
||||
|
||||
int indexShift = 0;
|
||||
|
||||
@@ -142,7 +144,7 @@ public class ItemsTooltipLineHandler implements ITooltipLineHandler {
|
||||
});
|
||||
}
|
||||
|
||||
GL11.glPopMatrix();
|
||||
GL11.glTranslatef(-xTranslation, -yTranslation, -zTranslation);
|
||||
GL11.glPopAttrib();
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ public class KeyManager {
|
||||
public static void tickKeyStates() {
|
||||
for (Entry<String, KeyState> entry : keyStates.entrySet()) {
|
||||
final int keyCode = NEIKeyboardUtils.unhash(NEIClientConfig.getKeyBinding(entry.getKey()));
|
||||
final boolean down = keyCode < Keyboard.KEYBOARD_SIZE ? Keyboard.isKeyDown(keyCode) : null;
|
||||
final boolean down = keyCode > 0 && keyCode < Keyboard.KEYBOARD_SIZE && Keyboard.isKeyDown(keyCode);
|
||||
final KeyState state = entry.getValue();
|
||||
|
||||
if (down) {
|
||||
|
||||
@@ -68,6 +68,7 @@ import codechicken.nei.guihook.IContainerTooltipHandler;
|
||||
import codechicken.nei.recipe.AutoCraftingManager;
|
||||
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 {
|
||||
@@ -102,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;
|
||||
|
||||
@@ -291,19 +292,6 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postRenderTooltips(GuiContainer gui, int mousex, int mousey, List<String> tooltip) {
|
||||
|
||||
if (!isHidden() && isEnabled() && GuiContainerManager.shouldShowTooltip(gui)) {
|
||||
final Widget focused = getWidgetUnderMouse(mousex, mousey);
|
||||
|
||||
if (focused != null) {
|
||||
focused.postDrawTooltips(mousex, mousey, tooltip);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> handleTooltip(GuiContainer gui, int mousex, int mousey, List<String> currenttip) {
|
||||
|
||||
@@ -354,6 +342,10 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
if (!isHidden() && isEnabled() && GuiContainerManager.shouldShowTooltip(gui)) {
|
||||
final Widget focused = getWidgetUnderMouse(mousex, mousey);
|
||||
|
||||
if (focused != null) {
|
||||
currenttip = focused.handleItemTooltip(itemstack, mousex, mousey, currenttip);
|
||||
}
|
||||
|
||||
if (focused instanceof IContainerTooltipHandler tip) {
|
||||
currenttip = tip.handleItemTooltip(gui, itemstack, mousex, mousey, currenttip);
|
||||
}
|
||||
@@ -368,9 +360,14 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
if (!isHidden() && isEnabled() && GuiContainerManager.shouldShowTooltip(gui)) {
|
||||
final Widget focused = getWidgetUnderMouse(mousex, mousey);
|
||||
|
||||
if (focused instanceof IContainerTooltipHandler tip) {
|
||||
hotkeys = tip.handleHotkeys(gui, mousex, mousey, hotkeys);
|
||||
if (focused != null) {
|
||||
hotkeys = focused.handleHotkeys(mousex, mousey, hotkeys);
|
||||
|
||||
if (focused instanceof IContainerTooltipHandler tip) {
|
||||
hotkeys = tip.handleHotkeys(gui, mousex, mousey, hotkeys);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return hotkeys;
|
||||
@@ -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) {
|
||||
@@ -783,9 +780,10 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
addWidget(itemZoom);
|
||||
|
||||
if (visiblity.showSubsetDropdown) {
|
||||
// Bookmarks or Subset/dropdown
|
||||
addWidget(dropDown);
|
||||
}
|
||||
|
||||
addWidget(DebugHandlerWidget.instance);
|
||||
}
|
||||
|
||||
public static LayoutStyle getLayoutStyle(int id) {
|
||||
@@ -905,6 +903,9 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
final int ty2 = ty + 20 - h2 - te;
|
||||
final int tx2 = 200 - w2 - te;
|
||||
|
||||
final boolean is2DTexture = GL11.glGetBoolean(GL11.GL_TEXTURE_2D);
|
||||
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
changeTexture("textures/gui/widgets.png");
|
||||
drawTexturedModalRect(x, y, tx1, ty1, w1, h1); // top left
|
||||
drawTexturedModalRect(x, y2, tx1, ty2, w1, h2); // bottom left
|
||||
@@ -917,6 +918,8 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
|
||||
drawTexturedModalRect(x2, y, tx2, ty1, w2, h1); // top right
|
||||
drawTexturedModalRect(x2, y2, tx2, ty2, w2, h2); // bottom right
|
||||
|
||||
if (!is2DTexture) GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
public static void drawItemPresenceOverlay(int slotX, int slotY, boolean isPresent, boolean slotHighlight) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -60,7 +60,7 @@ 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;
|
||||
|
||||
@@ -146,6 +146,9 @@ public class NEIClientConfig {
|
||||
tag.getTag("inventory.widgetsenabled").getBooleanValue(true);
|
||||
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);
|
||||
tag.getTag("inventory.hidden").getBooleanValue(false);
|
||||
@@ -206,6 +209,10 @@ public class NEIClientConfig {
|
||||
0,
|
||||
OptionIntegerField.UNSIGNED_INT_MAX));
|
||||
|
||||
tag.getTag("inventory.bookmarks.showRecipeHandlerIcon").setComment("Show Recipe Handler Icon")
|
||||
.getBooleanValue(false);
|
||||
API.addOption(new OptionToggleButton("inventory.bookmarks.showRecipeHandlerIcon", true));
|
||||
|
||||
tag.getTag("inventory.bookmarks.recipeChainDir").getIntValue(1);
|
||||
API.addOption(new OptionCycled("inventory.bookmarks.recipeChainDir", 2, true));
|
||||
|
||||
@@ -217,17 +224,17 @@ public class NEIClientConfig {
|
||||
.getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.bookmarks.bookmarkItemsWithRecipe", true));
|
||||
|
||||
tag.getTag("inventory.bookmarks.bookmarkRecipeWithCount").setComment("Bookmark recipe with count")
|
||||
.getBooleanValue(false);
|
||||
API.addOption(new OptionToggleButton("inventory.bookmarks.bookmarkRecipeWithCount", true));
|
||||
|
||||
tag.getTag("inventory.guirecipe.jeiStyleTabs").setComment("Enable/disable JEI Style Tabs")
|
||||
.getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButtonBoubs("inventory.guirecipe.jeiStyleTabs", true));
|
||||
|
||||
tag.getTag("inventory.guirecipe.jeiStyleRecipeCatalyst").setComment("Enable/disable JEI Style Recipe Catalysts")
|
||||
.getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.guirecipe.jeiStyleRecipeCatalyst", true));
|
||||
|
||||
tag.getTag("inventory.guirecipe.jeiStyleCycledIngredients").setComment("JEI styled cycled ingredients")
|
||||
.getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.guirecipe.jeiStyleCycledIngredients", true));
|
||||
tag.getTag("inventory.guirecipe.jeiStyleRecipeCatalyst")
|
||||
.setComment("JEI Style Recipe Catalysts (0 - none, 1 - grid, 2 - scroll)").getIntValue(1);
|
||||
API.addOption(new OptionCycled("inventory.guirecipe.jeiStyleRecipeCatalyst", 3, true));
|
||||
|
||||
tag.getTag("inventory.guirecipe.cycledIngredientsTooltip").setComment("Show cycled ingredients tooltip")
|
||||
.getBooleanValue(true);
|
||||
@@ -245,6 +252,13 @@ public class NEIClientConfig {
|
||||
.getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.guirecipe.slotHighlightPresent", true));
|
||||
|
||||
tag.getTag("inventory.guirecipe.infiniteScroll").setComment("Use Infinite Scroll for Handlers")
|
||||
.getBooleanValue(false);
|
||||
API.addOption(new OptionToggleButton("inventory.guirecipe.infiniteScroll", true));
|
||||
|
||||
tag.getTag("inventory.guirecipe.maxHeight").setComment("Recipe GUI Max Height").getIntValue(370);
|
||||
API.addOption(new OptionIntegerField("inventory.guirecipe.maxHeight", 166, 4000));
|
||||
|
||||
tag.getTag("inventory.guirecipe.shiftOverlayRecipe")
|
||||
.setComment("Require holding shift to move items when overlaying recipe").getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.guirecipe.shiftOverlayRecipe", true));
|
||||
@@ -252,6 +266,10 @@ public class NEIClientConfig {
|
||||
tag.getTag("inventory.guirecipe.profile").getBooleanValue(false);
|
||||
API.addOption(new OptionToggleButton("inventory.guirecipe.profile", true));
|
||||
|
||||
tag.getTag("inventory.guirecipe.handlerInfo").setComment("ADVANCED: Handler Info Widget")
|
||||
.getBooleanValue(false);
|
||||
API.addOption(new OptionToggleButton("inventory.guirecipe.handlerInfo", true));
|
||||
|
||||
tag.getTag("inventory.subsets.enabled").setComment("Enable/disable Subsets Dropdown").getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.subsets.enabled", true));
|
||||
|
||||
@@ -277,6 +295,10 @@ public class NEIClientConfig {
|
||||
tag.getTag("inventory.craftables.useRows").setComment("Rows used in craftables areas").getIntValue(2);
|
||||
API.addOption(new OptionIntegerField("inventory.craftables.useRows", 1, 5));
|
||||
|
||||
tag.getTag("inventory.craftables.favoritesOnly").setComment("Show Only Favorites Recipes")
|
||||
.getBooleanValue(false);
|
||||
API.addOption(new OptionToggleButton("inventory.craftables.favoritesOnly", true));
|
||||
|
||||
tag.getTag("inventory.collapsibleItems.enabled").getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.collapsibleItems.enabled", true) {
|
||||
|
||||
@@ -424,6 +446,24 @@ public class NEIClientConfig {
|
||||
tag.getTag("inventory.autocrafting").setComment("Autocrafting").getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.autocrafting", true));
|
||||
|
||||
tag.getTag("inventory.itemUntranslator").setComment("Item Untranslator").getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.itemUntranslator", true) {
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button) {
|
||||
super.onClick(button);
|
||||
|
||||
if (enableItemUntranslator()) {
|
||||
ItemUntranslator.getInstance().load();
|
||||
} else {
|
||||
ItemUntranslator.getInstance().unload();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
tag.getTag("tools.handler_load_from_config").setComment("ADVANCED: Load handlers from config")
|
||||
.getBooleanValue(false);
|
||||
API.addOption(new OptionToggleButton("tools.handler_load_from_config", true) {
|
||||
@@ -741,8 +781,7 @@ public class NEIClientConfig {
|
||||
@Override
|
||||
public boolean onClick(int button) {
|
||||
super.onClick(button);
|
||||
FavoriteRecipes.save();
|
||||
FavoriteRecipes.load();
|
||||
FavoriteRecipes.reload();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@@ -755,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));
|
||||
}
|
||||
|
||||
@@ -775,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);
|
||||
@@ -801,6 +853,7 @@ public class NEIClientConfig {
|
||||
API.addKeyBind("world.creative", 0);
|
||||
API.addHashBind("gui.copy_name", Keyboard.KEY_C + NEIClientUtils.CTRL_HASH);
|
||||
API.addHashBind("gui.copy_oredict", Keyboard.KEY_D + NEIClientUtils.CTRL_HASH);
|
||||
API.addHashBind("gui.copy_id", Keyboard.KEY_X + NEIClientUtils.CTRL_HASH);
|
||||
API.addHashBind("gui.chat_link_item", Keyboard.KEY_L + NEIClientUtils.CTRL_HASH);
|
||||
}
|
||||
|
||||
@@ -809,24 +862,27 @@ public class NEIClientConfig {
|
||||
}
|
||||
|
||||
public static void loadWorld(String worldPath) {
|
||||
final File specificDir = new File(CommonUtils.getMinecraftDir(), "saves/NEI/" + worldPath);
|
||||
final boolean newWorld = !specificDir.exists();
|
||||
unloadWorld();
|
||||
setInternalEnabled(true);
|
||||
|
||||
if (!worldPath.equals(NEIClientConfig.worldPath)) {
|
||||
if (!worldPath.equals(NEIClientConfig.worldPath) || newWorld) {
|
||||
NEIClientConfig.worldPath = worldPath;
|
||||
|
||||
logger.debug("Loading " + (Minecraft.getMinecraft().isSingleplayer() ? "Local" : "Remote") + " World");
|
||||
|
||||
final File specificDir = new File(CommonUtils.getMinecraftDir(), "saves/NEI/" + worldPath);
|
||||
final boolean newWorld = !specificDir.exists();
|
||||
|
||||
if (newWorld) {
|
||||
specificDir.mkdirs();
|
||||
}
|
||||
|
||||
world = new ConfigSet(new File(specificDir, "NEI.dat"), new ConfigFile(new File(specificDir, "NEI.cfg")));
|
||||
|
||||
if (newWorld && Minecraft.getMinecraft().isSingleplayer()) {
|
||||
world.config.getTag("inventory.cheatmode")
|
||||
.setIntValue(NEIClientUtils.mc().playerController.isInCreativeMode() ? 2 : 0);
|
||||
}
|
||||
|
||||
bootNEI();
|
||||
onWorldLoad(newWorld);
|
||||
onWorldLoad();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -834,7 +890,7 @@ public class NEIClientConfig {
|
||||
return NEIClientConfig.worldPath;
|
||||
}
|
||||
|
||||
private static void onWorldLoad(boolean newWorld) {
|
||||
private static void onWorldLoad() {
|
||||
world.config.setComment(
|
||||
"World based configuration of NEI.\nMost of these options can be changed ingame.\nDeleting any element will restore it to it's default value");
|
||||
|
||||
@@ -842,12 +898,6 @@ public class NEIClientConfig {
|
||||
creativeInv = new ItemStack[54];
|
||||
LayoutManager.searchField.setText(getSearchExpression());
|
||||
LayoutManager.quantity.setText(Integer.toString(getItemQuantity()));
|
||||
|
||||
if (newWorld && Minecraft.getMinecraft().isSingleplayer()) {
|
||||
world.config.getTag("inventory.cheatmode")
|
||||
.setIntValue(NEIClientUtils.mc().playerController.isInCreativeMode() ? 2 : 0);
|
||||
}
|
||||
|
||||
NEIInfo.load(ClientUtils.getWorld());
|
||||
}
|
||||
|
||||
@@ -861,6 +911,10 @@ public class NEIClientConfig {
|
||||
}
|
||||
|
||||
public static void unloadWorld() {
|
||||
if (world == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ItemPanels.bookmarkPanel != null) {
|
||||
ItemPanels.bookmarkPanel.save();
|
||||
}
|
||||
@@ -868,10 +922,7 @@ public class NEIClientConfig {
|
||||
SubsetWidget.saveHidden();
|
||||
FavoriteRecipes.save();
|
||||
CollapsibleItems.saveStates();
|
||||
|
||||
if (world != null) {
|
||||
world.saveNBT();
|
||||
}
|
||||
world.saveNBT();
|
||||
}
|
||||
|
||||
private static final Map<String, String> keySettings = new HashMap<>();
|
||||
@@ -926,7 +977,6 @@ public class NEIClientConfig {
|
||||
// main NEI config loading
|
||||
ItemInfo.load();
|
||||
GuiInfo.load();
|
||||
RecipeInfo.load();
|
||||
HeldItemHandler.load();
|
||||
LayoutManager.load();
|
||||
NEIController.load();
|
||||
@@ -958,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
|
||||
@@ -967,7 +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());
|
||||
|
||||
ItemList.loadItems.restart();
|
||||
}
|
||||
}.start();
|
||||
@@ -1064,8 +1112,8 @@ public class NEIClientConfig {
|
||||
return getBooleanSetting("inventory.guirecipe.slotHighlightPresent");
|
||||
}
|
||||
|
||||
public static boolean areJEIStyleRecipeCatalystsVisible() {
|
||||
return getBooleanSetting("inventory.guirecipe.jeiStyleRecipeCatalyst");
|
||||
public static int getJEIStyleRecipeCatalysts() {
|
||||
return getIntSetting("inventory.guirecipe.jeiStyleRecipeCatalyst");
|
||||
}
|
||||
|
||||
public static boolean useCreativeTabStyle() {
|
||||
@@ -1084,10 +1132,6 @@ public class NEIClientConfig {
|
||||
return getBooleanSetting("inventory.optimize_gui_overlap_computation");
|
||||
}
|
||||
|
||||
public static boolean useJEIStyledCycledIngredients() {
|
||||
return getBooleanSetting("inventory.guirecipe.jeiStyleCycledIngredients");
|
||||
}
|
||||
|
||||
public static boolean showCycledIngredientsTooltip() {
|
||||
return getBooleanSetting("inventory.guirecipe.cycledIngredientsTooltip");
|
||||
}
|
||||
@@ -1208,6 +1252,10 @@ public class NEIClientConfig {
|
||||
return getBooleanSetting("inventory.collapsibleItems.enabled");
|
||||
}
|
||||
|
||||
public static boolean enableItemUntranslator() {
|
||||
return getBooleanSetting("inventory.itemUntranslator");
|
||||
}
|
||||
|
||||
public static boolean getMagnetMode() {
|
||||
return enabledActions.contains("magnet");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -528,7 +527,9 @@ public class NEIClientUtils extends NEIServerUtils {
|
||||
}
|
||||
|
||||
public static void drawRect(double left, double top, double width, double height, Color color) {
|
||||
Tessellator tessellator = Tessellator.instance;
|
||||
final boolean is2DTexture = GL11.glGetBoolean(GL11.GL_TEXTURE_2D);
|
||||
final boolean isBlend = GL11.glGetBoolean(GL11.GL_BLEND);
|
||||
final Tessellator tessellator = Tessellator.instance;
|
||||
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
@@ -540,8 +541,9 @@ public class NEIClientUtils extends NEIServerUtils {
|
||||
tessellator.addVertex(left + width, top, 0.0D);
|
||||
tessellator.addVertex(left, top, 0.0D);
|
||||
tessellator.draw();
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
GL11.glDisable(GL11.GL_BLEND);
|
||||
GL11.glColor4f(1, 1, 1, 1);
|
||||
if (is2DTexture) GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
if (!isBlend) GL11.glDisable(GL11.GL_BLEND);
|
||||
}
|
||||
|
||||
public static void drawNEIOverlayText(String text, Rectangle4i rect, float scale, int color, boolean shadow,
|
||||
|
||||
@@ -14,6 +14,7 @@ import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.client.ClientCommandHandler;
|
||||
|
||||
import codechicken.core.CommonUtils;
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.nei.api.API;
|
||||
import codechicken.nei.api.GuiInfo;
|
||||
import codechicken.nei.api.IInfiniteItemHandler;
|
||||
@@ -21,6 +22,7 @@ import codechicken.nei.api.INEIGuiHandler;
|
||||
import codechicken.nei.api.ItemInfo;
|
||||
import codechicken.nei.commands.CommandBookmarkAdd;
|
||||
import codechicken.nei.commands.CommandRecipeId;
|
||||
import codechicken.nei.commands.CommandUntranslator;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.guihook.IContainerInputHandler;
|
||||
import codechicken.nei.guihook.IContainerSlotClickHandler;
|
||||
@@ -68,6 +70,7 @@ public class NEIController implements IContainerSlotClickHandler, IContainerInpu
|
||||
public static void registerClientCommands() {
|
||||
ClientCommandHandler.instance.registerCommand(new CommandBookmarkAdd());
|
||||
ClientCommandHandler.instance.registerCommand(new CommandRecipeId());
|
||||
ClientCommandHandler.instance.registerCommand(new CommandUntranslator());
|
||||
}
|
||||
|
||||
public static void updateUnlimitedItems(InventoryPlayer inventory) {
|
||||
@@ -136,7 +139,7 @@ public class NEIController implements IContainerSlotClickHandler, IContainerInpu
|
||||
return true;
|
||||
}
|
||||
|
||||
if (button == 1 && slot instanceof SlotCrafting) // right click
|
||||
if (button == 1 && modifier != 2 && slot instanceof SlotCrafting) // right click
|
||||
{
|
||||
for (int i1 = 0; i1 < 64; i1++) // click this slot 64 times
|
||||
manager.handleSlotClick(slot.slotNumber, button, 0);
|
||||
@@ -154,20 +157,32 @@ public class NEIController implements IContainerSlotClickHandler, IContainerInpu
|
||||
|
||||
if (GuiInfo.hasCustomSlots(gui)) return false;
|
||||
|
||||
if (slotIndex >= 0 && NEIClientUtils.shiftKey()
|
||||
&& NEIClientUtils.getHeldItem() != null
|
||||
&& !slot.getHasStack()) {
|
||||
ItemStack held = NEIClientUtils.getHeldItem();
|
||||
manager.handleSlotClick(slot.slotNumber, button, 0);
|
||||
if (slot.isItemValid(held) && !ItemInfo.fastTransferExemptions.contains(slot.getClass()))
|
||||
fastTransferManager.performMassTransfer(gui, pickedUpFromSlot, slotIndex, held);
|
||||
if (NEIClientUtils.shiftKey()) {
|
||||
// fix small mouse movement while clicking causing slotIndex to be -999
|
||||
if (slotIndex == -999) {
|
||||
final Point mouse = GuiDraw.getMousePosition();
|
||||
slot = gui.getSlotAtPosition(mouse.x, mouse.y);
|
||||
|
||||
return true;
|
||||
}
|
||||
if (slot != null) {
|
||||
slotIndex = slot.slotNumber;
|
||||
}
|
||||
}
|
||||
|
||||
if (slotIndex == -999 && NEIClientUtils.shiftKey() && button == 0) {
|
||||
fastTransferManager.throwAll(gui, pickedUpFromSlot);
|
||||
return true;
|
||||
if (slotIndex >= 0 && NEIClientUtils.getHeldItem() != null && !slot.getHasStack()) {
|
||||
final ItemStack held = NEIClientUtils.getHeldItem();
|
||||
manager.handleSlotClick(slot.slotNumber, button, 0);
|
||||
|
||||
if (slot.isItemValid(held) && !ItemInfo.fastTransferExemptions.contains(slot.getClass())) {
|
||||
fastTransferManager.performMassTransfer(gui, pickedUpFromSlot, slotIndex, held);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (slotIndex == -999 && button == 0) {
|
||||
fastTransferManager.throwAll(gui, pickedUpFromSlot);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -51,15 +51,18 @@ import cpw.mods.fml.relauncher.ReflectionHelper;
|
||||
|
||||
public class NEIServerUtils {
|
||||
|
||||
private static Class<?> gtMetaBaseItem;
|
||||
private static class GTMetaBaseItemHolder {
|
||||
|
||||
static {
|
||||
try {
|
||||
final ClassLoader loader = NEIServerUtils.class.getClassLoader();
|
||||
NEIServerUtils.gtMetaBaseItem = ReflectionHelper
|
||||
.getClass(loader, "gregtech.api.items.MetaBaseItem", "gregtech.api.items.GT_MetaBase_Item");
|
||||
} catch (Exception ignored) {
|
||||
/* Do nothing */
|
||||
private static final Class<?> gtMetaBaseItem = loadMetaBaseItem();
|
||||
|
||||
private static Class<?> loadMetaBaseItem() {
|
||||
try {
|
||||
final ClassLoader loader = NEIServerUtils.class.getClassLoader();
|
||||
return ReflectionHelper
|
||||
.getClass(loader, "gregtech.api.items.MetaBaseItem", "gregtech.api.items.GT_MetaBase_Item");
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,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());
|
||||
}
|
||||
|
||||
@@ -231,7 +234,8 @@ public class NEIServerUtils {
|
||||
* @return
|
||||
*/
|
||||
public static boolean isItemTool(ItemStack stack) {
|
||||
return NEIServerUtils.gtMetaBaseItem != null && NEIServerUtils.gtMetaBaseItem.isInstance(stack.getItem());
|
||||
return GTMetaBaseItemHolder.gtMetaBaseItem != null
|
||||
&& GTMetaBaseItemHolder.gtMetaBaseItem.isInstance(stack.getItem());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,14 +11,12 @@ import codechicken.lib.vec.Rectangle4i;
|
||||
import codechicken.nei.ItemsGrid.ItemsGridSlot;
|
||||
import codechicken.nei.api.GuiInfo;
|
||||
import codechicken.nei.api.INEIGuiHandler;
|
||||
import codechicken.nei.api.ShortcutInputHandler;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.guihook.IContainerTooltipHandler;
|
||||
import codechicken.nei.recipe.GuiCraftingRecipe;
|
||||
import codechicken.nei.recipe.GuiRecipe;
|
||||
import codechicken.nei.recipe.GuiUsageRecipe;
|
||||
|
||||
public abstract class PanelWidget<T extends ItemsGrid<? extends ItemsGridSlot, ? extends ItemsGrid.MouseContext>>
|
||||
extends Widget implements IContainerTooltipHandler {
|
||||
extends Widget {
|
||||
|
||||
protected static final int PADDING = 2;
|
||||
|
||||
@@ -84,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;
|
||||
@@ -147,7 +149,6 @@ public abstract class PanelWidget<T extends ItemsGrid<? extends ItemsGridSlot, ?
|
||||
LayoutManager.addWidget(pagePrev);
|
||||
LayoutManager.addWidget(pageNext);
|
||||
LayoutManager.addWidget(pageLabel);
|
||||
this.grid.setVisible();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -285,13 +286,7 @@ public abstract class PanelWidget<T extends ItemsGrid<? extends ItemsGridSlot, ?
|
||||
|
||||
if (NEIController.manager.window instanceof GuiRecipe || NEIClientUtils.shiftKey()
|
||||
|| !NEIClientConfig.canCheatItem(hoverSlot.getItemStack())) {
|
||||
|
||||
if (button == 0) {
|
||||
GuiCraftingRecipe.openRecipeGui("item", hoverSlot.getItemStack().copy());
|
||||
} else if (button == 1) {
|
||||
GuiUsageRecipe.openRecipeGui("item", hoverSlot.getItemStack().copy());
|
||||
}
|
||||
|
||||
ShortcutInputHandler.handleMouseClick(hoverSlot.getItemStack());
|
||||
} else {
|
||||
NEIClientUtils.cheatItem(getDraggedStackWithQuantity(hoverSlot.getItemStack()), button, -1);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -114,16 +114,25 @@ public class PositionedStack {
|
||||
return filteredItems.isEmpty() ? items : filteredItems;
|
||||
}
|
||||
|
||||
public boolean setPermutationToRender(ItemStack ingredient) {
|
||||
public int getPermutationIndex(ItemStack stack) {
|
||||
|
||||
for (int index = 0; index < this.items.length; index++) {
|
||||
if (NEIServerUtils.areStacksSameTypeCraftingWithNBT(this.items[index], ingredient)) {
|
||||
setPermutationToRender(index);
|
||||
return true;
|
||||
if (NEIServerUtils.areStacksSameType(items[index], stack)) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
public boolean setPermutationToRender(ItemStack ingredient) {
|
||||
final int stackIndex = getPermutationIndex(ingredient);
|
||||
|
||||
if (stackIndex >= 0) {
|
||||
setPermutationToRender(stackIndex);
|
||||
}
|
||||
|
||||
return stackIndex >= 0;
|
||||
}
|
||||
|
||||
public void setPermutationToRender(int index) {
|
||||
@@ -136,6 +145,10 @@ public class PositionedStack {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean contains(int mx, int my) {
|
||||
return mx >= this.relx - 1 && mx < this.relx + 17 && my >= this.rely - 1 && my < this.rely + 17;
|
||||
}
|
||||
|
||||
public boolean contains(ItemStack ingredient) {
|
||||
for (ItemStack item : items) if (NEIServerUtils.areStacksSameTypeCrafting(item, ingredient)) return true;
|
||||
|
||||
|
||||
@@ -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 + "\"";
|
||||
}
|
||||
|
||||
|
||||
@@ -122,10 +122,8 @@ public class SearchTokenParser {
|
||||
Language currentLanguage = Minecraft.getMinecraft().getLanguageManager().getCurrentLanguage();
|
||||
|
||||
if (!currentLanguage.getLanguageCode().equals(providersCache.languageCode)) {
|
||||
providersCache.providers = new ArrayList<>();
|
||||
providersCache.languageCode = currentLanguage.getLanguageCode();
|
||||
|
||||
Map<Character, ISearchParserProvider> providers = new HashMap<>();
|
||||
final List<ISearchParserProvider> providersList = new ArrayList<>();
|
||||
final Map<Character, ISearchParserProvider> providers = new HashMap<>();
|
||||
|
||||
for (int index = this.searchProviders.size() - 1; index >= 0; index--) {
|
||||
ISearchParserProvider provider = this.searchProviders.get(index);
|
||||
@@ -134,12 +132,14 @@ public class SearchTokenParser {
|
||||
if (provider.getSearchMode() == SearchMode.PREFIX && !providers.containsKey(provider.getPrefix())) {
|
||||
providers.put(provider.getPrefix(), provider);
|
||||
} else if (provider.getSearchMode() == SearchMode.ALWAYS) {
|
||||
providersCache.providers.add(provider);
|
||||
providersList.add(provider);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
providersCache.providers.addAll(providers.values());
|
||||
providersList.addAll(providers.values());
|
||||
providersCache.languageCode = currentLanguage.getLanguageCode();
|
||||
providersCache.providers = providersList;
|
||||
}
|
||||
|
||||
return providersCache.providers;
|
||||
@@ -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,15 +10,11 @@ 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;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
@@ -40,7 +36,6 @@ import codechicken.nei.api.API;
|
||||
import codechicken.nei.api.ItemFilter;
|
||||
import codechicken.nei.api.ItemFilter.ItemFilterProvider;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.guihook.IContainerTooltipHandler;
|
||||
import codechicken.nei.recipe.GuiCraftingRecipe;
|
||||
import codechicken.nei.recipe.GuiRecipeTab;
|
||||
import codechicken.nei.recipe.ICraftingHandler;
|
||||
@@ -49,15 +44,13 @@ import codechicken.nei.recipe.StackInfo;
|
||||
import codechicken.nei.util.NBTJson;
|
||||
import codechicken.nei.util.NEIMouseUtils;
|
||||
|
||||
public class SubsetWidget extends Button implements ItemFilterProvider, IContainerTooltipHandler {
|
||||
public class SubsetWidget extends Button implements ItemFilterProvider {
|
||||
|
||||
protected static final int SLOT_HEIGHT = 18;
|
||||
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 {
|
||||
|
||||
@@ -379,11 +372,18 @@ public class SubsetWidget extends Button implements ItemFilterProvider, IContain
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -416,6 +416,7 @@ public class SubsetWidget extends Button implements ItemFilterProvider, IContain
|
||||
* 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;
|
||||
@@ -438,6 +439,7 @@ public class SubsetWidget extends Button implements ItemFilterProvider, IContain
|
||||
}
|
||||
|
||||
updateHiddenItems();
|
||||
SearchField.searchParser.clearCache();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -449,24 +451,14 @@ public class SubsetWidget extends Button implements ItemFilterProvider, IContain
|
||||
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) {
|
||||
@@ -480,90 +472,45 @@ public class SubsetWidget extends Button implements ItemFilterProvider, IContain
|
||||
}
|
||||
|
||||
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() {
|
||||
@@ -648,29 +595,20 @@ public class SubsetWidget extends Button implements ItemFilterProvider, IContain
|
||||
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);
|
||||
@@ -688,14 +626,22 @@ public class SubsetWidget extends Button implements ItemFilterProvider, IContain
|
||||
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) {
|
||||
@@ -731,6 +677,7 @@ public class SubsetWidget extends Button implements ItemFilterProvider, IContain
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
SearchField.searchParser.clearCache();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -747,6 +694,11 @@ public class SubsetWidget extends Button implements ItemFilterProvider, IContain
|
||||
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;
|
||||
}
|
||||
@@ -788,7 +740,7 @@ public class SubsetWidget extends Button implements ItemFilterProvider, IContain
|
||||
|
||||
root.resize(screen, parent, dropRight);
|
||||
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
|
||||
GL11.glPushAttrib(GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT | GL11.GL_LIGHTING_BIT);
|
||||
GuiContainerManager.enable2DRender();
|
||||
GuiContainerManager.drawItems.zLevel += 100;
|
||||
|
||||
@@ -939,7 +891,7 @@ public class SubsetWidget extends Button implements ItemFilterProvider, IContain
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> handleHotkeys(GuiContainer gui, int mousex, int mousey, Map<String, String> hotkeys) {
|
||||
public Map<String, String> handleHotkeys(int mousex, int mousey, Map<String, String> hotkeys) {
|
||||
|
||||
if (SubsetWidget.hoverStack != null) {
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package codechicken.nei;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
@@ -14,8 +15,6 @@ public abstract class Widget {
|
||||
|
||||
public void postDraw(int mx, int my) {}
|
||||
|
||||
public void postDrawTooltips(int mx, int my, List<String> tooltip) {}
|
||||
|
||||
public boolean handleClick(int mx, int my, int button) {
|
||||
return true;
|
||||
}
|
||||
@@ -38,6 +37,10 @@ public abstract class Widget {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Map<String, String> handleHotkeys(int mousex, int mousey, Map<String, String> hotkeys) {
|
||||
return hotkeys;
|
||||
}
|
||||
|
||||
public void update() {}
|
||||
|
||||
public Rectangle4i bounds() {
|
||||
@@ -58,6 +61,14 @@ public abstract class Widget {
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
public List<String> handleItemTooltip(ItemStack itemstack, int mousex, int mousey, List<String> tooltip) {
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
public boolean isFocused() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void loseFocus() {}
|
||||
|
||||
public void gainFocus() {}
|
||||
@@ -67,4 +78,5 @@ public abstract class Widget {
|
||||
public int z;
|
||||
public int w;
|
||||
public int h;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
package codechicken.nei;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
|
||||
public class WidgetContainer extends Widget {
|
||||
|
||||
protected final List<Widget> widgets = new ArrayList<>();
|
||||
protected boolean isFocused = false;
|
||||
|
||||
public void addWidget(Widget widget) {
|
||||
this.widgets.add(widget);
|
||||
}
|
||||
|
||||
public void setWidgets(List<Widget> widgets) {
|
||||
final boolean isFocused = this.isFocused;
|
||||
clear();
|
||||
loseFocus();
|
||||
|
||||
for (Widget widget : widgets) {
|
||||
addWidget(widget);
|
||||
}
|
||||
|
||||
this.isFocused = isFocused;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.widgets.clear();
|
||||
this.isFocused = false;
|
||||
}
|
||||
|
||||
public List<Widget> getWidgets() {
|
||||
return Collections.unmodifiableList(this.widgets);
|
||||
}
|
||||
|
||||
public boolean removeIf(Predicate<Widget> filter) {
|
||||
return this.widgets.removeIf(filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int mousex, int mousey) {
|
||||
drawWidgets(mousex, mousey);
|
||||
}
|
||||
|
||||
protected void drawWidgets(int mousex, int mousey) {
|
||||
final Rectangle4i bounds = bounds();
|
||||
|
||||
for (Widget widget : this.widgets) {
|
||||
if (widget.bounds().intersects(bounds)) {
|
||||
widget.draw(mousex, mousey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
|
||||
for (Widget widget : this.widgets) {
|
||||
widget.update();
|
||||
}
|
||||
|
||||
Collections.sort(this.widgets, Comparator.comparingInt((Widget widget) -> widget.z));
|
||||
}
|
||||
|
||||
public Widget getWidgetUnderMouse(int mousex, int mousey) {
|
||||
|
||||
if (!bounds().contains(mousex, mousey)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int index = this.widgets.size() - 1; index >= 0; index--) {
|
||||
final Widget widget = this.widgets.get(index);
|
||||
if (widget.contains(mousex, mousey)) {
|
||||
return widget;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMouseWheel(int scroll, int mousex, int mousey) {
|
||||
final Widget widget = getWidgetUnderMouse(mousex, mousey);
|
||||
|
||||
return widget != null && widget.onMouseWheel(scroll, mousex, mousey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleClick(int mousex, int mousey, int button) {
|
||||
|
||||
if (contains(mousex, mousey)) {
|
||||
gainFocus();
|
||||
}
|
||||
|
||||
final Widget widget = getWidgetUnderMouse(mousex, mousey);
|
||||
|
||||
return widget != null && widget.handleClick(mousex, mousey, button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleClickExt(int mousex, int mousey, int button) {
|
||||
loseFocus();
|
||||
|
||||
for (int index = this.widgets.size() - 1; index >= 0; index--) {
|
||||
final Widget widget = this.widgets.get(index);
|
||||
if (!widget.contains(mousex, mousey) && widget.handleClickExt(mousex, mousey, button)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(int mousex, int mousey, int button, long heldTime) {
|
||||
|
||||
for (int index = this.widgets.size() - 1; index >= 0; index--) {
|
||||
final Widget widget = this.widgets.get(index);
|
||||
widget.mouseDragged(mousex, mousey, button, heldTime);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseUp(int mousex, int mousey, int button) {
|
||||
|
||||
for (int index = this.widgets.size() - 1; index >= 0; index--) {
|
||||
final Widget widget = this.widgets.get(index);
|
||||
widget.mouseUp(mousex, mousey, button);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleKeyPress(int keyCode, char keyChar) {
|
||||
|
||||
for (int index = this.widgets.size() - 1; index >= 0; index--) {
|
||||
final Widget widget = this.widgets.get(index);
|
||||
if (widget.handleKeyPress(keyCode, keyChar)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lastKeyTyped(int keyID, char keyChar) {
|
||||
|
||||
for (int index = this.widgets.size() - 1; index >= 0; index--) {
|
||||
final Widget widget = this.widgets.get(index);
|
||||
widget.lastKeyTyped(keyID, keyChar);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFocused() {
|
||||
return this.isFocused;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loseFocus() {
|
||||
|
||||
for (int index = this.widgets.size() - 1; index >= 0; index--) {
|
||||
final Widget widget = this.widgets.get(index);
|
||||
if (widget.isFocused()) {
|
||||
widget.loseFocus();
|
||||
}
|
||||
}
|
||||
|
||||
this.isFocused = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void gainFocus() {
|
||||
final Point mouse = GuiDraw.getMousePosition();
|
||||
final Widget widget = getWidgetUnderMouse(mouse.x, mouse.y);
|
||||
|
||||
if (widget != null) {
|
||||
|
||||
if (!widget.isFocused()) {
|
||||
loseFocus();
|
||||
widget.gainFocus();
|
||||
}
|
||||
|
||||
} else {
|
||||
loseFocus();
|
||||
}
|
||||
|
||||
this.isFocused = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackMouseOver(int mousex, int mousey) {
|
||||
final Widget widget = getWidgetUnderMouse(mousex, mousey);
|
||||
|
||||
if (widget != null) {
|
||||
return widget.getStackMouseOver(mousex, mousey);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postDraw(int mousex, int mousey) {
|
||||
|
||||
for (Widget widget : this.widgets) {
|
||||
widget.postDraw(mousex, mousey);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGuiClick(int mousex, int mousey) {
|
||||
|
||||
for (int index = this.widgets.size() - 1; index >= 0; index--) {
|
||||
final Widget widget = this.widgets.get(index);
|
||||
widget.onGuiClick(mousex, mousey);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> handleTooltip(int mousex, int mousey, List<String> tooltip) {
|
||||
final Widget widget = getWidgetUnderMouse(mousex, mousey);
|
||||
|
||||
if (widget != null) {
|
||||
return widget.handleTooltip(mousex, mousey, tooltip);
|
||||
}
|
||||
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> handleHotkeys(int mousex, int mousey, Map<String, String> hotkeys) {
|
||||
final Widget widget = getWidgetUnderMouse(mousex, mousey);
|
||||
|
||||
if (widget != null) {
|
||||
return widget.handleHotkeys(mousex, mousey, hotkeys);
|
||||
}
|
||||
|
||||
return hotkeys;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,7 +24,7 @@ public class DefaultOverlayRenderer implements IRecipeOverlayRenderer {
|
||||
|
||||
@Override
|
||||
public void renderOverlay(GuiContainerManager gui, Slot slot) {
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
|
||||
GL11.glPushAttrib(GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT | GL11.GL_LIGHTING_BIT);
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
GL11.glBlendFunc(770, 1);
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ import codechicken.nei.NEIDummySlotHandler;
|
||||
import codechicken.nei.NEIPotionGuiHandler;
|
||||
import codechicken.nei.recipe.CheatItemHandler;
|
||||
import codechicken.nei.recipe.FillFluidContainerHandler;
|
||||
import codechicken.nei.recipe.GuiRecipeCatalyst;
|
||||
import codechicken.nei.recipe.SearchInputDropHandler;
|
||||
|
||||
public class GuiInfo {
|
||||
@@ -31,7 +30,6 @@ public class GuiInfo {
|
||||
API.registerNEIGuiHandler(new NEICreativeGuiHandler());
|
||||
API.registerNEIGuiHandler(new NEIChestGuiHandler());
|
||||
API.registerNEIGuiHandler(new NEIDummySlotHandler());
|
||||
API.registerNEIGuiHandler(new GuiRecipeCatalyst(null));
|
||||
API.registerNEIGuiHandler(new SearchInputDropHandler());
|
||||
API.registerNEIGuiHandler(new FillFluidContainerHandler());
|
||||
API.registerNEIGuiHandler(new CheatItemHandler());
|
||||
|
||||
@@ -15,7 +15,7 @@ public interface IBookmarkContainerHandler {
|
||||
|
||||
for (int i = 0; i < slots.size() - 4 * 9; i++) {
|
||||
if (slots.get(i).getHasStack()) {
|
||||
stacks.add(slots.get(i).getStack());
|
||||
stacks.add(slots.get(i).getStack().copy());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,10 @@ public interface IStackStringifyHandler {
|
||||
return null;
|
||||
}
|
||||
|
||||
default ItemStack normalizeRecipeQueryStack(ItemStack stack) {
|
||||
return null;
|
||||
}
|
||||
|
||||
default void pauseItemDamageSound(boolean pause) {}
|
||||
|
||||
}
|
||||
@@ -65,6 +65,7 @@ import codechicken.nei.search.IdentifierFilter;
|
||||
import codechicken.nei.search.ModNameFilter;
|
||||
import codechicken.nei.search.OreDictionaryFilter;
|
||||
import codechicken.nei.search.TooltipFilter;
|
||||
import codechicken.nei.util.ItemUntranslator;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.registry.GameRegistry;
|
||||
@@ -137,6 +138,10 @@ public class ItemInfo {
|
||||
addSearchProviders();
|
||||
RecipeItemInputHandler.load();
|
||||
PresetsList.load();
|
||||
|
||||
if (NEIClientConfig.enableItemUntranslator()) {
|
||||
ItemUntranslator.getInstance().load();
|
||||
}
|
||||
}
|
||||
|
||||
private static void addSearchProviders() {
|
||||
@@ -416,30 +421,38 @@ public class ItemInfo {
|
||||
Block mouseoverBlock = world.getBlock(x, y, z);
|
||||
|
||||
ArrayList<ItemStack> items = new ArrayList<>();
|
||||
|
||||
ArrayList<IHighlightHandler> handlers = new ArrayList<>();
|
||||
|
||||
if (highlightIdentifiers.containsKey(null)) handlers.addAll(highlightIdentifiers.get(null));
|
||||
if (highlightIdentifiers.containsKey(mouseoverBlock)) handlers.addAll(highlightIdentifiers.get(mouseoverBlock));
|
||||
|
||||
for (IHighlightHandler ident : handlers) {
|
||||
ItemStack item = ident.identifyHighlight(world, player, hit);
|
||||
final ItemStack item = ident.identifyHighlight(world, player, hit);
|
||||
if (item != null) items.add(item);
|
||||
}
|
||||
|
||||
if (items.size() > 0) return items;
|
||||
if (!items.isEmpty()) return items;
|
||||
|
||||
ItemStack pick = mouseoverBlock.getPickBlock(hit, world, x, y, z, player);
|
||||
if (pick != null) items.add(pick);
|
||||
try {
|
||||
final ItemStack pick = mouseoverBlock.getPickBlock(hit, world, x, y, z, player);
|
||||
if (pick != null) items.add(pick);
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
if (!items.isEmpty()) return items;
|
||||
|
||||
if (mouseoverBlock instanceof IShearable shearable) {
|
||||
if (shearable.isShearable(new ItemStack(Items.shears), world, x, y, z)) {
|
||||
items.addAll(shearable.onSheared(new ItemStack(Items.shears), world, x, y, z, 0));
|
||||
}
|
||||
}
|
||||
|
||||
if (!items.isEmpty()) return items;
|
||||
|
||||
try {
|
||||
items.addAll(mouseoverBlock.getDrops(world, x, y, z, world.getBlockMetadata(x, y, z), 0));
|
||||
} catch (Exception ignored) {}
|
||||
if (mouseoverBlock instanceof IShearable) {
|
||||
IShearable shearable = (IShearable) mouseoverBlock;
|
||||
if (shearable.isShearable(new ItemStack(Items.shears), world, x, y, z))
|
||||
items.addAll(shearable.onSheared(new ItemStack(Items.shears), world, x, y, z, 0));
|
||||
}
|
||||
|
||||
if (items.size() == 0) items.add(0, new ItemStack(mouseoverBlock, 1, world.getBlockMetadata(x, y, z)));
|
||||
if (items.isEmpty()) items.add(new ItemStack(mouseoverBlock, 1, world.getBlockMetadata(x, y, z)));
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import codechicken.nei.SearchField;
|
||||
import codechicken.nei.bookmark.BookmarkGrid;
|
||||
import codechicken.nei.bookmark.BookmarkGroup;
|
||||
import codechicken.nei.bookmark.BookmarkItem;
|
||||
import codechicken.nei.bookmark.BookmarkItem.BookmarkItemType;
|
||||
import codechicken.nei.bookmark.BookmarksGridSlot;
|
||||
import codechicken.nei.recipe.AutoCraftingManager;
|
||||
import codechicken.nei.recipe.GuiCraftingRecipe;
|
||||
@@ -42,6 +43,31 @@ import codechicken.nei.util.NEIMouseUtils;
|
||||
|
||||
public abstract class ShortcutInputHandler {
|
||||
|
||||
private static class HotkeysCache {
|
||||
|
||||
public int mousex;
|
||||
public int mousey;
|
||||
public ItemStack stack;
|
||||
public int groupId;
|
||||
public Map<String, String> hotkeys = new HashMap<>();
|
||||
|
||||
public boolean matches(int mousex, int mousey, ItemStack stack, int groupId) {
|
||||
return Math.abs(this.mousex - mousex) < 16 && Math.abs(this.mousey - mousey) < 16
|
||||
&& (this.stack == null ? stack == null && this.groupId == groupId
|
||||
: stack != null && NEIClientUtils.areStacksSameTypeWithNBT(stack, this.stack));
|
||||
}
|
||||
|
||||
public void update(int mousex, int mousey, ItemStack stack, int groupId, Map<String, String> hotkeys) {
|
||||
this.mousex = mousex;
|
||||
this.mousey = mousey;
|
||||
this.stack = stack != null ? stack.copy() : null;
|
||||
this.groupId = groupId;
|
||||
this.hotkeys = hotkeys;
|
||||
}
|
||||
}
|
||||
|
||||
private static HotkeysCache hotkeysCache = new HotkeysCache();
|
||||
|
||||
public static boolean handleKeyEvent(ItemStack stackover) {
|
||||
|
||||
if (!NEIClientConfig.isLoaded()) {
|
||||
@@ -98,6 +124,9 @@ public abstract class ShortcutInputHandler {
|
||||
if (NEIClientConfig.isKeyHashDown("gui.copy_name")) {
|
||||
return copyItemStackName(stackover);
|
||||
}
|
||||
if (NEIClientConfig.isKeyHashDown("gui.copy_id")) {
|
||||
return copyItemStackID(stackover);
|
||||
}
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.copy_oredict")) {
|
||||
return copyItemStackOreDictionary(stackover);
|
||||
@@ -145,9 +174,9 @@ public abstract class ShortcutInputHandler {
|
||||
final int button = Mouse.getEventButton();
|
||||
|
||||
if (button == 0) {
|
||||
return GuiCraftingRecipe.openRecipeGui("item", stackover);
|
||||
return GuiCraftingRecipe.openRecipeGui("item", stackover.copy());
|
||||
} else if (button == 1) {
|
||||
return GuiUsageRecipe.openRecipeGui("item", stackover);
|
||||
return GuiUsageRecipe.openRecipeGui("item", stackover.copy());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,6 +188,14 @@ public abstract class ShortcutInputHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean copyItemStackID(ItemStack stackover) {
|
||||
if (stackover == null || stackover.getItem() == null) return false;
|
||||
GuiScreen.setClipboardString(
|
||||
stackover.getItem().delegate.name()
|
||||
+ (stackover.getItemDamage() != 0 ? "/" + stackover.getItemDamage() : ""));
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean sendItemStackChatLink(ItemStack stackover) {
|
||||
if (stackover == null) return false;
|
||||
|
||||
@@ -197,12 +234,12 @@ public abstract class ShortcutInputHandler {
|
||||
if (recipe != null) {
|
||||
math = RecipeChainMath.of(recipe, 1);
|
||||
}
|
||||
} else if (slot.getRecipeId() != null && !slot.isIngredient()) {
|
||||
} 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()
|
||||
@@ -276,11 +313,14 @@ public abstract class ShortcutInputHandler {
|
||||
private static boolean saveRecipeInBookmark(ItemStack stackover, boolean saveIngredients, boolean saveStackSize) {
|
||||
final Point mousePos = GuiDraw.getMousePosition();
|
||||
|
||||
// If no slot was removed from the bookmark panel on click:
|
||||
if (!ItemPanels.bookmarkPanel.removeSlot(mousePos.x, mousePos.y, saveIngredients)) {
|
||||
final Recipe recipe = getFocusedRecipe(stackover, mousePos.x, mousePos.y, saveIngredients);
|
||||
|
||||
// --- Case 1: saving a recipe (with ingredients) ---
|
||||
if (recipe != null && saveIngredients) {
|
||||
|
||||
// If the recipe is not already bookmarked, add it
|
||||
if (!ItemPanels.bookmarkPanel.removeRecipe(recipe.getRecipeId(), BookmarkGrid.DEFAULT_GROUP_ID)) {
|
||||
final Recipe singleRecipe = Recipe.of(
|
||||
Arrays.asList(recipe.getResult(stackover)),
|
||||
@@ -288,27 +328,38 @@ public abstract class ShortcutInputHandler {
|
||||
recipe.getIngredients());
|
||||
singleRecipe.setCustomRecipeId(recipe.getRecipeId());
|
||||
|
||||
ItemPanels.bookmarkPanel
|
||||
.addRecipe(singleRecipe, saveStackSize ? 1 : 0, BookmarkGrid.DEFAULT_GROUP_ID);
|
||||
ItemPanels.bookmarkPanel.addRecipe(
|
||||
singleRecipe,
|
||||
// Determine if stack size should be saved
|
||||
saveStackSize
|
||||
|| NEIClientConfig.getBooleanSetting("inventory.bookmarks.bookmarkRecipeWithCount")
|
||||
? 1
|
||||
: 0,
|
||||
BookmarkGrid.DEFAULT_GROUP_ID);
|
||||
}
|
||||
|
||||
// --- Case 2: saving an item only ---
|
||||
} else {
|
||||
final RecipeId recipeId = recipe != null ? recipe.getRecipeId() : null;
|
||||
|
||||
// Determine if the item is associated with a recipe and should be saved with it
|
||||
final boolean existsRecipe = recipeId != null
|
||||
&& ItemPanels.bookmarkPanel.existsRecipe(recipeId, BookmarkGrid.DEFAULT_GROUP_ID)
|
||||
|| NEIClientConfig.getBooleanSetting("inventory.bookmarks.bookmarkItemsWithRecipe");
|
||||
|
||||
// If the item was not removed from the bookmarks, add it
|
||||
if (!ItemPanels.bookmarkPanel
|
||||
.removeItem(stackover, existsRecipe ? recipeId : null, BookmarkGrid.DEFAULT_GROUP_ID)) {
|
||||
|
||||
// Determine whether to preserve the item count
|
||||
saveStackSize = saveStackSize || saveIngredients
|
||||
|| ItemPanels.bookmarkPanel.existsRecipe(recipeId, BookmarkGrid.DEFAULT_GROUP_ID);
|
||||
|
||||
if (!saveStackSize) {
|
||||
stackover = StackInfo.withAmount(stackover, 0);
|
||||
} else if (ItemPanels.itemPanel.contains(mousePos.x, mousePos.y)
|
||||
|| ItemPanels.itemPanel.historyPanel.contains(mousePos.x, mousePos.y)) {
|
||||
stackover = ItemQuantityField.prepareStackWithQuantity(stackover, 0);
|
||||
}
|
||||
} else if (ItemPanels.itemPanel.containsWithSubpanels(mousePos.x, mousePos.y)) {
|
||||
stackover = ItemQuantityField.prepareStackWithQuantity(stackover, 0);
|
||||
}
|
||||
|
||||
ItemPanels.bookmarkPanel
|
||||
.addItem(stackover, existsRecipe ? recipeId : null, BookmarkGrid.DEFAULT_GROUP_ID);
|
||||
@@ -380,8 +431,14 @@ public abstract class ShortcutInputHandler {
|
||||
return ItemPanels.bookmarkPanel.pullBookmarkItems(math, shift);
|
||||
}
|
||||
|
||||
public static Map<String, String> handleHotkeys(GuiContainer gui, int mousex, int mousey, ItemStack stack) {
|
||||
public static Map<String, String> handleHotkeys(int mousex, int mousey, ItemStack stack) {
|
||||
final int groupId = ItemPanels.bookmarkPanel.getHoveredGroupId(true);
|
||||
|
||||
if (hotkeysCache.matches(mousex, mousey, stack, groupId)) {
|
||||
return hotkeysCache.hotkeys;
|
||||
}
|
||||
|
||||
final GuiContainer gui = NEIClientUtils.getGuiContainer();
|
||||
final Map<String, String> hotkeys = new HashMap<>();
|
||||
|
||||
if (groupId != -1) {
|
||||
@@ -408,9 +465,13 @@ public abstract class ShortcutInputHandler {
|
||||
NEIClientConfig.getKeyName("gui.craft_items", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("bookmark.group.craft_all"));
|
||||
}
|
||||
|
||||
hotkeysCache.update(mousex, mousey, stack, groupId, hotkeys);
|
||||
return hotkeys;
|
||||
}
|
||||
|
||||
if (stack == null) {
|
||||
hotkeysCache.update(mousex, mousey, stack, groupId, hotkeys);
|
||||
return hotkeys;
|
||||
}
|
||||
|
||||
@@ -424,7 +485,7 @@ public abstract class ShortcutInputHandler {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("bookmark.group.remove_recipe"));
|
||||
} else if (slot.getRecipeId() == null) {
|
||||
} else if (slot.getRecipeId() == null || slot.getType() == BookmarkItemType.ITEM) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark"),
|
||||
NEIClientUtils.translate("bookmark.remove_item"));
|
||||
@@ -439,7 +500,7 @@ public abstract class ShortcutInputHandler {
|
||||
NEIClientConfig.getKeyName("gui.bookmark", NEIClientUtils.SHIFT_HASH),
|
||||
NEIClientUtils.translate("bookmark.remove_recipe"));
|
||||
|
||||
if (slot.isIngredient()) {
|
||||
if (slot.getType() == BookmarkItemType.INGREDIENT) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark"),
|
||||
NEIClientUtils.translate("bookmark.remove_item"));
|
||||
@@ -452,7 +513,8 @@ public abstract class ShortcutInputHandler {
|
||||
|
||||
if (ItemPanels.bookmarkPanel.getGrid().createChainItems(groupId).values().stream()
|
||||
.noneMatch(
|
||||
m -> !m.isIngredient && !m.equals(item) && item.equalsRecipe(m))) {
|
||||
m -> m.type == BookmarkItemType.RESULT && !m.equals(item)
|
||||
&& item.equalsRecipe(m))) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark"),
|
||||
NEIClientUtils.translate("bookmark.remove_recipe"));
|
||||
@@ -511,6 +573,7 @@ public abstract class ShortcutInputHandler {
|
||||
|
||||
hotkeys.put(NEIClientConfig.getKeyName("gui.copy_name"), NEIClientUtils.translate("itempanel.copy_name"));
|
||||
hotkeys.put(NEIClientConfig.getKeyName("gui.copy_oredict"), NEIClientUtils.translate("itempanel.copy_oredict"));
|
||||
hotkeys.put(NEIClientConfig.getKeyName("gui.copy_id"), NEIClientUtils.translate("itempanel.copy_id"));
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.chat_link_item"),
|
||||
NEIClientUtils.translate("itempanel.chat_link_item"));
|
||||
@@ -522,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),
|
||||
@@ -570,6 +636,8 @@ public abstract class ShortcutInputHandler {
|
||||
|
||||
}
|
||||
|
||||
hotkeysCache.update(mousex, mousey, stack, groupId, hotkeys);
|
||||
|
||||
return hotkeys;
|
||||
}
|
||||
|
||||
@@ -599,7 +667,7 @@ public abstract class ShortcutInputHandler {
|
||||
BookmarksGridSlot slot) {
|
||||
|
||||
if (slot != null) {
|
||||
return slot.isIngredient() ? null : slot.getRecipeId();
|
||||
return slot.getType() == BookmarkItemType.INGREDIENT ? null : slot.getRecipeId();
|
||||
}
|
||||
|
||||
ItemsGridSlot itemSlot = ItemPanels.itemPanel.getSlotMouseOver(mousex, mousey);
|
||||
|
||||
@@ -30,6 +30,7 @@ import codechicken.nei.ItemsGrid.MouseContext;
|
||||
import codechicken.nei.LayoutManager;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.bookmark.BookmarkItem.BookmarkItemType;
|
||||
import codechicken.nei.recipe.Recipe;
|
||||
import codechicken.nei.recipe.Recipe.RecipeId;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
@@ -88,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<>();
|
||||
@@ -367,19 +368,26 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
}
|
||||
|
||||
for (BookmarkItem item : this.bookmarkItems) {
|
||||
if (item.groupId == groupId && item.recipeId != null) {
|
||||
if (item.recipeId == null && item.type != BookmarkItemType.ITEM) {
|
||||
item.type = BookmarkItemType.ITEM;
|
||||
} else if (item.groupId == groupId && item.recipeId != null && item.type != BookmarkItemType.ITEM) {
|
||||
recipeState.put(
|
||||
item.recipeId,
|
||||
recipeState.getOrDefault(item.recipeId, 0) | (item.isIngredient ? 1 : 2));
|
||||
recipeState.getOrDefault(item.recipeId, 0)
|
||||
| (item.type == BookmarkItemType.INGREDIENT ? 1 : 2));
|
||||
}
|
||||
}
|
||||
|
||||
for (BookmarkItem item : this.bookmarkItems) {
|
||||
if (item.groupId == groupId && item.isIngredient
|
||||
&& (item.recipeId == null || recipeState.getOrDefault(item.recipeId, 1) == 1)) {
|
||||
if (item.groupId == groupId && item.type != BookmarkItemType.ITEM
|
||||
&& recipeState.getOrDefault(item.recipeId, 0) != 3) {
|
||||
|
||||
if (item.type == BookmarkItemType.INGREDIENT) {
|
||||
item.recipeId = null;
|
||||
}
|
||||
|
||||
recipeState.remove(item.recipeId);
|
||||
item.isIngredient = false;
|
||||
item.recipeId = null;
|
||||
item.type = BookmarkItemType.ITEM;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -405,7 +413,8 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
|
||||
for (int index = itemIndex; index < size; index++) {
|
||||
if (item.equalsRecipe(this.bookmarkItems.get(index))) {
|
||||
sortingRank.put(index, this.bookmarkItems.get(index).isIngredient ? 1 : -1);
|
||||
sortingRank
|
||||
.put(index, this.bookmarkItems.get(index).type == BookmarkItemType.INGREDIENT ? 1 : -1);
|
||||
items.add(index);
|
||||
}
|
||||
}
|
||||
@@ -632,6 +641,7 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
|
||||
if (group.crafting == null) {
|
||||
for (BookmarkItem item : chainItems) {
|
||||
item.type = BookmarkItemType.ITEM;
|
||||
item.recipeId = null;
|
||||
}
|
||||
}
|
||||
@@ -761,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;
|
||||
}
|
||||
@@ -820,7 +849,7 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
|
||||
for (int itemIndex = 0; itemIndex < this.bookmarkItems.size(); itemIndex++) {
|
||||
final BookmarkItem item = this.bookmarkItems.get(itemIndex);
|
||||
if (item.groupId == groupId && item.isIngredient == ingredient
|
||||
if (item.groupId == groupId && ingredient == (item.type == BookmarkItemType.INGREDIENT)
|
||||
&& (recipeId == item.recipeId || recipeId != null && recipeId.equals(item.recipeId))
|
||||
&& StackInfo.equalItemAndNBT(stackA, item.itemStack, true)) {
|
||||
return itemIndex;
|
||||
@@ -876,7 +905,12 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
for (ItemStack stack : ItemStackAmount.of(results).values()) {
|
||||
long factor = StackInfo.getAmount(stack);
|
||||
this.addItem(
|
||||
BookmarkItem.of(groupId, StackInfo.withAmount(stack, factor * multiplier), factor, recipeId, false),
|
||||
BookmarkItem.of(
|
||||
groupId,
|
||||
StackInfo.withAmount(stack, factor * multiplier),
|
||||
factor,
|
||||
recipeId,
|
||||
BookmarkItemType.RESULT),
|
||||
true);
|
||||
}
|
||||
|
||||
@@ -888,7 +922,7 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
StackInfo.withAmount(stack, factor * multiplier),
|
||||
factor,
|
||||
recipeId,
|
||||
true,
|
||||
BookmarkItemType.INGREDIENT,
|
||||
BookmarkItem.generatePermutations(stack, recipe)),
|
||||
true);
|
||||
}
|
||||
@@ -901,12 +935,12 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
return;
|
||||
}
|
||||
|
||||
if (!removeFullRecipe && item.recipeId != null && !item.isIngredient) {
|
||||
if (!removeFullRecipe && item.recipeId != null && item.type == BookmarkItemType.RESULT) {
|
||||
removeFullRecipe = this.bookmarkItems.stream()
|
||||
.noneMatch(m -> !m.isIngredient && !m.equals(item) && item.equalsRecipe(m));
|
||||
.noneMatch(m -> m.type == BookmarkItemType.RESULT && !m.equals(item) && item.equalsRecipe(m));
|
||||
}
|
||||
|
||||
if (item.recipeId != null && removeFullRecipe) {
|
||||
if (item.recipeId != null && item.type != BookmarkItemType.ITEM && removeFullRecipe) {
|
||||
removeRecipe(item.recipeId, item.groupId);
|
||||
} else if (itemIndex >= 0) {
|
||||
this.bookmarkItems.remove(itemIndex);
|
||||
@@ -925,7 +959,8 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
}
|
||||
|
||||
public boolean existsRecipe(RecipeId recipeId, int groupId) {
|
||||
return this.bookmarkItems.stream().anyMatch(item -> item.equalsRecipe(recipeId, groupId));
|
||||
return this.bookmarkItems.stream()
|
||||
.anyMatch(item -> item.type != BookmarkItemType.ITEM && item.equalsRecipe(recipeId, groupId));
|
||||
}
|
||||
|
||||
public RecipeId getRecipeId(int itemIndex) {
|
||||
@@ -1028,8 +1063,14 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
}
|
||||
|
||||
if (bookmarkItem != null && (group.crafting != null && group.viewMode == BookmarkViewMode.DEFAULT
|
||||
|| group.viewMode == BookmarkViewMode.TODO_LIST && !sortableItem.bookmarkItem.isIngredient)) {
|
||||
while (sortIndex > 0 && bookmarkItem.equalsRecipe(getCalculatedItem(sortedIndexes.get(sortIndex - 1)))) {
|
||||
|| group.viewMode == BookmarkViewMode.TODO_LIST
|
||||
&& sortableItem.bookmarkItem.type == BookmarkItemType.RESULT)) {
|
||||
BookmarkItem prevBookmarkItem = sortIndex > 1 ? getCalculatedItem(sortedIndexes.get(sortIndex - 1)) : null;
|
||||
|
||||
while (sortIndex > 0 && prevBookmarkItem != null
|
||||
&& prevBookmarkItem.type != BookmarkItemType.ITEM
|
||||
&& bookmarkItem.equalsRecipe(prevBookmarkItem)) {
|
||||
prevBookmarkItem = sortIndex > 1 ? getCalculatedItem(sortedIndexes.get(sortIndex - 1)) : null;
|
||||
sortIndex--;
|
||||
}
|
||||
|
||||
@@ -1058,7 +1099,7 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
if (nextSortIndex < sortedIndexes.size()) {
|
||||
final int nextItemIndex = sortedIndexes.get(nextSortIndex);
|
||||
|
||||
if (group.viewMode == BookmarkViewMode.TODO_LIST && !target.isIngredient
|
||||
if (group.viewMode == BookmarkViewMode.TODO_LIST && target.type == BookmarkItemType.RESULT
|
||||
&& target.equalsRecipe(getCalculatedItem(nextItemIndex))) {
|
||||
return -1;
|
||||
}
|
||||
@@ -1149,7 +1190,7 @@ public class BookmarkGrid extends ItemsGrid<BookmarksGridSlot, BookmarkGrid.Book
|
||||
|
||||
if (group.collapsed) {
|
||||
shiftGroupAmount(targetItem.groupId, shift);
|
||||
} else if (targetItem.recipeId != null) {
|
||||
} else if (targetItem.recipeId != null && targetItem.type != BookmarkItemType.ITEM) {
|
||||
final RecipeId recipeId = this.gridGenerator.itemToRecipe
|
||||
.getOrDefault(targetItemIndex, targetItem.recipeId);
|
||||
final boolean recipeInMiddle = group.crafting != null && group.crafting.recipeInMiddle.contains(recipeId);
|
||||
|
||||
@@ -11,6 +11,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
import codechicken.nei.BookmarkPanel.BookmarkViewMode;
|
||||
import codechicken.nei.ItemSorter;
|
||||
import codechicken.nei.bookmark.BookmarkItem.BookmarkItemType;
|
||||
import codechicken.nei.bookmark.RecipeChainDetails.BookmarkChainItem;
|
||||
import codechicken.nei.bookmark.RecipeChainDetails.CalculatedType;
|
||||
import codechicken.nei.recipe.Recipe.RecipeId;
|
||||
@@ -117,7 +118,7 @@ public class BookmarkGridGenerator {
|
||||
this.itemToSlot.put(collapsedItemIndex, absoluteSlotIndex);
|
||||
this.caclulatedItems.put(collapsedItemIndex, getItem(group, collapsedItemIndex));
|
||||
|
||||
if (!(shadows = getShadows(group, item.recipeId)).isEmpty()) {
|
||||
if (item.recipeId != null && !(shadows = getShadows(group, item.recipeId)).isEmpty()) {
|
||||
borderGrid.put(absoluteSlotIndex, "recipe:" + shadows.get(0));
|
||||
}
|
||||
}
|
||||
@@ -165,7 +166,7 @@ public class BookmarkGridGenerator {
|
||||
break;
|
||||
}
|
||||
|
||||
if (!bookmarkItem.isIngredient
|
||||
if (bookmarkItem.type != BookmarkItemType.INGREDIENT
|
||||
&& (group.crafting == null || group.crafting.calculatedItems.containsKey(itemIndex))) {
|
||||
results.add(itemIndex);
|
||||
}
|
||||
@@ -193,7 +194,7 @@ public class BookmarkGridGenerator {
|
||||
bookmarkItem.itemStack,
|
||||
1,
|
||||
bookmarkItem.recipeId,
|
||||
isIngredient,
|
||||
isIngredient ? BookmarkItemType.INGREDIENT : BookmarkItemType.RESULT,
|
||||
Collections.emptyMap());
|
||||
|
||||
if ((absoluteSlotIndex = nextSlotIndex(
|
||||
@@ -227,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++;
|
||||
@@ -238,17 +239,22 @@ public class BookmarkGridGenerator {
|
||||
return index;
|
||||
} else if (isFirstColumn && (meta.recipeId == null || previousMeta == null
|
||||
|| previousMeta.groupId != meta.groupId
|
||||
|| 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
|
||||
// if the second column is occupied
|
||||
return index;
|
||||
} else
|
||||
if (!isFirstColumn && meta.recipeId != null && meta.recipeId.equals(previousMeta.recipeId)) {
|
||||
return index;
|
||||
} else {
|
||||
index++;
|
||||
}
|
||||
if (!isFirstColumn && meta.type != BookmarkItemType.ITEM
|
||||
&& previousMeta.type != BookmarkItemType.ITEM
|
||||
&& meta.groupId == previousMeta.groupId
|
||||
&& meta.recipeId != null
|
||||
&& meta.recipeId.equals(previousMeta.recipeId)) {
|
||||
return index;
|
||||
} else {
|
||||
index++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,21 @@ import codechicken.nei.recipe.StackInfo;
|
||||
|
||||
public class BookmarkItem {
|
||||
|
||||
public enum BookmarkItemType {
|
||||
|
||||
INGREDIENT,
|
||||
RESULT,
|
||||
ITEM;
|
||||
|
||||
public static BookmarkItemType fromInt(int type) {
|
||||
return type == 0 ? ITEM : type == 1 ? RESULT : INGREDIENT;
|
||||
}
|
||||
|
||||
public int toInt() {
|
||||
return this == ITEM ? 0 : this == RESULT ? 1 : 2;
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<ItemStack, String> fuzzyPermutations = new HashMap<>();
|
||||
|
||||
public int groupId;
|
||||
@@ -28,10 +43,10 @@ public class BookmarkItem {
|
||||
|
||||
public long factor;
|
||||
public RecipeId recipeId;
|
||||
public boolean isIngredient = false;
|
||||
public BookmarkItemType type = BookmarkItemType.ITEM;
|
||||
|
||||
protected BookmarkItem(int groupId, long amount, int fluidCellAmount, ItemStack itemStack,
|
||||
Map<String, ItemStack> permutations, long factor, RecipeId recipeId, boolean isIngredient) {
|
||||
Map<String, ItemStack> permutations, long factor, RecipeId recipeId, BookmarkItemType type) {
|
||||
this.groupId = groupId;
|
||||
|
||||
this.amount = amount;
|
||||
@@ -41,10 +56,10 @@ public class BookmarkItem {
|
||||
|
||||
this.factor = factor;
|
||||
this.recipeId = recipeId;
|
||||
this.isIngredient = isIngredient;
|
||||
this.type = type == null ? BookmarkItemType.ITEM : type;
|
||||
}
|
||||
|
||||
public static BookmarkItem of(int groupId, ItemStack stack, long factor, RecipeId recipeId, boolean isIngredient,
|
||||
public static BookmarkItem of(int groupId, ItemStack stack, long factor, RecipeId recipeId, BookmarkItemType type,
|
||||
Map<String, ItemStack> permutations) {
|
||||
final FluidStack fluidStack = StackInfo.getFluid(stack);
|
||||
int fluidCellAmount = 1;
|
||||
@@ -65,18 +80,29 @@ public class BookmarkItem {
|
||||
permutations,
|
||||
factor * fluidCellAmount,
|
||||
recipeId,
|
||||
isIngredient);
|
||||
type);
|
||||
}
|
||||
|
||||
public static BookmarkItem of(int groupId, ItemStack stack, long factor, RecipeId recipeId, boolean isIngredient) {
|
||||
return of(groupId, stack, factor, recipeId, isIngredient, generatePermutations(stack, recipeId, isIngredient));
|
||||
public static BookmarkItem of(int groupId, ItemStack stack, long factor, RecipeId recipeId, BookmarkItemType type) {
|
||||
return of(
|
||||
groupId,
|
||||
stack,
|
||||
factor,
|
||||
recipeId,
|
||||
type,
|
||||
generatePermutations(stack, recipeId, type == BookmarkItemType.INGREDIENT));
|
||||
}
|
||||
|
||||
public static BookmarkItem of(int groupId, ItemStack stack) {
|
||||
final NBTTagCompound nbTag = StackInfo.itemStackToNBT(stack);
|
||||
final long factor = nbTag.hasKey("gtFluidName") ? Math.min(144, nbTag.getInteger("Count")) : 1;
|
||||
return BookmarkItem
|
||||
.of(groupId, stack, factor, null, false, Collections.singletonMap(getItemGUID(stack), stack));
|
||||
return BookmarkItem.of(
|
||||
groupId,
|
||||
stack,
|
||||
factor,
|
||||
null,
|
||||
BookmarkItemType.ITEM,
|
||||
Collections.singletonMap(getItemGUID(stack), stack));
|
||||
}
|
||||
|
||||
public BookmarkItem copyWithAmount(long amount) {
|
||||
@@ -88,7 +114,7 @@ public class BookmarkItem {
|
||||
this.permutations,
|
||||
this.factor,
|
||||
this.recipeId,
|
||||
this.isIngredient);
|
||||
this.type);
|
||||
}
|
||||
|
||||
public BookmarkItem copy() {
|
||||
@@ -186,14 +212,14 @@ public class BookmarkItem {
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(this.groupId, this.fluidCellAmount, this.isIngredient, this.recipeId);
|
||||
return Objects.hash(this.groupId, this.fluidCellAmount, this.type.toInt(), this.recipeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
|
||||
if (object instanceof BookmarkItem item) {
|
||||
return this.groupId == item.groupId && this.isIngredient == item.isIngredient
|
||||
return this.groupId == item.groupId && this.type == item.type
|
||||
&& this.fluidCellAmount == item.fluidCellAmount
|
||||
&& StackInfo.equalItemAndNBT(this.itemStack, item.itemStack, true)
|
||||
&& (this.recipeId == item.recipeId || this.recipeId != null && this.recipeId.equals(item.recipeId));
|
||||
|
||||
@@ -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;
|
||||
@@ -25,6 +25,7 @@ import com.google.gson.JsonSyntaxException;
|
||||
|
||||
import codechicken.nei.BookmarkPanel.BookmarkViewMode;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.bookmark.BookmarkItem.BookmarkItemType;
|
||||
import codechicken.nei.recipe.Recipe.RecipeId;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
import codechicken.nei.util.NBTJson;
|
||||
@@ -136,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");
|
||||
@@ -150,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
|
||||
@@ -195,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();
|
||||
@@ -239,7 +254,15 @@ public class BookmarkStorage {
|
||||
int groupId = jsonObject.has("groupId") ? jsonObject.get("groupId").getAsInt()
|
||||
: BookmarkGrid.DEFAULT_GROUP_ID;
|
||||
int factor = jsonObject.has("factor") ? Math.abs(jsonObject.get("factor").getAsInt()) : (isFluid ? 144 : 1);
|
||||
boolean isIngredient = jsonObject.has("ingredient") && jsonObject.get("ingredient").getAsBoolean();
|
||||
BookmarkItemType type = jsonObject.has("type") ? BookmarkItemType.fromInt(jsonObject.get("type").getAsInt())
|
||||
: null;
|
||||
|
||||
if (type == null) {
|
||||
// old format
|
||||
type = jsonObject.has("ingredient") && jsonObject.get("ingredient").getAsBoolean()
|
||||
? BookmarkItemType.INGREDIENT
|
||||
: BookmarkItemType.RESULT;
|
||||
}
|
||||
|
||||
if (jsonObject.get("recipeId") instanceof JsonObject recipeJson) {
|
||||
recipeId = RecipeId.of(recipeJson);
|
||||
@@ -249,51 +272,12 @@ public class BookmarkStorage {
|
||||
groupId = BookmarkGrid.DEFAULT_GROUP_ID;
|
||||
}
|
||||
|
||||
grid.addItem(BookmarkItem.of(groupId, itemStack, factor, recipeId, isIngredient), false);
|
||||
grid.addItem(BookmarkItem.of(groupId, itemStack, factor, recipeId, type), false);
|
||||
}
|
||||
|
||||
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.isIngredient && 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.isIngredient);
|
||||
} else {
|
||||
item.recipeId = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void save() {
|
||||
|
||||
if (this.bookmarkFile == null) {
|
||||
@@ -338,7 +322,7 @@ public class BookmarkStorage {
|
||||
|
||||
row.add("item", NBTJson.toJsonObject(StackInfo.itemStackToNBT(item.getItemStack())));
|
||||
row.add("factor", new JsonPrimitive(item.getFactor()));
|
||||
row.add("ingredient", new JsonPrimitive(item.isIngredient));
|
||||
row.add("type", new JsonPrimitive(item.type.toInt()));
|
||||
|
||||
if (item.groupId != BookmarkGrid.DEFAULT_GROUP_ID) {
|
||||
row.add("groupId", new JsonPrimitive(item.groupId));
|
||||
|
||||
@@ -4,6 +4,8 @@ import java.awt.Color;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
import codechicken.nei.BookmarkPanel.BookmarkViewMode;
|
||||
import codechicken.nei.ItemPanels;
|
||||
@@ -13,7 +15,11 @@ import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.NEIClientUtils.Alignment;
|
||||
import codechicken.nei.bookmark.BookmarkGrid.BookmarkMouseContext;
|
||||
import codechicken.nei.bookmark.BookmarkItem.BookmarkItemType;
|
||||
import codechicken.nei.bookmark.RecipeChainDetails.CalculatedType;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.recipe.GuiRecipeTab;
|
||||
import codechicken.nei.recipe.HandlerInfo;
|
||||
import codechicken.nei.recipe.Recipe.RecipeId;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
import codechicken.nei.util.ReadableNumberConverter;
|
||||
@@ -51,6 +57,7 @@ public class BookmarksGridSlot extends ItemsGridSlot {
|
||||
protected final CalculatedType calculatedType;
|
||||
protected final CalculatedType realType;
|
||||
protected final BookmarkItem bookmarkItem;
|
||||
protected HandlerInfo handlerInfo = null;
|
||||
|
||||
protected final boolean isOutputRecipe;
|
||||
protected final boolean isFirstOutput;
|
||||
@@ -83,7 +90,7 @@ public class BookmarksGridSlot extends ItemsGridSlot {
|
||||
this.realType = this.group.crafting.calculatedItems.get(this.itemIndex).calculatedType
|
||||
== CalculatedType.INGREDIENT ? CalculatedType.INGREDIENT : CalculatedType.RESULT;
|
||||
} else {
|
||||
this.realType = this.bookmarkItem.isIngredient
|
||||
this.realType = this.bookmarkItem.type == BookmarkItemType.INGREDIENT
|
||||
|| this.group.crafting != null && this.bookmarkItem.recipeId == null ? CalculatedType.INGREDIENT
|
||||
: CalculatedType.RESULT;
|
||||
}
|
||||
@@ -91,9 +98,10 @@ public class BookmarksGridSlot extends ItemsGridSlot {
|
||||
final BookmarkGrid grid = ItemPanels.bookmarkPanel.getGrid();
|
||||
final BookmarkItem prevItem = grid.getCalculatedItem(
|
||||
grid.gridGenerator.slotToItem.getOrDefault(grid.gridGenerator.itemToSlot.get(this.itemIndex) - 1, -1));
|
||||
this.isFirstOutput = this.itemIndex >= 0 && !this.bookmarkItem.isIngredient
|
||||
this.isFirstOutput = this.itemIndex >= 0 && this.bookmarkItem.type == BookmarkItemType.RESULT
|
||||
&& ((this.slotIndex % grid.getColumns()) == 0 || group.viewMode == BookmarkViewMode.DEFAULT)
|
||||
&& (prevItem == null || prevItem.isIngredient || !this.bookmarkItem.equalsRecipe(prevItem));
|
||||
&& (prevItem == null || prevItem.type == BookmarkItemType.INGREDIENT
|
||||
|| !this.bookmarkItem.equalsRecipe(prevItem));
|
||||
this.rowIndex = this.slotIndex / grid.getColumns();
|
||||
}
|
||||
|
||||
@@ -110,8 +118,8 @@ public class BookmarksGridSlot extends ItemsGridSlot {
|
||||
return this.bookmarkItem.recipeId;
|
||||
}
|
||||
|
||||
public boolean isIngredient() {
|
||||
return this.bookmarkItem.isIngredient;
|
||||
public BookmarkItemType getType() {
|
||||
return this.bookmarkItem.type;
|
||||
}
|
||||
|
||||
public BookmarkGroup getGroup() {
|
||||
@@ -145,11 +153,17 @@ public class BookmarksGridSlot extends ItemsGridSlot {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.group.crafting != null) {
|
||||
if (this.slotIndex == mouseContext.slotIndex || this.group.crafting != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.bookmarkItem.equalsRecipe(mouseContext.recipeId, mouseContext.groupId);
|
||||
if (this.bookmarkItem.type == BookmarkItemType.ITEM && this.group.viewMode == BookmarkViewMode.TODO_LIST
|
||||
&& mouseContext.rowIndex == this.rowIndex) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return this.bookmarkItem.type != BookmarkItemType.ITEM
|
||||
&& this.bookmarkItem.equalsRecipe(mouseContext.recipeId, mouseContext.groupId);
|
||||
}
|
||||
|
||||
protected boolean showRealItem(BookmarkMouseContext mouseContext) {
|
||||
@@ -167,7 +181,8 @@ public class BookmarksGridSlot extends ItemsGridSlot {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.bookmarkItem.equalsRecipe(mouseContext.recipeId, mouseContext.groupId)) {
|
||||
if (this.bookmarkItem.type != BookmarkItemType.ITEM
|
||||
&& this.bookmarkItem.equalsRecipe(mouseContext.recipeId, mouseContext.groupId)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -175,6 +190,13 @@ public class BookmarksGridSlot extends ItemsGridSlot {
|
||||
&& mouseContext.recipeId.equals(this.group.crafting.itemToRecipe.get(this.itemIndex));
|
||||
}
|
||||
|
||||
protected HandlerInfo getHandlerInfo() {
|
||||
if (this.bookmarkItem.recipeId != null && this.handlerInfo == null) {
|
||||
this.handlerInfo = GuiRecipeTab.getHandlerInfo(this.bookmarkItem.recipeId.getHandleName(), null);
|
||||
}
|
||||
return this.handlerInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawItem(Rectangle4i rect) {
|
||||
super.drawItem(this.emptyItemStack, rect);
|
||||
@@ -199,7 +221,7 @@ public class BookmarksGridSlot extends ItemsGridSlot {
|
||||
|
||||
}
|
||||
|
||||
if (!this.bookmarkItem.isIngredient && this.bookmarkItem.recipeId != null
|
||||
if (this.bookmarkItem.type != BookmarkItemType.INGREDIENT && this.bookmarkItem.recipeId != null
|
||||
&& calculatedType == null
|
||||
&& showMarker
|
||||
&& (mouseContext == null || mouseContext.slotIndex != this.slotIndex)) {
|
||||
@@ -246,7 +268,7 @@ public class BookmarksGridSlot extends ItemsGridSlot {
|
||||
|
||||
drawStackSize(rect, shownItemType);
|
||||
|
||||
if (this.bookmarkItem.isIngredient || this.bookmarkItem.recipeId == null) {
|
||||
if (this.bookmarkItem.type == BookmarkItemType.INGREDIENT || this.bookmarkItem.recipeId == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -255,27 +277,65 @@ public class BookmarksGridSlot extends ItemsGridSlot {
|
||||
drawMarker(
|
||||
rect,
|
||||
"x" + ReadableNumberConverter.INSTANCE.toWideReadableForm(this.realMultiplier),
|
||||
0xFFFFFF);
|
||||
0xFFFFFF,
|
||||
Alignment.TopLeft);
|
||||
} else if (shownItemType == ShownItemType.SHIFT) {
|
||||
drawMarker(rect, "x" + ReadableNumberConverter.INSTANCE.toWideReadableForm(getMultiplier()), 0xFFFFFF);
|
||||
drawMarker(
|
||||
rect,
|
||||
"x" + ReadableNumberConverter.INSTANCE.toWideReadableForm(getMultiplier()),
|
||||
0xFFFFFF,
|
||||
Alignment.TopLeft);
|
||||
} else if (this.isOutputRecipe || this.realMultiplier > 1) {
|
||||
drawMarker(
|
||||
rect,
|
||||
"x" + ReadableNumberConverter.INSTANCE.toWideReadableForm(this.realMultiplier),
|
||||
NEIClientConfig.getSetting("inventory.bookmarks.recipeMarkerColor").getHexValue());
|
||||
} else if (NEIClientConfig.showRecipeMarkerMode() == 1) {
|
||||
drawMarker(
|
||||
rect,
|
||||
"R",
|
||||
NEIClientConfig.getSetting("inventory.bookmarks.recipeMarkerColor").getHexValue());
|
||||
NEIClientConfig.getSetting("inventory.bookmarks.recipeMarkerColor").getHexValue(),
|
||||
Alignment.TopLeft);
|
||||
}
|
||||
} else if (NEIClientConfig.showRecipeMarkerMode() == 1) {
|
||||
drawMarker(rect, "R", NEIClientConfig.getSetting("inventory.bookmarks.recipeMarkerColor").getHexValue());
|
||||
}
|
||||
|
||||
if (this.isFirstOutput || NEIClientConfig.showRecipeMarkerMode() == 1) {
|
||||
drawRecipeMarker(rect);
|
||||
}
|
||||
}
|
||||
|
||||
protected void drawMarker(Rectangle4i rect, String text, int color) {
|
||||
protected void drawRecipeMarker(Rectangle4i rect) {
|
||||
if (NEIClientConfig.getBooleanSetting("inventory.bookmarks.showRecipeHandlerIcon")
|
||||
&& getHandlerInfo() != null) {
|
||||
drawHandlerIcon(rect);
|
||||
} else if (NEIClientConfig.showRecipeMarkerMode() == 1) {
|
||||
drawMarker(
|
||||
rect,
|
||||
"R",
|
||||
NEIClientConfig.getSetting("inventory.bookmarks.recipeMarkerColor").getHexValue(),
|
||||
Alignment.TopRight);
|
||||
}
|
||||
}
|
||||
|
||||
protected void drawHandlerIcon(Rectangle4i rect) {
|
||||
float panelFactor = 1;
|
||||
|
||||
if (rect.w != DEFAULT_SLOT_SIZE) {
|
||||
panelFactor = (rect.w - 2) / (DEFAULT_SLOT_SIZE - 2);
|
||||
}
|
||||
|
||||
panelFactor *= 0.4f;
|
||||
float x = rect.x + 2 + 16 - 16 * panelFactor;
|
||||
|
||||
GL11.glTranslatef(x, rect.y, 0);
|
||||
GL11.glScaled(panelFactor, panelFactor, 1.5f);
|
||||
|
||||
if (this.handlerInfo.getImage() != null) {
|
||||
this.handlerInfo.getImage().draw(0, 0);
|
||||
} else {
|
||||
GuiContainerManager.drawItem(0, 0, this.handlerInfo.getItemStack(), true, "");
|
||||
}
|
||||
|
||||
GL11.glScaled(1f / panelFactor, 1f / panelFactor, 1f / 1.5f);
|
||||
GL11.glTranslatef(-1 * x, -1 * rect.y, 0);
|
||||
}
|
||||
|
||||
protected void drawMarker(Rectangle4i rect, String text, int color, Alignment alignment) {
|
||||
final float panelFactor = (rect.w - 2) / (DEFAULT_SLOT_SIZE - 2);
|
||||
NEIClientUtils.drawNEIOverlayText(
|
||||
text,
|
||||
@@ -283,7 +343,7 @@ public class BookmarksGridSlot extends ItemsGridSlot {
|
||||
panelFactor,
|
||||
color,
|
||||
true,
|
||||
Alignment.TopLeft);
|
||||
alignment);
|
||||
}
|
||||
|
||||
protected void drawStackSize(Rectangle4i rect, ShownItemType shownItemType) {
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import codechicken.nei.BookmarkPanel.BookmarkViewMode;
|
||||
import codechicken.nei.bookmark.BookmarkItem.BookmarkItemType;
|
||||
import codechicken.nei.recipe.Recipe.RecipeId;
|
||||
|
||||
public class GroupingItem {
|
||||
@@ -124,7 +125,7 @@ public class GroupingItem {
|
||||
|
||||
final BookmarkItem item = this.grid.getCalculatedItem(itemIndex);
|
||||
|
||||
if (item.recipeId != null) {
|
||||
if (item.recipeId != null && item.type != BookmarkItemType.ITEM) {
|
||||
final List<Integer> sortedItems = this.grid.getSortedItems();
|
||||
final BookmarkGroup group = this.grid.getGroup(item.groupId);
|
||||
final boolean isCollapsedGroup = group.collapsed
|
||||
@@ -139,7 +140,8 @@ public class GroupingItem {
|
||||
for (Integer rItemIndex : sortedItems) {
|
||||
final BookmarkItem rItem = this.grid.getCalculatedItem(rItemIndex);
|
||||
|
||||
if (rItem.groupId == item.groupId && (isCollapsedGroup || recipeRelations.contains(rItem.recipeId))) {
|
||||
if (rItem.groupId == item.groupId && (isCollapsedGroup
|
||||
|| rItem.type != BookmarkItemType.ITEM && recipeRelations.contains(rItem.recipeId))) {
|
||||
return this.grid.getAbsoluteSlotIndex(rItemIndex) / this.grid.getColumns();
|
||||
}
|
||||
}
|
||||
@@ -160,7 +162,7 @@ public class GroupingItem {
|
||||
|
||||
final BookmarkItem item = this.grid.getCalculatedItem(itemIndex);
|
||||
|
||||
if (item.recipeId != null) {
|
||||
if (item.recipeId != null && item.type != BookmarkItemType.ITEM) {
|
||||
final List<Integer> sortedItems = this.grid.getSortedItems();
|
||||
final BookmarkGroup group = this.grid.getGroup(item.groupId);
|
||||
final boolean isCollapsedGroup = group.collapsed
|
||||
@@ -176,7 +178,8 @@ public class GroupingItem {
|
||||
final int rItemIndex = sortedItems.get(index);
|
||||
final BookmarkItem rItem = this.grid.getCalculatedItem(rItemIndex);
|
||||
|
||||
if (rItem.groupId == item.groupId && (isCollapsedGroup || recipeRelations.contains(rItem.recipeId))) {
|
||||
if (rItem.groupId == item.groupId && (isCollapsedGroup
|
||||
|| rItem.type != BookmarkItemType.ITEM && recipeRelations.contains(rItem.recipeId))) {
|
||||
return this.grid.getAbsoluteSlotIndex(rItemIndex) / this.grid.getColumns();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import codechicken.nei.bookmark.BookmarkItem.BookmarkItemType;
|
||||
import codechicken.nei.recipe.Recipe.RecipeId;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
import codechicken.nei.recipe.chain.RecipeChainMath;
|
||||
@@ -69,7 +70,7 @@ public class RecipeChainDetails {
|
||||
item,
|
||||
item.amount,
|
||||
item.amount,
|
||||
item.isIngredient ? CalculatedType.INGREDIENT : CalculatedType.RESULT);
|
||||
item.type == BookmarkItemType.INGREDIENT ? CalculatedType.INGREDIENT : CalculatedType.RESULT);
|
||||
}
|
||||
|
||||
public ItemStack getItemStack(long amount) {
|
||||
@@ -217,11 +218,12 @@ public class RecipeChainDetails {
|
||||
for (BookmarkChainItem value : items) {
|
||||
int itemIndex = sortingChainItems.get(value.getItem());
|
||||
|
||||
if (value.getItem().isIngredient || !recipeId.equals(value.getItem().recipeId)) {
|
||||
if (value.getItem().type == BookmarkItemType.INGREDIENT || !recipeId.equals(value.getItem().recipeId)) {
|
||||
itemIndex *= -1;
|
||||
}
|
||||
|
||||
if (!value.getItem().isIngredient && !math.outputRecipes.containsKey(value.getItem().recipeId)) {
|
||||
if (value.getItem().type == BookmarkItemType.RESULT
|
||||
&& !math.outputRecipes.containsKey(value.getItem().recipeId)) {
|
||||
value.calculatedType = CalculatedType.REMAINDER;
|
||||
}
|
||||
|
||||
@@ -251,7 +253,7 @@ public class RecipeChainDetails {
|
||||
for (BookmarkChainItem value : items) {
|
||||
int itemIndex = sortingChainItems.get(value.getItem());
|
||||
|
||||
if (value.getItem().isIngredient || !recipeId.equals(value.getItem().recipeId)) {
|
||||
if (value.getItem().type == BookmarkItemType.INGREDIENT || !recipeId.equals(value.getItem().recipeId)) {
|
||||
itemIndex *= -1;
|
||||
}
|
||||
|
||||
@@ -348,22 +350,20 @@ public class RecipeChainDetails {
|
||||
private Set<RecipeId> getRecipeParents(RecipeChainMath math, RecipeId recipeId, Set<RecipeId> parents,
|
||||
Set<RecipeId> visited) {
|
||||
final Set<RecipeId> recipeIds = math.preferredItems.entrySet().stream()
|
||||
.filter(
|
||||
entry -> entry.getValue() != null && recipeId.equals(entry.getValue().recipeId)
|
||||
&& !visited.contains(entry.getKey().recipeId))
|
||||
.filter(entry -> entry.getValue() != null && recipeId.equals(entry.getValue().recipeId))
|
||||
.map(entry -> entry.getKey().recipeId).collect(Collectors.toSet());
|
||||
|
||||
visited.addAll(recipeIds);
|
||||
|
||||
if (recipeIds.isEmpty()) {
|
||||
parents.add(recipeId);
|
||||
} else {
|
||||
|
||||
for (RecipeId ingrRecipeId : recipeIds) {
|
||||
if (math.outputRecipes.containsKey(ingrRecipeId)) {
|
||||
parents.add(ingrRecipeId);
|
||||
} else {
|
||||
getRecipeParents(math, ingrRecipeId, parents, visited);
|
||||
if (visited.add(ingrRecipeId)) {
|
||||
if (math.outputRecipes.containsKey(ingrRecipeId)) {
|
||||
parents.add(ingrRecipeId);
|
||||
} else {
|
||||
getRecipeParents(math, ingrRecipeId, parents, visited);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import java.util.Map;
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
import codechicken.nei.BookmarkPanel.BookmarkViewMode;
|
||||
import codechicken.nei.ItemsGrid;
|
||||
import codechicken.nei.bookmark.BookmarkItem.BookmarkItemType;
|
||||
import codechicken.nei.bookmark.RecipeChainDetails.BookmarkChainItem;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.recipe.Recipe.RecipeId;
|
||||
@@ -30,10 +31,10 @@ public class SortableItem {
|
||||
|
||||
this.grid = grid;
|
||||
this.bookmarkItem = bookmarkItem.copy();
|
||||
this.moveRecipe = bookmarkItem.recipeId != null && !bookmarkItem.isIngredient
|
||||
this.moveRecipe = bookmarkItem.recipeId != null && bookmarkItem.type == BookmarkItemType.RESULT
|
||||
&& (group.viewMode == BookmarkViewMode.TODO_LIST || group.crafting != null);
|
||||
this.crossGroup = !group.collapsed && group.viewMode == BookmarkViewMode.TODO_LIST
|
||||
&& !this.bookmarkItem.isIngredient;
|
||||
&& bookmarkItem.type != BookmarkItemType.INGREDIENT;
|
||||
this.isCollapsedRecipe = group.crafting != null && group.crafting.itemToRecipe.values().stream()
|
||||
.anyMatch(recipeId -> this.bookmarkItem.equalsRecipe(recipeId, this.bookmarkItem.groupId));
|
||||
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package codechicken.nei.commands;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.util.ChatComponentTranslation;
|
||||
import net.minecraft.util.ChatStyle;
|
||||
import net.minecraft.util.EnumChatFormatting;
|
||||
|
||||
import codechicken.nei.ItemList;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.util.ItemUntranslator;
|
||||
|
||||
public class CommandUntranslator extends CommandBase {
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return "untranslator";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandUsage(ICommandSender sender) {
|
||||
return "/untranslator dump OR /untranslator clear";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRequiredPermissionLevel() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCommand(ICommandSender sender, String[] args) {
|
||||
final String command = args.length == 0 ? null : args[0];
|
||||
|
||||
if ("dump".equals(command)) {
|
||||
if (ItemList.items.isEmpty()) {
|
||||
sendChatErrorMessage(sender, "nei.chat.untranslator.dump.error");
|
||||
return;
|
||||
} else {
|
||||
sendChatInfoMessage(sender, "nei.chat.untranslator.dump.start");
|
||||
ItemUntranslator.getInstance().generateUntranslatedNames();
|
||||
sendChatInfoMessage(sender, "nei.chat.untranslator.dump.finish");
|
||||
|
||||
if (NEIClientConfig.enableItemUntranslator()) {
|
||||
ItemUntranslator.getInstance().load();
|
||||
}
|
||||
}
|
||||
} else if ("clear".equals(command)) {
|
||||
final File file = new File(NEIClientConfig.configDir, "untranslator.cfg");
|
||||
|
||||
if (file.exists() && file.delete()) {
|
||||
sendChatInfoMessage(sender, "nei.chat.untranslator.clear");
|
||||
if (NEIClientConfig.enableItemUntranslator()) {
|
||||
ItemUntranslator.getInstance().load();
|
||||
}
|
||||
} else {
|
||||
sendChatErrorMessage(sender, "nei.chat.untranslator.clear.error");
|
||||
}
|
||||
} else {
|
||||
sendChatErrorMessage(sender, getCommandUsage(sender));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void sendChatInfoMessage(ICommandSender sender, String translationKey, Object... args) {
|
||||
sender.addChatMessage(
|
||||
new ChatComponentTranslation(translationKey, args)
|
||||
.setChatStyle(new ChatStyle().setColor(EnumChatFormatting.AQUA)));
|
||||
}
|
||||
|
||||
private static void sendChatErrorMessage(ICommandSender sender, String translationKey, Object... args) {
|
||||
sender.addChatMessage(
|
||||
new ChatComponentTranslation(translationKey, args)
|
||||
.setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED)));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -86,18 +86,21 @@ public class IMCHandler {
|
||||
info.setYShift(yShift);
|
||||
|
||||
try {
|
||||
final int imageHeight = tag.hasKey("handlerHeight") ? tag.getInteger("handlerHeight")
|
||||
final int handlerHeight = tag.hasKey("handlerHeight") ? tag.getInteger("handlerHeight")
|
||||
: HandlerInfo.DEFAULT_HEIGHT;
|
||||
final int imageWidth = tag.hasKey("handlerWidth") ? tag.getInteger("handlerWidth")
|
||||
final int handlerWidth = tag.hasKey("handlerWidth") ? tag.getInteger("handlerWidth")
|
||||
: HandlerInfo.DEFAULT_WIDTH;
|
||||
final int maxRecipesPerPage = tag.hasKey("maxRecipesPerPage") ? tag.getInteger("maxRecipesPerPage")
|
||||
: HandlerInfo.DEFAULT_MAX_PER_PAGE;
|
||||
info.setHandlerDimensions(imageHeight, imageWidth, maxRecipesPerPage);
|
||||
final boolean multipleWidgetsAllowed = tag.hasKey("multipleWidgetsAllowed")
|
||||
? tag.getBoolean("multipleWidgetsAllowed")
|
||||
: tag.hasKey("maxRecipesPerPage") && tag.getInteger("maxRecipesPerPage") > 1;
|
||||
info.setHandlerDimensions(handlerWidth, handlerHeight);
|
||||
info.setMultipleWidgetsAllowed(multipleWidgetsAllowed);
|
||||
} catch (NumberFormatException ignored) {
|
||||
NEIClientConfig.logger.info("Error setting handler dimensions for {}", handler);
|
||||
}
|
||||
|
||||
// true if not set to false
|
||||
info.setUseCustomScroll(tag.hasKey("useCustomScroll") && tag.getBoolean("useCustomScroll"));
|
||||
info.setShowFavoritesButton(!tag.hasKey("showFavoritesButton") || tag.getBoolean("showFavoritesButton"));
|
||||
info.setShowOverlayButton(!tag.hasKey("showOverlayButton") || tag.getBoolean("showOverlayButton"));
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ public class OptionUtilities extends OptionStringSet {
|
||||
LayoutManager.drawIcon(x + 4, 4, new Image(132, 12, 12, 12));
|
||||
x += 24;
|
||||
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
|
||||
GL11.glPushAttrib(GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT | GL11.GL_LIGHTING_BIT);
|
||||
RenderHelper.enableGUIStandardItemLighting();
|
||||
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
|
||||
ItemStack sword = new ItemStack(Items.diamond_sword);
|
||||
|
||||
@@ -4,6 +4,8 @@ import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Gui;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import codechicken.nei.Image;
|
||||
|
||||
public class DrawableResource extends Image {
|
||||
@@ -43,15 +45,160 @@ public class DrawableResource extends Image {
|
||||
}
|
||||
|
||||
public void draw(int xOffset, int yOffset, int maskTop, int maskBottom, int maskLeft, int maskRight) {
|
||||
Minecraft.getMinecraft().getTextureManager().bindTexture(this.resourceLocation);
|
||||
|
||||
final int x = xOffset + this.paddingLeft + maskLeft;
|
||||
final int y = yOffset + this.paddingTop + maskTop;
|
||||
final int textureX = this.x + maskLeft;
|
||||
final int textureY = this.y + maskTop;
|
||||
final boolean is2DTexture = GL11.glGetBoolean(GL11.GL_TEXTURE_2D);
|
||||
final int width = this.width - maskRight - maskLeft;
|
||||
final int height = this.height - maskBottom - maskTop;
|
||||
// drawModalRectWithCustomSizedTexture
|
||||
Gui.func_146110_a(x, y, textureX, textureY, width, height, textureWidth, textureHeight);
|
||||
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
Minecraft.getMinecraft().getTextureManager().bindTexture(this.resourceLocation);
|
||||
drawModalRectWithCustomSizedTexture(xOffset + maskLeft, yOffset + maskTop, maskLeft, maskTop, width, height);
|
||||
if (!is2DTexture) GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
public void draw(int xOffset, int yOffset, int width, int height, int sliceLeft, int sliceRight, int sliceTop,
|
||||
int sliceBottom) {
|
||||
final int textureWidth = getWidth();
|
||||
final int textureHeight = getHeight();
|
||||
final int middleWidth = textureWidth - sliceLeft - sliceRight;
|
||||
final int middleHeight = textureHeight - sliceTop - sliceBottom;
|
||||
final int tileWidth = width - sliceLeft - sliceRight;
|
||||
final int tileHeight = height - sliceTop - sliceBottom;
|
||||
|
||||
if (middleWidth > 0 && middleHeight > 0 && tileWidth > 0 && tileHeight > 0) {
|
||||
final boolean is2DTexture = GL11.glGetBoolean(GL11.GL_TEXTURE_2D);
|
||||
final int tileWidthCount = tileWidth / middleWidth;
|
||||
final int remainderWidth = tileWidth - (tileWidthCount * middleWidth);
|
||||
final int tileHeightCount = tileHeight / middleHeight;
|
||||
final int remainderHeight = tileHeight - (tileHeightCount * middleHeight);
|
||||
|
||||
GL11.glEnable(GL11.GL_TEXTURE_2D);
|
||||
Minecraft.getMinecraft().getTextureManager().bindTexture(this.resourceLocation);
|
||||
|
||||
// middle parts
|
||||
for (int tileW = 0; tileW <= tileWidthCount; tileW++) {
|
||||
final int tileWidthSize = (tileW == tileWidthCount) ? remainderWidth : middleWidth;
|
||||
final int x = xOffset + sliceLeft + tileW * middleWidth;
|
||||
|
||||
for (int tileH = 0; tileH <= tileHeightCount; tileH++) {
|
||||
final int tileHeightSize = (tileH == tileHeightCount) ? remainderHeight : middleHeight;
|
||||
drawModalRectWithCustomSizedTexture(
|
||||
x,
|
||||
yOffset + sliceTop + tileH * middleHeight,
|
||||
sliceLeft,
|
||||
sliceTop,
|
||||
tileWidthSize,
|
||||
tileHeightSize);
|
||||
}
|
||||
}
|
||||
|
||||
// border top
|
||||
if (sliceTop > 0) {
|
||||
for (int tileW = 0; tileW <= tileWidthCount; tileW++) {
|
||||
final int tileWidthSize = (tileW == tileWidthCount) ? remainderWidth : middleWidth;
|
||||
drawModalRectWithCustomSizedTexture(
|
||||
xOffset + sliceLeft + tileW * middleWidth,
|
||||
yOffset,
|
||||
sliceLeft,
|
||||
0,
|
||||
tileWidthSize,
|
||||
sliceTop);
|
||||
}
|
||||
}
|
||||
|
||||
// border bottom
|
||||
if (sliceBottom > 0) {
|
||||
for (int tileW = 0; tileW <= tileWidthCount; tileW++) {
|
||||
final int tileWidthSize = (tileW == tileWidthCount) ? remainderWidth : middleWidth;
|
||||
drawModalRectWithCustomSizedTexture(
|
||||
xOffset + sliceLeft + tileW * middleWidth,
|
||||
yOffset + sliceTop + tileHeight,
|
||||
sliceLeft,
|
||||
sliceTop + middleHeight,
|
||||
tileWidthSize,
|
||||
sliceBottom);
|
||||
}
|
||||
}
|
||||
|
||||
// border left
|
||||
if (sliceLeft > 0) {
|
||||
for (int tileH = 0; tileH <= tileHeightCount; tileH++) {
|
||||
final int tileHeightSize = (tileH == tileHeightCount) ? remainderHeight : middleHeight;
|
||||
drawModalRectWithCustomSizedTexture(
|
||||
xOffset,
|
||||
yOffset + sliceTop + tileH * middleHeight,
|
||||
0,
|
||||
sliceTop,
|
||||
sliceLeft,
|
||||
tileHeightSize);
|
||||
}
|
||||
}
|
||||
|
||||
// border right
|
||||
if (sliceRight > 0) {
|
||||
for (int tileH = 0; tileH <= tileHeightCount; tileH++) {
|
||||
final int tileHeightSize = (tileH == tileHeightCount) ? remainderHeight : middleHeight;
|
||||
drawModalRectWithCustomSizedTexture(
|
||||
xOffset + sliceLeft + tileWidth,
|
||||
yOffset + sliceTop + tileH * middleHeight,
|
||||
sliceLeft + middleWidth,
|
||||
sliceTop,
|
||||
sliceRight,
|
||||
tileHeightSize);
|
||||
}
|
||||
}
|
||||
|
||||
// angle left-top
|
||||
if (sliceLeft > 0 && sliceTop > 0) {
|
||||
drawModalRectWithCustomSizedTexture(xOffset, yOffset, 0, 0, sliceLeft, sliceTop);
|
||||
}
|
||||
|
||||
// angle right-top
|
||||
if (sliceRight > 0 && sliceTop > 0) {
|
||||
drawModalRectWithCustomSizedTexture(
|
||||
xOffset + sliceLeft + tileWidth,
|
||||
yOffset,
|
||||
sliceLeft + middleWidth,
|
||||
0,
|
||||
sliceRight,
|
||||
sliceTop);
|
||||
}
|
||||
|
||||
// angle left-bottom
|
||||
if (sliceLeft > 0 && sliceBottom > 0) {
|
||||
drawModalRectWithCustomSizedTexture(
|
||||
xOffset,
|
||||
yOffset + sliceTop + tileHeight,
|
||||
0,
|
||||
sliceTop + middleHeight,
|
||||
sliceLeft,
|
||||
sliceBottom);
|
||||
}
|
||||
|
||||
// angle right-bottom
|
||||
if (sliceRight > 0 && sliceBottom > 0) {
|
||||
drawModalRectWithCustomSizedTexture(
|
||||
xOffset + sliceLeft + tileWidth,
|
||||
yOffset + sliceTop + tileHeight,
|
||||
sliceLeft + middleWidth,
|
||||
sliceTop + middleHeight,
|
||||
sliceRight,
|
||||
sliceBottom);
|
||||
}
|
||||
|
||||
if (!is2DTexture) GL11.glDisable(GL11.GL_TEXTURE_2D);
|
||||
}
|
||||
}
|
||||
|
||||
private void drawModalRectWithCustomSizedTexture(int xOffset, int yOffset, int u, int v, int width, int height) {
|
||||
Gui.func_146110_a(
|
||||
xOffset + this.paddingLeft,
|
||||
yOffset + this.paddingTop,
|
||||
this.x + u,
|
||||
this.y + v,
|
||||
width,
|
||||
height,
|
||||
this.textureWidth,
|
||||
this.textureHeight);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
package codechicken.nei.drawable;
|
||||
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
/*
|
||||
* Taken from Mantle 1.12-1.3.3.49 under the MIT License The MIT License (MIT) Copyright (c) 2013-2014 Slime Knights
|
||||
* (mDiyo, fuj1n, Sunstrike, progwml6, pillbox, alexbegt) Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software
|
||||
* without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions: The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
|
||||
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class GuiElementDuex {
|
||||
|
||||
// this is totally completely ugly but it's a simple solution that doesn't clutter everything too much >_>
|
||||
public static int defaultTexW = 256;
|
||||
public static int defaultTexH = 256;
|
||||
|
||||
public final int x;
|
||||
public final int y;
|
||||
public final int w;
|
||||
public final int h;
|
||||
|
||||
public int texW;
|
||||
public int texH;
|
||||
|
||||
public GuiElementDuex(int x, int y, int w, int h, int texW, int texH) {
|
||||
this(x, y, w, h);
|
||||
setTextureSize(texW, texH);
|
||||
|
||||
defaultTexW = texW;
|
||||
defaultTexH = texH;
|
||||
}
|
||||
|
||||
public GuiElementDuex(int x, int y, int w, int h) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.w = w;
|
||||
this.h = h;
|
||||
setTextureSize(defaultTexW, defaultTexH);
|
||||
}
|
||||
|
||||
public GuiElementDuex setTextureSize(int w, int h) {
|
||||
texW = w;
|
||||
texH = h;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public GuiElementDuex shift(int xd, int yd) {
|
||||
return new GuiElementDuex(this.x + xd, this.y + yd, this.w, this.h, this.texW, this.texH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the element at the given x/y coordinates
|
||||
*
|
||||
* @param xPos X-Coordinate on the screen
|
||||
* @param yPos Y-Coordinate on the screen
|
||||
*/
|
||||
public int draw(int xPos, int yPos) {
|
||||
// drawModalRectWithCustomSizedTexture
|
||||
GL11.glColor4f(1, 1, 1, 1);
|
||||
GuiScreen.func_146110_a(xPos, yPos, x, y, w, h, texW, texH);
|
||||
return w;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
public int w;
|
||||
public int h;
|
||||
|
||||
public Builder(int w, int h) {
|
||||
this.w = w;
|
||||
this.h = h;
|
||||
}
|
||||
|
||||
public GuiElementDuex get(int x, int y, int w, int h) {
|
||||
return new GuiElementDuex(x, y, w, h, this.w, this.h);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
package codechicken.nei.drawable;
|
||||
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
|
||||
/*
|
||||
* Taken from Mantle 1.12-1.3.3.49 under the MIT License The MIT License (MIT) Copyright (c) 2013-2014 Slime Knights
|
||||
* (mDiyo, fuj1n, Sunstrike, progwml6, pillbox, alexbegt) Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software
|
||||
* without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
||||
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions: The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
|
||||
* AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
public class GuiElementScalable extends GuiElementDuex {
|
||||
|
||||
public GuiElementScalable(int x, int y, int w, int h, int texW, int texH) {
|
||||
super(x, y, w, h, texW, texH);
|
||||
}
|
||||
|
||||
public GuiElementScalable(int x, int y, int w, int h) {
|
||||
super(x, y, w, h);
|
||||
}
|
||||
|
||||
public int drawScaledX(int xPos, int yPos, int width) {
|
||||
for (int i = 0; i < width / w; i++) {
|
||||
draw(xPos + i * w, yPos);
|
||||
}
|
||||
// remainder that doesn't fit total width
|
||||
int remainder = width % w;
|
||||
if (remainder > 0) {
|
||||
GuiScreen.func_146110_a(xPos + width - remainder, yPos, x, y, remainder, h, texW, texH);
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
public int drawScaledY(int xPos, int yPos, int height) {
|
||||
for (int i = 0; i < height / h; i++) {
|
||||
draw(xPos, yPos + i * h);
|
||||
}
|
||||
// remainder that doesn't fit total width
|
||||
int remainder = height % h;
|
||||
if (remainder > 0) {
|
||||
// drawModalRectWithCustomSizedTexture
|
||||
GuiScreen.func_146110_a(xPos, yPos + height - remainder, x, y, w, remainder, texW, texH);
|
||||
}
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
public int drawScaled(int xPos, int yPos, int width, int height) {
|
||||
// we draw full height row-wise
|
||||
int full = height / this.h;
|
||||
for (int i = 0; i < full; i++) {
|
||||
drawScaledX(xPos, yPos + i * this.h, width);
|
||||
}
|
||||
|
||||
yPos += full * this.h;
|
||||
|
||||
// and the remainder is drawn manually
|
||||
int yRest = height % this.h;
|
||||
// the same as drawScaledX but with the remaining height
|
||||
for (int i = 0; i < width / w; i++) {
|
||||
drawScaledY(xPos + i * w, yPos, yRest);
|
||||
}
|
||||
// remainder that doesn't fit total width
|
||||
int remainder = width % w;
|
||||
if (remainder > 0) {
|
||||
// drawModalRectWithCustomSizedTexture
|
||||
GuiScreen.func_146110_a(xPos + width - remainder, yPos, x, y, remainder, yRest, texW, texH);
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuiElementScalable shift(int xd, int yd) {
|
||||
GuiElementScalable element = new GuiElementScalable(this.x + xd, this.y + yd, this.w, this.h);
|
||||
element.setTextureSize(texW, texH);
|
||||
return element;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -49,6 +50,7 @@ import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.NEIModContainer;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
import codechicken.nei.util.ItemUntranslator;
|
||||
import codechicken.nei.util.ReadableNumberConverter;
|
||||
import codechicken.nei.util.RenderTooltipEventHelper;
|
||||
|
||||
@@ -60,6 +62,10 @@ public class GuiContainerManager {
|
||||
public void onResourceManagerReload(IResourceManager p_110549_1_) {
|
||||
renderingErrorItems.clear();
|
||||
ItemList.loadItems.restart();
|
||||
|
||||
if (NEIClientConfig.enableItemUntranslator()) {
|
||||
ItemUntranslator.getInstance().load();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,6 +83,9 @@ public class GuiContainerManager {
|
||||
public static final LinkedList<IContainerSlotClickHandler> slotClickHandlers = new HideousLinkedList<>(
|
||||
new CopyOnWriteArrayList<>());
|
||||
|
||||
// Any item rendered with this z offset should render it on top of every other gui element
|
||||
public static final int TOOLTIP_Z_OFFSET = 400;
|
||||
|
||||
static {
|
||||
addSlotClickHandler(new DefaultSlotClickHandler());
|
||||
}
|
||||
@@ -156,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,
|
||||
@@ -191,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;
|
||||
}
|
||||
|
||||
@@ -224,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -399,7 +411,7 @@ public class GuiContainerManager {
|
||||
|
||||
public static void enableMatrixStackLogging() {
|
||||
if (!contextEnabled) {
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
|
||||
GL11.glPushAttrib(GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT | GL11.GL_LIGHTING_BIT);
|
||||
modelviewDepth = GL11.glGetInteger(GL11.GL_MODELVIEW_STACK_DEPTH);
|
||||
contextEnabled = true;
|
||||
}
|
||||
@@ -590,8 +602,6 @@ public class GuiContainerManager {
|
||||
}
|
||||
}
|
||||
|
||||
if (!tooltip.isEmpty()) tooltip.set(0, tooltip.get(0) + GuiDraw.TOOLTIP_LINESPACE); // add space after 'title'
|
||||
|
||||
if (showTooltip && NEIClientConfig.getBooleanSetting("inventory.showHotkeys")) {
|
||||
List<String> hotkeystips = collectHotkeyTips(mousex, mousey);
|
||||
|
||||
@@ -605,6 +615,19 @@ public class GuiContainerManager {
|
||||
}
|
||||
}
|
||||
|
||||
if (showTooltip && stack != null && !tooltip.isEmpty()) {
|
||||
final String secondDisplayName = ItemUntranslator.getInstance().getItemStackDisplayName(stack);
|
||||
|
||||
if (!secondDisplayName.isEmpty()) {
|
||||
tooltip.add(1, EnumChatFormatting.DARK_GRAY + secondDisplayName + GuiDraw.TOOLTIP_LINESPACE);
|
||||
} else {
|
||||
tooltip.set(0, tooltip.get(0) + GuiDraw.TOOLTIP_LINESPACE);
|
||||
}
|
||||
|
||||
} else if (!tooltip.isEmpty()) {
|
||||
tooltip.set(0, tooltip.get(0) + GuiDraw.TOOLTIP_LINESPACE);
|
||||
}
|
||||
|
||||
if (NEIModContainer.isGTNHLibLoaded() && !tooltip.isEmpty()) {
|
||||
if (RenderTooltipEventHelper.post(stack, this.window, mousex, mousey, font)) {
|
||||
return;
|
||||
@@ -632,9 +655,6 @@ public class GuiContainerManager {
|
||||
drawPagedTooltip(font, mousex + 12, mousey - 12, tooltip);
|
||||
}
|
||||
|
||||
for (IContainerDrawHandler drawHandler : drawHandlers) {
|
||||
drawHandler.postRenderTooltips(window, mousex, mousey, tooltip);
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> collectHotkeyTips(int mousex, int mousey) {
|
||||
@@ -648,12 +668,12 @@ public class GuiContainerManager {
|
||||
}
|
||||
}
|
||||
|
||||
hotkeys.remove(null);
|
||||
hotkeys.remove("");
|
||||
|
||||
if (!hotkeys.isEmpty()) {
|
||||
List<String> hotkeystips = new ArrayList<>();
|
||||
|
||||
Map<String, List<String>> messages = new HashMap<>();
|
||||
hotkeys.remove(null);
|
||||
hotkeys.remove("");
|
||||
|
||||
for (Map.Entry<String, String> entry : hotkeys.entrySet()) {
|
||||
messages.computeIfAbsent(entry.getValue(), m -> new ArrayList<>()).add(entry.getKey());
|
||||
@@ -688,13 +708,19 @@ public class GuiContainerManager {
|
||||
}
|
||||
|
||||
} else if (NEIClientConfig.getBooleanSetting("inventory.hotkeysHelpText")) {
|
||||
Map<String, String> hotkeys = new HashMap<>();
|
||||
boolean existsHotkeys = false;
|
||||
|
||||
synchronized (instanceTooltipHandlers) {
|
||||
for (IContainerTooltipHandler handler : instanceTooltipHandlers) {
|
||||
if (!handler.handleHotkeys(window, mousex, mousey, new HashMap<>()).isEmpty()) {
|
||||
existsHotkeys = true;
|
||||
break;
|
||||
if (!(hotkeys = handler.handleHotkeys(window, mousex, mousey, hotkeys)).isEmpty()) {
|
||||
hotkeys.remove("");
|
||||
hotkeys.remove(null);
|
||||
|
||||
if (!hotkeys.isEmpty()) {
|
||||
existsHotkeys = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package codechicken.nei.guihook;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.inventory.Slot;
|
||||
|
||||
@@ -9,14 +7,14 @@ public interface IContainerDrawHandler {
|
||||
|
||||
/**
|
||||
* Initialize your objects and the gui for drawing.
|
||||
*
|
||||
*
|
||||
* @param gui An instance of the currentscreen
|
||||
*/
|
||||
public void onPreDraw(GuiContainer gui);
|
||||
|
||||
/**
|
||||
* Draw your objects. Called after all normal gui rendering has been performed.
|
||||
*
|
||||
*
|
||||
* @param gui An instance of the currentscreen
|
||||
* @param mousex The x position of the mouse in pixels from left
|
||||
* @param mousey The y position of the mouse in pixels from top
|
||||
@@ -25,27 +23,16 @@ public interface IContainerDrawHandler {
|
||||
|
||||
/**
|
||||
* Use this to draw things that should always be on top, for example objects being held by the mouse.
|
||||
*
|
||||
*
|
||||
* @param gui An instance of the currentscreen
|
||||
* @param mousex The x position of the mouse in pixels from left
|
||||
* @param mousey The y position of the mouse in pixels from top
|
||||
*/
|
||||
public void postRenderObjects(GuiContainer gui, int mousex, int mousey);
|
||||
|
||||
/**
|
||||
* Use this to draw things that should be drawn just after vanilla slot tooltips, on top of buttons and other
|
||||
* usually always-on-top widgets.
|
||||
*
|
||||
* @param gui An instance of the currentscreen
|
||||
* @param mousex The x position of the mouse in pixels from left
|
||||
* @param mousey The y position of the mouse in pixels from top
|
||||
* @param tooltip The contents of the tooltip that has previously been drawn
|
||||
*/
|
||||
default void postRenderTooltips(GuiContainer gui, int mousex, int mousey, List<String> tooltip) {}
|
||||
|
||||
/**
|
||||
* Render something over a slot before the item in the slot.
|
||||
*
|
||||
*
|
||||
* @param gui An instance of the currentscreen
|
||||
* @param slot The slot being rendered.
|
||||
*/
|
||||
@@ -53,7 +40,7 @@ public interface IContainerDrawHandler {
|
||||
|
||||
/**
|
||||
* Render something over a slot after the item in the slot.
|
||||
*
|
||||
*
|
||||
* @param gui An instance of the currentscreen
|
||||
* @param slot The slot being rendered.
|
||||
*/
|
||||
|
||||
@@ -11,7 +11,7 @@ import codechicken.nei.NEIClientUtils;
|
||||
|
||||
public class AcceptsFollowingTooltipLineHandler extends ItemsTooltipLineHandler {
|
||||
|
||||
protected static final int DEFAULT_MAX_ROWS = 5;
|
||||
protected static final int DEFAULT_MAX_ROWS = 4;
|
||||
|
||||
public Object tooltipGUID;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,122 +2,29 @@ package codechicken.nei.recipe;
|
||||
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.Container;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import codechicken.nei.PositionedStack;
|
||||
import codechicken.nei.api.ShortcutInputHandler;
|
||||
|
||||
public class ContainerRecipe extends Container {
|
||||
|
||||
private class RecipeInventory implements IInventory {
|
||||
private ItemStack activeStack = null;
|
||||
|
||||
@Override
|
||||
public boolean isUseableByPlayer(EntityPlayer entityplayer) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSizeInventory() {
|
||||
return inventorySlots.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlot(int i) {
|
||||
if (i < 0 || i > inventoryItemStacks.size()) return null;
|
||||
return (ItemStack) inventoryItemStacks.get(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack decrStackSize(int i, int j) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInventorySlotContents(int slot, ItemStack itemstack) {
|
||||
if (slot < 0 || slot >= inventoryItemStacks.size()) return;
|
||||
|
||||
inventoryItemStacks.set(slot, itemstack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInventoryName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInventoryStackLimit() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void markDirty() {}
|
||||
|
||||
@Override
|
||||
public void openInventory() {}
|
||||
|
||||
@Override
|
||||
public void closeInventory() {}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackInSlotOnClosing(int var1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValidForSlot(int i, ItemStack itemstack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCustomInventoryName() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private final RecipeInventory recipeInventory = new RecipeInventory();
|
||||
|
||||
public void clearInventory() {
|
||||
inventoryItemStacks.clear();
|
||||
inventorySlots.clear();
|
||||
}
|
||||
|
||||
public ItemStack slotClick(int slot, int button, boolean flag, EntityPlayer entityplayer) {
|
||||
if (slot < 0) return null;
|
||||
|
||||
ItemStack stack = recipeInventory.getStackInSlot(slot);
|
||||
if (stack != null) {
|
||||
|
||||
if (button == 0) {
|
||||
GuiCraftingRecipe.openRecipeGui("item", stack);
|
||||
} else if (button == 1) {
|
||||
GuiUsageRecipe.openRecipeGui("item", stack);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public ItemStack slotClick(int slotId, int clickedButton, int mode, EntityPlayer player) {
|
||||
ShortcutInputHandler.handleMouseClick(this.activeStack);
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addSlot(PositionedStack stack, int recipex, int recipey) {
|
||||
int slot = inventorySlots.size();
|
||||
addSlotToContainer(new Slot(recipeInventory, slot, recipex + stack.relx, recipey + stack.rely) {
|
||||
|
||||
@Override
|
||||
public boolean isItemValid(ItemStack par1ItemStack) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
recipeInventory.setInventorySlotContents(slot, stack.item);
|
||||
}
|
||||
|
||||
public Slot getSlotWithStack(PositionedStack stack, int recipex, int recipey) {
|
||||
for (Object inventorySlot : inventorySlots) {
|
||||
Slot slot = (Slot) inventorySlot;
|
||||
if (slot.xDisplayPosition == (stack.relx + recipex) && slot.yDisplayPosition == (stack.rely + recipey))
|
||||
return slot;
|
||||
}
|
||||
return null;
|
||||
public void setActiveStack(ItemStack activeStack) {
|
||||
this.inventorySlots.clear();
|
||||
this.inventoryItemStacks.clear();
|
||||
this.activeStack = activeStack;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInteractWith(EntityPlayer entityplayer) {
|
||||
return true;
|
||||
}
|
||||
@@ -131,4 +38,9 @@ public class ContainerRecipe extends Container {
|
||||
public ItemStack transferStackInSlot(EntityPlayer par1EntityPlayer, int par2) {
|
||||
return null; // no shift clicking (scrolling...)
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Slot getSlotWithStack(PositionedStack stack, int recipex, int recipey) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -6,10 +6,10 @@ import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.client.entity.EntityClientPlayerMP;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.entity.player.InventoryPlayer;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.inventory.SlotCrafting;
|
||||
@@ -50,17 +50,17 @@ public class DefaultOverlayHandler implements IOverlayHandler {
|
||||
public Slot[] slots;
|
||||
}
|
||||
|
||||
public DefaultOverlayHandler(int x, int y) {
|
||||
offsetx = x;
|
||||
offsety = y;
|
||||
}
|
||||
public int offsetx;
|
||||
public int offsety;
|
||||
|
||||
public DefaultOverlayHandler() {
|
||||
this(5, 11);
|
||||
}
|
||||
|
||||
public int offsetx;
|
||||
public int offsety;
|
||||
public DefaultOverlayHandler(int x, int y) {
|
||||
this.offsetx = x;
|
||||
this.offsety = y;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void overlayRecipe(GuiContainer gui, IRecipeHandler handler, int recipeIndex, boolean maxTransfer) {
|
||||
@@ -72,7 +72,7 @@ public class DefaultOverlayHandler implements IOverlayHandler {
|
||||
final List<PositionedStack> ingredients = handler.getIngredientStacks(recipeIndex);
|
||||
final List<DistributedIngred> ingredStacks = getPermutationIngredients(ingredients);
|
||||
|
||||
if (!clearIngredients(gui)) return 0;
|
||||
if (!clearIngredients(gui, handler)) return 0;
|
||||
|
||||
findInventoryQuantities(gui, ingredStacks);
|
||||
|
||||
@@ -98,13 +98,22 @@ public class DefaultOverlayHandler implements IOverlayHandler {
|
||||
&& presenceOverlay(firstGui, handler, recipeIndex).stream().allMatch(state -> state.isPresent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean craft(GuiContainer firstGui, IRecipeHandler recipe, int recipeIndex, int multiplier) {
|
||||
final EntityClientPlayerMP thePlayer = NEIClientUtils.mc().thePlayer;
|
||||
boolean craft = false;
|
||||
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 = getCraftingResultSlot(firstGui);
|
||||
|
||||
if (craftingSlot == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean craft = false;
|
||||
while (multiplier > 0) {
|
||||
final int transfer = transferRecipe(firstGui, recipe, recipeIndex, multiplier);
|
||||
final int transfer = transferRecipe(firstGui, handler, recipeIndex, multiplier);
|
||||
|
||||
if (transfer <= 0) {
|
||||
break;
|
||||
@@ -112,43 +121,89 @@ public class DefaultOverlayHandler implements IOverlayHandler {
|
||||
|
||||
multiplier -= transfer;
|
||||
|
||||
for (Slot slot : firstGui.inventorySlots.inventorySlots) {
|
||||
if (slot.getHasStack() && slot instanceof SlotCrafting && slot.canTakeStack(thePlayer)) {
|
||||
FastTransferManager.clickSlot(firstGui, slot.slotNumber, 0, 1);
|
||||
craft = true;
|
||||
break;
|
||||
}
|
||||
if (craftingSlot.getHasStack() && craftingSlot.canTakeStack(firstGui.mc.thePlayer)) {
|
||||
FastTransferManager.clickSlot(firstGui, craftingSlot.slotNumber, 0, 1);
|
||||
craft = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
clearIngredients(firstGui);
|
||||
clearIngredients(firstGui, handler);
|
||||
|
||||
return craft;
|
||||
}
|
||||
|
||||
private boolean clearIngredients(GuiContainer gui) {
|
||||
final EntityClientPlayerMP thePlayer = NEIClientUtils.mc().thePlayer;
|
||||
protected boolean clearIngredients(GuiContainer gui, IRecipeHandler handler) {
|
||||
|
||||
for (Slot slot : gui.inventorySlots.inventorySlots) {
|
||||
if (slot.getHasStack() && !canMoveFrom(slot, gui)
|
||||
&& !(slot instanceof SlotCrafting)
|
||||
&& slot.canTakeStack(thePlayer)) {
|
||||
for (Slot slot : getCraftMatrixSlots(gui, handler)) {
|
||||
if (slot.canTakeStack(gui.mc.thePlayer)) {
|
||||
FastTransferManager.clickSlot(gui, slot.slotNumber, 0, 1);
|
||||
if (slot.getHasStack()) return false;
|
||||
}
|
||||
}
|
||||
|
||||
return dropOffMouseStack(thePlayer, gui);
|
||||
FastTransferManager.dropHeldItem(gui);
|
||||
|
||||
return gui.mc.thePlayer.inventory.getItemStack() == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the slots in the crafting matrix for the given GUI and recipe handler.
|
||||
*
|
||||
* @param gui
|
||||
* @param handler
|
||||
* @return
|
||||
*/
|
||||
protected Set<Slot> getCraftMatrixSlots(GuiContainer gui, IRecipeHandler handler) {
|
||||
final PositionedStack firstIngr = handler.getIngredientStacks(0).get(0);
|
||||
final Map<Integer, Slot> grid = new HashMap<>();
|
||||
final Set<Slot> ingredSlots = new HashSet<>();
|
||||
|
||||
for (Slot slot : gui.inventorySlots.inventorySlots) {
|
||||
final int key = (slot.xDisplayPosition - this.offsetx) * 10_000 + (slot.yDisplayPosition - this.offsety);
|
||||
grid.put(key, slot);
|
||||
}
|
||||
|
||||
int left = firstIngr.relx;
|
||||
int top = firstIngr.rely;
|
||||
int right = left;
|
||||
int bottom = top;
|
||||
|
||||
while (grid.containsKey((left - 18) * 10_000 + firstIngr.rely)) {
|
||||
left -= 18;
|
||||
}
|
||||
|
||||
while (grid.containsKey((right + 18) * 10_000 + firstIngr.rely)) {
|
||||
right += 18;
|
||||
}
|
||||
|
||||
while (grid.containsKey(firstIngr.relx * 10_000 + (top - 18))) {
|
||||
top -= 18;
|
||||
}
|
||||
|
||||
while (grid.containsKey(firstIngr.relx * 10_000 + (bottom + 18))) {
|
||||
bottom += 18;
|
||||
}
|
||||
|
||||
for (int x = left; x <= right; x += 18) {
|
||||
for (int y = top; y <= bottom; y += 18) {
|
||||
final Slot slot = grid.get(x * 10_000 + y);
|
||||
if (slot != null && !(slot.inventory instanceof InventoryPlayer)) {
|
||||
ingredSlots.add(slot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ingredSlots;
|
||||
}
|
||||
|
||||
private void moveIngredients(GuiContainer gui, List<IngredientDistribution> assignedIngredients, int multiplier) {
|
||||
final EntityClientPlayerMP thePlayer = NEIClientUtils.mc().thePlayer;
|
||||
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(thePlayer))
|
||||
|| !slot.canTakeStack(gui.mc.thePlayer))
|
||||
continue;
|
||||
ItemStack stack = slot.getStack();
|
||||
int slotTransferCap = stack.getMaxStackSize();
|
||||
@@ -186,7 +241,7 @@ public class DefaultOverlayHandler implements IOverlayHandler {
|
||||
|
||||
}
|
||||
|
||||
if (thePlayer.inventory.getItemStack() != null) {
|
||||
if (gui.mc.thePlayer.inventory.getItemStack() != null) {
|
||||
FastTransferManager.clickSlot(gui, slot.slotNumber);
|
||||
}
|
||||
}
|
||||
@@ -194,33 +249,6 @@ public class DefaultOverlayHandler implements IOverlayHandler {
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean dropOffMouseStack(EntityPlayer entityPlayer, GuiContainer gui) {
|
||||
|
||||
if (entityPlayer.inventory.getItemStack() == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < gui.inventorySlots.inventorySlots.size(); i++) {
|
||||
Slot slot = gui.inventorySlots.inventorySlots.get(i);
|
||||
|
||||
if (slot.inventory == entityPlayer.inventory) {
|
||||
ItemStack mouseItem = entityPlayer.inventory.getItemStack();
|
||||
ItemStack slotStack = slot.getStack();
|
||||
|
||||
if (slotStack == null || NEIClientUtils.areStacksSameType(mouseItem, slotStack)) {
|
||||
FastTransferManager.clickSlot(gui, i, 0, 0);
|
||||
}
|
||||
|
||||
if (entityPlayer.inventory.getItemStack() == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return entityPlayer.inventory.getItemStack() == null;
|
||||
}
|
||||
|
||||
private int calculateRecipeQuantity(List<IngredientDistribution> assignedIngredients) {
|
||||
int quantity = Integer.MAX_VALUE;
|
||||
|
||||
@@ -399,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);
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ public class FurnaceRecipeHandler extends TemplateRecipeHandler {
|
||||
}
|
||||
|
||||
public List<PositionedStack> getIngredients() {
|
||||
return getCycledIngredients(cycleticks / 48, Collections.singletonList(ingred));
|
||||
return Collections.singletonList(ingred);
|
||||
}
|
||||
|
||||
public PositionedStack getResult() {
|
||||
|
||||
@@ -13,13 +13,15 @@ import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.nei.FavoriteRecipes;
|
||||
import codechicken.nei.ItemPanels;
|
||||
import codechicken.nei.ItemsGrid.ItemsGridSlot;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
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.stackinfo.GTFluidStackStringifyHandler;
|
||||
import codechicken.nei.recipe.TemplateRecipeHandler.RecipeTransferRect;
|
||||
|
||||
public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
|
||||
|
||||
@@ -35,10 +37,13 @@ public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
|
||||
final Minecraft mc = NEIClientUtils.mc();
|
||||
final RecipeId recipeId;
|
||||
|
||||
if ("item".equals(outputId)) {
|
||||
for (int i = 0; i < results.length; i++) {
|
||||
results[i] = normalizeItemStack((ItemStack) results[i]);
|
||||
for (int i = 0; i < results.length; i++) {
|
||||
if (results[i] instanceof ItemStack stack) {
|
||||
results[i] = StackInfo.normalizeRecipeQueryStack(stack.copy());
|
||||
}
|
||||
}
|
||||
|
||||
if ("item".equals(outputId)) {
|
||||
recipeId = getRecipeId(mc.currentScreen, (ItemStack) results[0]);
|
||||
} else if ("recipeId".equals(outputId)) {
|
||||
recipeId = (RecipeId) results[1];
|
||||
@@ -49,7 +54,7 @@ public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
|
||||
final ArrayList<ICraftingHandler> handlers = getCraftingHandlers(outputId, results);
|
||||
|
||||
if (!handlers.isEmpty()) {
|
||||
final GuiCraftingRecipe gui = new GuiCraftingRecipe(handlers, "recipeId".equals(outputId));
|
||||
final GuiCraftingRecipe gui = new GuiCraftingRecipe(handlers);
|
||||
|
||||
if (open) {
|
||||
|
||||
@@ -73,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());
|
||||
@@ -94,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))
|
||||
@@ -104,13 +129,6 @@ public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
|
||||
return GuiRecipeTab.getHandlerInfo(handler).getHandlerName();
|
||||
}
|
||||
|
||||
private static ItemStack normalizeItemStack(ItemStack stack) {
|
||||
GTFluidStackStringifyHandler.replaceAE2FCFluidDrop = true;
|
||||
stack = StackInfo.loadFromNBT(StackInfo.itemStackToNBT(stack));
|
||||
GTFluidStackStringifyHandler.replaceAE2FCFluidDrop = false;
|
||||
return stack;
|
||||
}
|
||||
|
||||
public static RecipeId getRecipeId(GuiScreen gui, ItemStack stackover) {
|
||||
|
||||
if (gui instanceof GuiRecipe guiRecipe) {
|
||||
@@ -123,10 +141,11 @@ public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
|
||||
|
||||
final Point mouseover = GuiDraw.getMousePosition();
|
||||
final BookmarksGridSlot panelSlot = ItemPanels.bookmarkPanel.getSlotMouseOver(mouseover.x, mouseover.y);
|
||||
RecipeId recipeId = null;
|
||||
|
||||
if (panelSlot != null && !panelSlot.isIngredient()) {
|
||||
recipeId = panelSlot.getRecipeId();
|
||||
if (panelSlot != null) {
|
||||
return panelSlot.getType() == BookmarkItemType.INGREDIENT || panelSlot.getRecipeId() == null
|
||||
? FavoriteRecipes.getFavorite(stackover)
|
||||
: panelSlot.getRecipeId();
|
||||
}
|
||||
|
||||
ItemsGridSlot itemSlot = ItemPanels.itemPanel.getSlotMouseOver(mouseover.x, mouseover.y);
|
||||
@@ -143,12 +162,11 @@ public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
|
||||
return itemSlot.getRecipeId();
|
||||
}
|
||||
|
||||
return recipeId;
|
||||
return null;
|
||||
}
|
||||
|
||||
private GuiCraftingRecipe(ArrayList<ICraftingHandler> handlers, boolean limitToOneRecipe) {
|
||||
private GuiCraftingRecipe(ArrayList<ICraftingHandler> handlers) {
|
||||
super(NEIClientUtils.mc().currentScreen);
|
||||
this.limitToOneRecipe = limitToOneRecipe;
|
||||
this.currenthandlers = handlers;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
@@ -55,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) {
|
||||
@@ -73,7 +72,7 @@ public class GuiFavoriteButton extends GuiRecipeButton {
|
||||
}
|
||||
|
||||
public boolean isFavorite() {
|
||||
return favorite;
|
||||
return this.favorite;
|
||||
}
|
||||
|
||||
public void toggleFavorite() {
|
||||
@@ -87,6 +86,11 @@ public class GuiFavoriteButton extends GuiRecipeButton {
|
||||
.setFavorite(this.favoriteResult.getItemStack(), this.favorite ? this.recipe.getRecipeId() : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
this.favorite = this.favorite && FavoriteRecipes.getManualFavorite(this.recipe.getRecipeId()) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawContent(Minecraft minecraft, int y, int x, boolean mouseOver) {
|
||||
final DrawableResource icon = isFavorite() ? ICON_STATE_ON : ICON_STATE_OFF;
|
||||
@@ -116,7 +120,7 @@ public class GuiFavoriteButton extends GuiRecipeButton {
|
||||
return Recipe.of(this.handlerRef);
|
||||
}
|
||||
|
||||
public void lastKeyTyped(GuiRecipe<?> gui, char keyChar, int keyID) {
|
||||
public void lastKeyTyped(char keyChar, int keyID) {
|
||||
|
||||
if (NEIClientConfig.isKeyHashDown("gui.bookmark") && NEIClientUtils.shiftKey()) {
|
||||
saveRecipeInBookmark();
|
||||
@@ -125,7 +129,7 @@ public class GuiFavoriteButton extends GuiRecipeButton {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> handleHotkeys(GuiContainer gui, int mousex, int mousey, Map<String, String> hotkeys) {
|
||||
public Map<String, String> handleHotkeys(int mousex, int mousey, Map<String, String> hotkeys) {
|
||||
hotkeys.put(
|
||||
NEIClientConfig.getKeyName("gui.bookmark", NEIClientUtils.SHIFT_HASH),
|
||||
translate("recipe.favorite.bookmark_recipe"));
|
||||
@@ -140,9 +144,8 @@ public class GuiFavoriteButton extends GuiRecipeButton {
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> handleTooltip(GuiRecipe<?> gui, List<String> currenttip) {
|
||||
public List<String> handleTooltip(List<String> currenttip) {
|
||||
currenttip.add(translate("recipe.favorite"));
|
||||
|
||||
return currenttip;
|
||||
}
|
||||
|
||||
@@ -161,7 +164,7 @@ public class GuiFavoriteButton extends GuiRecipeButton {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseScrolled(GuiRecipe<?> gui, int scroll) {
|
||||
public boolean mouseScrolled(int scroll) {
|
||||
if (this.selectedResult == null) return true;
|
||||
|
||||
final List<RecipeIngredient> results = new ArrayList<>(this.recipe.getResults());
|
||||
@@ -174,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;
|
||||
@@ -202,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,26 +96,32 @@ 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();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> handleTooltip(GuiRecipe<?> gui, List<String> currenttip) {
|
||||
currenttip.add(NEIClientUtils.translate("recipe.overlay"));
|
||||
public List<String> handleTooltip(List<String> currenttip) {
|
||||
|
||||
if (!this.enabled && this.requireShiftForOverlayRecipe && this.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 ((!this.requireShiftForOverlayRecipe || NEIClientUtils.shiftKey()) && this.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);
|
||||
@@ -129,7 +134,7 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> handleHotkeys(GuiContainer gui, int mousex, int mousey, Map<String, String> hotkeys) {
|
||||
public Map<String, String> handleHotkeys(int mousex, int mousey, Map<String, String> hotkeys) {
|
||||
|
||||
if (requireShiftForOverlayRecipe()) {
|
||||
|
||||
@@ -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 (this.hasOverlay && (!this.requireShiftForOverlayRecipe || NEIClientUtils.shiftKey())) {
|
||||
if (this.canFillCraftingGrid && (!requireShiftForOverlayRecipe() || NEIClientUtils.shiftKey())) {
|
||||
icon = this.missedMaterialsTooltipLineHandler == null ? ICON_FILL : ICON_FILL_ERROR;
|
||||
}
|
||||
|
||||
@@ -206,18 +211,21 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
}
|
||||
|
||||
protected List<ItemOverlayState> ingredientsOverlay() {
|
||||
List<PositionedStack> ingredients = this.handlerRef.handler.getIngredientStacks(this.handlerRef.recipeIndex);
|
||||
final List<PositionedStack> ingredients = this.handlerRef.handler
|
||||
.getIngredientStacks(this.handlerRef.recipeIndex);
|
||||
|
||||
if (this.itemPresenceCache.size() != ingredients.size()) {
|
||||
this.itemPresenceCache.clear();
|
||||
|
||||
if (this.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));
|
||||
}
|
||||
}
|
||||
|
||||
List<ItemStack> items = this.itemPresenceCache.stream().filter(state -> !state.isPresent())
|
||||
final List<ItemStack> items = this.itemPresenceCache.stream().filter(state -> !state.isPresent())
|
||||
.map(state -> state.getSlot().item).collect(Collectors.toList());
|
||||
|
||||
if (!items.isEmpty()) {
|
||||
@@ -229,6 +237,8 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
} else {
|
||||
this.missedMaterialsTooltipLineHandler = null;
|
||||
}
|
||||
|
||||
updateEnabled();
|
||||
}
|
||||
|
||||
return this.itemPresenceCache;
|
||||
@@ -236,7 +246,12 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
|
||||
public void setRequireShiftForOverlayRecipe(boolean require) {
|
||||
this.requireShiftForOverlayRecipe = require;
|
||||
this.enabled = this.hasOverlay && (this.requireShiftForOverlayRecipe || this.canFillCraftingGrid);
|
||||
updateEnabled();
|
||||
}
|
||||
|
||||
private void updateEnabled() {
|
||||
this.enabled = hasOverlay() || this.canFillCraftingGrid
|
||||
&& (this.requireShiftForOverlayRecipe || this.missedMaterialsTooltipLineHandler == null);
|
||||
}
|
||||
|
||||
public void setCanUseOverlayRenderer(boolean use) {
|
||||
@@ -252,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() {
|
||||
@@ -263,8 +278,8 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
return Recipe.of(this.handlerRef);
|
||||
}
|
||||
|
||||
private List<ItemOverlayState> presenceOverlay(List<PositionedStack> ingredients) {
|
||||
final List<ItemOverlayState> itemPresenceSlots = new ArrayList<>();
|
||||
protected List<ItemOverlayState> presenceOverlay(List<PositionedStack> ingredients) {
|
||||
final List<ItemOverlayState> states = new ArrayList<>();
|
||||
final List<ItemStack> invStacks = this.firstGui.inventorySlots.inventorySlots.stream()
|
||||
.filter(
|
||||
s -> s != null && s.getStack() != null
|
||||
@@ -274,36 +289,36 @@ 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 (!this.hasOverlay) return;
|
||||
|
||||
if (!this.requireShiftForOverlayRecipe || shift) {
|
||||
if (canFillCraftingGrid()) {
|
||||
if (!requireShiftForOverlayRecipe() || shift) {
|
||||
if (this.canFillCraftingGrid) {
|
||||
this.handlerRef.fillCraftingGrid(this.firstGui, 0);
|
||||
}
|
||||
} else if (useOverlayRenderer()) {
|
||||
} else if (hasOverlay() && useOverlayRenderer()) {
|
||||
this.handlerRef.useOverlayRenderer(this.firstGui);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lastKeyTyped(GuiRecipe<?> gui, char keyChar, int keyID) {
|
||||
|
||||
public void lastKeyTyped(char keyChar, int keyID) {
|
||||
if (NEIClientConfig.isKeyHashDown("gui.bookmark") && NEIClientUtils.shiftKey()) {
|
||||
saveRecipeInBookmark();
|
||||
}
|
||||
@@ -313,8 +328,11 @@ public class GuiOverlayButton extends GuiRecipeButton {
|
||||
final Recipe recipe = getRecipe();
|
||||
|
||||
if (!ItemPanels.bookmarkPanel.removeRecipe(recipe.getRecipeId(), BookmarkGrid.DEFAULT_GROUP_ID)) {
|
||||
ItemPanels.bookmarkPanel
|
||||
.addRecipe(recipe, NEIClientUtils.controlKey() ? 1 : 0, BookmarkGrid.DEFAULT_GROUP_ID);
|
||||
ItemPanels.bookmarkPanel.addRecipe(
|
||||
recipe,
|
||||
NEIClientUtils.controlKey()
|
||||
|| NEIClientConfig.getBooleanSetting("inventory.bookmarks.bookmarkRecipeWithCount") ? 1 : 0,
|
||||
BookmarkGrid.DEFAULT_GROUP_ID);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -4,7 +4,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraftforge.client.event.GuiScreenEvent;
|
||||
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
@@ -16,33 +15,30 @@ public abstract class GuiRecipeButton extends GuiNEIButton {
|
||||
public static class UpdateRecipeButtonsEvent extends GuiScreenEvent {
|
||||
|
||||
public List<GuiRecipeButton> buttonList;
|
||||
public NEIRecipeWidget recipeWidget;
|
||||
|
||||
public UpdateRecipeButtonsEvent(GuiRecipe<?> gui, List<GuiRecipeButton> buttonList) {
|
||||
public UpdateRecipeButtonsEvent(GuiRecipe<?> gui, NEIRecipeWidget recipeWidget,
|
||||
List<GuiRecipeButton> buttonList) {
|
||||
super(gui);
|
||||
this.recipeWidget = recipeWidget;
|
||||
this.buttonList = new ArrayList<>(buttonList);
|
||||
}
|
||||
|
||||
@Cancelable
|
||||
public static class Pre extends UpdateRecipeButtonsEvent {
|
||||
|
||||
public int xOffset;
|
||||
public int yOffset;
|
||||
public int height;
|
||||
public HandlerInfo handlerInfo;
|
||||
|
||||
public Pre(GuiRecipe<?> gui, int xOffset, int yOffset, int height, HandlerInfo handlerInfo) {
|
||||
super(gui, new ArrayList<>());
|
||||
this.xOffset = xOffset;
|
||||
this.yOffset = yOffset;
|
||||
this.height = height;
|
||||
public Pre(GuiRecipe<?> gui, NEIRecipeWidget recipeWidget, HandlerInfo handlerInfo) {
|
||||
super(gui, recipeWidget, new ArrayList<>());
|
||||
this.handlerInfo = handlerInfo;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Post extends UpdateRecipeButtonsEvent {
|
||||
|
||||
public Post(GuiRecipe<?> gui, List<GuiRecipeButton> buttonList) {
|
||||
super(gui, buttonList);
|
||||
public Post(GuiRecipe<?> gui, NEIRecipeWidget recipeWidget, List<GuiRecipeButton> buttonList) {
|
||||
super(gui, recipeWidget, buttonList);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,15 +53,19 @@ public abstract class GuiRecipeButton extends GuiNEIButton {
|
||||
this.handlerRef = point;
|
||||
}
|
||||
|
||||
abstract List<String> handleTooltip(GuiRecipe<?> gui, List<String> currenttip);
|
||||
public abstract List<String> handleTooltip(List<String> currenttip);
|
||||
|
||||
abstract Map<String, String> handleHotkeys(GuiContainer gui, int mousex, int mousey, Map<String, String> hotkeys);
|
||||
public abstract Map<String, String> handleHotkeys(int mousex, int mousey, Map<String, String> hotkeys);
|
||||
|
||||
abstract void lastKeyTyped(GuiRecipe<?> gui, char keyChar, int keyID);
|
||||
public abstract void lastKeyTyped(char keyChar, int keyID);
|
||||
|
||||
abstract void drawItemOverlay();
|
||||
public abstract void drawItemOverlay();
|
||||
|
||||
public boolean mouseScrolled(GuiRecipe<?> gui, int scroll) {
|
||||
public void update() {
|
||||
|
||||
}
|
||||
|
||||
public boolean mouseScrolled(int scroll) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,159 +1,195 @@
|
||||
package codechicken.nei.recipe;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.lwjgl.util.Rectangle;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import codechicken.nei.api.INEIGuiAdapter;
|
||||
import codechicken.nei.drawable.GuiElementDuex;
|
||||
import codechicken.nei.drawable.GuiElementScalable;
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.NEIServerUtils;
|
||||
import codechicken.nei.PositionedStack;
|
||||
import codechicken.nei.Widget;
|
||||
import codechicken.nei.api.ShortcutInputHandler;
|
||||
import codechicken.nei.drawable.DrawableBuilder;
|
||||
import codechicken.nei.drawable.DrawableResource;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.scroll.ScrollBar;
|
||||
import codechicken.nei.scroll.ScrollContainer;
|
||||
|
||||
public class GuiRecipeCatalyst extends INEIGuiAdapter {
|
||||
public class GuiRecipeCatalyst extends ScrollContainer {
|
||||
|
||||
private GuiRecipe<?> guiRecipe;
|
||||
public static final int ingredientSize = 16;
|
||||
public static final int ingredientBorder = 1;
|
||||
public static final int tabBorder = 5;
|
||||
public static final int fullBorder = ingredientBorder + tabBorder;
|
||||
protected static class ItemStackWidget extends Widget {
|
||||
|
||||
private static final Rectangle catalystRect = new Rectangle();
|
||||
private static final Rectangle targetRect = new Rectangle();
|
||||
private final PositionedStack pStack;
|
||||
|
||||
public GuiRecipeCatalyst(GuiRecipe<?> guiRecipe) {
|
||||
this.guiRecipe = guiRecipe;
|
||||
public ItemStackWidget(PositionedStack pStack) {
|
||||
this.pStack = pStack;
|
||||
this.x = pStack.relx;
|
||||
this.y = pStack.rely;
|
||||
this.w = SLOT_SIZE;
|
||||
this.h = SLOT_SIZE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int mx, int my) {
|
||||
GuiContainerManager.drawItem(this.x, this.y, this.pStack.item);
|
||||
|
||||
if (contains(mx, my)) {
|
||||
NEIClientUtils.gl2DRenderContext(() -> GuiDraw.drawRect(this.x, this.y, this.w, this.h, 0x80FFFFFF));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleClick(int mx, int my, int button) {
|
||||
return ShortcutInputHandler.handleMouseClick(this.pStack.item);
|
||||
}
|
||||
}
|
||||
|
||||
public void draw() {
|
||||
if (guiRecipe == null) return;
|
||||
int catalystsSize = RecipeCatalysts.getRecipeCatalysts(guiRecipe.getHandler()).size();
|
||||
if (catalystsSize == 0) return;
|
||||
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 + TRANSPARENCY_BORDER * 2,
|
||||
28 + TRANSPARENCY_BORDER * 2).setTextureSize(28 + TRANSPARENCY_BORDER * 2, 28 + TRANSPARENCY_BORDER * 2)
|
||||
.build();
|
||||
|
||||
int availableHeight = RecipeCatalysts.getHeight();
|
||||
int columnCount = RecipeCatalysts.getColumnCount(availableHeight, catalystsSize);
|
||||
int rowCount = RecipeCatalysts.getRowCount(availableHeight, catalystsSize);
|
||||
int width, height, xPos, yPos;
|
||||
private static final DrawableResource FG_TEXTURE = new DrawableBuilder("nei:textures/slot.png", 0, 0, 18, 18)
|
||||
.setTextureSize(18, 18).build();
|
||||
|
||||
width = (ingredientBorder * 2) + (tabBorder * 2) + (columnCount * ingredientSize);
|
||||
height = (ingredientBorder * 2) + (tabBorder * 2) + (rowCount * ingredientSize);
|
||||
xPos = guiRecipe.guiLeft - width + tabBorder + 1;
|
||||
yPos = guiRecipe.guiTop;
|
||||
drawBordered("nei:textures/catalyst_tab.png", xPos, yPos, width, height, 28, 28, 6, 6, 6, 6);
|
||||
private static final ScrollBar VERTICAL_SCROLLBAR = ScrollBar.defaultVerticalBar()
|
||||
.setOverflowType(ScrollBar.OverflowType.AUTO).setTrackPadding(0, BORDER_PADDING, -13, BORDER_PADDING)
|
||||
.setScrollPlace(ScrollBar.ScrollPlace.START);
|
||||
|
||||
width = (ingredientBorder * 2) + (columnCount * ingredientSize);
|
||||
height = (ingredientBorder * 2) + (rowCount * ingredientSize);
|
||||
xPos = guiRecipe.guiLeft - width + ingredientBorder + 1;
|
||||
yPos = guiRecipe.guiTop + fullBorder - ingredientBorder;
|
||||
drawBordered("nei:textures/slot.png", xPos, yPos, width, height, 18, 18, 1, 1, 1, 1);
|
||||
private PositionedStack[] items = new PositionedStack[0];
|
||||
private boolean showWidget = false;
|
||||
private int availableHeight = 0;
|
||||
|
||||
public GuiRecipeCatalyst() {
|
||||
setPaddingBlock(BORDER_PADDING + 1, BORDER_PADDING + 1);
|
||||
}
|
||||
|
||||
public void setCatalysts(List<PositionedStack> items) {
|
||||
this.items = items.toArray(new PositionedStack[0]);
|
||||
createWidgets();
|
||||
}
|
||||
|
||||
public void setAvailableHeight(int height) {
|
||||
if (this.availableHeight != height) {
|
||||
this.availableHeight = height;
|
||||
createWidgets();
|
||||
}
|
||||
}
|
||||
|
||||
public int getAvailableHeight() {
|
||||
return this.availableHeight;
|
||||
}
|
||||
|
||||
public boolean isShowWidget() {
|
||||
return this.showWidget;
|
||||
}
|
||||
|
||||
public int getColumnCount() {
|
||||
if (NEIClientConfig.getJEIStyleRecipeCatalysts() == 1) {
|
||||
final int maxItemsPerColumn = Math.max(0, this.availableHeight - 2 - BORDER_PADDING * 2) / SLOT_SIZE;
|
||||
return maxItemsPerColumn > 0 ? NEIServerUtils.divideCeil(this.items.length, maxItemsPerColumn) : 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
public int getRowCount() {
|
||||
final int columnCount = getColumnCount();
|
||||
return columnCount > 0 ? NEIServerUtils.divideCeil(this.items.length, columnCount) : 0;
|
||||
}
|
||||
|
||||
protected void createWidgets() {
|
||||
final int columns = getColumnCount();
|
||||
final int rows = getRowCount();
|
||||
|
||||
setVerticalScroll(null);
|
||||
setPaddingInline(BORDER_PADDING + 1, BORDER_PADDING - 3);
|
||||
|
||||
this.h = rows * SLOT_SIZE + this.paddingBlockStart + this.paddingBlockEnd;
|
||||
this.w = columns * SLOT_SIZE + this.paddingInlineStart + this.paddingInlineEnd;
|
||||
|
||||
if (NEIClientConfig.getJEIStyleRecipeCatalysts() == 2
|
||||
&& rows * SLOT_SIZE + this.paddingBlockStart + this.paddingBlockEnd > this.availableHeight) {
|
||||
this.h = Math.min(this.h, this.availableHeight);
|
||||
this.w += VERTICAL_SCROLLBAR.getTrackWidth();
|
||||
|
||||
setVerticalScroll(VERTICAL_SCROLLBAR);
|
||||
setPaddingInline(BORDER_PADDING + 1 + VERTICAL_SCROLLBAR.getTrackWidth(), this.paddingInlineEnd);
|
||||
}
|
||||
|
||||
this.showWidget = rows * columns > 0;
|
||||
|
||||
if (rows == 0 || columns == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int visibleWidth = getVisibleWidth();
|
||||
final List<Widget> widgets = new ArrayList<>();
|
||||
int index = 0;
|
||||
|
||||
for (PositionedStack pStack : this.items) {
|
||||
pStack.relx = visibleWidth - SLOT_SIZE - (index / rows) * SLOT_SIZE;
|
||||
pStack.rely = (index % rows) * SLOT_SIZE;
|
||||
index++;
|
||||
|
||||
widgets.add(new ItemStackWidget(pStack));
|
||||
}
|
||||
|
||||
setWidgets(widgets);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hideItemPanelSlot(GuiContainer gui, int x, int y, int w, int h) {
|
||||
if (!(gui instanceof GuiRecipe)) return false;
|
||||
guiRecipe = (GuiRecipe<?>) gui;
|
||||
int catalystsSize = RecipeCatalysts.getRecipeCatalysts(guiRecipe.getHandler()).size();
|
||||
if (catalystsSize == 0) return false;
|
||||
public void draw(int mx, int my) {
|
||||
if (!this.showWidget) return;
|
||||
|
||||
int availableHeight = RecipeCatalysts.getHeight();
|
||||
int columnCount = RecipeCatalysts.getColumnCount(availableHeight, catalystsSize);
|
||||
int rowCount = RecipeCatalysts.getRowCount(availableHeight, catalystsSize);
|
||||
int margin = 4;
|
||||
GL11.glColor4f(1, 1, 1, 1);
|
||||
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,
|
||||
this.w - this.paddingInlineStart - this.paddingInlineEnd + 2,
|
||||
this.h - this.paddingBlockStart - this.paddingBlockEnd + 2,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1);
|
||||
|
||||
int width = (ingredientBorder * 2) + (tabBorder * 2) + (columnCount * ingredientSize) + margin;
|
||||
int height = (ingredientBorder * 2) + (tabBorder * 2) + (rowCount * ingredientSize) + margin;
|
||||
int xOffset = guiRecipe.guiLeft - width + tabBorder;
|
||||
int yOffset = guiRecipe.guiTop;
|
||||
catalystRect.setBounds(xOffset, yOffset, width, height);
|
||||
targetRect.setBounds(x, y, w, h);
|
||||
return targetRect.intersects(catalystRect);
|
||||
super.draw(mx, my);
|
||||
}
|
||||
|
||||
private void drawBordered(String location, int xPos, int yPos, int width, int height, int texWidth, int texHeight,
|
||||
int sliceLeft, int sliceRight, int sliceTop, int sliceBottom) {
|
||||
Minecraft.getMinecraft().renderEngine.bindTexture(new ResourceLocation(location));
|
||||
public PositionedStack getPositionedStackMouseOver(int mx, int my) {
|
||||
final Widget widget = getWidgetUnderMouse(mx, my);
|
||||
|
||||
GuiElementDuex cornerTopLeft = new GuiElementDuex(0, 0, sliceLeft, sliceTop, texWidth, texHeight);
|
||||
GuiElementDuex cornerTopRight = new GuiElementDuex(
|
||||
texWidth - sliceRight,
|
||||
0,
|
||||
sliceRight,
|
||||
sliceTop,
|
||||
texWidth,
|
||||
texHeight);
|
||||
GuiElementDuex cornerBottomLeft = new GuiElementDuex(
|
||||
0,
|
||||
texHeight - sliceBottom,
|
||||
sliceLeft,
|
||||
sliceBottom,
|
||||
texWidth,
|
||||
texHeight);
|
||||
GuiElementDuex cornerBottomRight = new GuiElementDuex(
|
||||
texWidth - sliceRight,
|
||||
texHeight - sliceBottom,
|
||||
sliceRight,
|
||||
sliceBottom,
|
||||
texWidth,
|
||||
texHeight);
|
||||
if (widget instanceof ItemStackWidget stackWidget) {
|
||||
return stackWidget.pStack;
|
||||
}
|
||||
|
||||
GuiElementScalable borderTop = new GuiElementScalable(
|
||||
sliceLeft,
|
||||
0,
|
||||
texWidth - sliceLeft - sliceRight,
|
||||
sliceTop,
|
||||
texWidth,
|
||||
texHeight);
|
||||
GuiElementScalable borderBottom = new GuiElementScalable(
|
||||
sliceLeft,
|
||||
texHeight - sliceBottom,
|
||||
texWidth - sliceLeft - sliceRight,
|
||||
sliceBottom,
|
||||
texWidth,
|
||||
texHeight);
|
||||
GuiElementScalable borderLeft = new GuiElementScalable(
|
||||
0,
|
||||
sliceTop,
|
||||
sliceLeft,
|
||||
texHeight - sliceTop - sliceBottom,
|
||||
texWidth,
|
||||
texHeight);
|
||||
GuiElementScalable borderRight = new GuiElementScalable(
|
||||
texWidth - sliceRight,
|
||||
sliceTop,
|
||||
sliceRight,
|
||||
texHeight - sliceTop - sliceBottom,
|
||||
texWidth,
|
||||
texHeight);
|
||||
GuiElementScalable center = new GuiElementScalable(
|
||||
sliceLeft,
|
||||
sliceTop,
|
||||
texWidth - sliceLeft - sliceRight,
|
||||
texHeight - sliceTop - sliceBottom,
|
||||
texWidth,
|
||||
texHeight);
|
||||
|
||||
int midW = width - borderLeft.w - borderRight.w;
|
||||
int midH = height - borderTop.h - borderBottom.h;
|
||||
|
||||
// top row
|
||||
int x = xPos;
|
||||
int y = yPos;
|
||||
x += cornerTopLeft.draw(x, y);
|
||||
x += borderTop.drawScaledX(x, y, midW);
|
||||
cornerTopRight.draw(x, y);
|
||||
|
||||
// center row
|
||||
x = xPos;
|
||||
y += borderTop.h;
|
||||
x += borderLeft.drawScaledY(x, y, midH);
|
||||
x += center.drawScaled(x, y, midW, midH);
|
||||
borderRight.drawScaledY(x, y, midH);
|
||||
|
||||
// bottom row
|
||||
x = xPos;
|
||||
y += midH;
|
||||
x += cornerBottomLeft.draw(x, y);
|
||||
x += borderBottom.drawScaledX(x, y, midW);
|
||||
cornerBottomRight.draw(x, y);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static final int ingredientSize = 16;
|
||||
@Deprecated
|
||||
public static final int ingredientBorder = 1;
|
||||
@Deprecated
|
||||
public static final int tabBorder = 5;
|
||||
@Deprecated
|
||||
public static final int fullBorder = ingredientBorder + tabBorder;
|
||||
|
||||
}
|
||||
@@ -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 {
|
||||
@@ -42,10 +43,9 @@ public abstract class GuiRecipeTab extends Widget {
|
||||
public static HashMap<String, HandlerInfo> handlerAdderFromIMC = new HashMap<>();
|
||||
public static Set<String> handlerRemoverFromIMC = new HashSet<>();
|
||||
|
||||
private final GuiRecipe<?> guiRecipe;
|
||||
private final IRecipeHandler handler;
|
||||
private final String handlerName;
|
||||
private final String handlerID;
|
||||
protected final IRecipeHandler handler;
|
||||
protected final String handlerName;
|
||||
protected final String handlerID;
|
||||
|
||||
private boolean selected;
|
||||
|
||||
@@ -61,7 +61,7 @@ public abstract class GuiRecipeTab extends Widget {
|
||||
|
||||
protected abstract int getForegroundIconY();
|
||||
|
||||
public GuiRecipeTab(GuiRecipe<?> guiRecipe, IRecipeHandler handler, int x, int y) {
|
||||
public GuiRecipeTab(IRecipeHandler handler, int x, int y) {
|
||||
super();
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
@@ -69,7 +69,6 @@ public abstract class GuiRecipeTab extends Widget {
|
||||
this.h = getHeight();
|
||||
this.handler = handler;
|
||||
this.handlerName = handler.getHandlerId();
|
||||
this.guiRecipe = guiRecipe;
|
||||
this.selected = false;
|
||||
|
||||
if (handler instanceof TemplateRecipeHandler) {
|
||||
@@ -154,16 +153,10 @@ public abstract class GuiRecipeTab extends Widget {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean onButtonPress(boolean rightclick) {
|
||||
int newIdx = guiRecipe.currenthandlers.indexOf(handler);
|
||||
if (newIdx == -1) return false;
|
||||
public abstract boolean onButtonPress(boolean rightclick);
|
||||
|
||||
guiRecipe.setRecipePage(newIdx);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setSelected(IRecipeHandler current) {
|
||||
selected = handler == current;
|
||||
public void setSelected(boolean selected) {
|
||||
this.selected = selected;
|
||||
}
|
||||
|
||||
public static HandlerInfo getHandlerInfo(IRecipeHandler handler) {
|
||||
@@ -263,16 +256,17 @@ public abstract class GuiRecipeTab extends Widget {
|
||||
if (yShift != null && !yShift.equals("")) info.setYShift(Integer.parseInt(yShift));
|
||||
|
||||
try {
|
||||
final int imageHeight = intOrDefault(record.get("handlerHeight"), HandlerInfo.DEFAULT_HEIGHT);
|
||||
final int imageWidth = intOrDefault(record.get("handlerWidth"), HandlerInfo.DEFAULT_WIDTH);
|
||||
final int maxRecipesPerPage = intOrDefault(
|
||||
record.get("maxRecipesPerPage"),
|
||||
HandlerInfo.DEFAULT_MAX_PER_PAGE);
|
||||
info.setHandlerDimensions(imageHeight, imageWidth, maxRecipesPerPage);
|
||||
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);
|
||||
info.setMultipleWidgetsAllowed(multipleWidgetsAllowed);
|
||||
} catch (NumberFormatException ignored) {
|
||||
NEIClientConfig.logger.info("Error setting handler dimensions for " + handler);
|
||||
}
|
||||
|
||||
info.setUseCustomScroll(
|
||||
record.isSet("useCustomScroll") ? Boolean.parseBoolean(record.get("useCustomScroll")) : false);
|
||||
handlerMap.put(handler, info);
|
||||
NEIClientConfig.logger.info("Loaded " + handler);
|
||||
}
|
||||
@@ -300,14 +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_HEIGHT,
|
||||
HandlerInfo.DEFAULT_WIDTH,
|
||||
HandlerInfo.DEFAULT_MAX_PER_PAGE);
|
||||
info.setHandlerDimensions(HandlerInfo.DEFAULT_WIDTH, HandlerInfo.DEFAULT_HEIGHT);
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ package codechicken.nei.recipe;
|
||||
import codechicken.nei.drawable.DrawableBuilder;
|
||||
import codechicken.nei.drawable.DrawableResource;
|
||||
|
||||
public class GuiRecipeTabCreative extends GuiRecipeTab {
|
||||
public abstract class GuiRecipeTabCreative extends GuiRecipeTab {
|
||||
|
||||
public static final int TAB_WIDTH = 28;
|
||||
public static final int TAB_HEIGHT = 31;
|
||||
@@ -20,8 +20,8 @@ public class GuiRecipeTabCreative extends GuiRecipeTab {
|
||||
28,
|
||||
30).build();
|
||||
|
||||
public GuiRecipeTabCreative(GuiRecipe<?> guiRecipe, IRecipeHandler handler, int x, int y) {
|
||||
super(guiRecipe, handler, x, y);
|
||||
public GuiRecipeTabCreative(IRecipeHandler handler, int x, int y) {
|
||||
super(handler, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,7 +3,7 @@ package codechicken.nei.recipe;
|
||||
import codechicken.nei.drawable.DrawableBuilder;
|
||||
import codechicken.nei.drawable.DrawableResource;
|
||||
|
||||
public class GuiRecipeTabJEI extends GuiRecipeTab {
|
||||
public abstract class GuiRecipeTabJEI extends GuiRecipeTab {
|
||||
|
||||
public static final int TAB_WIDTH = 24;
|
||||
public static final int TAB_HEIGHT = 24;
|
||||
@@ -20,8 +20,8 @@ public class GuiRecipeTabJEI extends GuiRecipeTab {
|
||||
24,
|
||||
24).build();
|
||||
|
||||
public GuiRecipeTabJEI(GuiRecipe<?> guiRecipe, IRecipeHandler handler, int x, int y) {
|
||||
super(guiRecipe, handler, x, y);
|
||||
public GuiRecipeTabJEI(IRecipeHandler handler, int x, int y) {
|
||||
super(handler, x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,168 +1,154 @@
|
||||
package codechicken.nei.recipe;
|
||||
|
||||
import static codechicken.lib.gui.GuiDraw.getMousePosition;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.nei.Button;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
|
||||
public class GuiRecipeTabs {
|
||||
|
||||
private final GuiRecipe<?> guiRecipe;
|
||||
private final List<GuiRecipeTab> tabs = new ArrayList<>();
|
||||
private final List<Button> buttons = new ArrayList<>();
|
||||
|
||||
private final Rectangle area = new Rectangle();
|
||||
private List<? extends IRecipeHandler> currenthandlers;
|
||||
|
||||
private int pageCount = 1;
|
||||
private int pageNumber = 0;
|
||||
private int categoriesPerPage = 1;
|
||||
private int numHandlers = 1;
|
||||
private int tabWidth;
|
||||
private int tabHeight;
|
||||
private int recipetype;
|
||||
|
||||
public GuiRecipeTabs(GuiRecipe<?> guiRecipe) {
|
||||
this.guiRecipe = guiRecipe;
|
||||
}
|
||||
private final Button prevTab = new Button("<") {
|
||||
|
||||
public void initLayout() {
|
||||
if (NEIClientConfig.useCreativeTabStyle()) {
|
||||
tabWidth = GuiRecipeTabCreative.TAB_WIDTH;
|
||||
tabHeight = GuiRecipeTabCreative.TAB_HEIGHT;
|
||||
} else {
|
||||
tabWidth = GuiRecipeTabJEI.TAB_WIDTH;
|
||||
tabHeight = GuiRecipeTabJEI.TAB_HEIGHT;
|
||||
@Override
|
||||
public boolean onButtonPress(boolean rightClick) {
|
||||
if (!rightClick) {
|
||||
NEIClientUtils.playClickSound();
|
||||
return previousPage();
|
||||
} else return false;
|
||||
}
|
||||
|
||||
int totalWidth = 0;
|
||||
categoriesPerPage = 0;
|
||||
numHandlers = guiRecipe.currenthandlers.size();
|
||||
};
|
||||
|
||||
for (int i = 0; i < numHandlers; i++) {
|
||||
if (totalWidth + tabWidth < (guiRecipe.xSize - 4)) {
|
||||
totalWidth += tabWidth;
|
||||
categoriesPerPage++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
private final Button nextTab = new Button(">") {
|
||||
|
||||
@Override
|
||||
public boolean onButtonPress(boolean rightclick) {
|
||||
if (!rightclick) {
|
||||
NEIClientUtils.playClickSound();
|
||||
return nextPage();
|
||||
} else return false;
|
||||
}
|
||||
|
||||
area.width = totalWidth;
|
||||
area.height = tabHeight;
|
||||
area.x = guiRecipe.guiLeft + 4;
|
||||
area.y = guiRecipe.guiTop - tabHeight + 3;
|
||||
};
|
||||
|
||||
pageCount = (int) Math.ceil((float) numHandlers / categoriesPerPage);
|
||||
calcPageNumber();
|
||||
Rectangle navigationArea = new Rectangle(area);
|
||||
navigationArea.height = 20;
|
||||
navigationArea.translate(0, -(2 + navigationArea.height));
|
||||
public static int getTabWidth() {
|
||||
return NEIClientConfig.useCreativeTabStyle() ? GuiRecipeTabCreative.TAB_WIDTH : GuiRecipeTabJEI.TAB_WIDTH;
|
||||
}
|
||||
|
||||
public void calcPageNumber() {
|
||||
pageNumber = guiRecipe.recipetype / Math.max(categoriesPerPage, 1);
|
||||
public static int getTabHeight() {
|
||||
return NEIClientConfig.useCreativeTabStyle() ? GuiRecipeTabCreative.TAB_HEIGHT : GuiRecipeTabJEI.TAB_HEIGHT;
|
||||
}
|
||||
|
||||
public void update(GuiRecipe<?> guiRecipe) {
|
||||
final int tabWidth = getTabWidth();
|
||||
final int tabHeight = getTabHeight();
|
||||
|
||||
this.recipetype = guiRecipe.recipetype;
|
||||
this.currenthandlers = guiRecipe.currenthandlers;
|
||||
this.numHandlers = this.currenthandlers.size();
|
||||
this.categoriesPerPage = (guiRecipe.xSize - 4) / tabWidth;
|
||||
this.pageNumber = this.recipetype / Math.max(this.categoriesPerPage, 1);
|
||||
this.pageCount = (int) Math.ceil((float) this.numHandlers / this.categoriesPerPage);
|
||||
|
||||
this.area.width = this.categoriesPerPage * tabWidth;
|
||||
this.area.height = tabHeight;
|
||||
this.area.x = guiRecipe.guiLeft + 4;
|
||||
this.area.y = guiRecipe.guiTop - tabHeight + 3;
|
||||
|
||||
refreshPage();
|
||||
updateArrows(tabHeight);
|
||||
}
|
||||
|
||||
public void refreshPage() {
|
||||
tabs.clear();
|
||||
buttons.clear();
|
||||
final int startIndex = this.pageNumber * this.categoriesPerPage;
|
||||
final int tabWidth = getTabWidth();
|
||||
|
||||
final int startIndex = pageNumber * categoriesPerPage;
|
||||
for (int i = 0; i < categoriesPerPage; i++) {
|
||||
this.tabs.clear();
|
||||
|
||||
for (int i = 0; i < this.categoriesPerPage && i + startIndex < numHandlers; i++) {
|
||||
final int index = i + startIndex;
|
||||
if (index >= numHandlers) break;
|
||||
IRecipeHandler handler = guiRecipe.currenthandlers.get(index);
|
||||
int tabX = area.x + (i * tabWidth);
|
||||
final IRecipeHandler handler = this.currenthandlers.get(index);
|
||||
final int tabX = this.area.x + (i * tabWidth);
|
||||
|
||||
if (NEIClientConfig.useCreativeTabStyle()) {
|
||||
tabs.add(new GuiRecipeTabCreative(guiRecipe, handler, tabX, area.y));
|
||||
tabs.add(new GuiRecipeTabCreative(handler, tabX, this.area.y) {
|
||||
|
||||
@Override
|
||||
public boolean onButtonPress(boolean rightclick) {
|
||||
setRecipePage(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
} else {
|
||||
tabs.add(new GuiRecipeTabJEI(guiRecipe, handler, tabX, area.y));
|
||||
tabs.add(new GuiRecipeTabJEI(handler, tabX, this.area.y) {
|
||||
|
||||
@Override
|
||||
public boolean onButtonPress(boolean rightclick) {
|
||||
setRecipePage(index);
|
||||
return true;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Maybe add buttons
|
||||
if (numHandlers > categoriesPerPage) {
|
||||
Button prevTab = new Button("prevTab") {
|
||||
private void updateArrows(int tabHeight) {
|
||||
this.buttons.clear();
|
||||
|
||||
@Override
|
||||
public boolean onButtonPress(boolean rightClick) {
|
||||
if (!rightClick) {
|
||||
NEIClientUtils.playClickSound();
|
||||
return previousPage();
|
||||
} else return false;
|
||||
}
|
||||
if (this.numHandlers > this.categoriesPerPage) {
|
||||
this.prevTab.w = this.nextTab.w = 8;
|
||||
this.prevTab.h = this.nextTab.h = tabHeight - 4;
|
||||
this.prevTab.y = this.nextTab.y = this.area.y + 2;
|
||||
|
||||
@Override
|
||||
public String getRenderLabel() {
|
||||
return "<";
|
||||
}
|
||||
};
|
||||
prevTab.w = 8;
|
||||
prevTab.h = tabHeight - 4;
|
||||
prevTab.x = area.x - prevTab.w + 1;
|
||||
prevTab.y = area.y + 2;
|
||||
buttons.add(prevTab);
|
||||
this.prevTab.x = this.area.x - this.prevTab.w + 1;
|
||||
this.nextTab.x = this.area.x + this.area.width - 1;
|
||||
|
||||
Button nextTab = new Button("nextTab") {
|
||||
|
||||
@Override
|
||||
public boolean onButtonPress(boolean rightclick) {
|
||||
if (!rightclick) {
|
||||
NEIClientUtils.playClickSound();
|
||||
return nextPage();
|
||||
} else return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRenderLabel() {
|
||||
return ">";
|
||||
}
|
||||
};
|
||||
nextTab.w = prevTab.w;
|
||||
nextTab.h = prevTab.h;
|
||||
nextTab.x = area.x + area.width - 1;
|
||||
nextTab.y = prevTab.y;
|
||||
buttons.add(nextTab);
|
||||
this.buttons.add(this.prevTab);
|
||||
this.buttons.add(this.nextTab);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean nextPage() {
|
||||
if (hasNext()) pageNumber++;
|
||||
else pageNumber = 0;
|
||||
protected void setRecipePage(int recipetype) {}
|
||||
|
||||
public boolean nextPage() {
|
||||
this.pageNumber = (this.pageNumber + 1) % this.pageCount;
|
||||
refreshPage();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return pageNumber + 1 < pageCount;
|
||||
}
|
||||
|
||||
public boolean previousPage() {
|
||||
if (hasPrevious()) pageNumber--;
|
||||
else pageNumber = pageCount - 1;
|
||||
|
||||
this.pageNumber = (this.pageCount + this.pageNumber - 1) % this.pageCount;
|
||||
refreshPage();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean hasPrevious() {
|
||||
return pageNumber > 0;
|
||||
}
|
||||
|
||||
public void draw(int mouseX, int mouseY) {
|
||||
IRecipeHandler current = guiRecipe.currenthandlers.get(guiRecipe.recipetype);
|
||||
for (GuiRecipeTab tab : tabs) {
|
||||
tab.setSelected(current);
|
||||
final int indexShift = this.pageNumber * this.categoriesPerPage;
|
||||
|
||||
for (int index = 0; index < this.tabs.size(); index++) {
|
||||
final GuiRecipeTab tab = this.tabs.get(index);
|
||||
tab.setSelected(indexShift + index == this.recipetype);
|
||||
tab.draw(mouseX, mouseY);
|
||||
}
|
||||
for (Button button : buttons) {
|
||||
|
||||
for (Button button : this.buttons) {
|
||||
button.draw(mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
@@ -170,12 +156,12 @@ public class GuiRecipeTabs {
|
||||
public void handleTooltip(int mousex, int mousey, List<String> tooltips) {
|
||||
if (!NEIClientConfig.areJEIStyleTabsVisible()) return;
|
||||
|
||||
for (GuiRecipeTab tab : tabs) {
|
||||
for (GuiRecipeTab tab : this.tabs) {
|
||||
if (tab.contains(mousex, mousey)) {
|
||||
tab.addTooltips(tooltips);
|
||||
}
|
||||
}
|
||||
for (Button button : buttons) {
|
||||
for (Button button : this.buttons) {
|
||||
if (button.contains(mousex, mousey)) {
|
||||
button.addTooltips(tooltips);
|
||||
}
|
||||
@@ -185,27 +171,26 @@ public class GuiRecipeTabs {
|
||||
protected boolean mouseClicked(int x, int y, int mouseButton) {
|
||||
if (!NEIClientConfig.areJEIStyleTabsVisible()) return false;
|
||||
|
||||
for (Button button : buttons) {
|
||||
for (Button button : this.buttons) {
|
||||
if (button.contains(x, y)) {
|
||||
return button.onButtonPress(mouseButton == 1);
|
||||
}
|
||||
}
|
||||
for (GuiRecipeTab tab : tabs) {
|
||||
|
||||
for (GuiRecipeTab tab : this.tabs) {
|
||||
if (tab.contains(x, y)) {
|
||||
return tab.onButtonPress(mouseButton == 1);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean mouseScrolled(int i) {
|
||||
Point mousePosition = getMousePosition();
|
||||
protected boolean mouseScrolled(int scroll) {
|
||||
|
||||
// Switch between recipe handlers if the cursor is over the tabbar.
|
||||
if (NEIClientConfig.areJEIStyleTabsVisible() && area.contains(mousePosition)) {
|
||||
if (i < 0) guiRecipe.nextType();
|
||||
else guiRecipe.prevType();
|
||||
|
||||
if (NEIClientConfig.areJEIStyleTabsVisible() && this.area.contains(GuiDraw.getMousePosition())) {
|
||||
setRecipePage(this.recipetype - scroll);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import codechicken.nei.ItemPanels;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.recipe.Recipe.RecipeId;
|
||||
import codechicken.nei.recipe.stackinfo.GTFluidStackStringifyHandler;
|
||||
import codechicken.nei.recipe.TemplateRecipeHandler.RecipeTransferRect;
|
||||
|
||||
public class GuiUsageRecipe extends GuiRecipe<IUsageHandler> {
|
||||
|
||||
@@ -22,9 +22,9 @@ public class GuiUsageRecipe extends GuiRecipe<IUsageHandler> {
|
||||
|
||||
public static boolean openRecipeGui(String inputId, Object... ingredients) {
|
||||
|
||||
if ("item".equals(inputId)) {
|
||||
for (int i = 0; i < ingredients.length; i++) {
|
||||
ingredients[i] = normalizeItemStack((ItemStack) ingredients[i]);
|
||||
for (int i = 0; i < ingredients.length; i++) {
|
||||
if (ingredients[i] instanceof ItemStack stack) {
|
||||
ingredients[i] = StackInfo.normalizeRecipeQueryStack(stack.copy());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,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;
|
||||
}
|
||||
|
||||
@@ -56,21 +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 ItemStack normalizeItemStack(ItemStack stack) {
|
||||
GTFluidStackStringifyHandler.replaceAE2FCFluidDrop = true;
|
||||
stack = StackInfo.loadFromNBT(StackInfo.itemStackToNBT(stack));
|
||||
GTFluidStackStringifyHandler.replaceAE2FCFluidDrop = false;
|
||||
return stack;
|
||||
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) {
|
||||
@@ -99,7 +112,7 @@ public class GuiUsageRecipe extends GuiRecipe<IUsageHandler> {
|
||||
private static IUsageHandler getUsageOrCatalystHandler(IUsageHandler handler, String inputId,
|
||||
Object... ingredients) {
|
||||
boolean skipCatalyst = NEIClientUtils.controlKey();
|
||||
if (NEIClientConfig.areJEIStyleRecipeCatalystsVisible() && !skipCatalyst) {
|
||||
if (NEIClientConfig.getJEIStyleRecipeCatalysts() != 0 && !skipCatalyst) {
|
||||
return handler.getUsageAndCatalystHandler(inputId, ingredients);
|
||||
} else {
|
||||
return handler.getUsageHandler(inputId, ingredients);
|
||||
|
||||
@@ -12,6 +12,8 @@ public class HandlerInfo {
|
||||
|
||||
public static int DEFAULT_HEIGHT = 65;
|
||||
public static int DEFAULT_WIDTH = 166;
|
||||
|
||||
@Deprecated
|
||||
public static int DEFAULT_MAX_PER_PAGE = 1;
|
||||
|
||||
private String handlerName;
|
||||
@@ -21,15 +23,14 @@ public class HandlerInfo {
|
||||
private boolean requiresMod;
|
||||
private String excludedModId;
|
||||
|
||||
private String itemId;
|
||||
private String nbtString;
|
||||
|
||||
private int yShift = 0;
|
||||
private int height = DEFAULT_HEIGHT;
|
||||
private int width = DEFAULT_WIDTH;
|
||||
private int maxRecipesPerPage = DEFAULT_MAX_PER_PAGE;
|
||||
|
||||
private boolean multipleWidgetsAllowed = false;
|
||||
private boolean showFavoritesButton = true;
|
||||
private boolean showOverlayButton = true;
|
||||
private boolean useCustomScroll = false;
|
||||
|
||||
private ItemStack itemStack = null;
|
||||
private DrawableResource image = null;
|
||||
@@ -42,22 +43,27 @@ public class HandlerInfo {
|
||||
this.excludedModId = excludedModId;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setHandlerDimensions(int height, int width, int maxRecipesPerPage) {
|
||||
setHandlerDimensions(width, height);
|
||||
setMultipleWidgetsAllowed(maxRecipesPerPage > 1);
|
||||
}
|
||||
|
||||
public void setHandlerDimensions(int width, int height) {
|
||||
this.height = height;
|
||||
this.width = width;
|
||||
this.maxRecipesPerPage = maxRecipesPerPage;
|
||||
}
|
||||
|
||||
public boolean setItem(String itemId, String nbtString) {
|
||||
if (hasImageOrItem()) return false;
|
||||
|
||||
itemStack = NEIServerUtils.getModdedItem(itemId, nbtString);
|
||||
if (itemStack == null) NEIClientConfig.logger.info("Couldn't find " + modName + " - " + itemId);
|
||||
else {
|
||||
this.itemId = itemId;
|
||||
this.nbtString = nbtString;
|
||||
this.itemStack = NEIServerUtils.getModdedItem(itemId, nbtString);
|
||||
|
||||
if (this.itemStack == null) {
|
||||
NEIClientConfig.logger.info("Couldn't find " + this.modName + " - " + itemId);
|
||||
}
|
||||
return (itemStack != null);
|
||||
|
||||
return this.itemStack != null;
|
||||
}
|
||||
|
||||
public boolean setImage(String resourceLocation, int imageX, int imageY, int imageWidth, int imageHeight) {
|
||||
@@ -68,46 +74,52 @@ public class HandlerInfo {
|
||||
}
|
||||
|
||||
public DrawableResource getImage() {
|
||||
return image;
|
||||
return this.image;
|
||||
}
|
||||
|
||||
public ItemStack getItemStack() {
|
||||
return itemStack;
|
||||
return this.itemStack;
|
||||
}
|
||||
|
||||
public String getModName() {
|
||||
return modName;
|
||||
return this.modName;
|
||||
}
|
||||
|
||||
public String getModId() {
|
||||
return modId;
|
||||
return this.modId;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
return this.height;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
return this.width;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public int getMaxRecipesPerPage() {
|
||||
return Math.max(maxRecipesPerPage, 1);
|
||||
return this.multipleWidgetsAllowed ? Integer.MAX_VALUE : 1;
|
||||
}
|
||||
|
||||
public void setMultipleWidgetsAllowed(boolean multipleWidgetsAllowed) {
|
||||
this.multipleWidgetsAllowed = multipleWidgetsAllowed;
|
||||
}
|
||||
|
||||
public boolean isMultipleWidgetsAllowed() {
|
||||
return this.multipleWidgetsAllowed;
|
||||
}
|
||||
|
||||
public int getYShift() {
|
||||
return yShift;
|
||||
return this.yShift;
|
||||
}
|
||||
|
||||
public String getHandlerName() {
|
||||
return handlerName;
|
||||
return this.handlerName;
|
||||
}
|
||||
|
||||
public boolean hasImageOrItem() {
|
||||
if (image != null) return true;
|
||||
if (itemStack != null) return true;
|
||||
|
||||
return false;
|
||||
return this.image != null || this.itemStack != null;
|
||||
}
|
||||
|
||||
public void setYShift(int yShift) {
|
||||
@@ -130,6 +142,14 @@ public class HandlerInfo {
|
||||
this.showOverlayButton = showOverlayButton;
|
||||
}
|
||||
|
||||
public boolean getUseCustomScroll() {
|
||||
return this.useCustomScroll;
|
||||
}
|
||||
|
||||
public void setUseCustomScroll(boolean useCustomScroll) {
|
||||
this.useCustomScroll = useCustomScroll;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private final HandlerInfo info;
|
||||
@@ -143,47 +163,72 @@ public class HandlerInfo {
|
||||
this(handlerClazz.getName(), modName, modId);
|
||||
}
|
||||
|
||||
public Builder setDisplayStack(String itemId, String nbtString) {
|
||||
return setDisplayStack(NEIServerUtils.getModdedItem(itemId, nbtString));
|
||||
}
|
||||
|
||||
public Builder setDisplayStack(ItemStack stack) {
|
||||
info.image = null;
|
||||
info.itemStack = stack;
|
||||
this.info.image = null;
|
||||
this.info.itemStack = stack;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setDisplayImage(DrawableResource drawable) {
|
||||
info.itemStack = null;
|
||||
info.image = drawable;
|
||||
this.info.itemStack = null;
|
||||
this.info.image = drawable;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setDisplayImage(ResourceLocation location, int imageX, int imageY, int imageWidth,
|
||||
int imageHeight) {
|
||||
info.itemStack = null;
|
||||
info.setImage(location.toString(), imageX, imageY, imageWidth, imageHeight);
|
||||
this.info.itemStack = null;
|
||||
this.info.setImage(location.toString(), imageX, imageY, imageWidth, imageHeight);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setUseCustomScroll(boolean useCustomScroll) {
|
||||
this.info.setUseCustomScroll(useCustomScroll);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setShiftY(int shiftY) {
|
||||
info.setYShift(shiftY);
|
||||
this.info.setYShift(shiftY);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setWidth(int width) {
|
||||
info.setHandlerDimensions(info.height, width, info.maxRecipesPerPage);
|
||||
this.info.width = width;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setHeight(int height) {
|
||||
info.setHandlerDimensions(height, info.width, info.maxRecipesPerPage);
|
||||
this.info.height = height;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setShowOverlayButton(boolean showOverlayButton) {
|
||||
this.info.showOverlayButton = showOverlayButton;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setShowFavoritesButton(boolean showFavoritesButton) {
|
||||
this.info.showFavoritesButton = showFavoritesButton;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Builder setMaxRecipesPerPage(int maxRecipesPerPage) {
|
||||
info.setHandlerDimensions(info.height, info.width, maxRecipesPerPage);
|
||||
this.info.multipleWidgetsAllowed = maxRecipesPerPage > 1;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setMultipleWidgetsAllowed(boolean multipleWidgetsAllowed) {
|
||||
this.info.multipleWidgetsAllowed = multipleWidgetsAllowed;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HandlerInfo build() {
|
||||
return info;
|
||||
return this.info;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,10 @@ public interface IRecipeHandler {
|
||||
return getRecipeName();
|
||||
}
|
||||
|
||||
default int getRecipeHeight(int recipe) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return The number of recipes that this handler contains.
|
||||
@@ -126,12 +130,6 @@ public interface IRecipeHandler {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return The number of recipes that can fit on a page in the viewer (1 or 2)
|
||||
*/
|
||||
int recipiesPerPage();
|
||||
|
||||
/**
|
||||
*
|
||||
* @param gui An instance of the currentscreen
|
||||
@@ -178,4 +176,12 @@ public interface IRecipeHandler {
|
||||
default boolean mouseScrolled(GuiRecipe<?> gui, int scroll, int recipe) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @return The number of recipes that can fit on a page in the viewer (1 or 2)
|
||||
*/
|
||||
default int recipiesPerPage() {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
@@ -34,13 +37,12 @@ public class InformationHandler extends TemplateRecipeHandler {
|
||||
|
||||
@Override
|
||||
public void drawExtras(int recipe) {
|
||||
CachedInfoPage page = (CachedInfoPage) this.arecipes.get(recipe);
|
||||
drawWrappedText(StatCollector.translateToLocal(page.getPage().info).replace("\\n", "\n"), 4, 24);
|
||||
final CachedInfoPage page = (CachedInfoPage) this.arecipes.get(recipe);
|
||||
drawWrappedText(page.getLines(), 4, 24);
|
||||
}
|
||||
|
||||
private void drawWrappedText(String text, int x, int y) {
|
||||
FontRenderer font = Minecraft.getMinecraft().fontRenderer;
|
||||
List<String> lines = font.listFormattedStringToWidth(text, 156);
|
||||
private void drawWrappedText(List<String> lines, int x, int y) {
|
||||
final FontRenderer font = Minecraft.getMinecraft().fontRenderer;
|
||||
for (String line : lines) {
|
||||
font.drawString(line, x, y, 0);
|
||||
y += 10;
|
||||
@@ -82,14 +84,30 @@ 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);
|
||||
return 24 + page.getLines().size() * 10;
|
||||
}
|
||||
|
||||
private class CachedInfoPage extends CachedRecipe {
|
||||
|
||||
private final InformationPage page;
|
||||
private final PositionedStack stack;
|
||||
private final List<String> lines;
|
||||
|
||||
public CachedInfoPage(InformationPage page) {
|
||||
this.page = page;
|
||||
stack = new PositionedStack(page.items, 75, 2);
|
||||
final FontRenderer font = Minecraft.getMinecraft().fontRenderer;
|
||||
final String info = StatCollector.translateToLocal(page.info).replace("\\n", "\n");
|
||||
|
||||
this.lines = font.listFormattedStringToWidth(info, 156);
|
||||
this.stack = new PositionedStack(page.items, 75, 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,11 +117,11 @@ public class InformationHandler extends TemplateRecipeHandler {
|
||||
|
||||
@Override
|
||||
public List<PositionedStack> getIngredients() {
|
||||
return getCycledIngredients(cycleticks / 20, Collections.singletonList(this.stack));
|
||||
return Collections.singletonList(this.stack);
|
||||
}
|
||||
|
||||
public InformationPage getPage() {
|
||||
return page;
|
||||
public List<String> getLines() {
|
||||
return lines;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,635 @@
|
||||
package codechicken.nei.recipe;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.function.Function;
|
||||
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;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL12;
|
||||
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.nei.FavoriteRecipes;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.NEIServerUtils;
|
||||
import codechicken.nei.PositionedStack;
|
||||
import codechicken.nei.Widget;
|
||||
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 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;
|
||||
|
||||
protected final RecipeHandlerRef handlerRef;
|
||||
protected final HandlerInfo handlerInfo;
|
||||
|
||||
protected boolean showAsWidget = false;
|
||||
protected List<GuiRecipeButton> recipeButtons = null;
|
||||
|
||||
public NEIRecipeWidget(RecipeHandlerRef handlerRef) {
|
||||
this.handlerRef = handlerRef;
|
||||
this.handlerInfo = GuiRecipeTab.getHandlerInfo(this.handlerRef.handler);
|
||||
update();
|
||||
}
|
||||
|
||||
public void setLocation(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public void update() {
|
||||
|
||||
if (this.showAsWidget || !this.handlerInfo.getUseCustomScroll()) {
|
||||
final int recipeHeight = this.handlerRef.handler.getRecipeHeight(this.handlerRef.recipeIndex);
|
||||
this.w = Math.max(166, this.handlerInfo.getWidth());
|
||||
this.h = recipeHeight > 0 ? recipeHeight : this.handlerInfo.getHeight();
|
||||
this.h += this.handlerInfo.getYShift();
|
||||
}
|
||||
|
||||
this.update = true;
|
||||
}
|
||||
|
||||
public List<GuiRecipeButton> getRecipeButtons() {
|
||||
|
||||
if (this.recipeButtons == null) {
|
||||
if (!getOutputs().isEmpty()) {
|
||||
this.recipeButtons = initButtons();
|
||||
} else {
|
||||
this.recipeButtons = Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList(this.recipeButtons);
|
||||
}
|
||||
|
||||
protected List<GuiRecipeButton> getRecipeButtonsIfInit() {
|
||||
|
||||
if (this.recipeButtons == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList(this.recipeButtons);
|
||||
}
|
||||
|
||||
public RecipeHandlerRef getRecipeHandlerRef() {
|
||||
return this.handlerRef;
|
||||
}
|
||||
|
||||
public Recipe getRecipe() {
|
||||
return Recipe.of(this.handlerRef);
|
||||
}
|
||||
|
||||
public HandlerInfo getHandlerInfo() {
|
||||
return this.handlerInfo;
|
||||
}
|
||||
|
||||
public void showAsWidget(boolean show) {
|
||||
this.showAsWidget = show;
|
||||
}
|
||||
|
||||
protected List<GuiRecipeButton> initButtons() {
|
||||
final GuiRecipe<?> guiRecipe = getGuiRecipe();
|
||||
|
||||
if (guiRecipe != null) {
|
||||
final UpdateRecipeButtonsEvent.Pre preEvent = new UpdateRecipeButtonsEvent.Pre(
|
||||
guiRecipe,
|
||||
this,
|
||||
this.handlerInfo);
|
||||
|
||||
if (MinecraftForge.EVENT_BUS.post(preEvent)) {
|
||||
return preEvent.buttonList;
|
||||
} else {
|
||||
final UpdateRecipeButtonsEvent.Post postEvent = new UpdateRecipeButtonsEvent.Post(
|
||||
guiRecipe,
|
||||
this,
|
||||
getDefaultButtons());
|
||||
MinecraftForge.EVENT_BUS.post(postEvent);
|
||||
return postEvent.buttonList;
|
||||
}
|
||||
|
||||
} else {
|
||||
return getDefaultButtons();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected List<GuiRecipeButton> getDefaultButtons() {
|
||||
GuiContainer guiContainer = NEIClientUtils.getGuiContainer();
|
||||
final List<GuiRecipeButton> buttons = new ArrayList<>();
|
||||
final boolean showFavorites = NEIClientConfig.favoritesEnabled() && handlerInfo.getShowFavoritesButton();
|
||||
final boolean showOverlay = handlerInfo.getShowOverlayButton();
|
||||
final int x = Math.min(168, this.w) - GuiRecipeButton.BUTTON_WIDTH;
|
||||
int y = this.h - GuiRecipeButton.BUTTON_HEIGHT - 6;
|
||||
|
||||
if (guiContainer instanceof IGuiContainerOverlay overlay) {
|
||||
guiContainer = overlay.getFirstScreen();
|
||||
}
|
||||
|
||||
if (showOverlay) {
|
||||
buttons.add(new GuiOverlayButton(guiContainer, this.handlerRef, x, y));
|
||||
y -= GuiRecipeButton.BUTTON_HEIGHT + 1;
|
||||
}
|
||||
|
||||
if (showFavorites) {
|
||||
buttons.add(new GuiFavoriteButton(handlerRef, x, y));
|
||||
}
|
||||
|
||||
return buttons;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int mouseX, int mouseY) {
|
||||
final int yShift = this.handlerInfo.getYShift();
|
||||
|
||||
if (this.update) {
|
||||
this.update = false;
|
||||
|
||||
if (!NEIClientUtils.shiftKey() && ((this.cycleticks++) / 20) != this.lastcycle || this.lastcycle == -1) {
|
||||
this.lastcycle = this.cycleticks / 20;
|
||||
updatePermutations();
|
||||
}
|
||||
|
||||
for (GuiRecipeButton button : getRecipeButtons()) {
|
||||
button.update();
|
||||
}
|
||||
}
|
||||
|
||||
GL11.glPushAttrib(GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT | GL11.GL_LIGHTING_BIT);
|
||||
GL11.glTranslatef(this.x, this.y + yShift, 0);
|
||||
|
||||
this.handlerRef.handler.drawBackground(this.handlerRef.recipeIndex);
|
||||
|
||||
RenderHelper.enableGUIStandardItemLighting();
|
||||
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
|
||||
GL11.glColor4f(1, 1, 1, 1);
|
||||
|
||||
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)) {
|
||||
NEIClientUtils.gl2DRenderContext(() -> GuiDraw.drawRect(pStack.relx, pStack.rely, 16, 16, 0x80FFFFFF));
|
||||
}
|
||||
}
|
||||
|
||||
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)) {
|
||||
NEIClientUtils.gl2DRenderContext(() -> GuiDraw.drawRect(pStack.relx, pStack.rely, 16, 16, 0x80FFFFFF));
|
||||
}
|
||||
}
|
||||
|
||||
for (PositionedStack pStack : getOutputs()) {
|
||||
GuiContainerManager.drawItem(pStack.relx, pStack.rely, pStack.item);
|
||||
|
||||
if (pStack.contains(mouseX - this.x, mouseY - this.y - yShift)) {
|
||||
NEIClientUtils.gl2DRenderContext(() -> GuiDraw.drawRect(pStack.relx, pStack.rely, 16, 16, 0x80FFFFFF));
|
||||
}
|
||||
}
|
||||
|
||||
GuiContainerManager.disableMatrixStackLogging();
|
||||
|
||||
this.handlerRef.handler.drawForeground(this.handlerRef.recipeIndex);
|
||||
|
||||
final GuiRecipeButton overlayButton = forEachButtons(
|
||||
button -> (this.showAsWidget ? button instanceof GuiOverlayButton : button.contains(mouseX, mouseY))
|
||||
? button
|
||||
: null,
|
||||
(GuiRecipeButton) null);
|
||||
|
||||
if (overlayButton != null) {
|
||||
NEIClientUtils.gl2DRenderContext(() -> overlayButton.drawItemOverlay());
|
||||
}
|
||||
|
||||
GL11.glTranslatef(-this.x, -this.y - yShift, 0);
|
||||
GL11.glPopAttrib();
|
||||
|
||||
if (!this.showAsWidget) {
|
||||
final Minecraft mc = NEIClientUtils.mc();
|
||||
for (GuiRecipeButton button : getRecipeButtons()) {
|
||||
button.xPosition += this.x;
|
||||
button.yPosition += this.y;
|
||||
button.drawButton(mc, mouseX, mouseY);
|
||||
button.xPosition -= this.x;
|
||||
button.yPosition -= this.y;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void lastKeyTyped(int keyID, char keyChar) {
|
||||
final Point mouse = GuiDraw.getMousePosition();
|
||||
|
||||
forEachButtons(button -> {
|
||||
|
||||
if (button.contains(mouse.x, mouse.y)) {
|
||||
button.lastKeyTyped(keyChar, keyID);
|
||||
}
|
||||
|
||||
return null;
|
||||
}, null);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleClick(int mouseX, int mouseY, int button) {
|
||||
|
||||
if (ShortcutInputHandler.handleMouseClick(getStackMouseOver(mouseX, mouseY))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (button == 0) {
|
||||
final Minecraft mc = NEIClientUtils.mc();
|
||||
|
||||
if (forEachButtons(guibutton -> {
|
||||
|
||||
if (guibutton.mousePressed(mc, mouseX, mouseY)) {
|
||||
NEIClientUtils.playClickSound();
|
||||
guibutton.mouseReleased(mouseX, mouseY);
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}, false)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
final GuiRecipe<?> guiRecipe = getGuiRecipe();
|
||||
if (guiRecipe == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.handlerRef.handler.mouseClicked(guiRecipe, button, this.handlerRef.recipeIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> handleTooltip(int mouseX, int mouseY, List<String> tooltip) {
|
||||
final GuiRecipe<?> guiRecipe = getGuiRecipe();
|
||||
|
||||
if (guiRecipe == null) {
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
final List<String> localTooltip = this.handlerRef.handler
|
||||
.handleTooltip(guiRecipe, tooltip, this.handlerRef.recipeIndex);
|
||||
|
||||
return forEachButtons(
|
||||
button -> button.contains(mouseX, mouseY) ? button.handleTooltip(localTooltip) : null,
|
||||
localTooltip);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> handleItemTooltip(ItemStack itemstack, int mousex, int mousey, List<String> tooltip) {
|
||||
final GuiRecipe<?> guiRecipe = getGuiRecipe();
|
||||
|
||||
if (guiRecipe == null) {
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
tooltip = this.handlerRef.handler.handleItemTooltip(guiRecipe, itemstack, tooltip, this.handlerRef.recipeIndex);
|
||||
|
||||
if (NEIClientConfig.showCycledIngredientsTooltip() && itemstack != null) {
|
||||
final int yShift = this.handlerInfo.getYShift();
|
||||
PositionedStack hovered = null;
|
||||
|
||||
for (PositionedStack pStack : getInputs()) {
|
||||
if (pStack.contains(mousex - this.x, mousey - this.y - yShift)) {
|
||||
hovered = pStack;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hovered == null) {
|
||||
for (PositionedStack pStack : getCatalysts()) {
|
||||
if (pStack.contains(mousex - this.x, mousey - this.y - yShift)) {
|
||||
hovered = pStack;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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, this.permutations.get(hovered), hovered.item);
|
||||
}
|
||||
} else if (this.acceptsFollowingTooltipLineHandler != null) {
|
||||
this.acceptsFollowingTooltipLineHandler = null;
|
||||
}
|
||||
|
||||
if (this.acceptsFollowingTooltipLineHandler != null) {
|
||||
tooltip.add(GuiDraw.TOOLTIP_HANDLER + GuiDraw.getTipLineId(this.acceptsFollowingTooltipLineHandler));
|
||||
}
|
||||
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
@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);
|
||||
|
||||
if (this.acceptsFollowingTooltipLineHandler != null) {
|
||||
buttonHotkeys.put(
|
||||
NEIClientUtils.getKeyName(
|
||||
NEIClientUtils.SHIFT_HASH,
|
||||
NEIMouseUtils.MOUSE_BTN_NONE + NEIMouseUtils.MOUSE_SCROLL),
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMouseWheel(int scroll, int mx, int my) {
|
||||
|
||||
if (forEachButtons(button -> button.contains(mx, my) ? button.mouseScrolled(scroll) : null, false)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (scrollPermutations(scroll, mx, my)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final GuiRecipe<?> guiRecipe = getGuiRecipe();
|
||||
|
||||
return guiRecipe != null
|
||||
&& this.handlerRef.handler.mouseScrolled(guiRecipe, scroll, this.handlerRef.recipeIndex);
|
||||
}
|
||||
|
||||
protected boolean scrollPermutations(int scroll, int mx, int my) {
|
||||
if (!NEIClientUtils.shiftKey()) return false;
|
||||
final PositionedStack overStack = getPositionedStackMouseOver(mx, my);
|
||||
|
||||
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());
|
||||
|
||||
Stream.concat(getInputs().stream(), getCatalysts().stream()).filter(pStack -> pStack.containsWithNBT(stack))
|
||||
.forEach(pStack -> pStack.setPermutationToRender(stack));
|
||||
|
||||
if (this.acceptsFollowingTooltipLineHandler != null) {
|
||||
this.acceptsFollowingTooltipLineHandler
|
||||
.setActiveStack(((PositionedStack) this.acceptsFollowingTooltipLineHandler.tooltipGUID).item);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected int indexOf(List<ItemStack> list, ItemStack stack) {
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (NEIServerUtils.areStacksSameTypeCraftingWithNBT(list.get(i), stack)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
protected <R> R forEachButtons(Function<GuiRecipeButton, R> callback, R defaultValue) {
|
||||
|
||||
for (GuiRecipeButton button : getRecipeButtonsIfInit()) {
|
||||
button.xPosition += this.x;
|
||||
button.yPosition += this.y;
|
||||
|
||||
final R result = callback.apply(button);
|
||||
|
||||
button.xPosition -= this.x;
|
||||
button.yPosition -= this.y;
|
||||
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public boolean isFocusedRecipe(int mx, int my) {
|
||||
final int yShift = this.handlerInfo.getYShift();
|
||||
|
||||
for (PositionedStack pStackOver : getOutputs()) {
|
||||
if (pStackOver.contains(mx - this.x, my - this.y - yShift)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public PositionedStack getPositionedStackMouseOver(int mx, int my) {
|
||||
final int yShift = this.handlerInfo.getYShift();
|
||||
|
||||
for (PositionedStack pStack : getInputs()) {
|
||||
if (pStack.contains(mx - this.x, my - this.y - yShift)) {
|
||||
return pStack;
|
||||
}
|
||||
}
|
||||
|
||||
for (PositionedStack pStack : getCatalysts()) {
|
||||
if (pStack.contains(mx - this.x, my - this.y - yShift)) {
|
||||
return pStack;
|
||||
}
|
||||
}
|
||||
|
||||
for (PositionedStack pStack : getOutputs()) {
|
||||
if (pStack.contains(mx - this.x, my - this.y - yShift)) {
|
||||
return pStack;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getStackMouseOver(int mx, int my) {
|
||||
final PositionedStack pStack = getPositionedStackMouseOver(mx, my);
|
||||
return pStack != null ? pStack.item : null;
|
||||
}
|
||||
|
||||
protected GuiRecipe<?> getGuiRecipe() {
|
||||
final GuiContainer guiContainer = NEIClientUtils.getGuiContainer();
|
||||
|
||||
if (guiContainer instanceof GuiRecipe<?>guiRecipe) {
|
||||
return guiRecipe;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected GuiContainer getFirstGui() {
|
||||
final GuiContainer guiContainer = NEIClientUtils.getGuiContainer();
|
||||
|
||||
if (guiContainer instanceof GuiRecipe<?>guiRecipe) {
|
||||
return guiRecipe.firstGui;
|
||||
}
|
||||
|
||||
return guiContainer;
|
||||
}
|
||||
|
||||
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()) {
|
||||
updatePermutationsFor(pStack);
|
||||
}
|
||||
|
||||
for (PositionedStack pStack : getCatalysts()) {
|
||||
updatePermutationsFor(pStack);
|
||||
}
|
||||
|
||||
if (this.acceptsFollowingTooltipLineHandler != null) {
|
||||
this.acceptsFollowingTooltipLineHandler
|
||||
.setActiveStack(((PositionedStack) this.acceptsFollowingTooltipLineHandler.tooltipGUID).item);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
protected List<PositionedStack> getOutputs() {
|
||||
final PositionedStack pStackResult = this.handlerRef.handler.getResultStack(this.handlerRef.recipeIndex);
|
||||
return pStackResult != null ? Arrays.asList(pStackResult)
|
||||
: this.handlerRef.handler.getOtherStacks(this.handlerRef.recipeIndex);
|
||||
}
|
||||
|
||||
protected List<PositionedStack> getCatalysts() {
|
||||
if (this.handlerRef.handler.getResultStack(this.handlerRef.recipeIndex) == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return this.handlerRef.handler.getOtherStacks(this.handlerRef.recipeIndex);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -102,11 +102,6 @@ public class ProfilerRecipeHandler implements ICraftingHandler, IUsageHandler {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int recipiesPerPage() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> handleTooltip(GuiRecipe<?> gui, List<String> currenttip, int recipe) {
|
||||
return currenttip;
|
||||
|
||||
@@ -18,6 +18,7 @@ import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.NEIServerUtils;
|
||||
import codechicken.nei.PositionedStack;
|
||||
import codechicken.nei.api.ItemInfo;
|
||||
@@ -50,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<>();
|
||||
@@ -235,7 +254,8 @@ public class Recipe {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.result != null && anRecipeId.result != null
|
||||
if (isShapedRecipe() && this.result != null
|
||||
&& anRecipeId.result != null
|
||||
&& !StackInfo.equalItemAndNBT(this.result, anRecipeId.result, true)) {
|
||||
return false;
|
||||
}
|
||||
@@ -311,7 +331,8 @@ public class Recipe {
|
||||
}
|
||||
|
||||
public boolean contains(ItemStack stackA) {
|
||||
return getPermutations().stream().anyMatch(stackB -> StackInfo.equalItemAndNBT(stackA, stackB, true));
|
||||
return getPermutations().stream()
|
||||
.anyMatch(stackB -> NEIClientUtils.areStacksSameTypeWithNBT(stackB, stackA));
|
||||
}
|
||||
|
||||
public List<ItemStack> getPermutations() {
|
||||
|
||||
@@ -17,6 +17,7 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
@@ -37,10 +38,8 @@ public class RecipeCatalysts {
|
||||
private static final Map<String, List<ItemStack>> catalystsRemoverFromAPI = new HashMap<>();
|
||||
public static final Map<String, CatalystInfoList> catalystsAdderFromIMC = new HashMap<>();
|
||||
public static final Map<String, List<ItemStack>> catalystsRemoverFromIMC = new HashMap<>();
|
||||
private static final Map<String, CatalystInfoList> recipeCatalystMap = new HashMap<>();
|
||||
private static Map<String, List<PositionedStack>> positionedRecipeCatalystMap = new HashMap<>();
|
||||
private static final Map<String, List<PositionedStack>> recipeCatalystMap = new HashMap<>();
|
||||
private static final List<String> forceClassNameList = new ArrayList<>();
|
||||
private static int heightCache;
|
||||
|
||||
public static void addRecipeCatalyst(String handlerID, CatalystInfo catalystInfo) {
|
||||
if (handlerID == null || handlerID.isEmpty() || catalystInfo.getStack() == null) return;
|
||||
@@ -49,6 +48,7 @@ public class RecipeCatalysts {
|
||||
|
||||
public static void removeRecipeCatalyst(String handlerID, ItemStack stack) {
|
||||
if (handlerID == null || handlerID.isEmpty() || stack == null) return;
|
||||
|
||||
if (catalystsRemoverFromAPI.containsKey(handlerID)) {
|
||||
catalystsRemoverFromAPI.get(handlerID).add(stack);
|
||||
} else {
|
||||
@@ -56,8 +56,23 @@ public class RecipeCatalysts {
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, List<PositionedStack>> getPositionedRecipeCatalystMap() {
|
||||
return positionedRecipeCatalystMap;
|
||||
public static void putRecipeCatalysts(String handlerID, List<ItemStack> items) {
|
||||
if (handlerID == null || handlerID.isEmpty()) return;
|
||||
|
||||
final CatalystInfoList catalystInfoList = new CatalystInfoList(handlerID);
|
||||
int stackIndex = 0;
|
||||
|
||||
for (ItemStack stack : items) {
|
||||
catalystInfoList.add(new CatalystInfo(stack, stackIndex++));
|
||||
}
|
||||
|
||||
putRecipeCatalysts(handlerID, catalystInfoList);
|
||||
}
|
||||
|
||||
public static void putRecipeCatalysts(String handlerID, CatalystInfoList catalystInfoList) {
|
||||
if (handlerID == null || handlerID.isEmpty()) return;
|
||||
catalystsAdderFromAPI.put(handlerID, catalystInfoList);
|
||||
recipeCatalystMap.put(handlerID, convertToPositionedStackList(catalystInfoList));
|
||||
}
|
||||
|
||||
public static List<PositionedStack> getRecipeCatalysts(IRecipeHandler handler) {
|
||||
@@ -65,10 +80,7 @@ public class RecipeCatalysts {
|
||||
}
|
||||
|
||||
public static List<PositionedStack> getRecipeCatalysts(String handlerID) {
|
||||
if (!NEIClientConfig.areJEIStyleTabsVisible() || !NEIClientConfig.areJEIStyleRecipeCatalystsVisible()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return positionedRecipeCatalystMap.getOrDefault(handlerID, Collections.emptyList());
|
||||
return recipeCatalystMap.getOrDefault(handlerID, Collections.emptyList());
|
||||
}
|
||||
|
||||
public static boolean containsCatalyst(IRecipeHandler handler, ItemStack candidate) {
|
||||
@@ -76,63 +88,21 @@ public class RecipeCatalysts {
|
||||
}
|
||||
|
||||
public static boolean containsCatalyst(String handlerID, ItemStack candidate) {
|
||||
|
||||
if (recipeCatalystMap.containsKey(handlerID)) {
|
||||
return recipeCatalystMap.get(handlerID).contains(candidate);
|
||||
return recipeCatalystMap.get(handlerID).stream().anyMatch(pStack -> pStack.contains(candidate));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void updatePosition(int availableHeight, boolean force) {
|
||||
if (availableHeight == heightCache && !force) return;
|
||||
|
||||
Map<String, List<PositionedStack>> newMap = new HashMap<>();
|
||||
for (Map.Entry<String, CatalystInfoList> entry : recipeCatalystMap.entrySet()) {
|
||||
CatalystInfoList catalysts = entry.getValue();
|
||||
catalysts.sort();
|
||||
List<PositionedStack> newStacks = new ArrayList<>();
|
||||
int rowCount = getRowCount(availableHeight, catalysts.size());
|
||||
|
||||
for (int index = 0; index < catalysts.size(); index++) {
|
||||
ItemStack catalyst = catalysts.get(index).getStack();
|
||||
int column = index / rowCount;
|
||||
int row = index % rowCount;
|
||||
newStacks.add(
|
||||
new PositionedStack(
|
||||
catalyst,
|
||||
-column * GuiRecipeCatalyst.ingredientSize,
|
||||
row * GuiRecipeCatalyst.ingredientSize));
|
||||
}
|
||||
newMap.put(entry.getKey(), newStacks);
|
||||
}
|
||||
positionedRecipeCatalystMap = newMap;
|
||||
heightCache = availableHeight;
|
||||
}
|
||||
|
||||
public static void updatePosition(int availableHeight) {
|
||||
updatePosition(availableHeight, false);
|
||||
}
|
||||
|
||||
public static int getHeight() {
|
||||
return heightCache;
|
||||
}
|
||||
|
||||
public static int getColumnCount(int availableHeight, int catalystsSize) {
|
||||
int maxItemsPerColumn = availableHeight / GuiRecipeCatalyst.ingredientSize;
|
||||
return NEIServerUtils.divideCeil(catalystsSize, maxItemsPerColumn);
|
||||
}
|
||||
|
||||
public static int getRowCount(int availableHeight, int catalystsSize) {
|
||||
int columnCount = getColumnCount(availableHeight, catalystsSize);
|
||||
return NEIServerUtils.divideCeil(catalystsSize, columnCount);
|
||||
}
|
||||
|
||||
public static void loadCatalystInfo() {
|
||||
final boolean fromJar = NEIClientConfig.loadCatalystsFromJar();
|
||||
final URL handlerUrl = RecipeCatalysts.class.getResource("/assets/nei/csv/catalysts.csv");
|
||||
final Map<String, CatalystInfoList> calculatedCatalysts = new HashMap<>();
|
||||
NEIClientConfig.logger.info("Loading catalyst info from " + (fromJar ? "JAR" : "Config"));
|
||||
recipeCatalystMap.clear();
|
||||
URL handlerUrl = RecipeCatalysts.class.getResource("/assets/nei/csv/catalysts.csv");
|
||||
|
||||
resolveAdderQueue();
|
||||
resolveAdderQueue(calculatedCatalysts);
|
||||
|
||||
URL url;
|
||||
if (fromJar) {
|
||||
@@ -211,7 +181,7 @@ public class RecipeCatalysts {
|
||||
|
||||
// Prefer info added by API if we're using default jar config.
|
||||
// If not, user config overwrites it.
|
||||
addOrPut(recipeCatalystMap, handlerID, catalystInfo, !fromJar);
|
||||
addOrPut(calculatedCatalysts, handlerID, catalystInfo, !fromJar);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
NEIClientConfig.logger.warn("Error parsing CSV");
|
||||
@@ -219,13 +189,17 @@ public class RecipeCatalysts {
|
||||
}
|
||||
|
||||
if (fromJar) {
|
||||
resolveRemoverQueue();
|
||||
resolveRemoverQueue(calculatedCatalysts);
|
||||
}
|
||||
|
||||
recipeCatalystMap.clear();
|
||||
for (Map.Entry<String, CatalystInfoList> entry : calculatedCatalysts.entrySet()) {
|
||||
recipeCatalystMap.put(entry.getKey(), convertToPositionedStackList(entry.getValue()));
|
||||
}
|
||||
|
||||
updatePosition(getHeight(), true);
|
||||
}
|
||||
|
||||
private static void resolveAdderQueue() {
|
||||
private static void resolveAdderQueue(Map<String, CatalystInfoList> recipeCatalystMap) {
|
||||
for (Map.Entry<String, CatalystInfoList> entry : catalystsAdderFromAPI.entrySet()) {
|
||||
String handlerID = entry.getKey();
|
||||
for (CatalystInfo catalyst : entry.getValue()) {
|
||||
@@ -256,7 +230,7 @@ public class RecipeCatalysts {
|
||||
}
|
||||
}
|
||||
|
||||
private static void resolveRemoverQueue() {
|
||||
private static void resolveRemoverQueue(Map<String, CatalystInfoList> recipeCatalystMap) {
|
||||
for (Map.Entry<String, List<ItemStack>> entry : catalystsRemoverFromAPI.entrySet()) {
|
||||
String handlerID = entry.getKey();
|
||||
if (recipeCatalystMap.containsKey(handlerID)) {
|
||||
@@ -308,16 +282,49 @@ public class RecipeCatalysts {
|
||||
}
|
||||
}
|
||||
|
||||
private static List<PositionedStack> convertToPositionedStackList(CatalystInfoList catalystInfoList) {
|
||||
catalystInfoList.sort();
|
||||
return catalystInfoList.stream().filter(catalyst -> catalyst.getStack() != null)
|
||||
.map(catalyst -> new PositionedStack(catalyst.getStack(), 0, 0, false)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void addRecipeCatalyst(List<ItemStack> stacks, Class<? extends IRecipeHandler> handler) {}
|
||||
|
||||
@Deprecated
|
||||
public static List<PositionedStack> getRecipeCatalysts(Class<? extends IRecipeHandler> handler) {
|
||||
return Collections.emptyList();
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static boolean containsCatalyst(Class<? extends IRecipeHandler> handler, ItemStack candidate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static Map<String, List<PositionedStack>> getPositionedRecipeCatalystMap() {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void updatePosition(int availableHeight, boolean force) {}
|
||||
|
||||
@Deprecated
|
||||
public static void updatePosition(int availableHeight) {}
|
||||
|
||||
@Deprecated
|
||||
public static int getHeight() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static int getColumnCount(int availableHeight, int catalystsSize) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static int getRowCount(int availableHeight, int catalystsSize) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -62,7 +62,13 @@ public class RecipeHandlerQuery<T extends IRecipeHandler> {
|
||||
|
||||
private ArrayList<T> getRecipeHandlersParallel() throws InterruptedException, ExecutionException {
|
||||
// Pre-find the fuels so we're not fighting over it
|
||||
FuelRecipeHandler.findFuelsOnceParallel();
|
||||
|
||||
if (NEIClientConfig.getBooleanSetting("findFuelsParallel")) {
|
||||
FuelRecipeHandler.findFuelsOnceParallel();
|
||||
} else {
|
||||
FuelRecipeHandler.findFuelsOnce();
|
||||
}
|
||||
|
||||
ArrayList<T> handlers = getSerialHandlersWithRecipes();
|
||||
handlers.addAll(getHandlersWithRecipes());
|
||||
handlers.sort(NEIClientConfig.HANDLER_COMPARATOR);
|
||||
|
||||
@@ -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) {
|
||||
@@ -61,6 +66,10 @@ public class RecipeHandlerRef {
|
||||
return firstGui != null && firstGui.inventorySlots != null ? firstGui : null;
|
||||
}
|
||||
|
||||
public NEIRecipeWidget getRecipeWidget() {
|
||||
return new NEIRecipeWidget(this);
|
||||
}
|
||||
|
||||
public IOverlayHandler getOverlayHandler(GuiContainer gui) {
|
||||
final GuiContainer firstGui = prepareGui(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));
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import codechicken.nei.ItemPanels;
|
||||
import codechicken.nei.ItemsGrid.ItemsGridSlot;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.api.ShortcutInputHandler;
|
||||
import codechicken.nei.bookmark.BookmarkItem.BookmarkItemType;
|
||||
import codechicken.nei.bookmark.BookmarksGridSlot;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.guihook.IContainerInputHandler;
|
||||
@@ -37,23 +38,16 @@ public class RecipeItemInputHandler implements IContainerInputHandler, IContaine
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(GuiContainer gui, int mousex, int mousey, int button) {
|
||||
if (!(gui instanceof GuiRecipe) || ItemPanels.itemPanel.contains(mousex, mousey)
|
||||
|| ItemPanels.bookmarkPanel.contains(mousex, mousey)
|
||||
|| ItemPanels.itemPanel.historyPanel.contains(mousex, mousey))
|
||||
return false;
|
||||
|
||||
return ShortcutInputHandler.handleMouseClick(GuiContainerManager.getStackMouseOver(gui));
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> handleHotkeys(GuiContainer gui, int mousex, int mousey, Map<String, String> hotkeys) {
|
||||
|
||||
if ((gui instanceof GuiRecipe) || ItemPanels.itemPanel.contains(mousex, mousey)
|
||||
|| ItemPanels.bookmarkPanel.contains(mousex, mousey)
|
||||
|| ItemPanels.itemPanel.historyPanel.contains(mousex, mousey)) {
|
||||
if (gui instanceof GuiRecipe || ItemPanels.itemPanel.containsWithSubpanels(mousex, mousey)
|
||||
|| ItemPanels.bookmarkPanel.contains(mousex, mousey)) {
|
||||
hotkeys.putAll(
|
||||
ShortcutInputHandler
|
||||
.handleHotkeys(gui, mousex, mousey, GuiContainerManager.getStackMouseOver(gui)));
|
||||
ShortcutInputHandler.handleHotkeys(mousex, mousey, GuiContainerManager.getStackMouseOver(gui)));
|
||||
}
|
||||
|
||||
return hotkeys;
|
||||
@@ -88,7 +82,7 @@ public class RecipeItemInputHandler implements IContainerInputHandler, IContaine
|
||||
final BookmarksGridSlot slot = ItemPanels.bookmarkPanel.getSlotMouseOver(mousex, mousey);
|
||||
|
||||
if (slot != null && slot.getRecipeId() != null
|
||||
&& !slot.isIngredient()
|
||||
&& slot.getType() != BookmarkItemType.INGREDIENT
|
||||
&& NEIClientConfig.getRecipeTooltipsMode() != 0) {
|
||||
final int tooltipMode = NEIClientConfig.getRecipeTooltipsMode();
|
||||
final BookmarkViewMode viewMode = slot.getGroup().viewMode;
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
package codechicken.nei.recipe;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.Widget;
|
||||
import codechicken.nei.scroll.ScrollContainer;
|
||||
|
||||
public class RecipePageManager {
|
||||
|
||||
private SearchRecipeHandler<?> handler;
|
||||
private ScrollContainer container;
|
||||
private HandlerInfo handlerInfo;
|
||||
|
||||
private String cacheKey = "";
|
||||
private int currentPageIndex = -1;
|
||||
private List<Integer> recipeIndices = new ArrayList<>();
|
||||
private List<List<Widget>> pageWidgets = new ArrayList<>();
|
||||
|
||||
public RecipePageManager(SearchRecipeHandler<?> handler, HandlerInfo handlerInfo, ScrollContainer container) {
|
||||
this.handler = handler;
|
||||
this.handlerInfo = handlerInfo;
|
||||
this.container = container;
|
||||
|
||||
rebuildPages();
|
||||
}
|
||||
|
||||
public boolean rebuildPages() {
|
||||
final String cacheKey = handlerInfo.getHandlerName() + ":"
|
||||
+ getNumRecipes()
|
||||
+ ":"
|
||||
+ this.container.getVisibleHeight()
|
||||
+ ":"
|
||||
+ GuiRecipe.searchField.text();
|
||||
|
||||
if (cacheKey.equals(this.cacheKey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.cacheKey = cacheKey;
|
||||
this.pageWidgets.clear();
|
||||
|
||||
final boolean useCustomScroll = this.handlerInfo.getUseCustomScroll();
|
||||
final int handlerHeight = this.handlerInfo.getHeight() + this.handlerInfo.getYShift();
|
||||
final boolean multipleWidgetsAllowed = !useCustomScroll && handlerInfo.isMultipleWidgetsAllowed();
|
||||
final boolean infiniteScroll = !useCustomScroll
|
||||
&& NEIClientConfig.getBooleanSetting("inventory.guirecipe.infiniteScroll");
|
||||
|
||||
final int heightAvailable = this.container.getVisibleHeight();
|
||||
final int width = Math.max(166, this.handlerInfo.getWidth());
|
||||
final int numRecipes = getNumRecipes();
|
||||
List<Widget> widgets = new ArrayList<>();
|
||||
int shiftY = 0;
|
||||
|
||||
for (int i = 0; i < numRecipes; i++) {
|
||||
final int recipeIndex = this.handler.ref(i);
|
||||
final NEIRecipeWidget widget = RecipeHandlerRef.of(this.handler.original, recipeIndex).getRecipeWidget();
|
||||
widget.w = width;
|
||||
|
||||
if (useCustomScroll) {
|
||||
widget.h = Math.min(handlerHeight, heightAvailable);
|
||||
}
|
||||
|
||||
if (!widgets.isEmpty()
|
||||
&& (!multipleWidgetsAllowed || !infiniteScroll && shiftY + widget.h > heightAvailable)) {
|
||||
this.pageWidgets.add(widgets);
|
||||
widgets = new ArrayList<>();
|
||||
shiftY = 0;
|
||||
}
|
||||
|
||||
widgets.add(widget);
|
||||
shiftY += widget.h;
|
||||
}
|
||||
|
||||
if (!widgets.isEmpty()) {
|
||||
this.pageWidgets.add(widgets);
|
||||
}
|
||||
|
||||
changePage(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isMultipleWidgetsAllowed() {
|
||||
return !this.handlerInfo.getUseCustomScroll() && this.handlerInfo.isMultipleWidgetsAllowed();
|
||||
}
|
||||
|
||||
public int getNumRecipes() {
|
||||
return this.handler.numRecipes();
|
||||
}
|
||||
|
||||
public int getCurrentPageIndex() {
|
||||
return this.currentPageIndex;
|
||||
}
|
||||
|
||||
public int getNumPages() {
|
||||
return this.pageWidgets.size();
|
||||
}
|
||||
|
||||
public void changePage(int delta) {
|
||||
final int numPages = getNumPages();
|
||||
final int page = numPages > 0 ? (numPages + Math.max(0, this.currentPageIndex) + delta) % numPages : 0;
|
||||
|
||||
if (this.currentPageIndex == page) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.currentPageIndex = page;
|
||||
this.recipeIndices = new ArrayList<>();
|
||||
|
||||
for (Widget widget : getCurrentPageWidgets()) {
|
||||
if (widget instanceof NEIRecipeWidget recipeWidget) {
|
||||
this.recipeIndices.add(recipeWidget.getRecipeHandlerRef().recipeIndex);
|
||||
}
|
||||
}
|
||||
|
||||
this.container.setVerticalScrollOffset(0);
|
||||
}
|
||||
|
||||
public void gotoRefIndex(int refIndex) {
|
||||
int page = 0;
|
||||
|
||||
for (int i = 0; i < this.pageWidgets.size(); i++) {
|
||||
refIndex -= this.pageWidgets.get(i).size();
|
||||
if (refIndex < 0) {
|
||||
page = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
changePage(page);
|
||||
}
|
||||
|
||||
public List<Widget> getCurrentPageWidgets() {
|
||||
if (this.pageWidgets.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<Widget> currentWidgets = this.pageWidgets.get(this.currentPageIndex);
|
||||
int shiftY = 0;
|
||||
|
||||
for (Widget widget : currentWidgets) {
|
||||
if (widget instanceof NEIRecipeWidget recipeWidget) {
|
||||
recipeWidget.setLocation(2, shiftY);
|
||||
}
|
||||
shiftY += widget.h;
|
||||
}
|
||||
|
||||
return currentWidgets;
|
||||
}
|
||||
|
||||
public List<Integer> getRecipeIndices() {
|
||||
return this.recipeIndices;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,23 +1,35 @@
|
||||
package codechicken.nei.recipe;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.renderer.RenderHelper;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL12;
|
||||
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.lib.gui.GuiDraw.ITooltipLineHandler;
|
||||
import codechicken.nei.drawable.DrawableBuilder;
|
||||
import codechicken.nei.drawable.DrawableResource;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.recipe.Recipe.RecipeId;
|
||||
import codechicken.nei.scroll.GuiHelper;
|
||||
|
||||
public class RecipeTooltipLineHandler implements ITooltipLineHandler {
|
||||
|
||||
private static final int BG_PADDING = 5;
|
||||
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();
|
||||
|
||||
protected long lastUpdate = System.currentTimeMillis();
|
||||
protected String recipeName = "";
|
||||
protected GuiRecipe<?> gui = null;
|
||||
protected RecipeHandlerRef handlerRef = null;
|
||||
protected NEIRecipeWidget widget = null;
|
||||
protected RecipeId recipeId = null;
|
||||
protected boolean createdGui = false;
|
||||
|
||||
@@ -36,19 +48,22 @@ public class RecipeTooltipLineHandler implements ITooltipLineHandler {
|
||||
@Override
|
||||
public Dimension getSize() {
|
||||
|
||||
if (this.gui == null && !this.createdGui) {
|
||||
this.gui = GuiCraftingRecipe.createRecipeGui("recipeId", false, this.recipeId.getResult(), this.recipeId);
|
||||
if (this.widget == null && !this.createdGui) {
|
||||
this.handlerRef = RecipeHandlerRef.of(this.recipeId);
|
||||
this.createdGui = true;
|
||||
|
||||
if (this.gui != null) {
|
||||
this.gui.initGui();
|
||||
this.gui.guiTop = 0;
|
||||
this.gui.guiLeft = 0;
|
||||
if (handlerRef != null) {
|
||||
this.widget = new NEIRecipeWidget(this.handlerRef);
|
||||
this.widget.showAsWidget(true);
|
||||
this.widget.x = BG_PADDING;
|
||||
this.widget.y = BG_PADDING + 12;
|
||||
|
||||
this.recipeName = this.widget.getRecipeHandlerRef().handler.getRecipeName().trim();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.gui != null) {
|
||||
return this.gui.getWidgetSize();
|
||||
if (this.widget != null) {
|
||||
return new Dimension(this.widget.w + BG_PADDING * 2, this.widget.h + BG_PADDING * 2 + 12);
|
||||
}
|
||||
|
||||
return new Dimension(0, 0);
|
||||
@@ -56,41 +71,48 @@ public class RecipeTooltipLineHandler implements ITooltipLineHandler {
|
||||
|
||||
@Override
|
||||
public void draw(int x, int y) {
|
||||
if (this.gui == null) return;
|
||||
if (this.widget == null) return;
|
||||
|
||||
if ((System.currentTimeMillis() - lastUpdate) > 50) {
|
||||
lastUpdate = System.currentTimeMillis();
|
||||
this.gui.onUpdate();
|
||||
this.handlerRef.handler.onUpdate();
|
||||
this.widget.update();
|
||||
}
|
||||
|
||||
GL11.glPushMatrix();
|
||||
GL11.glScaled(1, 1, 3);
|
||||
GL11.glTranslatef(x, y, 0);
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
|
||||
RenderHelper.disableStandardItemLighting();
|
||||
final Dimension size = getSize();
|
||||
|
||||
this.gui.drawGuiContainerBackgroundLayer(0.0f, -100, -100);
|
||||
GL11.glPushAttrib(GL11.GL_ENABLE_BIT | GL11.GL_COLOR_BUFFER_BIT | GL11.GL_LIGHTING_BIT);
|
||||
|
||||
final int zTranslation = GuiContainerManager.TOOLTIP_Z_OFFSET;
|
||||
GL11.glTranslatef(x, y, zTranslation);
|
||||
|
||||
GuiContainerManager.enable2DRender();
|
||||
GL11.glColor4f(1, 1, 1, 1);
|
||||
|
||||
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);
|
||||
|
||||
GuiDraw.drawRect(BG_PADDING, BG_PADDING, size.width - BG_PADDING * 2, 12, 0x30000000);
|
||||
GuiDraw.drawStringC(this.recipeName, this.widget.w / 2, BG_PADDING + 2, 0xffffff);
|
||||
|
||||
GuiHelper.useScissor(
|
||||
this.widget.x,
|
||||
this.widget.y,
|
||||
this.widget.w,
|
||||
this.widget.h,
|
||||
() -> { this.widget.draw(0, 0); });
|
||||
|
||||
GL11.glPopAttrib();
|
||||
|
||||
if (this.gui.slotcontainer != null) {
|
||||
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
|
||||
RenderHelper.enableGUIStandardItemLighting();
|
||||
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST);
|
||||
List<Slot> slots = this.gui.slotcontainer.inventorySlots;
|
||||
|
||||
for (Slot slot : slots) {
|
||||
if (slot != null && slot.getStack() != null) {
|
||||
GuiContainerManager.drawItem(slot.xDisplayPosition, slot.yDisplayPosition, slot.getStack());
|
||||
}
|
||||
}
|
||||
|
||||
GL11.glPopAttrib();
|
||||
}
|
||||
|
||||
this.gui.drawGuiContainerForegroundLayer(-100, -100);
|
||||
|
||||
GL11.glPopMatrix();
|
||||
GL11.glTranslatef(-x, -y, -zTranslation);
|
||||
}
|
||||
|
||||
}
|
||||
Loaded 100 of 143 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user