Compare commits

...
Author SHA1 Message Date
querns 1ed004e619 Holding ALT now increases bookmark stack increase in increments of output item's stack size (#418) 2023-09-09 09:22:33 +02:00
Nico Spiske 153da523d6 Hide bookmarkItemPulling button if currently opened gui is not supported (#419)
* [minor] hide pullBookmarkedItems button if open container is not supported

* [minor] spotless apply
2023-09-08 07:16:37 +02:00
miozune c732361bbc More readable packet IDs (#417) 2023-09-06 11:05:15 +02:00
miozune bdb206b45d Fix world specific settings on MP being also specific to dimension (#414) 2023-08-18 21:42:20 +02:00
Raven Szewczyk aa44a97f80 Partial fix for the NEI custom diagram in recipe tooltip issue (#413) 2023-08-17 10:36:15 +02:00
Nico Spiske 00c4411ec5 Pull bookmarked items from container to player inventory (#410)
* [major] first potential version for basic chests

* [major] added api to register chest/inventory guis for bookmark item pulling

* [minor] added hotkey to pull all bookmarked items

* [major] finished

* [minor] spotless apply

* [minor] removed bak file

* [minor] function cleanup

* [minor] fixed bookmarks being set to 0

* [minor] little oversight

* [minor] private attribute and curly brackets
2023-08-07 15:29:05 +02:00
miozune 4f23d21d37 Fix recipe tooltip crash with BetterQuesting (#409)
* updateBuildScript

* Fix recipe tooltip crash with BetterQuesting
2023-07-28 13:20:45 +02:00
8569431e1d Recipe tooltip fixes (#402)
* Unconditionally override Minecraft.currentScreen when drawing tooltips

* Fix bad item lighting in recipe tooltips

* Update buildscript

* Fix NEI ignoring handler switching on click

Handlers might call Minecraft#displayGuiScreen and overwrite Minecraft.currentScreen, but the height hack would unconditionally undo this again.

* spotlessApply (#404)

Co-authored-by: GitHub GTNH Actions <>

* Attempt to fix CME when opening recipes immediately after load (#403)

* Rename the internal private class HeightHack->CompatibilityHacks to better reflect the new usage.

* Move trueGui assignment down.

* Fix overlay button y offsets

* Fix wrong recipe tooltip background rendering

* Apply spotless

---------

Co-authored-by: Wilhelm Schuster <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2023-07-23 08:04:31 +02:00
Wilhelm Schuster 5b9c27e253 Fix potential NPE when calling ItemMobSpawner#loadSpawners. (#405) 2023-07-16 14:29:31 +02:00
22 changed files with 465 additions and 157 deletions

No files matched your search

+9 -2
View File
@@ -1,6 +1,7 @@
.gradle
.settings
/.idea/
/.vscode/
/run/
/build/
/eclipse/
@@ -25,6 +26,12 @@ whitelist.json
*.iml
*.ipr
*.iws
src/main/resources/mixins.*.json
src/main/resources/mixins.*([!.]).json
*.bat
.DS_Store
*.DS_Store
!gradlew.bat
.factorypath
addon.local.gradle
addon.local.gradle.kts
addon.late.local.gradle
addon.late.local.gradle.kts
+141 -62
View File
@@ -1,4 +1,4 @@
//version: 1685785062
//version: 1692122114
/*
DO NOT CHANGE THIS FILE!
Also, you may replace this file at any time if there is an update available.
@@ -69,7 +69,7 @@ plugins {
id 'com.diffplug.spotless' version '6.13.0' apply false // 6.13.0 is the last jvm8 supporting version
id 'com.modrinth.minotaur' version '2.+' apply false
id 'com.matthewprenger.cursegradle' version '1.4.0' apply false
id 'com.gtnewhorizons.retrofuturagradle' version '1.3.14'
id 'com.gtnewhorizons.retrofuturagradle' version '1.3.24'
}
print("You might want to check out './gradlew :faq' if your build fails.\n")
@@ -115,6 +115,8 @@ propertyDefaultIfUnset("usesMixinDebug", project.usesMixins)
propertyDefaultIfUnset("forceEnableMixins", false)
propertyDefaultIfUnset("channel", "stable")
propertyDefaultIfUnset("mappingsVersion", "12")
propertyDefaultIfUnset("usesMavenPublishing", true)
propertyDefaultIfUnset("mavenPublishUrl", "http://jenkins.usrv.eu:8081/nexus/content/repositories/releases")
propertyDefaultIfUnset("modrinthProjectId", "")
propertyDefaultIfUnset("modrinthRelations", "")
propertyDefaultIfUnset("curseForgeProjectId", "")
@@ -357,7 +359,27 @@ catch (Exception ignored) {
String identifiedVersion
String versionOverride = System.getenv("VERSION") ?: null
try {
identifiedVersion = versionOverride == null ? gitVersion() : versionOverride
// Produce a version based on the tag, or for branches something like 0.2.2-configurable-maven-and-extras.38+43090270b6-dirty
if (versionOverride == null) {
def gitDetails = versionDetails()
def isDirty = gitVersion().endsWith(".dirty") // No public API for this, isCleanTag has a different meaning
String branchName = gitDetails.branchName ?: (System.getenv('GIT_BRANCH') ?: 'git')
if (branchName.startsWith('origin/')) {
branchName = branchName.minus('origin/')
}
branchName = branchName.replaceAll("[^a-zA-Z0-9-]+", "-") // sanitize branch names for semver
identifiedVersion = gitDetails.lastTag ?: '${gitDetails.gitHash}'
if (gitDetails.commitDistance > 0) {
identifiedVersion += "-${branchName}.${gitDetails.commitDistance}+${gitDetails.gitHash}"
if (isDirty) {
identifiedVersion += "-dirty"
}
} else if (isDirty) {
identifiedVersion += "-${branchName}+${gitDetails.gitHash}-dirty"
}
} else {
identifiedVersion = versionOverride
}
}
catch (Exception ignored) {
out.style(Style.Failure).text(
@@ -379,9 +401,13 @@ if (identifiedVersion == versionOverride) {
group = "com.github.GTNewHorizons"
if (project.hasProperty("customArchiveBaseName") && customArchiveBaseName) {
archivesBaseName = customArchiveBaseName
base {
archivesName = customArchiveBaseName
}
} else {
archivesBaseName = modId
base {
archivesName = modId
}
}
@@ -465,10 +491,19 @@ sourceSets {
}
}
if (file('addon.gradle').exists()) {
if (file('addon.gradle.kts').exists()) {
apply from: 'addon.gradle.kts'
} else if (file('addon.gradle').exists()) {
apply from: 'addon.gradle'
}
// File for local tweaks not commited to Git
if (file('addon.local.gradle.kts').exists()) {
apply from: 'addon.local.gradle.kts'
} else if (file('addon.local.gradle').exists()) {
apply from: 'addon.local.gradle'
}
// Allow unsafe repos but warn
repositories.configureEach { repo ->
if (repo instanceof org.gradle.api.artifacts.repositories.UrlArtifactRepository) {
@@ -479,7 +514,14 @@ repositories.configureEach { repo ->
}
}
apply from: 'repositories.gradle'
if (file('repositories.gradle.kts').exists()) {
apply from: 'repositories.gradle.kts'
} else if (file('repositories.gradle').exists()) {
apply from: 'repositories.gradle'
} else {
logger.error("Neither repositories.gradle.kts nor repositories.gradle was found, make sure you extracted the full ExampleMod template.")
throw new RuntimeException("Missing repositories.gradle[.kts]")
}
configurations {
runtimeClasspath.extendsFrom(runtimeOnlyNonPublishable)
@@ -520,9 +562,6 @@ repositories {
maven {
name 'Overmind forge repo mirror'
url 'https://gregtech.overminddl1.com/'
mavenContent {
excludeGroup("net.minecraftforge") // missing the `universal` artefact
}
}
maven {
name = "GTNH Maven"
@@ -537,13 +576,28 @@ repositories {
}
}
if (includeWellKnownRepositories.toBoolean()) {
maven {
name "CurseMaven"
url "https://cursemaven.com"
content {
exclusiveContent {
forRepository {
maven {
name "CurseMaven"
url "https://cursemaven.com"
}
}
filter {
includeGroup "curse.maven"
}
}
exclusiveContent {
forRepository {
maven {
name = "Modrinth"
url = "https://api.modrinth.com/maven"
}
}
filter {
includeGroup "maven.modrinth"
}
}
maven {
name = "ic2"
url = "https://maven.ic2.player.to/"
@@ -574,6 +628,8 @@ def mixinProviderSpecNoClassifer = "${mixinProviderGroup}:${mixinProviderModule}
def mixinProviderSpec = "${mixinProviderSpecNoClassifer}:dev"
ext.mixinProviderSpec = mixinProviderSpec
def mixingConfigRefMap = 'mixins.' + modId + '.refmap.json'
dependencies {
if (usesMixins.toBoolean()) {
annotationProcessor('org.ow2.asm:asm-debug-all:5.0.3')
@@ -585,7 +641,7 @@ dependencies {
}
}
if (usesMixins.toBoolean()) {
implementation(mixinProviderSpec)
implementation(modUtils.enableMixins(mixinProviderSpec, mixingConfigRefMap))
} else if (forceEnableMixins.toBoolean()) {
runtimeOnlyNonPublishable(mixinProviderSpec)
}
@@ -611,12 +667,32 @@ configurations.all {
}
}
apply from: 'dependencies.gradle'
dependencies {
constraints {
def minGtnhLibVersion = "0.0.13"
implementation("com.github.GTNewHorizons:GTNHLib:${minGtnhLibVersion}") {
because("fixes duplicate mod errors in java 17 configurations using old gtnhlib")
}
runtimeOnly("com.github.GTNewHorizons:GTNHLib:${minGtnhLibVersion}") {
because("fixes duplicate mod errors in java 17 configurations using old gtnhlib")
}
devOnlyNonPublishable("com.github.GTNewHorizons:GTNHLib:${minGtnhLibVersion}") {
because("fixes duplicate mod errors in java 17 configurations using old gtnhlib")
}
runtimeOnlyNonPublishable("com.github.GTNewHorizons:GTNHLib:${minGtnhLibVersion}") {
because("fixes duplicate mod errors in java 17 configurations using old gtnhlib")
}
}
}
def mixingConfigRefMap = 'mixins.' + modId + '.refmap.json'
def mixinTmpDir = buildDir.path + File.separator + 'tmp' + File.separator + 'mixins'
def refMap = "${mixinTmpDir}" + File.separator + mixingConfigRefMap
def mixinSrg = "${mixinTmpDir}" + File.separator + "mixins.srg"
if (file('dependencies.gradle.kts').exists()) {
apply from: 'dependencies.gradle.kts'
} else if (file('dependencies.gradle').exists()) {
apply from: 'dependencies.gradle'
} else {
logger.error("Neither dependencies.gradle.kts nor dependencies.gradle was found, make sure you extracted the full ExampleMod template.")
throw new RuntimeException("Missing dependencies.gradle[.kts]")
}
tasks.register('generateAssets') {
group = "GTNH Buildscript"
@@ -648,46 +724,17 @@ tasks.register('generateAssets') {
}
if (usesMixins.toBoolean()) {
tasks.named("reobfJar", ReobfuscatedJar).configure {
extraSrgFiles.from(mixinSrg)
}
tasks.named("processResources").configure {
dependsOn("generateAssets")
}
tasks.named("compileJava", JavaCompile).configure {
doFirst {
new File(mixinTmpDir).mkdirs()
}
options.compilerArgs += [
"-AreobfSrgFile=${tasks.reobfJar.srg.get().asFile}",
"-AoutSrgFile=${mixinSrg}",
"-AoutRefMapFile=${refMap}",
// Elan: from what I understand they are just some linter configs so you get some warning on how to properly code
"-XDenableSunApiLintControl",
"-XDignore.symbol.file"
]
}
pluginManager.withPlugin('org.jetbrains.kotlin.kapt') {
kapt {
correctErrorTypes = true
javacOptions {
option("-AreobfSrgFile=${tasks.reobfJar.srg.get().asFile}")
option("-AoutSrgFile=$mixinSrg")
option("-AoutRefMapFile=$refMap")
}
}
tasks.configureEach { task ->
if (task.name == "kaptKotlin") {
task.doFirst {
new File(mixinTmpDir).mkdirs()
}
}
}
}
}
tasks.named("processResources", ProcessResources).configure {
@@ -705,7 +752,6 @@ tasks.named("processResources", ProcessResources).configure {
}
if (usesMixins.toBoolean()) {
from refMap
dependsOn("compileJava", "compileScala")
}
}
@@ -724,16 +770,16 @@ ext.java17PatchDependenciesCfg = configurations.create("java17PatchDependencies"
}
dependencies {
def lwjgl3ifyVersion = '1.3.5'
def lwjgl3ifyVersion = '1.4.0'
def asmVersion = '9.4'
if (modId != 'lwjgl3ify') {
java17Dependencies("com.github.GTNewHorizons:lwjgl3ify:${lwjgl3ifyVersion}")
}
if (modId != 'hodgepodge') {
java17Dependencies('com.github.GTNewHorizons:Hodgepodge:2.2.13')
java17Dependencies('com.github.GTNewHorizons:Hodgepodge:2.2.26')
}
java17PatchDependencies('net.minecraft:launchwrapper:1.15') {transitive = false}
java17PatchDependencies('net.minecraft:launchwrapper:1.17.2') {transitive = false}
java17PatchDependencies("org.ow2.asm:asm:${asmVersion}")
java17PatchDependencies("org.ow2.asm:asm-commons:${asmVersion}")
java17PatchDependencies("org.ow2.asm:asm-tree:${asmVersion}")
@@ -979,6 +1025,9 @@ idea {
}
}
runConfigurations {
"0. Build and Test"(Gradle) {
taskNames = ["build"]
}
"1. Run Client"(Gradle) {
taskNames = ["runClient"]
}
@@ -1098,6 +1147,14 @@ tasks.named("processIdeaSettings").configure {
dependsOn("injectTags")
}
tasks.named("ideVirtualMainClasses").configure {
// Make IntelliJ "Build project" build the mod jars
dependsOn("jar", "reobfJar")
if (!disableSpotless) {
dependsOn("spotlessCheck")
}
}
// workaround variable hiding in pom processing
def projectConfigs = project.configurations
@@ -1118,12 +1175,14 @@ publishing {
}
repositories {
maven {
url = "http://jenkins.usrv.eu:8081/nexus/content/repositories/releases"
allowInsecureProtocol = true
credentials {
username = System.getenv("MAVEN_USER") ?: "NONE"
password = System.getenv("MAVEN_PASSWORD") ?: "NONE"
if (usesMavenPublishing.toBoolean()) {
maven {
url = mavenPublishUrl
allowInsecureProtocol = mavenPublishUrl.startsWith("http://") // Mostly for the GTNH maven
credentials {
username = System.getenv("MAVEN_USER") ?: "NONE"
password = System.getenv("MAVEN_PASSWORD") ?: "NONE"
}
}
}
}
@@ -1238,7 +1297,7 @@ def addCurseForgeRelation(String type, String name) {
// Updating
def buildscriptGradleVersion = "8.1.1"
def buildscriptGradleVersion = "8.2.1"
tasks.named('wrapper', Wrapper).configure {
gradleVersion = buildscriptGradleVersion
@@ -1344,8 +1403,14 @@ boolean isNewBuildScriptVersionAvailable() {
String currentBuildScript = getFile("build.gradle").getText()
String currentBuildScriptHash = getVersionHash(currentBuildScript)
String availableBuildScript = availableBuildScriptUrl().newInputStream(parameters).getText()
String availableBuildScriptHash = getVersionHash(availableBuildScript)
String availableBuildScriptHash
try {
String availableBuildScript = availableBuildScriptUrl().newInputStream(parameters).getText()
availableBuildScriptHash = getVersionHash(availableBuildScript)
} catch (IOException e) {
logger.warn("Could not check for buildscript update availability: {}", e.message)
return false
}
boolean isUpToDate = currentBuildScriptHash.empty || availableBuildScriptHash.empty || currentBuildScriptHash == availableBuildScriptHash
return !isUpToDate
@@ -1510,3 +1575,17 @@ def getSecondaryArtifacts() {
if (apiPackage) secondaryArtifacts += [apiJar]
return secondaryArtifacts
}
// For easier scripting of things that require variables defined earlier in the buildscript
if (file('addon.late.gradle.kts').exists()) {
apply from: 'addon.late.gradle.kts'
} else if (file('addon.late.gradle').exists()) {
apply from: 'addon.late.gradle'
}
// File for local tweaks not commited to Git
if (file('addon.late.local.gradle.kts').exists()) {
apply from: 'addon.late.local.gradle.kts'
} else if (file('addon.late.local.gradle').exists()) {
apply from: 'addon.late.local.gradle'
}
Binary file not shown.
+1 -1
View File
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+4 -3
View File
@@ -85,9 +85,6 @@ done
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -197,6 +194,10 @@ if "$cygwin" || "$msys" ; then
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
@@ -0,0 +1,31 @@
package codechicken.nei;
import java.util.HashMap;
import net.minecraft.client.gui.inventory.GuiChest;
import net.minecraft.client.gui.inventory.GuiContainer;
import codechicken.nei.api.API;
import codechicken.nei.api.IBookmarkContainerHandler;
public class BookmarkContainerInfo {
private static final HashMap<Class<? extends GuiContainer>, IBookmarkContainerHandler> handlerMap = new HashMap<>();
public static void registerBookmarkContainerHandler(Class<? extends GuiContainer> classz,
IBookmarkContainerHandler handler) {
handlerMap.put(classz, handler);
}
public static boolean hasBookmarkContainerHandler(Class<? extends GuiContainer> classz) {
return handlerMap.containsKey(classz);
}
public static IBookmarkContainerHandler getBookmarkContainerHandler(GuiContainer gui) {
return handlerMap.get(gui.getClass());
}
public static void load() {
API.registerBookmarkContainerHandler(GuiChest.class, new DefaultBookmarkContainerHandler());
}
}
@@ -2,6 +2,7 @@ package codechicken.nei;
import static codechicken.lib.gui.GuiDraw.drawRect;
import static codechicken.lib.gui.GuiDraw.getMousePosition;
import static codechicken.nei.NEIClientUtils.getGuiContainer;
import static codechicken.nei.NEIClientUtils.translate;
import java.awt.Point;
@@ -32,6 +33,7 @@ import com.google.gson.JsonSyntaxException;
import codechicken.core.CommonUtils;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.ItemPanel.ItemPanelSlot;
import codechicken.nei.api.IBookmarkContainerHandler;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.recipe.BookmarkRecipeId;
import codechicken.nei.recipe.StackInfo;
@@ -47,6 +49,7 @@ public class BookmarkPanel extends PanelWidget {
public Button namespacePrev;
public Button namespaceNext;
public Button pullBookmarkedItems;
public Label namespaceLabel;
protected List<BookmarkGrid> namespaces = new ArrayList<>();
@@ -417,6 +420,21 @@ public class BookmarkPanel extends PanelWidget {
}
};
pullBookmarkedItems = new Button("Pull") {
public boolean onButtonPress(boolean rightclick) {
if (rightclick) {
return false;
}
return pullBookmarkItems();
}
@Override
public String getRenderLabel() {
return "P";
}
};
namespaces.add(new BookmarkGrid());
grid = namespaces.get(activeNamespaceIndex);
}
@@ -820,9 +838,9 @@ public class BookmarkPanel extends PanelWidget {
final int center = leftBorder + Math.max(0, (rightBorder - leftBorder) / 2);
int labelWidth = 2;
namespacePrev.h = namespaceNext.h = BUTTON_SIZE;
namespacePrev.w = namespaceNext.w = BUTTON_SIZE;
namespacePrev.y = namespaceNext.y = y + h - BUTTON_SIZE;
namespacePrev.h = namespaceNext.h = pullBookmarkedItems.h = BUTTON_SIZE;
namespacePrev.w = namespaceNext.w = pullBookmarkedItems.w = BUTTON_SIZE;
namespacePrev.y = namespaceNext.y = pullBookmarkedItems.y = y + h - BUTTON_SIZE;
if (rightBorder - leftBorder >= 70) {
labelWidth = 36;
@@ -837,6 +855,7 @@ public class BookmarkPanel extends PanelWidget {
namespacePrev.x = center - labelWidth / 2 - 2 - namespacePrev.w;
namespaceNext.x = center + labelWidth / 2 + 2;
pullBookmarkedItems.x = center + 2 * labelWidth / 2 + 2;
return BUTTON_SIZE + 2;
}
@@ -849,6 +868,9 @@ public class BookmarkPanel extends PanelWidget {
LayoutManager.addWidget(namespacePrev);
LayoutManager.addWidget(namespaceNext);
LayoutManager.addWidget(namespaceLabel);
if (BookmarkContainerInfo.getBookmarkContainerHandler(getGuiContainer()) != null) {
LayoutManager.addWidget(pullBookmarkedItems);
}
}
}
@@ -1035,6 +1057,10 @@ public class BookmarkPanel extends PanelWidget {
.contains(mx, my)) {
tooltip.add(translate("bookmark.viewmode.toggle.tip"));
}
if (new Rectangle4i(pullBookmarkedItems.x, pullBookmarkedItems.y, pullBookmarkedItems.w, pullBookmarkedItems.h)
.contains(mx, my) && BookmarkContainerInfo.getBookmarkContainerHandler(getGuiContainer()) != null) {
tooltip.add(translate("bookmark.pullBookmarkedItems.tip"));
}
return super.handleTooltip(mx, my, tooltip);
}
@@ -1084,6 +1110,10 @@ public class BookmarkPanel extends PanelWidget {
final BookmarkRecipeId recipeId = BGrid.getRecipeId(slot.slotIndex);
final boolean addFullRecipe = NEIClientUtils.shiftKey();
if (NEIClientUtils.altKey()) {
shift *= slot.item.getMaxStackSize();
}
if (addFullRecipe) {
BookmarkStackMeta iMeta;
@@ -1122,4 +1152,14 @@ public class BookmarkPanel extends PanelWidget {
}
}
}
public boolean pullBookmarkItems() {
IBookmarkContainerHandler containerHandler = BookmarkContainerInfo
.getBookmarkContainerHandler(getGuiContainer());
if (containerHandler == null) {
return false;
}
containerHandler.pullBookmarkItemsFromContainer(getGuiContainer(), ((BookmarkGrid) grid).realItems);
return true;
}
}
@@ -0,0 +1,47 @@
package codechicken.nei;
import java.util.ArrayList;
import java.util.LinkedList;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.ItemStack;
import codechicken.nei.api.IBookmarkContainerHandler;
public class DefaultBookmarkContainerHandler implements IBookmarkContainerHandler {
@Override
public void pullBookmarkItemsFromContainer(GuiContainer guiContainer, ArrayList<ItemStack> bookmarkItems) {
FastTransferManager manager = new FastTransferManager();
LinkedList<ItemStack> containerStacks = manager.saveContainer(guiContainer.inventorySlots);
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);
manager.transferItems(guiContainer, i, transferAmount);
bookmarkItem.stackSize -= transferAmount;
if (bookmarkItem.stackSize == 0) {
break;
}
}
}
bookmarkItem.stackSize = bookmarkSizeBackup;
}
}
}
@@ -184,6 +184,12 @@ public class FastTransferManager {
moveOutputSet(window, fromSlot, toSlot);
}
public void transferItems(GuiContainer window, int fromSlot, int itemCount) {
for (int i = 0; i < itemCount; i++) {
transferItem(window, fromSlot);
}
}
public void moveOutputSet(GuiContainer window, int fromSlot, int toSlot) {
if (NEIClientUtils.getHeldItem() != null) return;
@@ -22,8 +22,8 @@ import net.minecraftforge.client.MinecraftForgeClient;
public class ItemMobSpawner extends ItemBlock {
private static Map<Integer, EntityLiving> entityHashMap;
private static Map<Integer, String> IDtoNameMap;
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;
@@ -32,9 +32,6 @@ public class ItemMobSpawner extends ItemBlock {
hasSubtypes = true;
MinecraftForgeClient.registerItemRenderer(this, new SpawnerRenderer());
entityHashMap = new HashMap<>();
IDtoNameMap = new HashMap<>();
}
/**
@@ -16,12 +16,14 @@ import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.ScaledResolution;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.shader.Framebuffer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL12;
import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.ItemPanel.ItemPanelSlot;
@@ -354,8 +356,14 @@ public class ItemsGrid {
} else {
gui = null;
}
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
RenderHelper.disableStandardItemLighting();
recipeTooltipGui.drawGuiContainerBackgroundLayer(0.0f, -100, -100);
GL11.glPopAttrib();
if (recipeTooltipGui.slotcontainer != null) {
GL11.glPushAttrib(GL11.GL_ALL_ATTRIB_BITS);
RenderHelper.enableGUIStandardItemLighting();
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
@SuppressWarnings("unchecked")
List<Slot> slots = (List<Slot>) recipeTooltipGui.slotcontainer.inventorySlots;
for (Slot slot : slots) {
@@ -363,6 +371,7 @@ public class ItemsGrid {
GuiContainerManager.drawItem(slot.xDisplayPosition, slot.yDisplayPosition, slot.getStack());
}
}
GL11.glPopAttrib();
}
recipeTooltipGui.drawGuiContainerForegroundLayer(-100, -100);
for (GuiButton btn : recipeTooltipGui.getOverlayButtons()) {
@@ -226,6 +226,10 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
return true;
}
if (NEIClientConfig.isKeyHashDown("gui.bookmark_pull_items")) {
return bookmarkPanel.pullBookmarkItems();
}
if (isEnabled() && !isHidden()) {
for (Widget widget : controlWidgets) if (inputFocused == null) widget.lastKeyTyped(keyID, keyChar);
}
+33 -31
View File
@@ -1,5 +1,7 @@
package codechicken.nei;
import static codechicken.nei.PacketIDs.*;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.inventory.GuiInventory;
import net.minecraft.item.ItemStack;
@@ -20,37 +22,37 @@ public class NEICPH implements IClientPacketHandler {
@Override
public void handlePacket(PacketCustom packet, Minecraft mc, INetHandlerPlayClient netHandler) {
switch (packet.getType()) {
case 1:
case S2C.SEND_SERVER_SIDE_CHECK:
handleSMPCheck(packet.readUByte(), packet.readString(), mc.theWorld);
break;
case 10:
case S2C.SEND_LOGIN_STATE:
handleLoginState(packet);
break;
case 11:
case S2C.SEND_ACTION_DISABLED:
handleActionDisabled(packet);
break;
case 12:
case S2C.SEND_ACTION_ENABLED:
handleActionEnabled(packet);
break;
case 13:
case S2C.SEND_MAGNETIC_ITEM:
ClientHandler.instance().addSMPMagneticItem(packet.readInt(), mc.theWorld);
break;
case 14:
case S2C.SEND_GAME_MODE:
handleGamemode(mc, packet.readUByte());
break;
case 21:
case S2C.OPEN_ENCHANTMENT_GUI:
ClientUtils.openSMPGui(
packet.readUByte(),
new GuiEnchantmentModifier(mc.thePlayer.inventory, mc.theWorld, 0, 0, 0));
break;
case 23:
case S2C.SET_CREATIVE_PLUS_MODE:
if (packet.readBoolean()) ClientUtils.openSMPGui(
packet.readUByte(),
new GuiExtendedCreativeInv(
new ContainerCreativeInv(mc.thePlayer, new ExtendedCreativeInv(null, Side.CLIENT))));
else mc.displayGuiScreen(new GuiInventory(mc.thePlayer));
break;
case 24:
case S2C.OPEN_POTION_GUI:
ClientUtils.openSMPGui(packet.readUByte(), new GuiPotionCreator(mc.thePlayer.inventory));
break;
}
@@ -102,7 +104,7 @@ public class NEICPH implements IClientPacketHandler {
try {
ClientHandler.instance().loadWorld(world, true);
NEIClientConfig.setHasSMPCounterPart(true);
NEIClientConfig.loadWorld(getSaveName(worldName));
NEIClientConfig.loadWorld(getSaveName());
sendRequestLoginInfo();
} catch (Exception e) {
NEIClientConfig.logger.error("Error handling SMP Check", e);
@@ -110,14 +112,14 @@ public class NEICPH implements IClientPacketHandler {
}
}
private static String getSaveName(String worldName) {
private static String getSaveName() {
if (Minecraft.getMinecraft().isSingleplayer()) return "local/" + ClientUtils.getWorldSaveName();
return "remote/" + ClientUtils.getServerIP().replace(':', '~') + "/" + worldName;
return "remote/" + ClientUtils.getServerIP().replace(':', '~');
}
public static void sendGiveItem(ItemStack spawnstack, boolean infinite, boolean doSpawn) {
PacketCustom packet = new PacketCustom(channel, 1);
PacketCustom packet = new PacketCustom(channel, C2S.GIVE_ITEM);
packet.writeItemStack(spawnstack, true);
packet.writeBoolean(infinite);
packet.writeBoolean(doSpawn);
@@ -125,7 +127,7 @@ public class NEICPH implements IClientPacketHandler {
}
public static void sendDeleteAllItems() {
PacketCustom packet = new PacketCustom(channel, 4);
PacketCustom packet = new PacketCustom(channel, C2S.DELETE_ALL_ITEMS);
packet.sendToServer();
}
@@ -139,18 +141,18 @@ public class NEICPH implements IClientPacketHandler {
sendSetSlot(slot, item, false);
}
PacketCustom packet = new PacketCustom(channel, 11);
PacketCustom packet = new PacketCustom(channel, C2S.REQUEST_CONTAINER_CONTENTS);
packet.sendToServer();
}
public static void sendRequestContainer() {
PacketCustom packet = new PacketCustom(channel, 16);
PacketCustom packet = new PacketCustom(channel, C2S.REQUEST_CONTAINER);
packet.writeInt(Minecraft.getMinecraft().thePlayer.openContainer.getInventory().size());
packet.sendToServer();
}
public static void sendSetSlot(int slot, ItemStack stack, boolean container) {
PacketCustom packet = new PacketCustom(channel, 5);
PacketCustom packet = new PacketCustom(channel, C2S.SET_SLOT);
packet.writeBoolean(container);
packet.writeShort(slot);
packet.writeItemStack(stack);
@@ -158,38 +160,38 @@ public class NEICPH implements IClientPacketHandler {
}
private static void sendRequestLoginInfo() {
PacketCustom packet = new PacketCustom(channel, 10);
PacketCustom packet = new PacketCustom(channel, C2S.REQUEST_LOGIN_INFO);
packet.sendToServer();
}
public static void sendToggleMagnetMode() {
PacketCustom packet = new PacketCustom(channel, 6);
PacketCustom packet = new PacketCustom(channel, C2S.TOGGLE_MAGNET);
packet.sendToServer();
}
public static void sendSetTime(int hour) {
PacketCustom packet = new PacketCustom(channel, 7);
PacketCustom packet = new PacketCustom(channel, C2S.SET_TIME);
packet.writeByte(hour);
packet.sendToServer();
}
public static void sendHeal() {
PacketCustom packet = new PacketCustom(channel, 8);
PacketCustom packet = new PacketCustom(channel, C2S.HEAL);
packet.sendToServer();
}
public static void sendToggleRain() {
PacketCustom packet = new PacketCustom(channel, 9);
PacketCustom packet = new PacketCustom(channel, C2S.TOGGLE_RAIN);
packet.sendToServer();
}
public static void sendOpenEnchantmentWindow() {
PacketCustom packet = new PacketCustom(channel, 21);
PacketCustom packet = new PacketCustom(channel, C2S.REQUEST_ENCHANTMENT_GUI);
packet.sendToServer();
}
public static void sendModifyEnchantment(int enchID, int level, boolean add) {
PacketCustom packet = new PacketCustom(channel, 22);
PacketCustom packet = new PacketCustom(channel, C2S.MODIFY_ENCHANTMENT);
packet.writeByte(enchID);
packet.writeByte(level);
packet.writeBoolean(add);
@@ -197,30 +199,30 @@ public class NEICPH implements IClientPacketHandler {
}
public static void sendSetPropertyDisabled(String name, boolean enable) {
PacketCustom packet = new PacketCustom(channel, 12);
PacketCustom packet = new PacketCustom(channel, C2S.CHANGE_PROPERTY);
packet.writeString(name);
packet.writeBoolean(enable);
packet.sendToServer();
}
public static void sendGamemode(int mode) {
new PacketCustom(channel, 13).writeByte(mode).sendToServer();
new PacketCustom(channel, C2S.SET_GAME_MODE).writeByte(mode).sendToServer();
}
public static void sendCreativeInv(boolean open) {
PacketCustom packet = new PacketCustom(channel, 23);
PacketCustom packet = new PacketCustom(channel, C2S.SET_CREATIVE_PLUS_MODE);
packet.writeBoolean(open);
packet.sendToServer();
}
public static void sendCreativeScroll(int steps) {
PacketCustom packet = new PacketCustom(channel, 14);
PacketCustom packet = new PacketCustom(channel, C2S.CYCLE_CREATIVE_INV);
packet.writeInt(steps);
packet.sendToServer();
}
public static void sendMobSpawnerID(int x, int y, int z, String mobtype) {
PacketCustom packet = new PacketCustom(channel, 15);
PacketCustom packet = new PacketCustom(channel, C2S.SEND_MOB_SPAWNER_ID);
packet.writeCoord(x, y, z);
packet.writeString(mobtype);
packet.sendToServer();
@@ -231,13 +233,13 @@ public class NEICPH implements IClientPacketHandler {
InventoryUtils.readItemStacksFromTag(
potionStore,
NEIClientConfig.global.nbt.getCompoundTag("potionStore").getTagList("items", 10));
PacketCustom packet = new PacketCustom(channel, 24);
PacketCustom packet = new PacketCustom(channel, C2S.REQUEST_POTION_GUI);
for (ItemStack stack : potionStore) packet.writeItemStack(stack);
packet.sendToServer();
}
public static void sendDummySlotSet(int slotNumber, ItemStack stack) {
PacketCustom packet = new PacketCustom(channel, 25);
PacketCustom packet = new PacketCustom(channel, C2S.SET_DUMMY_SLOT);
packet.writeShort(slotNumber);
packet.writeItemStack(stack, true);
packet.sendToServer();
@@ -354,6 +354,7 @@ public class NEIClientConfig {
API.addHashBind(
"gui.bookmark_recipe_count",
Keyboard.KEY_A + NEIClientUtils.SHIFT_HASH + NEIClientUtils.CTRL_HASH);
API.addHashBind("gui.bookmark_pull_items", Keyboard.KEY_V);
API.addHashBind("gui.overlay", Keyboard.KEY_S);
API.addHashBind("gui.overlay_use", Keyboard.KEY_S + NEIClientUtils.SHIFT_HASH);
API.addHashBind("gui.overlay_hide", Keyboard.KEY_S + NEIClientUtils.CTRL_HASH);
@@ -476,7 +477,7 @@ public class NEIClientConfig {
LayoutManager.load();
NEIController.load();
RecipeCatalysts.loadCatalystInfo();
BookmarkContainerInfo.load();
mainNEIConfigLoaded = true;
new Thread("NEI Plugin Loader") {
+31 -28
View File
@@ -1,5 +1,7 @@
package codechicken.nei;
import static codechicken.nei.PacketIDs.*;
import java.util.LinkedList;
import java.util.Set;
@@ -28,61 +30,61 @@ public class NEISPH implements IServerPacketHandler {
if (!NEIServerConfig.authenticatePacket(sender, packet)) return;
switch (packet.getType()) {
case 1:
case C2S.GIVE_ITEM:
handleGiveItem(sender, packet);
break;
case 4:
case C2S.DELETE_ALL_ITEMS:
NEIServerUtils.deleteAllItems(sender);
break;
case 5:
case C2S.SET_SLOT:
setInventorySlot(sender, packet);
break;
case 6:
case C2S.TOGGLE_MAGNET:
NEIServerUtils.toggleMagnetMode(sender);
break;
case 7:
case C2S.SET_TIME:
NEIServerUtils.setHourForward(sender.worldObj, packet.readUByte(), true);
break;
case 8:
case C2S.HEAL:
NEIServerUtils.healPlayer(sender);
break;
case 9:
case C2S.TOGGLE_RAIN:
NEIServerUtils.toggleRaining(sender.worldObj, true);
break;
case 10:
case C2S.REQUEST_LOGIN_INFO:
sendLoginState(sender);
break;
case 11:
case C2S.REQUEST_CONTAINER_CONTENTS:
sender.sendContainerAndContentsToPlayer(sender.openContainer, sender.openContainer.getInventory());
break;
case 12:
case C2S.CHANGE_PROPERTY:
handlePropertyChange(sender, packet);
break;
case 13:
case C2S.SET_GAME_MODE:
NEIServerUtils.setGamemode(sender, packet.readUByte());
break;
case 14:
case C2S.CYCLE_CREATIVE_INV:
NEIServerUtils.cycleCreativeInv(sender, packet.readInt());
break;
case 15:
case C2S.SEND_MOB_SPAWNER_ID:
handleMobSpawnerID(sender.worldObj, packet.readCoord(), packet.readString());
break;
case 16:
case C2S.REQUEST_CONTAINER:
handleRequestContainer(sender, packet.readInt());
break;
case 21:
case C2S.REQUEST_ENCHANTMENT_GUI:
openEnchantmentGui(sender);
break;
case 22:
case C2S.MODIFY_ENCHANTMENT:
modifyEnchantment(sender, packet.readUByte(), packet.readUByte(), packet.readBoolean());
break;
case 23:
case C2S.SET_CREATIVE_PLUS_MODE:
processCreativeInv(sender, packet.readBoolean());
break;
case 24:
case C2S.REQUEST_POTION_GUI:
openPotionGui(sender, packet);
break;
case 25:
case C2S.SET_DUMMY_SLOT:
handleDummySlotSet(sender, packet);
break;
}
@@ -126,14 +128,14 @@ public class NEISPH implements IServerPacketHandler {
NEIServerConfig.forPlayer(sender.getCommandSenderName()),
Side.SERVER)),
(player, windowId) -> {
PacketCustom packet = new PacketCustom(channel, 23);
PacketCustom packet = new PacketCustom(channel, S2C.SET_CREATIVE_PLUS_MODE);
packet.writeBoolean(true);
packet.writeByte(windowId);
packet.sendToPlayer(player);
});
} else {
sender.closeContainer();
PacketCustom packet = new PacketCustom(channel, 23);
PacketCustom packet = new PacketCustom(channel, S2C.SET_CREATIVE_PLUS_MODE);
packet.writeBoolean(false);
packet.sendToPlayer(sender);
}
@@ -169,7 +171,7 @@ public class NEISPH implements IServerPacketHandler {
player,
new ContainerEnchantmentModifier(player.inventory, player.worldObj, 0, 0, 0),
(player1, windowId) -> {
PacketCustom packet = new PacketCustom(channel, 21);
PacketCustom packet = new PacketCustom(channel, S2C.OPEN_ENCHANTMENT_GUI);
packet.writeByte(windowId);
packet.sendToPlayer(player1);
});
@@ -179,18 +181,19 @@ public class NEISPH implements IServerPacketHandler {
InventoryBasic b = new InventoryBasic("potionStore", true, 9);
for (int i = 0; i < b.getSizeInventory(); i++) b.setInventorySlotContents(i, packet.readItemStack());
ServerUtils.openSMPContainer(player, new ContainerPotionCreator(player.inventory, b), (player1, windowId) -> {
PacketCustom packet1 = new PacketCustom(channel, 24);
PacketCustom packet1 = new PacketCustom(channel, S2C.OPEN_POTION_GUI);
packet1.writeByte(windowId);
packet1.sendToPlayer(player1);
});
}
public static void sendActionDisabled(int dim, String name, boolean disable) {
new PacketCustom(channel, 11).writeString(name).writeBoolean(disable).sendToDimension(dim);
new PacketCustom(channel, S2C.SEND_ACTION_DISABLED).writeString(name).writeBoolean(disable)
.sendToDimension(dim);
}
public static void sendActionEnabled(EntityPlayerMP player, String name, boolean enable) {
new PacketCustom(channel, 12).writeString(name).writeBoolean(enable).sendToPlayer(player);
new PacketCustom(channel, S2C.SEND_ACTION_ENABLED).writeString(name).writeBoolean(enable).sendToPlayer(player);
}
private void sendLoginState(EntityPlayerMP player) {
@@ -209,7 +212,7 @@ public class NEISPH implements IServerPacketHandler {
if (!NEIServerConfig.isPlayerInList(player.getCommandSenderName(), entry.value, true))
bannedItems.add(entry.key);
PacketCustom packet = new PacketCustom(channel, 10);
PacketCustom packet = new PacketCustom(channel, S2C.SEND_LOGIN_STATE);
packet.writeByte(actions.size());
for (String s : actions) packet.writeString(s);
@@ -228,7 +231,7 @@ public class NEISPH implements IServerPacketHandler {
public static void sendHasServerSideTo(EntityPlayerMP player) {
NEIServerConfig.logger.debug("Sending serverside check to: " + player.getCommandSenderName());
PacketCustom packet = new PacketCustom(channel, 1);
PacketCustom packet = new PacketCustom(channel, S2C.SEND_SERVER_SIDE_CHECK);
packet.writeByte(NEIActions.protocol);
packet.writeString(CommonUtils.getWorldName(player.worldObj));
@@ -236,7 +239,7 @@ public class NEISPH implements IServerPacketHandler {
}
public static void sendAddMagneticItemTo(EntityPlayerMP player, EntityItem item) {
PacketCustom packet = new PacketCustom(channel, 13);
PacketCustom packet = new PacketCustom(channel, S2C.SEND_MAGNETIC_ITEM);
packet.writeInt(item.getEntityId());
packet.sendToPlayer(player);
@@ -42,6 +42,7 @@ import codechicken.core.ServerUtils;
import codechicken.lib.inventory.InventoryRange;
import codechicken.lib.inventory.InventoryUtils;
import codechicken.lib.packet.PacketCustom;
import codechicken.nei.PacketIDs.S2C;
import codechicken.nei.util.NBTHelper;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.registry.GameRegistry;
@@ -295,7 +296,7 @@ public class NEIServerUtils {
player.theItemInWorldManager.setGameType(getGameType(mode));
// tell the client to change it
new PacketCustom(NEISPH.channel, 14).writeByte(mode).sendToPlayer(player);
new PacketCustom(NEISPH.channel, S2C.SEND_GAME_MODE).writeByte(mode).sendToPlayer(player);
player.addChatMessage(new ChatComponentTranslation("nei.chat.gamemode." + mode));
}
@@ -0,0 +1,40 @@
package codechicken.nei;
public final class PacketIDs {
public static final class C2S {
public static final int GIVE_ITEM = 1;
public static final int DELETE_ALL_ITEMS = 4;
public static final int SET_SLOT = 5;
public static final int TOGGLE_MAGNET = 6;
public static final int SET_TIME = 7;
public static final int HEAL = 8;
public static final int TOGGLE_RAIN = 9;
public static final int REQUEST_LOGIN_INFO = 10;
public static final int REQUEST_CONTAINER_CONTENTS = 11;
public static final int CHANGE_PROPERTY = 12;
public static final int SET_GAME_MODE = 13;
public static final int CYCLE_CREATIVE_INV = 14;
public static final int SEND_MOB_SPAWNER_ID = 15;
public static final int REQUEST_CONTAINER = 16;
public static final int REQUEST_ENCHANTMENT_GUI = 21;
public static final int MODIFY_ENCHANTMENT = 22;
public static final int SET_CREATIVE_PLUS_MODE = 23;
public static final int REQUEST_POTION_GUI = 24;
public static final int SET_DUMMY_SLOT = 25;
}
public static final class S2C {
public static final int SEND_SERVER_SIDE_CHECK = 1;
public static final int SEND_LOGIN_STATE = 10;
public static final int SEND_ACTION_DISABLED = 11;
public static final int SEND_ACTION_ENABLED = 12;
public static final int SEND_MAGNETIC_ITEM = 13;
public static final int SEND_GAME_MODE = 14;
public static final int OPEN_ENCHANTMENT_GUI = 21;
public static final int SET_CREATIVE_PLUS_MODE = 23;
public static final int OPEN_POTION_GUI = 24;
}
}
@@ -14,6 +14,7 @@ import org.lwjgl.input.Keyboard;
import com.google.common.collect.Sets;
import codechicken.nei.BookmarkContainerInfo;
import codechicken.nei.ItemList;
import codechicken.nei.ItemSorter;
import codechicken.nei.ItemStackSet;
@@ -390,6 +391,11 @@ public class API {
RecipeCatalysts.removeRecipeCatalyst(handlerID, stack);
}
public static void registerBookmarkContainerHandler(Class<? extends GuiContainer> gui,
IBookmarkContainerHandler handler) {
BookmarkContainerInfo.registerBookmarkContainerHandler(gui, handler);
}
@Deprecated
public static void addRecipeCatalyst(List<ItemStack> stacks, IRecipeHandler handler) {
for (ItemStack stack : stacks) {
@@ -0,0 +1,11 @@
package codechicken.nei.api;
import java.util.ArrayList;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.ItemStack;
public interface IBookmarkContainerHandler {
void pullBookmarkItemsFromContainer(GuiContainer guiContainer, ArrayList<ItemStack> realItems);
}
@@ -105,6 +105,7 @@ public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
public static void registerRecipeHandler(ICraftingHandler handler) {
final String handlerId = handler.getHandlerId();
if (craftinghandlers.stream().anyMatch(h -> h.getHandlerId().equals(handlerId))
|| serialCraftingHandlers.stream().anyMatch(h -> h.getHandlerId().equals(handlerId)))
return;
@@ -13,7 +13,6 @@ import java.util.regex.Matcher;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.ScaledResolution;
@@ -108,7 +107,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
/**
* This will only be true iff height hacking has been configured for the current recipe handler AND we are currently
* within the scope of an active {@link HeightHack} instance.
* within the scope of an active {@link CompatibilityHacks} instance.
*/
private boolean isHeightHackApplied = false;
@@ -133,25 +132,36 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
limitToOneRecipe = true;
}
/** Checks if the gui only displays one recipe at a time, e.g. for tooltip usage */
public boolean isLimitedToOneRecipe() {
return limitToOneRecipe;
}
/**
* Many old mods assumed a fixed NEI window height of {@code 166} pixels. Now that this is no longer the case, their
* tooltip and click zone handling is broken. This helper class fixes these old mods by hacking the {@link #height}
* property's value so that these old mods' calculations return the correct value for the new height.
*
* <p>
* New and old mods often assume that the handler is only drawn when {@link GuiRecipe} is the currently active
* screen in {@link net.minecraft.client.Minecraft}. This is no longer true since the addition of recipe tooltips
* which need to render the recipe in other containers on mouse hover, this class temporarily switches the active
* screen to {@code this} while rendering them to avoid ClassCastExceptions and other similar crashes.
*
* <p>
* This class is an {@link AutoCloseable} so that it can be used with try-with-resources, which will ensure that
* {@link #height} is returned to the correct value afterwards.
* {@link #height} and {@link net.minecraft.client.Minecraft#currentScreen} is returned to the correct value
* afterwards.
*/
private class HeightHack implements AutoCloseable {
private class CompatibilityHacks implements AutoCloseable {
private final int trueHeight;
private final int trueGuiTop;
private final GuiScreen trueGui;
private HeightHack() {
private CompatibilityHacks() {
trueHeight = height;
trueGuiTop = guiTop;
trueGui = Minecraft.getMinecraft().currentScreen;
isHeightHackApplied = NEIClientConfig.heightHackHandlerRegex.stream()
.map(pattern -> pattern.matcher(handler.getHandlerId())).anyMatch(Matcher::matches);
@@ -176,12 +186,13 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
// guiWidth (the x-value of the left edge of the NEI recipe screen). So if we wanted to override width
// as well, we'd do this:
// width = (2 * guiWidth) + 176;
}
// Recipe handlers may assume the current screen is the GuiRecipe object, which is not the case in
// recipe tooltips drawn on the bookmarks panel with the main inventory open.
if (limitToOneRecipe) {
Minecraft.getMinecraft().currentScreen = GuiRecipe.this;
}
// Recipe handlers may assume the current screen is the GuiRecipe object, which is not the case in
// recipe tooltips drawn on the bookmarks panel with the main inventory open.
trueGui = NEIClientUtils.mc().currentScreen;
if (limitToOneRecipe) {
NEIClientUtils.mc().currentScreen = GuiRecipe.this;
}
}
@@ -189,7 +200,13 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
public void close() {
guiTop = trueGuiTop;
height = trueHeight;
Minecraft.getMinecraft().currentScreen = trueGui;
// Only restore currentScreen if it hasn't been altered by a recipe handler (for example through
// Minecraft#displayGuiScreen).
if (limitToOneRecipe && NEIClientUtils.mc().currentScreen == GuiRecipe.this) {
NEIClientUtils.mc().currentScreen = trueGui;
}
isHeightHackApplied = false;
}
}
@@ -207,7 +224,8 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
super.initGui();
} else {
this.guiLeft = (this.width - this.xSize) / 2;
this.mc = Minecraft.getMinecraft();
this.ySize = this.getHeightAsWidget();
this.mc = NEIClientUtils.mc();
this.fontRendererObj = mc.fontRenderer;
ScaledResolution scaledresolution = new ScaledResolution(
this.mc,
@@ -253,13 +271,14 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
final int recipesPerPage = getRecipesPerPage();
overlayButtons = new GuiButton[recipesPerPage];
final int xOffset = limitToOneRecipe ? ((xSize / 2) - 2) : (width / 2);
final int yOffset = limitToOneRecipe ? 0 : guiTop - 18;
final String overlayKeyName = NEIClientConfig
.getKeyName(NEIClientConfig.getKeyBinding("gui.overlay_use"), true);
for (int i = 0; i < recipesPerPage; i++) {
overlayButtons[i] = new GuiNEIButton(
OVERLAY_BUTTON_ID_START + i,
xOffset + 65,
16 + (handlerInfo.getHeight() * (i + 1)) - 2,
yOffset + getRecipePosition(i).y + handlerInfo.getHeight(),
buttonWidth,
buttonHeight,
"?");
@@ -389,7 +408,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
}
if (GuiContainerManager.getManager(this).lastKeyTyped(i, c)) return;
try (HeightHack heightHack = new HeightHack()) {
try (CompatibilityHacks compatibilityHacks = new CompatibilityHacks()) {
for (int recipe : getRecipeIndices()) if (handler.keyTyped(this, c, i, recipe)) return;
}
@@ -411,7 +430,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
@Override
protected void mouseClicked(int x, int y, int button) {
try (HeightHack heightHack = new HeightHack()) {
try (CompatibilityHacks compatibilityHacks = new CompatibilityHacks()) {
for (int recipe : getRecipeIndices()) if (handler.mouseClicked(this, button, recipe)) return;
}
@@ -488,7 +507,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
@Override
public List<String> handleTooltip(GuiContainer gui, int mousex, int mousey, List<String> currenttip) {
try (HeightHack heightHack = new HeightHack()) {
try (CompatibilityHacks compatibilityHacks = new CompatibilityHacks()) {
for (int i : getRecipeIndices()) currenttip = handler.handleTooltip(this, currenttip, i);
}
recipeTabs.handleTooltip(mousex, mousey, currenttip);
@@ -498,7 +517,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
@Override
public List<String> handleItemTooltip(GuiContainer gui, ItemStack stack, int mousex, int mousey,
List<String> currenttip) {
try (HeightHack heightHack = new HeightHack()) {
try (CompatibilityHacks compatibilityHacks = new CompatibilityHacks()) {
for (int i : getRecipeIndices()) currenttip = handler.handleItemTooltip(this, stack, currenttip, i);
}
@@ -656,10 +675,11 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
GL11.glPushMatrix();
GL11.glTranslatef(5, 32 - ySkip + yShift, 0);
try (HeightHack heightHack = new HeightHack()) {
try (CompatibilityHacks compatibilityHacks = new CompatibilityHacks()) {
for (int i = page * recipesPerPage; i < handler.numRecipes() && i < (page + 1) * recipesPerPage; i++) {
handler.drawForeground(i);
if (drawItemPresence && (isMouseOverOverlayButton(i - page * recipesPerPage) || limitToOneRecipe)
&& firstGui != null
&& firstGui.inventorySlots != null) {
List<PositionedStack> ingredients = handler.getIngredientStacks(i);
if (itemPresenceCacheRecipe != i || itemPresenceCacheSlots == null
@@ -711,7 +731,7 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
GL11.glPushMatrix();
GL11.glTranslatef(guiLeft + 5, guiTop - ySkip + 32 + yShift, 0);
try (HeightHack heightHack = new HeightHack()) {
try (CompatibilityHacks compatibilityHacks = new CompatibilityHacks()) {
for (int i = page * recipesPerPage; i < handler.numRecipes() && i < (page + 1) * recipesPerPage; i++) {
handler.drawBackground(i);
GL11.glTranslatef(0, handlerInfo.getHeight(), 0);
@@ -9,6 +9,7 @@ nei.key.ctrl.mac=CMD
nei.bookmark.toggle=Bookmarks
nei.bookmark.toggle.tip=Toggle visibility of the Bookmark Panel
nei.bookmark.viewmode.toggle.tip=Toggle Bookmark View Mode
nei.bookmark.pullBookmarkedItems.tip=Pull all bookmarked items from storage to inventory
nei.itempanel.quantity.default=One stack
nei.itempanel.loading=Loading Item List...
@@ -106,6 +107,7 @@ nei.options.keys.gui.search=Focus Search Bar
nei.options.keys.gui.bookmark=Add Bookmark
nei.options.keys.gui.bookmark_recipe=Add Bookmark with Recipe
nei.options.keys.gui.bookmark_count=Add Bookmark with Count
nei.options.keys.gui.bookmark_pull_items=Pull all Bookmarked Items
nei.options.keys.gui.bookmark_recipe_count=Add Bookmark with Recipe & Count
nei.options.keys.gui.hide_bookmarks=Toggle Bookmark Panel Visibility
nei.options.keys.gui.overlay=Overlay Recipe