mirror of
https://github.com/GTNewHorizons/NotEnoughItems.git
synced 2026-11-15 09:44:44 +00:00
Compare commits
29
Commits
2.1.16
..
2.2.3-GTNH
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
75c02f0357 | ||
|
|
51ea8bba34 | ||
|
|
b0c6f358f7 | ||
|
|
c73edaa72e | ||
|
|
caebccc1fd | ||
|
|
a0c5ea42b9 | ||
|
|
23d4be06e8 | ||
|
|
1e36822fa4 | ||
|
|
3ce702343d | ||
|
|
a3387f0290 | ||
|
|
116b96f67b | ||
|
|
60fe49d18c | ||
|
|
cab0aff563 | ||
|
|
144a37cebb | ||
|
|
2d18dcf42b | ||
|
|
5bbcc570f9 | ||
|
|
98c9f03e74 | ||
|
|
5dde7cad8b | ||
|
|
ce17ec8026 | ||
|
|
63f49a5e4a | ||
|
|
e2a9d02c4c | ||
|
|
6695185c54 | ||
|
|
e5b8a4c9c9 | ||
|
|
60d033e879 | ||
|
|
0310b4177f | ||
|
|
304cc12750 | ||
|
|
a7ca6c8527 | ||
|
|
43b71b1de6 | ||
|
|
b6070dd508 |
No files matched your search
@@ -0,0 +1,9 @@
|
||||
directory="run/crash-reports"
|
||||
if [ -d $directory ]; then
|
||||
echo "Crash reports detected:"
|
||||
cat $directory/*
|
||||
exit 1
|
||||
else
|
||||
echo "No crash reports detected"
|
||||
exit 0
|
||||
fi
|
||||
@@ -1,14 +1,16 @@
|
||||
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
|
||||
|
||||
name: Build pull request
|
||||
name: Build and test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ master, main ]
|
||||
push:
|
||||
branches: [ master, main ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
build-and-test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
@@ -30,3 +32,14 @@ jobs:
|
||||
|
||||
- name: Build the mod
|
||||
run: ./gradlew build
|
||||
|
||||
- name: Run server for 1 minute
|
||||
run: |
|
||||
mkdir run
|
||||
echo "eula=true" > run/eula.txt
|
||||
timeout 10 ./gradlew runServer || true
|
||||
|
||||
- name: Test no crashes happend
|
||||
run: |
|
||||
chmod +x .github/scripts/test-no-crash-reports.sh
|
||||
.github/scripts/test-no-crash-reports.sh
|
||||
@@ -0,0 +1,51 @@
|
||||
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
|
||||
|
||||
name: Release tagged build
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set release version
|
||||
run: echo "RELEASE_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
|
||||
|
||||
- name: Set up JDK 8
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: '8'
|
||||
distribution: 'adopt'
|
||||
cache: gradle
|
||||
|
||||
- name: Grant execute permission for gradlew
|
||||
run: chmod +x gradlew
|
||||
|
||||
- name: Setup the workspace
|
||||
run: ./gradlew setupCIWorkspace
|
||||
|
||||
- name: Build the mod
|
||||
run: ./gradlew build
|
||||
|
||||
- name: Release under current tag
|
||||
uses: "marvinpinto/action-automatic-releases@latest"
|
||||
with:
|
||||
repo_token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
automatic_release_tag: "${{ env.RELEASE_VERSION }}"
|
||||
prerelease: false
|
||||
title: "${{ env.RELEASE_VERSION }}"
|
||||
files: build/libs/*.jar
|
||||
|
||||
- name: Publish to Maven
|
||||
run: ./gradlew publish
|
||||
env:
|
||||
MAVEN_USER: ${{ secrets.MAVEN_USER }}
|
||||
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
|
||||
@@ -1,41 +0,0 @@
|
||||
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
|
||||
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
|
||||
|
||||
name: Build and release main branch
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master, main ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up JDK 8
|
||||
uses: actions/setup-java@v2
|
||||
with:
|
||||
java-version: '8'
|
||||
distribution: 'adopt'
|
||||
cache: gradle
|
||||
|
||||
- name: Grant execute permission for gradlew
|
||||
run: chmod +x gradlew
|
||||
|
||||
- name: Setup the workspace
|
||||
run: ./gradlew setupCIWorkspace
|
||||
|
||||
- name: Build the mod
|
||||
run: ./gradlew build
|
||||
|
||||
- uses: "marvinpinto/action-automatic-releases@latest"
|
||||
with:
|
||||
repo_token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
automatic_release_tag: "latest"
|
||||
prerelease: true
|
||||
title: "Latest Development Build"
|
||||
files: build/libs/*.jar
|
||||
|
||||
@@ -26,3 +26,4 @@ whitelist.json
|
||||
*.ipr
|
||||
*.iws
|
||||
src/main/resources/mixins.*.json
|
||||
*.bat
|
||||
@@ -0,0 +1,3 @@
|
||||
# Any Github changes require admin approval
|
||||
/.github/** @GTNewHorizons/admin
|
||||
|
||||
+205
-57
@@ -1,9 +1,9 @@
|
||||
//version: eb0b030ab9cb1d0f9a31f11e69e1ceed1dab2c89
|
||||
//version: 1642872913
|
||||
/*
|
||||
DO NOT CHANGE THIS FILE!
|
||||
|
||||
Also, you may replace this file at any time if there is an update available.
|
||||
Please check https://github.com/SinTh0r4s/ExampleMod1.7.10/blob/main/build.gradle for updates.
|
||||
Please check https://github.com/GTNewHorizons/ExampleMod1.7.10/blob/main/build.gradle for updates.
|
||||
*/
|
||||
|
||||
|
||||
@@ -32,16 +32,19 @@ buildscript {
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.github.GTNewHorizons:ForgeGradle:1.2.4'
|
||||
classpath 'com.github.GTNewHorizons:ForgeGradle:1.2.5'
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'idea'
|
||||
id 'eclipse'
|
||||
id 'scala'
|
||||
id("org.ajoberstar.grgit") version("3.1.1")
|
||||
id("com.github.johnrengelman.shadow") version("4.0.4")
|
||||
id("com.palantir.git-version") version("0.12.3")
|
||||
id('de.undercouch.download') version('4.1.2')
|
||||
id("maven-publish")
|
||||
}
|
||||
|
||||
apply plugin: 'forge'
|
||||
@@ -62,6 +65,10 @@ idea {
|
||||
}
|
||||
}
|
||||
|
||||
if(JavaVersion.current() != JavaVersion.VERSION_1_8) {
|
||||
throw new GradleException("This project requires Java 8, but it's running on " + JavaVersion.current())
|
||||
}
|
||||
|
||||
checkPropertyExists("modName")
|
||||
checkPropertyExists("modId")
|
||||
checkPropertyExists("modGroup")
|
||||
@@ -83,33 +90,28 @@ checkPropertyExists("containsMixinsAndOrCoreModOnly")
|
||||
checkPropertyExists("usesShadowedDependencies")
|
||||
checkPropertyExists("developmentEnvironmentUserName")
|
||||
|
||||
def checkPropertyExists(String propertyName) {
|
||||
if (project.hasProperty(propertyName) == false) {
|
||||
throw new GradleException("This project requires a property \"" + propertyName + "\"! Please add it your \"gradle.properties\". You can find all properties and their description here: https://github.com/SinTh0r4s/ExampleMod1.7.10/blob/main/gradle.properties")
|
||||
}
|
||||
}
|
||||
|
||||
boolean noPublishedSources = project.findProperty("noPublishedSources") ? project.noPublishedSources.toBoolean() : false
|
||||
|
||||
String javaSourceDir = "src/main/java/"
|
||||
String scalaSourceDir = "src/main/scala/"
|
||||
|
||||
String targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/")
|
||||
String targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/")
|
||||
if((new File(targetPackageJava).exists() || new File(targetPackageScala).exists()) == false) {
|
||||
if((getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists()) == false) {
|
||||
throw new GradleException("Could not resolve \"modGroup\"! Could not find " + targetPackageJava + " or " + targetPackageScala)
|
||||
}
|
||||
|
||||
if(apiPackage) {
|
||||
targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/")
|
||||
targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/")
|
||||
if((new File(targetPackageJava).exists() || new File(targetPackageScala).exists()) == false) {
|
||||
if((getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists()) == false) {
|
||||
throw new GradleException("Could not resolve \"apiPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala)
|
||||
}
|
||||
}
|
||||
|
||||
if(accessTransformersFile) {
|
||||
String targetFile = "src/main/resources/META-INF/" + accessTransformersFile
|
||||
if(new File(targetFile).exists() == false) {
|
||||
if(getFile(targetFile).exists() == false) {
|
||||
throw new GradleException("Could not resolve \"accessTransformersFile\"! Could not find " + targetFile)
|
||||
}
|
||||
}
|
||||
@@ -121,14 +123,14 @@ if(usesMixins.toBoolean()) {
|
||||
|
||||
targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/")
|
||||
targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/")
|
||||
if((new File(targetPackageJava).exists() || new File(targetPackageScala).exists()) == false) {
|
||||
if((getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists()) == false) {
|
||||
throw new GradleException("Could not resolve \"mixinsPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala)
|
||||
}
|
||||
|
||||
String targetFileJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".java"
|
||||
String targetFileScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".scala"
|
||||
String targetFileScalaJava = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".java"
|
||||
if((new File(targetFileJava).exists() || new File(targetFileScala).exists() || new File(targetFileScalaJava).exists()) == false) {
|
||||
if((getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists()) == false) {
|
||||
throw new GradleException("Could not resolve \"mixinPlugin\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava)
|
||||
}
|
||||
}
|
||||
@@ -137,7 +139,7 @@ if(coreModClass) {
|
||||
String targetFileJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".java"
|
||||
String targetFileScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".scala"
|
||||
String targetFileScalaJava = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".java"
|
||||
if((new File(targetFileJava).exists() || new File(targetFileScala).exists() || new File(targetFileScalaJava).exists()) == false) {
|
||||
if((getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists()) == false) {
|
||||
throw new GradleException("Could not resolve \"coreModClass\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava)
|
||||
}
|
||||
}
|
||||
@@ -152,10 +154,25 @@ configurations.all {
|
||||
|
||||
// Fix Jenkins' Git: chmod a file should not be detected as a change and append a '.dirty' to the version
|
||||
'git config core.fileMode false'.execute()
|
||||
// Pulls version from git tag
|
||||
version = minecraftVersion + "-" + gitVersion()
|
||||
|
||||
// Pulls version first from the VERSION env and then git tag
|
||||
String identifiedVersion
|
||||
try {
|
||||
String versionOverride = System.getenv("VERSION") ?: null
|
||||
identifiedVersion = versionOverride == null ? gitVersion() : versionOverride
|
||||
version = minecraftVersion + "-" + identifiedVersion
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalStateException("This mod must be version controlled by Git AND the repository must provide at least one tag, or the VERSION override must be set!");
|
||||
}
|
||||
|
||||
group = modGroup
|
||||
archivesBaseName = modId
|
||||
if(project.hasProperty("customArchiveBaseName") && customArchiveBaseName) {
|
||||
archivesBaseName = customArchiveBaseName
|
||||
}
|
||||
else {
|
||||
archivesBaseName = modId
|
||||
}
|
||||
|
||||
minecraft {
|
||||
version = minecraftVersion + "-" + forgeVersion + "-" + minecraftVersion
|
||||
@@ -185,7 +202,9 @@ if(file("addon.gradle").exists()) {
|
||||
apply from: 'repositories.gradle'
|
||||
|
||||
configurations {
|
||||
implementation.extendsFrom(shadowImplementation)
|
||||
implementation.extendsFrom(shadowImplementation) // TODO: remove after all uses are refactored
|
||||
implementation.extendsFrom(shadowCompile)
|
||||
implementation.extendsFrom(shadeCompile)
|
||||
}
|
||||
|
||||
repositories {
|
||||
@@ -211,7 +230,7 @@ dependencies {
|
||||
annotationProcessor("com.google.code.gson:gson:2.8.6")
|
||||
annotationProcessor("org.spongepowered:mixin:0.8-SNAPSHOT")
|
||||
// using 0.8 to workaround a issue in 0.7 which fails mixin application
|
||||
compile("org.spongepowered:mixin:0.7.11-SNAPSHOT") {
|
||||
compile("com.github.GTNewHorizons:SpongePoweredMixin:0.7.12-GTNH") {
|
||||
// Mixin includes a lot of dependencies that are too up-to-date
|
||||
exclude module: "launchwrapper"
|
||||
exclude module: "guava"
|
||||
@@ -219,20 +238,19 @@ dependencies {
|
||||
exclude module: "commons-io"
|
||||
exclude module: "log4j-core"
|
||||
}
|
||||
compile("com.github.GTNewHorizons:SpongeMixins:1.3.3:dev")
|
||||
compile("com.github.GTNewHorizons:SpongeMixins:1.5.0")
|
||||
}
|
||||
}
|
||||
|
||||
apply from: 'dependencies.gradle'
|
||||
|
||||
def mixinConfigJson = "mixins." + modId + ".json"
|
||||
def mixingConfigRefMap = "mixins." + modId + ".refmap.json"
|
||||
def refMap = "${tasks.compileJava.temporaryDir}" + File.separator + mixingConfigRefMap
|
||||
def mixinSrg = "${tasks.reobf.temporaryDir}" + File.separator + "mixins.srg"
|
||||
|
||||
task generateAssets {
|
||||
if(usesMixins.toBoolean()) {
|
||||
new File(projectDir.toString() + "/src/main/resources/", mixinConfigJson).text = """{
|
||||
getFile("/src/main/resources/mixins." + modId + ".json").text = """{
|
||||
"required": true,
|
||||
"minVersion": "0.7.11",
|
||||
"package": "${modGroup}.${mixinsPackage}",
|
||||
@@ -252,16 +270,28 @@ task relocateShadowJar(type: ConfigureShadowRelocation) {
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
project.configurations.shadeCompile.each { dep ->
|
||||
from(project.zipTree(dep)) {
|
||||
exclude 'META-INF', 'META-INF/**'
|
||||
}
|
||||
}
|
||||
|
||||
manifest {
|
||||
attributes(getManifestAttributes())
|
||||
}
|
||||
|
||||
minimize() // This will only allow shading for actually used classes
|
||||
configurations = [project.configurations.shadowImplementation]
|
||||
configurations = [project.configurations.shadowImplementation, project.configurations.shadowCompile]
|
||||
dependsOn(relocateShadowJar)
|
||||
}
|
||||
|
||||
jar {
|
||||
project.configurations.shadeCompile.each { dep ->
|
||||
from(project.zipTree(dep)) {
|
||||
exclude 'META-INF', 'META-INF/**'
|
||||
}
|
||||
}
|
||||
|
||||
manifest {
|
||||
attributes(getManifestAttributes())
|
||||
}
|
||||
@@ -335,31 +365,35 @@ tasks.withType(JavaExec).configureEach {
|
||||
}
|
||||
|
||||
processResources
|
||||
{
|
||||
// this will ensure that this task is redone when the versions change.
|
||||
inputs.property "version", project.version
|
||||
inputs.property "mcversion", project.minecraft.version
|
||||
{
|
||||
// this will ensure that this task is redone when the versions change.
|
||||
inputs.property "version", project.version
|
||||
inputs.property "mcversion", project.minecraft.version
|
||||
|
||||
// replace stuff in mcmod.info, nothing else
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
include 'mcmod.info'
|
||||
// replace stuff in mcmod.info, nothing else
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
include 'mcmod.info'
|
||||
|
||||
// replace version and mcversion
|
||||
expand "minecraftVersion": project.minecraft.version,
|
||||
"modVersion": versionDetails().lastTag,
|
||||
"modId": modId,
|
||||
"modName": modName
|
||||
}
|
||||
// replace version and mcversion
|
||||
expand "minecraftVersion": project.minecraft.version,
|
||||
"modVersion": versionDetails().lastTag,
|
||||
"modId": modId,
|
||||
"modName": modName
|
||||
}
|
||||
|
||||
// copy everything else, thats not the mcmod.info
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
exclude 'mcmod.info'
|
||||
}
|
||||
}
|
||||
if(usesMixins.toBoolean()) {
|
||||
from refMap
|
||||
}
|
||||
|
||||
// copy everything else, thats not the mcmod.info
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
exclude 'mcmod.info'
|
||||
}
|
||||
}
|
||||
|
||||
def getManifestAttributes() {
|
||||
def manifestAttributes = [:]
|
||||
if(containsMixinsAndOrCoreModOnly.toBoolean() == false) {
|
||||
if(containsMixinsAndOrCoreModOnly.toBoolean() == false && (usesMixins.toBoolean() || coreModClass)) {
|
||||
manifestAttributes += ["FMLCorePluginContainsFMLMod": true]
|
||||
}
|
||||
|
||||
@@ -374,7 +408,7 @@ def getManifestAttributes() {
|
||||
if(usesMixins.toBoolean()) {
|
||||
manifestAttributes += [
|
||||
"TweakClass" : "org.spongepowered.asm.launch.MixinTweaker",
|
||||
"MixinConfigs" : mixinConfigJson,
|
||||
"MixinConfigs" : "mixins." + modId + ".json",
|
||||
"ForceLoadAsMod" : containsMixinsAndOrCoreModOnly.toBoolean() == false
|
||||
]
|
||||
}
|
||||
@@ -388,6 +422,12 @@ task sourcesJar(type: Jar) {
|
||||
}
|
||||
|
||||
task shadowDevJar(type: ShadowJar) {
|
||||
project.configurations.shadeCompile.each { dep ->
|
||||
from(project.zipTree(dep)) {
|
||||
exclude 'META-INF', 'META-INF/**'
|
||||
}
|
||||
}
|
||||
|
||||
from sourceSets.main.output
|
||||
getArchiveClassifier().set("dev")
|
||||
|
||||
@@ -396,7 +436,7 @@ task shadowDevJar(type: ShadowJar) {
|
||||
}
|
||||
|
||||
minimize() // This will only allow shading for actually used classes
|
||||
configurations = [project.configurations.shadowImplementation]
|
||||
configurations = [project.configurations.shadowImplementation, project.configurations.shadowCompile]
|
||||
}
|
||||
|
||||
task relocateShadowDevJar(type: ConfigureShadowRelocation) {
|
||||
@@ -411,6 +451,12 @@ task circularResolverJar(type: Jar) {
|
||||
}
|
||||
|
||||
task devJar(type: Jar) {
|
||||
project.configurations.shadeCompile.each { dep ->
|
||||
from(project.zipTree(dep)) {
|
||||
exclude 'META-INF', 'META-INF/**'
|
||||
}
|
||||
}
|
||||
|
||||
from sourceSets.main.output
|
||||
getArchiveClassifier().set("dev")
|
||||
|
||||
@@ -426,11 +472,11 @@ task devJar(type: Jar) {
|
||||
|
||||
task apiJar(type: Jar) {
|
||||
from (sourceSets.main.allJava) {
|
||||
include modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString() + '/**'
|
||||
include modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + '/**'
|
||||
}
|
||||
|
||||
from (sourceSets.main.output) {
|
||||
include modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString() + '/**'
|
||||
include modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + '/**'
|
||||
}
|
||||
|
||||
from (sourceSets.main.resources.srcDirs) {
|
||||
@@ -441,37 +487,92 @@ task apiJar(type: Jar) {
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives sourcesJar
|
||||
if(!noPublishedSources) {
|
||||
archives sourcesJar
|
||||
}
|
||||
archives devJar
|
||||
if(apiPackage) {
|
||||
archives apiJar
|
||||
}
|
||||
}
|
||||
|
||||
// The gradle metadata includes all of the additional deps that we disabled from POM generation (including forgeBin with no groupID),
|
||||
// and isn't strictly needed with the POM so just disable it.
|
||||
tasks.withType(GenerateModuleMetadata) {
|
||||
enabled = false
|
||||
}
|
||||
|
||||
|
||||
// publishing
|
||||
publishing {
|
||||
publications {
|
||||
maven(MavenPublication) {
|
||||
from components.java
|
||||
if(usesShadowedDependencies.toBoolean()) {
|
||||
artifact source: shadowJar, classifier: ""
|
||||
}
|
||||
if(!noPublishedSources) {
|
||||
artifact source: sourcesJar, classifier: "src"
|
||||
}
|
||||
artifact source: usesShadowedDependencies.toBoolean() ? shadowDevJar : devJar, classifier: "dev"
|
||||
if (apiPackage) {
|
||||
artifact source: apiJar, classifier: "api"
|
||||
}
|
||||
|
||||
groupId = System.getenv("ARTIFACT_GROUP_ID") ?: "com.github.GTNewHorizons"
|
||||
artifactId = System.getenv("ARTIFACT_ID") ?: project.name
|
||||
// Using the identified version, not project.version as it has the prepended 1.7.10
|
||||
version = System.getenv("RELEASE_VERSION") ?: identifiedVersion
|
||||
|
||||
// Remove all non GTNH deps here.
|
||||
// Original intention was to remove an invalid forgeBin being generated without a groupId (mandatory), but
|
||||
// it also removes all of the MC deps
|
||||
pom.withXml {
|
||||
Node pomNode = asNode()
|
||||
pomNode.dependencies.'*'.findAll() {
|
||||
it.groupId.text() != 'com.github.GTNewHorizons'
|
||||
}.each() {
|
||||
it.parent().remove(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url = "http://jenkins.usrv.eu:8081/nexus/content/repositories/releases"
|
||||
credentials {
|
||||
username = System.getenv("MAVEN_USER") ?: "NONE"
|
||||
password = System.getenv("MAVEN_PASSWORD") ?: "NONE"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Updating
|
||||
task updateBuildScript {
|
||||
doLast {
|
||||
if (updateBuildScript()) return
|
||||
if (performBuildScriptUpdate(projectDir.toString())) return
|
||||
|
||||
print("Build script already up-to-date!")
|
||||
}
|
||||
}
|
||||
|
||||
if (isNewBuildScriptVersionAvailable()) {
|
||||
if (isNewBuildScriptVersionAvailable(projectDir.toString())) {
|
||||
if (autoUpdateBuildScript.toBoolean()) {
|
||||
updateBuildScript()
|
||||
performBuildScriptUpdate(projectDir.toString())
|
||||
} else {
|
||||
println("Build script update available! Run 'gradle updateBuildScript'")
|
||||
}
|
||||
}
|
||||
|
||||
static URL availableBuildScriptUrl() {
|
||||
new URL("https://raw.githubusercontent.com/SinTh0r4s/ExampleMod1.7.10/main/build.gradle")
|
||||
new URL("https://raw.githubusercontent.com/GTNewHorizons/ExampleMod1.7.10/main/build.gradle")
|
||||
}
|
||||
|
||||
static boolean updateBuildScript() {
|
||||
if (isNewBuildScriptVersionAvailable()) {
|
||||
def buildscriptFile = new File("build.gradle")
|
||||
boolean performBuildScriptUpdate(String projectDir) {
|
||||
if (isNewBuildScriptVersionAvailable(projectDir)) {
|
||||
def buildscriptFile = getFile("build.gradle")
|
||||
availableBuildScriptUrl().withInputStream { i -> buildscriptFile.withOutputStream { it << i } }
|
||||
print("Build script updated. Please REIMPORT the project or RESTART your IDE!")
|
||||
return true
|
||||
@@ -479,10 +580,10 @@ static boolean updateBuildScript() {
|
||||
return false
|
||||
}
|
||||
|
||||
static boolean isNewBuildScriptVersionAvailable() {
|
||||
boolean isNewBuildScriptVersionAvailable(String projectDir) {
|
||||
Map parameters = ["connectTimeout": 2000, "readTimeout": 2000]
|
||||
|
||||
String currentBuildScript = new File("build.gradle").getText()
|
||||
String currentBuildScript = getFile("build.gradle").getText()
|
||||
String currentBuildScriptHash = getVersionHash(currentBuildScript)
|
||||
String availableBuildScript = availableBuildScriptUrl().newInputStream(parameters).getText()
|
||||
String availableBuildScriptHash = getVersionHash(availableBuildScript)
|
||||
@@ -503,3 +604,50 @@ configure(updateBuildScript) {
|
||||
group = 'forgegradle'
|
||||
description = 'Updates the build script to the latest version'
|
||||
}
|
||||
|
||||
// Deobfuscation
|
||||
|
||||
def deobf(String sourceURL, String fileName) {
|
||||
def bon2File = "$projectDir/deobf/BON2-2.5.0.jar"
|
||||
def cacheFile = "$projectDir/deobf/out/" + fileName + ".jar"
|
||||
def deobfFile = "$projectDir/deobf/out/" + fileName + "-deobf.jar"
|
||||
|
||||
if(file(deobfFile).exists()) {
|
||||
return files(deobfFile)
|
||||
}
|
||||
|
||||
download {
|
||||
src 'https://github.com/GTNewHorizons/BON2/releases/download/2.5.0/BON2-2.5.0.CUSTOM-all.jar'
|
||||
dest bon2File
|
||||
quiet true
|
||||
overwrite false
|
||||
}
|
||||
|
||||
download {
|
||||
src sourceURL
|
||||
dest cacheFile
|
||||
quiet true
|
||||
overwrite false
|
||||
}
|
||||
|
||||
exec {
|
||||
commandLine 'java', '-jar', bon2File, '--inputJar', cacheFile, '--outputJar', deobfFile, '--mcVer', '1.7.10', '--mappingsVer', 'stable_12', '--notch'
|
||||
workingDir "$projectDir/deobf"
|
||||
standardOutput = new ByteArrayOutputStream()
|
||||
}
|
||||
|
||||
delete(cacheFile)
|
||||
return files(deobfFile)
|
||||
}
|
||||
|
||||
// Helper methods
|
||||
|
||||
def checkPropertyExists(String propertyName) {
|
||||
if (project.hasProperty(propertyName) == false) {
|
||||
throw new GradleException("This project requires a property \"" + propertyName + "\"! Please add it your \"gradle.properties\". You can find all properties and their description here: https://github.com/GTNewHorizons/ExampleMod1.7.10/blob/main/gradle.properties")
|
||||
}
|
||||
}
|
||||
|
||||
def getFile(String relativePath) {
|
||||
return new File(projectDir, relativePath)
|
||||
}
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
// Add your dependencies here
|
||||
|
||||
dependencies {
|
||||
compile("com.github.GTNewHorizons:CodeChickenLib:master-SNAPSHOT:dev")
|
||||
compile("com.github.GTNewHorizons:CodeChickenCore:master-SNAPSHOT:dev")
|
||||
compile("com.github.GTNewHorizons:CodeChickenLib:1.1.5.1:dev")
|
||||
compile("com.github.GTNewHorizons:CodeChickenCore:1.1.3:dev")
|
||||
shadowImplementation("org.apache.commons:commons-csv:1.5")
|
||||
}
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven {
|
||||
name = "GTNH Maven"
|
||||
url = "http://jenkins.usrv.eu:8081/nexus/content/groups/public/"
|
||||
}
|
||||
maven {
|
||||
url = "https://jitpack.io"
|
||||
}
|
||||
|
||||
@@ -1,174 +1,818 @@
|
||||
package codechicken.nei;
|
||||
|
||||
import codechicken.core.CommonUtils;
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
import codechicken.nei.util.NBTJson;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
import codechicken.nei.recipe.BookmarkRecipeId;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import cpw.mods.fml.common.registry.GameData;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import static codechicken.lib.gui.GuiDraw.getMousePosition;
|
||||
import static codechicken.lib.gui.GuiDraw.drawRect;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
* 1) Bookmark button to toggle visibility
|
||||
*/
|
||||
public class BookmarkPanel extends ItemPanel {
|
||||
public class BookmarkPanel extends ItemPanel
|
||||
{
|
||||
|
||||
public void init() {
|
||||
protected File bookmarkFile;
|
||||
protected boolean bookmarksIsLoaded = false;
|
||||
public int sortedStackIndex = -1;
|
||||
public int sortedNamespaceIndex = -1;
|
||||
|
||||
|
||||
public Button namespacePrev;
|
||||
public Button namespaceNext;
|
||||
public Label namespaceLabel;
|
||||
|
||||
|
||||
protected ArrayList<BookmarkGrid> namespaces = new ArrayList<>();
|
||||
public int activeNamespaceIndex = 0;
|
||||
|
||||
|
||||
protected static class BookmarkStackMeta
|
||||
{
|
||||
public int factor;
|
||||
public BookmarkRecipeId recipeId;
|
||||
public boolean ingredient = false;
|
||||
|
||||
|
||||
public BookmarkStackMeta(BookmarkRecipeId recipeId, int count, boolean ingredient)
|
||||
{
|
||||
this.recipeId = recipeId;
|
||||
this.factor = count;
|
||||
this.ingredient = ingredient;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected static class BookmarkGrid extends ItemsGrid
|
||||
{
|
||||
protected List<BookmarkStackMeta> metadata = new ArrayList<>();
|
||||
|
||||
public int indexOf(ItemStack stackA, BookmarkRecipeId recipeId)
|
||||
{
|
||||
final boolean useNBT = NEIClientConfig.useNBTInBookmarks();
|
||||
|
||||
for (int idx = 0; idx < realItems.size(); idx++) {
|
||||
final BookmarkStackMeta meta = getMetadata(idx);
|
||||
if ((recipeId == null && meta.recipeId == null || recipeId != null && meta.recipeId != null && recipeId.equals(meta.recipeId)) && StackInfo.equalItemAndNBT(stackA, realItems.get(idx), useNBT)) {
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public BookmarkStackMeta getMetadata(int idx)
|
||||
{
|
||||
return metadata.get(idx);
|
||||
}
|
||||
|
||||
public void addItem(ItemStack stackA, BookmarkStackMeta meta)
|
||||
{
|
||||
realItems.add(stackA);
|
||||
metadata.add(meta);
|
||||
}
|
||||
|
||||
public void replaceItem(int idx, ItemStack stack)
|
||||
{
|
||||
realItems.set(idx, stack);
|
||||
}
|
||||
|
||||
public void removeRecipe(int idx, boolean removeFullRecipe)
|
||||
{
|
||||
final BookmarkStackMeta meta = getMetadata(idx);
|
||||
|
||||
if (removeFullRecipe && meta.recipeId != null) {
|
||||
removeRecipe(meta.recipeId);
|
||||
} else {
|
||||
removeItem(idx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void removeRecipe(BookmarkRecipeId recipeIdA)
|
||||
{
|
||||
BookmarkRecipeId recipeIdB;
|
||||
|
||||
for (int slotIndex = metadata.size() - 1; slotIndex >= 0; slotIndex--) {
|
||||
recipeIdB = getRecipeId(slotIndex);
|
||||
|
||||
if (recipeIdB != null && recipeIdA.equals(recipeIdB)) {
|
||||
removeItem(slotIndex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected boolean removeItem(int idx)
|
||||
{
|
||||
realItems.remove(idx);
|
||||
metadata.remove(idx);
|
||||
return true;
|
||||
}
|
||||
|
||||
public BookmarkRecipeId getRecipeId(int idx)
|
||||
{
|
||||
return getMetadata(idx).recipeId;
|
||||
}
|
||||
|
||||
public BookmarkRecipeId findRecipeId(ItemStack stackA)
|
||||
{
|
||||
final boolean useNBT = NEIClientConfig.useNBTInBookmarks();
|
||||
|
||||
for (int idx = 0; idx < realItems.size(); idx++) {
|
||||
if (StackInfo.equalItemAndNBT(stackA, getItem(idx), useNBT)) {
|
||||
return getRecipeId(idx);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void moveItem(int src, int dst)
|
||||
{
|
||||
realItems.add(dst, realItems.remove(src));
|
||||
metadata.add(dst, metadata.remove(src));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void drawItem(Rectangle4i rect, int idx, ItemPanelSlot focus)
|
||||
{
|
||||
|
||||
if (LayoutManager.bookmarkPanel.sortedNamespaceIndex == LayoutManager.bookmarkPanel.activeNamespaceIndex && LayoutManager.bookmarkPanel.sortedStackIndex == idx) {
|
||||
drawRect(rect.x, rect.y, rect.w, rect.h, 0xee555555);//highlight
|
||||
} else {
|
||||
|
||||
if (focus != null) {
|
||||
|
||||
if (focus.slotIndex == idx) {
|
||||
drawRect(rect.x, rect.y, rect.w, rect.h, 0xee555555);//highlight
|
||||
} else if (
|
||||
LayoutManager.bookmarkPanel.sortedStackIndex == -1 && //disabled when sorting
|
||||
NEIClientUtils.shiftKey() && //show only with shift key
|
||||
getRecipeId(focus.slotIndex) != null && getRecipeId(idx) != null && getRecipeId(focus.slotIndex).equals(getRecipeId(idx))//is some recipeId
|
||||
) {
|
||||
drawRect(rect.x, rect.y, rect.w, rect.h, getMetadata(idx).ingredient? 0x88b3b300: 0x88009933);//highlight recipe
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GuiContainerManager.drawItem(rect.x + 1, rect.y + 1, getItem(idx), true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public BookmarkPanel()
|
||||
{
|
||||
grid = new BookmarkGrid();
|
||||
}
|
||||
|
||||
public void init()
|
||||
{
|
||||
super.init();
|
||||
|
||||
namespaceLabel = new Label("1", true);
|
||||
|
||||
namespacePrev = new Button("Prev")
|
||||
{
|
||||
public boolean onButtonPress(boolean rightclick)
|
||||
{
|
||||
|
||||
if (rightclick) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return prevNamespace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRenderLabel()
|
||||
{
|
||||
return "<";
|
||||
}
|
||||
};
|
||||
|
||||
namespaceNext = new Button("Next")
|
||||
{
|
||||
public boolean onButtonPress(boolean rightclick)
|
||||
{
|
||||
if (rightclick) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return nextNamespace();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRenderLabel()
|
||||
{
|
||||
return ">";
|
||||
}
|
||||
};
|
||||
|
||||
namespaces.add(new BookmarkGrid());
|
||||
grid = namespaces.get(activeNamespaceIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setItems() {
|
||||
realItems = _items;
|
||||
public String getLabelText()
|
||||
{
|
||||
return super.getLabelText() + " [" + grid.size() + "]";
|
||||
}
|
||||
|
||||
public String getLabelText() {
|
||||
return super.getLabelText() + " [" + realItems.size() + "]";
|
||||
public void addOrRemoveItem(ItemStack stackA)
|
||||
{
|
||||
addOrRemoveItem(stackA, "", null);
|
||||
}
|
||||
|
||||
public void addOrRemoveItem(ItemStack item) {
|
||||
ItemStack normalized = normalize(item);
|
||||
if(!remove(normalized)) {
|
||||
_items.add(normalized);
|
||||
public void addOrRemoveItem(ItemStack stackover, String handlerName, List<PositionedStack> ingredients)
|
||||
{
|
||||
loadBookmarksIfNeeded();
|
||||
|
||||
final Point mousePos = getMousePosition();
|
||||
final ItemPanelSlot slot = getSlotMouseOver(mousePos.x, mousePos.y);
|
||||
final boolean addFullRecipe = NEIClientUtils.shiftKey();
|
||||
final BookmarkGrid BGrid = (BookmarkGrid) grid;
|
||||
|
||||
if (slot != null && StackInfo.equalItemAndNBT(slot.item, stackover, true)) {
|
||||
BGrid.removeRecipe(slot.slotIndex, addFullRecipe);
|
||||
} else {
|
||||
final boolean saveStackSize = NEIClientUtils.controlKey();
|
||||
final NBTTagCompound nbTagA = StackInfo.itemStackToNBT(stackover, saveStackSize);
|
||||
final ItemStack normalizedA = StackInfo.loadFromNBT(nbTagA);
|
||||
BookmarkRecipeId recipeId = null;
|
||||
|
||||
if (NEIClientConfig.saveCurrentRecipeInBookmarksEnabled() && handlerName != "" && ingredients != null && ingredients.size() > 0) {
|
||||
recipeId = new BookmarkRecipeId(handlerName, ingredients);
|
||||
}
|
||||
|
||||
final int idx = BGrid.indexOf(normalizedA, recipeId);
|
||||
|
||||
if (idx != -1) {
|
||||
BGrid.removeRecipe(idx, addFullRecipe);
|
||||
} else {
|
||||
|
||||
if (addFullRecipe && handlerName != "" && ingredients != null) {
|
||||
final Map<NBTTagCompound, Integer> unique = new HashMap<>();
|
||||
final ArrayList<NBTTagCompound> sorted = new ArrayList<>();
|
||||
|
||||
BGrid.removeRecipe(recipeId);
|
||||
|
||||
for (PositionedStack stack : ingredients) {
|
||||
final NBTTagCompound nbTag = StackInfo.itemStackToNBT(stack.item, saveStackSize);
|
||||
|
||||
if (unique.get(nbTag) == null) {
|
||||
unique.put(nbTag, 1);
|
||||
sorted.add(nbTag);
|
||||
} else if (saveStackSize) {
|
||||
unique.put(nbTag, unique.get(nbTag) + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (NBTTagCompound nbTag : sorted) {
|
||||
nbTag.setInteger("Count", nbTag.getInteger("Count") * unique.get(nbTag));
|
||||
BGrid.addItem(StackInfo.loadFromNBT(nbTag), new BookmarkStackMeta(recipeId, nbTag.getInteger("Count"), true));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BGrid.addItem(normalizedA, new BookmarkStackMeta(recipeId, nbTagA.getInteger("Count"), false));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
fixCountOfNamespaces();
|
||||
saveBookmarks();
|
||||
}
|
||||
|
||||
public static NBTTagCompound itemStackToNBT(ItemStack stack, NBTTagCompound nbTag)
|
||||
public BookmarkRecipeId getBookmarkRecipeId(ItemStack stackA)
|
||||
{
|
||||
String strId = Item.itemRegistry.getNameForObject(stack.getItem());
|
||||
nbTag.setString("strId", strId);
|
||||
nbTag.setByte("Count", (byte)stack.stackSize);
|
||||
nbTag.setShort("Damage", (short)stack.getItemDamage());
|
||||
|
||||
if (stack.stackTagCompound != null)
|
||||
{
|
||||
nbTag.setTag("tag", stack.stackTagCompound);
|
||||
final Point mousePos = getMousePosition();
|
||||
final ItemPanelSlot slot = getSlotMouseOver(mousePos.x, mousePos.y);
|
||||
|
||||
if (slot != null && StackInfo.equalItemAndNBT(slot.item, stackA, true)) {
|
||||
return ((BookmarkGrid) grid).getRecipeId(slot.slotIndex);
|
||||
}
|
||||
|
||||
return nbTag;
|
||||
BookmarkRecipeId recipeId = ((BookmarkGrid) grid).findRecipeId(stackA);
|
||||
|
||||
if (recipeId == null) {
|
||||
|
||||
for (int idx = 0; idx < namespaces.size() && recipeId == null; idx++) {
|
||||
if (idx == activeNamespaceIndex) continue;
|
||||
recipeId = namespaces.get(idx).findRecipeId(stackA);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return recipeId;
|
||||
}
|
||||
|
||||
public static ItemStack loadFromNBT(NBTTagCompound nbtTag)
|
||||
protected String getNamespaceLabelText(boolean shortFormat)
|
||||
{
|
||||
if (!nbtTag.hasKey("id")) {
|
||||
final short id = (short)GameData.getItemRegistry().getId(nbtTag.getString("strId"));
|
||||
nbtTag.setShort("id", id);
|
||||
}
|
||||
ItemStack stack = ItemStack.loadItemStackFromNBT(nbtTag);
|
||||
return stack;
|
||||
String activePage = String.valueOf(activeNamespaceIndex + 1);
|
||||
|
||||
return shortFormat? activePage: (activePage + "/" + fixCountOfNamespaces());
|
||||
}
|
||||
|
||||
public void saveBookmarks() {
|
||||
List<String> strings = new ArrayList<>();
|
||||
for (ItemStack item:_items) {
|
||||
strings.add(NBTJson.toJson(itemStackToNBT(item, new NBTTagCompound())));
|
||||
protected int fixCountOfNamespaces()
|
||||
{
|
||||
|
||||
if (namespaces.get(namespaces.size() - 1).size() > 0) {
|
||||
namespaces.add(new BookmarkGrid());
|
||||
} else if (activeNamespaceIndex == namespaces.size() - 2 && grid.size() == 0) {
|
||||
namespaces.remove(namespaces.size() - 1);
|
||||
}
|
||||
File file = NEIClientConfig.bookmarkFile;
|
||||
if(file != null) {
|
||||
try(FileWriter writer = new FileWriter(file)) {
|
||||
|
||||
return namespaces.size();
|
||||
}
|
||||
|
||||
protected boolean removeEmptyNamespaces()
|
||||
{
|
||||
|
||||
if (activeNamespaceIndex != namespaces.size() - 1 && grid.size() == 0) {
|
||||
namespaces.remove(activeNamespaceIndex);
|
||||
grid = namespaces.get(activeNamespaceIndex);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean prevNamespace()
|
||||
{
|
||||
if (!bookmarksIsLoaded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fixCountOfNamespaces();
|
||||
removeEmptyNamespaces();
|
||||
|
||||
if (activeNamespaceIndex == 0) {
|
||||
activeNamespaceIndex = namespaces.size() - 1;
|
||||
} else {
|
||||
activeNamespaceIndex --;
|
||||
}
|
||||
|
||||
grid = namespaces.get(activeNamespaceIndex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean nextNamespace()
|
||||
{
|
||||
if (!bookmarksIsLoaded) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (removeEmptyNamespaces()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (activeNamespaceIndex == fixCountOfNamespaces() - 1) {
|
||||
activeNamespaceIndex = 0;
|
||||
} else {
|
||||
activeNamespaceIndex ++;
|
||||
}
|
||||
|
||||
grid = namespaces.get(activeNamespaceIndex);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setBookmarkFile(String worldPath)
|
||||
{
|
||||
|
||||
final File dir = new File(CommonUtils.getMinecraftDir(), "saves/NEI/" + worldPath);
|
||||
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
|
||||
bookmarkFile = new File(dir, "bookmarks.ini");
|
||||
|
||||
if (!bookmarkFile.exists()) {
|
||||
final File globalBookmarks = new File(CommonUtils.getMinecraftDir(), "saves/NEI/global/bookmarks.ini");
|
||||
final File configBookmarks = new File(NEIClientConfig.configDir, "bookmarks.ini");
|
||||
final File defaultBookmarks = configBookmarks.exists()? configBookmarks: globalBookmarks;
|
||||
|
||||
if (defaultBookmarks.exists()) {
|
||||
|
||||
try {
|
||||
bookmarkFile.createNewFile();
|
||||
|
||||
InputStream src = new FileInputStream(defaultBookmarks);
|
||||
OutputStream dst = new FileOutputStream(bookmarkFile);
|
||||
|
||||
IOUtils.copy(src, dst);
|
||||
|
||||
src.close();
|
||||
dst.close();
|
||||
|
||||
} catch(IOException e) {}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bookmarksIsLoaded = false;
|
||||
}
|
||||
|
||||
public void saveBookmarks()
|
||||
{
|
||||
|
||||
ArrayList<String> strings = new ArrayList<>();
|
||||
|
||||
for (int grpIdx = 0; grpIdx < namespaces.size() - 1; grpIdx++) {
|
||||
final BookmarkGrid grid = namespaces.get(grpIdx);
|
||||
|
||||
if (grpIdx > 0) {
|
||||
strings.add("");//namespace separator; ignore first namespace
|
||||
}
|
||||
|
||||
for (int idx = 0; idx < grid.size(); idx++) {
|
||||
|
||||
try {
|
||||
final NBTTagCompound nbTag = StackInfo.itemStackToNBT(grid.getItem(idx));
|
||||
|
||||
if (nbTag != null) {
|
||||
JsonObject row = new JsonObject();
|
||||
BookmarkStackMeta meta = grid.getMetadata(idx);
|
||||
|
||||
row.add("item", NBTJson.toJsonObject(nbTag));
|
||||
row.add("factor", new JsonPrimitive(meta.factor));
|
||||
row.add("ingredient", new JsonPrimitive(meta.ingredient));
|
||||
|
||||
if (meta.recipeId != null) {
|
||||
row.add("recipeId", meta.recipeId.toJsonObject());
|
||||
}
|
||||
|
||||
strings.add(NBTJson.toJson(row));
|
||||
}
|
||||
|
||||
} catch (JsonSyntaxException e) {
|
||||
NEIClientConfig.logger.error("Failed to stringify bookmarked ItemStack to json string");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (bookmarkFile != null) {
|
||||
try(FileWriter writer = new FileWriter(bookmarkFile)) {
|
||||
IOUtils.writeLines(strings, "\n", writer);
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Filed to save bookmarks list to file {}", file, e);
|
||||
NEIClientConfig.logger.error("Filed to save bookmarks list to file {}", bookmarkFile, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void loadBookmarks() {
|
||||
File file = NEIClientConfig.bookmarkFile;
|
||||
if (file == null || !file.exists()) {
|
||||
public void loadBookmarksIfNeeded()
|
||||
{
|
||||
|
||||
if (bookmarksIsLoaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
bookmarksIsLoaded = true;
|
||||
|
||||
if (bookmarkFile == null || !bookmarkFile.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> itemStrings;
|
||||
try (FileReader reader = new FileReader(file)) {
|
||||
NEIClientConfig.logger.info("Loading bookmarks from file {}", file);
|
||||
try (FileReader reader = new FileReader(bookmarkFile)) {
|
||||
NEIClientConfig.logger.info("Loading bookmarks from file {}", bookmarkFile);
|
||||
itemStrings = IOUtils.readLines(reader);
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to load bookmarks from file {}", file, e);
|
||||
NEIClientConfig.logger.error("Failed to load bookmarks from file {}", bookmarkFile, e);
|
||||
return;
|
||||
}
|
||||
_items.clear();
|
||||
JsonParser parser = new JsonParser();
|
||||
|
||||
namespaces.clear();
|
||||
namespaces.add(new BookmarkGrid());
|
||||
activeNamespaceIndex = 0;
|
||||
|
||||
final JsonParser parser = new JsonParser();
|
||||
|
||||
for (String itemStr: itemStrings) {
|
||||
try {
|
||||
NBTTagCompound itemStackNBT = (NBTTagCompound) NBTJson.toNbt(parser.parse(itemStr));
|
||||
ItemStack itemStack = loadFromNBT(itemStackNBT);
|
||||
|
||||
if (itemStr.isEmpty()) {
|
||||
|
||||
if (namespaces.get(activeNamespaceIndex).size() > 0) {
|
||||
//do not create empty namespaces
|
||||
namespaces.add(new BookmarkGrid());
|
||||
activeNamespaceIndex++;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
JsonObject jsonObject = parser.parse(itemStr).getAsJsonObject();
|
||||
BookmarkRecipeId recipeId = null;
|
||||
NBTTagCompound itemStackNBT;
|
||||
|
||||
if (jsonObject.get("item") != null) {
|
||||
itemStackNBT = (NBTTagCompound) NBTJson.toNbt(jsonObject.get("item"));
|
||||
} else {// old format
|
||||
itemStackNBT = (NBTTagCompound) NBTJson.toNbt(jsonObject);
|
||||
}
|
||||
|
||||
if (jsonObject.get("recipeId") != null && jsonObject.get("recipeId") instanceof JsonObject) {
|
||||
recipeId = new BookmarkRecipeId((JsonObject) jsonObject.get("recipeId"));
|
||||
}
|
||||
|
||||
ItemStack itemStack = StackInfo.loadFromNBT(itemStackNBT);
|
||||
|
||||
|
||||
if (itemStack != null) {
|
||||
_items.add(itemStack);
|
||||
namespaces.get(activeNamespaceIndex).addItem(itemStack, new BookmarkStackMeta(
|
||||
recipeId,
|
||||
jsonObject.has("factor")? jsonObject.get("factor").getAsInt(): 1,
|
||||
jsonObject.has("ingredient")? jsonObject.get("ingredient").getAsBoolean(): false
|
||||
));
|
||||
} else {
|
||||
NEIClientConfig.logger.warn("Failed to load bookmarked ItemStack from json string, the item no longer exists:\n{}", itemStr);
|
||||
}
|
||||
|
||||
} catch (IllegalArgumentException | JsonSyntaxException e) {
|
||||
NEIClientConfig.logger.error("Failed to load bookmarked ItemStack from json string:\n{}", itemStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected ItemStack normalize(ItemStack item) {
|
||||
ItemStack copy = item.copy();
|
||||
copy.stackSize = 1;
|
||||
return copy;
|
||||
}
|
||||
private boolean remove(ItemStack item) {
|
||||
int i = 0;
|
||||
for (ItemStack existing : _items) {
|
||||
if (existing == item || existing.isItemEqual(item)) {
|
||||
_items.remove(i);
|
||||
return true;
|
||||
}
|
||||
i++;
|
||||
if (namespaces.get(activeNamespaceIndex).size() == 0) {
|
||||
activeNamespaceIndex = Math.max(activeNamespaceIndex - 1, 0);
|
||||
}
|
||||
return false;
|
||||
|
||||
grid = namespaces.get(activeNamespaceIndex);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void resize(GuiContainer gui)
|
||||
{
|
||||
loadBookmarksIfNeeded();
|
||||
super.resize(gui);
|
||||
|
||||
final int buttonHeight = 16;
|
||||
final int buttonWidth = 16;
|
||||
|
||||
final int buttonTop = gui.height - buttonHeight - 2;
|
||||
final int leftBorder = LayoutManager.bookmarksButton.x + LayoutManager.bookmarksButton.w + 2;
|
||||
final int rightBorder = x + w;
|
||||
final int center = leftBorder + (rightBorder - leftBorder) / 2;
|
||||
int labelWidth = 2;
|
||||
|
||||
namespacePrev.h = namespaceNext.h = buttonHeight;
|
||||
namespacePrev.w = namespaceNext.w = buttonWidth;
|
||||
namespacePrev.y = namespaceNext.y = buttonTop;
|
||||
|
||||
|
||||
if (rightBorder - leftBorder >= 70) {
|
||||
labelWidth = 36;
|
||||
namespaceLabel.text = getNamespaceLabelText(false);
|
||||
} else {
|
||||
labelWidth = 18;
|
||||
namespaceLabel.text = getNamespaceLabelText(true);
|
||||
}
|
||||
|
||||
namespaceLabel.y = buttonTop + 5;
|
||||
namespaceLabel.x = center;
|
||||
|
||||
namespacePrev.x = center - labelWidth / 2 - 2 - namespacePrev.w;
|
||||
namespaceNext.x = center + labelWidth / 2 + 2;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getX(GuiContainer gui) {
|
||||
public void setVisible()
|
||||
{
|
||||
super.setVisible();
|
||||
|
||||
LayoutManager.addWidget(namespacePrev);
|
||||
LayoutManager.addWidget(namespaceNext);
|
||||
LayoutManager.addWidget(namespaceLabel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMarginLeft(GuiContainer gui)
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMarginLeft() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getButtonTop() {
|
||||
public int getMarginTop(GuiContainer gui)
|
||||
{
|
||||
LayoutStyleMinecraft layout = (LayoutStyleMinecraft)LayoutManager.getLayoutStyle();
|
||||
return 2 + (((int)Math.ceil((double)layout.buttonCount / layout.numButtons)) * 18);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNextX(GuiContainer gui) {
|
||||
return gui.width - prev.w - 2 - ((gui.xSize + gui.width) /2 + 2) - 16;
|
||||
public int getWidth(GuiContainer gui)
|
||||
{
|
||||
return LayoutManager.getLeftSize(gui) - ((gui.xSize + gui.width) / 2 + 3) - 16;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPrevX(GuiContainer gui) {
|
||||
return 2;
|
||||
public int getHeight(GuiContainer gui)
|
||||
{
|
||||
// - 19 = 22 + 1 -> input in bottom
|
||||
return gui.height - getMarginTop(gui) - 23;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void mouseDragged(int mousex, int mousey, int button, long heldTime)
|
||||
{
|
||||
|
||||
if (button == 0 && NEIClientUtils.shiftKey() && mouseDownSlot >= 0) {
|
||||
ItemPanelSlot mouseOverSlot = getSlotMouseOver(mousex, mousey);
|
||||
|
||||
if (sortedStackIndex == -1) {
|
||||
final ItemStack stack = grid.getItem(mouseDownSlot);
|
||||
|
||||
if (stack != null && (mouseOverSlot == null || mouseOverSlot.slotIndex != mouseDownSlot || heldTime > 250)) {
|
||||
sortedNamespaceIndex = activeNamespaceIndex;
|
||||
sortedStackIndex = mouseDownSlot;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (mouseOverSlot == null && sortedNamespaceIndex != activeNamespaceIndex) {
|
||||
mouseOverSlot = getNextSlot(mousex, mousey);
|
||||
}
|
||||
|
||||
if (mouseOverSlot != null) {
|
||||
|
||||
if (sortedNamespaceIndex != activeNamespaceIndex) {
|
||||
BookmarkGrid BGrid = namespaces.get(sortedNamespaceIndex);
|
||||
BookmarkStackMeta meta = BGrid.getMetadata(sortedStackIndex);
|
||||
ItemStack stack = BGrid.getItem(sortedStackIndex);
|
||||
BGrid.removeItem(sortedStackIndex);
|
||||
|
||||
((BookmarkGrid) grid).addItem(stack, meta);
|
||||
|
||||
sortedNamespaceIndex = activeNamespaceIndex;
|
||||
sortedStackIndex = grid.size() - 1;
|
||||
}
|
||||
|
||||
if (mouseOverSlot.slotIndex != sortedStackIndex) {
|
||||
((BookmarkGrid) grid).moveItem(sortedStackIndex, mouseOverSlot.slotIndex);
|
||||
sortedStackIndex = mouseOverSlot.slotIndex;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
super.mouseDragged(mousex, mousey, button, heldTime);
|
||||
}
|
||||
|
||||
private ItemPanelSlot getNextSlot(int mousex, int mousey)
|
||||
{
|
||||
int idx = grid.getPage() * grid.getPerPage() - grid.getPerPage();
|
||||
int gSize = grid.size();
|
||||
|
||||
for (int i = 0; i < grid.getRows() * grid.getColumns() && idx <= gSize; i++) {
|
||||
|
||||
if (!grid.isInvalidSlot(i)) {
|
||||
|
||||
if (idx == gSize && grid.getSlotRect(i).contains(mousex, mousey)) {
|
||||
return new ItemPanelSlot(idx, null);
|
||||
}
|
||||
|
||||
idx++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPageX(GuiContainer gui) {
|
||||
return gui.guiLeft * 3 / 2 + gui.xSize + 1 - ((gui.xSize + gui.width) / 2 + 2) - 16;
|
||||
public void postDraw(int mousex, int mousey)
|
||||
{
|
||||
|
||||
if (sortedStackIndex != -1) {
|
||||
GuiContainerManager.drawItems.zLevel += 100;
|
||||
GuiContainerManager.drawItem(mousex - 8, mousey - 8, namespaces.get(sortedNamespaceIndex).getItem(sortedStackIndex).copy(), true);
|
||||
GuiContainerManager.drawItems.zLevel -= 100;
|
||||
}
|
||||
|
||||
super.postDraw(mousex, mousey);
|
||||
}
|
||||
|
||||
public int getHightAdjustment() {
|
||||
return 0;
|
||||
@Override
|
||||
protected ItemStack getDraggedStackWithQuantity(int mouseDownSlot)
|
||||
{
|
||||
ItemStack stack = grid.getItem(mouseDownSlot);
|
||||
|
||||
return stack != null? stack.copy(): null;
|
||||
}
|
||||
|
||||
public int getWidth(GuiContainer gui) {
|
||||
return LayoutManager.getLeftSize(gui) - ( (gui.xSize + gui.width) / 2 + 3 ) - 16;
|
||||
@Override
|
||||
public void mouseUp(int mousex, int mousey, int button)
|
||||
{
|
||||
if (sortedStackIndex != -1) {
|
||||
sortedNamespaceIndex = -1;
|
||||
sortedStackIndex = -1;
|
||||
mouseDownSlot = -1;
|
||||
saveBookmarks();
|
||||
} else {
|
||||
super.mouseUp(mousex, mousey, button);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onMouseWheel(int shift, int mousex, int mousey)
|
||||
{
|
||||
|
||||
if (new Rectangle4i(namespacePrev.x, namespacePrev.y, namespaceNext.x + namespaceNext.w - namespacePrev.x, namespacePrev.h).contains(mousex, mousey)) {
|
||||
|
||||
if (shift > 0) {
|
||||
prevNamespace();
|
||||
} else {
|
||||
nextNamespace();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!contains(mousex, mousey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NEIClientUtils.controlKey()) {
|
||||
final ItemPanelSlot slot = getSlotMouseOver(mousex, mousey);
|
||||
|
||||
if (slot != null) {
|
||||
final BookmarkGrid BGrid = (BookmarkGrid)grid;
|
||||
final BookmarkRecipeId recipeId = BGrid.getRecipeId(slot.slotIndex);
|
||||
final BookmarkStackMeta meta = BGrid.getMetadata(slot.slotIndex);
|
||||
final boolean addFullRecipe = NEIClientUtils.shiftKey();
|
||||
|
||||
if (addFullRecipe) {
|
||||
BookmarkStackMeta iMeta;
|
||||
|
||||
for (int slotIndex = grid.size() - 1; slotIndex >= 0; slotIndex--) {
|
||||
iMeta = BGrid.getMetadata(slotIndex);
|
||||
|
||||
if (iMeta.recipeId != null && iMeta.recipeId.equals(recipeId)) {
|
||||
NBTTagCompound nbTag = StackInfo.itemStackToNBT(BGrid.getItem(slotIndex), true);
|
||||
nbTag.setInteger("Count", Math.max(nbTag.getInteger("Count") + iMeta.factor * shift, iMeta.factor));
|
||||
BGrid.replaceItem(slotIndex, StackInfo.loadFromNBT(nbTag));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NBTTagCompound nbTag = StackInfo.itemStackToNBT(slot.item, true);
|
||||
nbTag.setInteger("Count", Math.max(nbTag.getInteger("Count") + meta.factor * shift, meta.factor));
|
||||
BGrid.replaceItem(slot.slotIndex, StackInfo.loadFromNBT(nbTag));
|
||||
|
||||
saveBookmarks();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return super.onMouseWheel(shift, mousex, mousey);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -46,18 +46,24 @@ import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ClientHandler
|
||||
{
|
||||
private static String[] defaultSerialHandlers = {
|
||||
"WayofTime.alchemicalWizardry.client.nei.NEIAlchemyRecipeHandler"
|
||||
};
|
||||
private static String[] defaultHeightHackHandlers = {
|
||||
"ic2.neiIntegration.core.recipehandler.FluidCannerRecipeHandler",
|
||||
"tconstruct.plugins.nei.RecipeHandlerAlloying",
|
||||
"tconstruct.plugins.nei.RecipeHandlerCastingBasin",
|
||||
"tconstruct.plugins.nei.RecipeHandlerCastingTable",
|
||||
"tconstruct.plugins.nei.RecipeHandlerMelting",
|
||||
private static String[] defaultHeightHackHandlerRegex = {
|
||||
"buildcraft.compat.nei.*",
|
||||
"cofh.thermalexpansion.plugins.nei.handlers.*",
|
||||
"crazypants.enderio.nei.*",
|
||||
"forestry.factory.recipes.nei.*",
|
||||
"ic2.neiIntegration.core.recipehandler.*",
|
||||
"mariculture.plugins.nei.*",
|
||||
"redgear.brewcraft.plugins.nei.*",
|
||||
"tconstruct.plugins.nei.*",
|
||||
"WayofTime.alchemicalWizardry.client.nei.*",
|
||||
};
|
||||
private static String[] defaultHandlerOrdering = {
|
||||
"# Each line in this file should either be a comment (starts with '#') or an ordering.",
|
||||
@@ -180,7 +186,7 @@ public class ClientHandler
|
||||
if (!file.exists()) {
|
||||
try (FileWriter writer = new FileWriter(file)) {
|
||||
NEIClientConfig.logger.info("Creating default height hack handlers list {}", file);
|
||||
Collection<String> toSave = Loader.isModLoaded("dreamcraft") ? Collections.singletonList("") : Arrays.asList(defaultHeightHackHandlers);
|
||||
Collection<String> toSave = Arrays.asList(defaultHeightHackHandlerRegex);
|
||||
IOUtils.writeLines(toSave, "\n", writer);
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to save default height hack handlers list to file {}", file, e);
|
||||
@@ -189,7 +195,10 @@ public class ClientHandler
|
||||
|
||||
try (FileReader reader = new FileReader(file)) {
|
||||
NEIClientConfig.logger.info("Loading height hack handlers from file {}", file);
|
||||
NEIClientConfig.heightHackHandlers = new HashSet<>(IOUtils.readLines(reader));
|
||||
NEIClientConfig.heightHackHandlerRegex =
|
||||
IOUtils.readLines(reader).stream()
|
||||
.map(Pattern::compile)
|
||||
.collect(Collectors.toCollection(HashSet::new));
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to load height hack handlers from file {}", file, e);
|
||||
}
|
||||
|
||||
@@ -185,13 +185,13 @@ public class ItemList
|
||||
@SuppressWarnings("unchecked")
|
||||
public void execute() {
|
||||
// System.out.println("Executing NEI Item Loading");
|
||||
ThreadOperationTimer timer = getTimer(500);
|
||||
ThreadOperationTimer timer = getTimer(NEIClientConfig.getItemLoadingTimeout());
|
||||
|
||||
LinkedList<ItemStack> items = new LinkedList<>();
|
||||
LinkedList<ItemStack> permutations = new LinkedList<>();
|
||||
ListMultimap<Item, ItemStack> itemMap = ArrayListMultimap.create();
|
||||
|
||||
timer.setLimit(500);
|
||||
timer.setLimit(NEIClientConfig.getItemLoadingTimeout());
|
||||
for (Item item : (Iterable<Item>) Item.itemRegistry) {
|
||||
if (interrupted()) return;
|
||||
|
||||
|
||||
@@ -1,85 +1,121 @@
|
||||
package codechicken.nei;
|
||||
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
import codechicken.nei.api.GuiInfo;
|
||||
import codechicken.nei.api.INEIGuiHandler;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.recipe.GuiCraftingRecipe;
|
||||
import codechicken.nei.recipe.GuiRecipe;
|
||||
import codechicken.nei.recipe.GuiUsageRecipe;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.client.gui.inventory.GuiContainerCreative;
|
||||
import net.minecraft.inventory.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.IFluidContainerItem;
|
||||
|
||||
import static codechicken.nei.LayoutManager.searchField;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static codechicken.lib.gui.GuiDraw.drawRect;
|
||||
import static codechicken.nei.NEIClientConfig.canPerformAction;
|
||||
|
||||
public class ItemPanel extends Widget {
|
||||
/**
|
||||
* Backwards compat :-/
|
||||
*/
|
||||
public static ArrayList<ItemStack> items = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Should not be externally modified, use updateItemList
|
||||
*/
|
||||
public ArrayList<ItemStack> realItems = new ArrayList<>();
|
||||
/**
|
||||
* Swapped into visible items on update
|
||||
*/
|
||||
protected ArrayList<ItemStack> _items = realItems;
|
||||
|
||||
public ArrayList<ItemStack> getItems() {
|
||||
return realItems;
|
||||
}
|
||||
|
||||
public static void updateItemList(ArrayList<ItemStack> newItems) {
|
||||
ItemPanels.itemPanel._items = newItems;
|
||||
}
|
||||
|
||||
public class ItemPanelSlot
|
||||
{
|
||||
public ItemStack item;
|
||||
public int slotIndex;
|
||||
|
||||
public ItemPanelSlot(int index) {
|
||||
item = realItems.get(index);
|
||||
slotIndex = index;
|
||||
}
|
||||
}
|
||||
public class ItemPanel extends Widget
|
||||
{
|
||||
|
||||
public ItemStack draggedStack;
|
||||
public int mouseDownSlot = -1;
|
||||
|
||||
public Button prev;
|
||||
public Button next;
|
||||
public Button pagePrev;
|
||||
public Button pageNext;
|
||||
public Label pageLabel;
|
||||
|
||||
/**
|
||||
* Backwards compat :-/
|
||||
*/
|
||||
@Deprecated
|
||||
private int itemsPerPage = 0;
|
||||
|
||||
private int marginLeft;
|
||||
private int marginTop;
|
||||
private int rows;
|
||||
private int columns;
|
||||
@Deprecated
|
||||
public static ArrayList<ItemStack> items = new ArrayList<>();
|
||||
|
||||
private boolean[] validSlotMap;
|
||||
private int firstIndex;
|
||||
private int itemsPerPage;
|
||||
@Deprecated
|
||||
public ArrayList<ItemStack> realItems = new ArrayList<>();
|
||||
|
||||
private int page;
|
||||
private int numPages;
|
||||
protected Pattern SPECIAL_REGEX_CHARS = Pattern.compile("[{}()\\[\\].+*?^$\\\\|]");
|
||||
|
||||
public static class ItemPanelSlot
|
||||
{
|
||||
public ItemStack item;
|
||||
public int slotIndex;
|
||||
|
||||
public ItemPanelSlot(int idx, ItemStack stack)
|
||||
{
|
||||
slotIndex = idx;
|
||||
item = stack;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public ItemPanelSlot(int idx)
|
||||
{
|
||||
this(idx, ItemPanels.itemPanel.getGrid().getItem(idx));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected static class ItemPanelGrid extends ItemsGrid
|
||||
{
|
||||
public ArrayList<ItemStack> newItems;
|
||||
|
||||
public void setItems(ArrayList<ItemStack> items)
|
||||
{
|
||||
newItems = items;
|
||||
}
|
||||
|
||||
public void refresh(GuiContainer gui)
|
||||
{
|
||||
|
||||
if (newItems != null) {
|
||||
realItems = newItems;
|
||||
newItems = null;
|
||||
}
|
||||
|
||||
super.refresh(gui);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected ItemsGrid grid = new ItemPanelGrid();
|
||||
|
||||
public ArrayList<ItemStack> getItems()
|
||||
{
|
||||
return grid.getItems();
|
||||
}
|
||||
|
||||
public static void updateItemList(ArrayList<ItemStack> newItems)
|
||||
{
|
||||
((ItemPanelGrid) ItemPanels.itemPanel.getGrid()).setItems(newItems);
|
||||
ItemPanels.itemPanel.realItems = newItems;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void scroll(int i)
|
||||
{
|
||||
grid.shiftPage(i);
|
||||
}
|
||||
|
||||
public ItemsGrid getGrid()
|
||||
{
|
||||
return grid;
|
||||
}
|
||||
|
||||
public void init() {
|
||||
pageLabel = new Label("(0/0)", true);
|
||||
|
||||
prev = new Button("Prev")
|
||||
pagePrev = new Button("Prev")
|
||||
{
|
||||
public boolean onButtonPress(boolean rightclick) {
|
||||
if (!rightclick) {
|
||||
scroll(-1);
|
||||
grid.shiftPage(-1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -90,11 +126,11 @@ public class ItemPanel extends Widget {
|
||||
return "<";
|
||||
}
|
||||
};
|
||||
next = new Button("Next")
|
||||
pageNext = new Button("Next")
|
||||
{
|
||||
public boolean onButtonPress(boolean rightclick) {
|
||||
if (!rightclick) {
|
||||
scroll(1);
|
||||
grid.shiftPage(1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -105,169 +141,89 @@ public class ItemPanel extends Widget {
|
||||
return ">";
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
public int getX(GuiContainer gui) {
|
||||
return (gui.xSize + gui.width) / 2 + 3;
|
||||
public int getMarginLeft(GuiContainer gui)
|
||||
{
|
||||
if (gui instanceof GuiContainerCreative && NEIClientUtils.getGamemode() == 2) {
|
||||
//then activate creative+ first render creative gui and oly then creative+
|
||||
return (gui.width + 176) / 2 + 2;
|
||||
}
|
||||
|
||||
return (gui.width + gui.xSize) / 2 + 2;
|
||||
}
|
||||
|
||||
public int getMarginLeft() {
|
||||
return x + (w % 18) / 2;
|
||||
}
|
||||
|
||||
public int getMarginTop() {
|
||||
return y + (h % 18) / 2;
|
||||
}
|
||||
|
||||
public int getButtonTop() {
|
||||
public int getMarginTop(GuiContainer gui)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
public int getNextX(GuiContainer gui) {
|
||||
return gui.width - prev.w - 2;
|
||||
public int getWidth(GuiContainer gui)
|
||||
{
|
||||
return LayoutManager.getSideWidth(gui) - getMarginLeft(gui);
|
||||
}
|
||||
|
||||
public int getPrevX(GuiContainer gui) {
|
||||
return (gui.xSize + gui.width) / 2 + 2;
|
||||
public int getHeight(GuiContainer gui)
|
||||
{
|
||||
// - 19 = 2 + 16 + 1 -> input in bottom
|
||||
return gui.height - getMarginTop(gui) - 19;
|
||||
}
|
||||
|
||||
public int getPageX(GuiContainer gui) {
|
||||
return gui.guiLeft * 3 / 2 + gui.xSize + 1;
|
||||
public String getLabelText()
|
||||
{
|
||||
return "(" + getPage() + "/" + Math.max(1, getNumPages()) + ")";
|
||||
}
|
||||
|
||||
public int getHeight(GuiContainer gui) {
|
||||
return gui.height - 15 - y;
|
||||
}
|
||||
|
||||
public int getWidth(GuiContainer gui) {
|
||||
return LayoutManager.getSideWidth(gui) - x;
|
||||
}
|
||||
|
||||
public String getLabelText() {
|
||||
return pageLabel.text = "(" + getPage() + "/" + getNumPages() + ")";
|
||||
}
|
||||
|
||||
protected void setItems() {
|
||||
realItems = _items;
|
||||
|
||||
// Backwards compat
|
||||
ItemPanels.itemPanel._items = _items;
|
||||
}
|
||||
|
||||
public void resize(GuiContainer gui) {
|
||||
setItems();
|
||||
public void resize(GuiContainer gui)
|
||||
{
|
||||
final int marginLeft = getMarginLeft(gui);
|
||||
final int marginTop = getMarginTop(gui);
|
||||
final int width = getWidth(gui);
|
||||
final int height = getHeight(gui);
|
||||
final int buttonHeight = 16;
|
||||
final int buttonWidth = 16;
|
||||
|
||||
prev.x = getPrevX(gui);
|
||||
prev.y = getButtonTop();
|
||||
prev.h = buttonHeight;
|
||||
prev.w = buttonWidth;
|
||||
pagePrev.w = pageNext.w = buttonWidth;
|
||||
pagePrev.h = pageNext.h = buttonHeight;
|
||||
pagePrev.y = pageNext.y = marginTop;
|
||||
|
||||
next.x = getNextX(gui);
|
||||
next.y = getButtonTop();
|
||||
next.h = buttonHeight;
|
||||
next.w = buttonWidth;
|
||||
pagePrev.x = marginLeft;
|
||||
pageNext.x = marginLeft + width - buttonWidth;
|
||||
|
||||
pageLabel.x = getPageX(gui);
|
||||
pageLabel.y = prev.y + 5;
|
||||
pageLabel.x = marginLeft + width / 2;
|
||||
pageLabel.y = marginTop + 5;
|
||||
pageLabel.text = getLabelText();
|
||||
|
||||
y = prev.h + prev.y;
|
||||
x = getX(gui);
|
||||
w = getWidth(gui);
|
||||
h = getHeight(gui);
|
||||
|
||||
marginLeft = getMarginLeft();
|
||||
marginTop = getMarginTop();
|
||||
columns = w / 18;
|
||||
rows = h / 18;
|
||||
//sometimes width and height can be negative with certain resizing
|
||||
if(rows < 0) rows = 0;
|
||||
if(columns < 0) columns = 0;
|
||||
y = marginTop + buttonHeight + 2;
|
||||
x = marginLeft;
|
||||
w = width;
|
||||
h = height - buttonHeight - 2;
|
||||
|
||||
grid.setGridSize(x, y, w, h);
|
||||
grid.refresh(gui);
|
||||
|
||||
calculatePage();
|
||||
updateValidSlots();
|
||||
}
|
||||
|
||||
private void calculatePage() {
|
||||
if (itemsPerPage == 0)
|
||||
numPages = 0;
|
||||
else
|
||||
numPages = (int) Math.ceil((float) realItems.size() / (float) itemsPerPage);
|
||||
|
||||
if (firstIndex >= realItems.size())
|
||||
firstIndex = 0;
|
||||
|
||||
if (numPages == 0)
|
||||
page = 0;
|
||||
else
|
||||
page = firstIndex / itemsPerPage + 1;
|
||||
}
|
||||
|
||||
public void setVisible() {
|
||||
LayoutManager.addWidget(prev);
|
||||
LayoutManager.addWidget(next);
|
||||
public void setVisible()
|
||||
{
|
||||
LayoutManager.addWidget(pagePrev);
|
||||
LayoutManager.addWidget(pageNext);
|
||||
LayoutManager.addWidget(pageLabel);
|
||||
|
||||
}
|
||||
private void updateValidSlots() {
|
||||
GuiContainer gui = NEIClientUtils.getGuiContainer();
|
||||
validSlotMap = new boolean[rows * columns];
|
||||
itemsPerPage = 0;
|
||||
for (int i = 0; i < validSlotMap.length; i++)
|
||||
if (slotValid(gui, i)) {
|
||||
validSlotMap[i] = true;
|
||||
itemsPerPage++;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean slotValid(GuiContainer gui, int i) {
|
||||
Rectangle4i rect = getSlotRect(i);
|
||||
try {
|
||||
GuiInfo.readLock.lock();
|
||||
if(GuiInfo.guiHandlers.stream().anyMatch(handler -> handler.hideItemPanelSlot(gui, rect.x, rect.y, rect.w, rect.h)))
|
||||
return false;
|
||||
} finally {
|
||||
GuiInfo.readLock.unlock();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public Rectangle4i getSlotRect(int i) {
|
||||
return getSlotRect(i / columns, i % columns);
|
||||
}
|
||||
|
||||
public Rectangle4i getSlotRect(int row, int column) {
|
||||
return new Rectangle4i(marginLeft + column * 18, marginTop + row * 18, 18, 18);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int mousex, int mousey) {
|
||||
if (itemsPerPage == 0)
|
||||
return;
|
||||
|
||||
GuiContainerManager.enableMatrixStackLogging();
|
||||
int index = firstIndex;
|
||||
for (int i = 0; i < rows * columns && index < realItems.size(); i++) {
|
||||
if (validSlotMap[i]) {
|
||||
Rectangle4i rect = getSlotRect(i);
|
||||
if (rect.contains(mousex, mousey))
|
||||
drawRect(rect.x, rect.y, rect.w, rect.h, 0xee555555);//highlight
|
||||
|
||||
GuiContainerManager.drawItem(rect.x + 1, rect.y + 1, realItems.get(index));
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
GuiContainerManager.disableMatrixStackLogging();
|
||||
public void draw(int mousex, int mousey)
|
||||
{
|
||||
grid.draw(mousex, mousey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postDraw(int mousex, int mousey) {
|
||||
if (draggedStack != null) {
|
||||
GuiContainerManager.drawItems.zLevel += 100;
|
||||
GuiContainerManager.drawItem(mousex - 8, mousey - 8, draggedStack);
|
||||
GuiContainerManager.drawItem(mousex - 8, mousey - 8, draggedStack, true);
|
||||
GuiContainerManager.drawItems.zLevel -= 100;
|
||||
}
|
||||
}
|
||||
@@ -277,29 +233,42 @@ public class ItemPanel extends Widget {
|
||||
if (mouseDownSlot >= 0 && draggedStack == null && NEIClientUtils.getHeldItem() == null &&
|
||||
NEIClientConfig.hasSMPCounterPart() && !GuiInfo.hasCustomSlots(NEIClientUtils.getGuiContainer())) {
|
||||
ItemPanelSlot mouseOverSlot = getSlotMouseOver(mousex, mousey);
|
||||
ItemStack stack = new ItemPanelSlot(mouseDownSlot).item;
|
||||
if (stack != null && (mouseOverSlot == null || mouseOverSlot.slotIndex != mouseDownSlot || heldTime > 500)) {
|
||||
int amount = NEIClientConfig.getItemQuantity();
|
||||
if (amount == 0)
|
||||
amount = stack.getMaxStackSize();
|
||||
|
||||
draggedStack = NEIServerUtils.copyStack(stack, amount);
|
||||
if (mouseOverSlot == null || mouseOverSlot.slotIndex != mouseDownSlot || heldTime > 500) {
|
||||
draggedStack = getDraggedStackWithQuantity(mouseDownSlot);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected ItemStack getDraggedStackWithQuantity(int mouseDownSlot)
|
||||
{
|
||||
ItemStack stack = grid.getItem(mouseDownSlot);
|
||||
|
||||
if (stack != null) {
|
||||
int amount = NEIClientConfig.getItemQuantity();
|
||||
|
||||
if (amount == 0) {
|
||||
amount = stack.getMaxStackSize();
|
||||
}
|
||||
|
||||
return NEIServerUtils.copyStack(stack, amount);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleClick(int mousex, int mousey, int button) {
|
||||
if (handleDraggedClick(mousex, mousey, button))
|
||||
public boolean handleClick(int mousex, int mousey, int button)
|
||||
{
|
||||
|
||||
if (handleClickExt(mousex, mousey, button))
|
||||
return true;
|
||||
|
||||
if (NEIClientUtils.getHeldItem() != null) {
|
||||
try {
|
||||
GuiInfo.readLock.lock();
|
||||
if (GuiInfo.guiHandlers.stream().anyMatch(handler -> handler.hideItemPanelSlot(NEIClientUtils.getGuiContainer(), mousex, mousey, 1, 1)))
|
||||
return false;
|
||||
} finally {
|
||||
GuiInfo.readLock.unlock();
|
||||
|
||||
if (!grid.contains(mousex, mousey)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NEIClientConfig.canPerformAction("delete") && NEIClientConfig.canPerformAction("item"))
|
||||
@@ -315,84 +284,199 @@ public class ItemPanel extends Widget {
|
||||
|
||||
ItemPanelSlot hoverSlot = getSlotMouseOver(mousex, mousey);
|
||||
if (hoverSlot != null) {
|
||||
if (button == 2) {
|
||||
ItemStack stack = hoverSlot.item;
|
||||
if (stack != null) {
|
||||
int amount = NEIClientConfig.getItemQuantity();
|
||||
if (amount == 0)
|
||||
amount = stack.getMaxStackSize();
|
||||
|
||||
draggedStack = NEIServerUtils.copyStack(stack, amount);
|
||||
if (button == 2) {
|
||||
|
||||
if (hoverSlot.item != null) {
|
||||
draggedStack = getDraggedStackWithQuantity(hoverSlot.slotIndex);
|
||||
}
|
||||
|
||||
} else {
|
||||
mouseDownSlot = hoverSlot.slotIndex;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean handleDraggedClick(int mousex, int mousey, int button) {
|
||||
if (draggedStack == null)
|
||||
return false;
|
||||
|
||||
GuiContainer gui = NEIClientUtils.getGuiContainer();
|
||||
boolean handled = false;
|
||||
try {
|
||||
GuiInfo.readLock.lock();
|
||||
for (INEIGuiHandler handler : GuiInfo.guiHandlers) {
|
||||
if (handler.handleDragNDrop(gui, mousex, mousey, draggedStack, button)) {
|
||||
handled = true;
|
||||
if (draggedStack.stackSize == 0) {
|
||||
draggedStack = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
GuiInfo.readLock.unlock();
|
||||
@Override
|
||||
public boolean handleClickExt(int mouseX, int mouseY, int button)
|
||||
{
|
||||
if (ItemPanels.itemPanel.draggedStack != null) {
|
||||
return ItemPanels.itemPanel.handleDraggedClick(mouseX, mouseY, button);
|
||||
}
|
||||
|
||||
if (handled)
|
||||
|
||||
if (ItemPanels.bookmarkPanel.draggedStack != null) {
|
||||
return ItemPanels.bookmarkPanel.handleDraggedClick(mouseX, mouseY, button);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean handleDraggedClick(int mouseX, int mouseY, int button)
|
||||
{
|
||||
if (draggedStack == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (handleFillFluidContainerClick(mouseX, mouseY, button)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Slot overSlot = gui.getSlotAtPosition(mousex, mousey);
|
||||
if (overSlot != null && overSlot.isItemValid(draggedStack)) {
|
||||
if (NEIClientConfig.canCheatItem(draggedStack)) {
|
||||
int contents = overSlot.getHasStack() ? overSlot.getStack().stackSize : 0;
|
||||
int add = button == 0 ? draggedStack.stackSize : 1;
|
||||
if (overSlot.getHasStack() && !NEIServerUtils.areStacksSameType(draggedStack, overSlot.getStack()))
|
||||
contents = 0;
|
||||
int total = Math.min(contents + add, Math.min(overSlot.getSlotStackLimit(), draggedStack.getMaxStackSize()));
|
||||
if (handleSearchInputClick(mouseX, mouseY, button)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (total > contents) {
|
||||
NEIClientUtils.setSlotContents(overSlot.slotNumber, NEIServerUtils.copyStack(draggedStack, total), true);
|
||||
NEICPH.sendGiveItem(NEIServerUtils.copyStack(draggedStack, total), false, false);
|
||||
draggedStack.stackSize -= total - contents;
|
||||
}
|
||||
if (draggedStack.stackSize == 0)
|
||||
draggedStack = null;
|
||||
} else {
|
||||
draggedStack = null;
|
||||
}
|
||||
} else if (mousex < gui.guiLeft || mousey < gui.guiTop || mousex >= gui.guiLeft + gui.xSize || mousey >= gui.guiTop + gui.ySize) {
|
||||
if (handleGUIContainerClick(mouseX, mouseY, button)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (handleCheatItemClick(mouseX, mouseY, button)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final GuiContainer gui = NEIClientUtils.getGuiContainer();
|
||||
if (mouseX < gui.guiLeft || mouseY < gui.guiTop || mouseX >= gui.guiLeft + gui.xSize || mouseY >= gui.guiTop + gui.ySize) {
|
||||
draggedStack = null;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleClickExt(int mousex, int mousey, int button) {
|
||||
return handleDraggedClick(mousex, mousey, button);
|
||||
protected boolean handleFillFluidContainerClick(int mouseX, int mouseY, int button)
|
||||
{
|
||||
|
||||
if (button == 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ItemPanelSlot mouseOverSlot = ItemPanels.itemPanel.getSlotMouseOver(mouseX, mouseY);
|
||||
|
||||
if (mouseOverSlot == null) {
|
||||
mouseOverSlot = ItemPanels.bookmarkPanel.getSlotMouseOver(mouseX, mouseY);
|
||||
}
|
||||
|
||||
if (mouseOverSlot != null && draggedStack.getItem() instanceof IFluidContainerItem) {
|
||||
FluidStack fluidStack = StackInfo.getFluid(mouseOverSlot.item);
|
||||
|
||||
if (fluidStack != null) {
|
||||
final int stackSize = draggedStack.stackSize;
|
||||
|
||||
fluidStack = fluidStack.copy();
|
||||
|
||||
if (fluidStack.amount == 0) {
|
||||
fluidStack.amount = 1000;
|
||||
}
|
||||
|
||||
if (mouseOverSlot.item.stackSize > 1) {
|
||||
fluidStack.amount *= mouseOverSlot.item.stackSize;
|
||||
}
|
||||
|
||||
draggedStack.stackSize = 1;
|
||||
((IFluidContainerItem) draggedStack.getItem()).fill(draggedStack, fluidStack, true);
|
||||
draggedStack.stackSize = stackSize;
|
||||
|
||||
if (button == 1 && ((IFluidContainerItem) draggedStack.getItem()).getFluid(draggedStack) != null) {
|
||||
ItemPanels.bookmarkPanel.addOrRemoveItem(draggedStack.copy());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean handleGUIContainerClick(int mouseX, int mouseY, int button)
|
||||
{
|
||||
final GuiContainer gui = NEIClientUtils.getGuiContainer();
|
||||
boolean handled = false;
|
||||
|
||||
try {
|
||||
GuiInfo.readLock.lock();
|
||||
for (INEIGuiHandler handler : GuiInfo.guiHandlers) {
|
||||
if (handler.handleDragNDrop(gui, mouseX, mouseY, draggedStack, button)) {
|
||||
handled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
GuiInfo.readLock.unlock();
|
||||
}
|
||||
|
||||
if (draggedStack.stackSize == 0) {
|
||||
draggedStack = null;
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
protected boolean handleCheatItemClick(int mouseX, int mouseY, int button)
|
||||
{
|
||||
final GuiContainer gui = NEIClientUtils.getGuiContainer();
|
||||
final Slot overSlot = gui.getSlotAtPosition(mouseX, mouseY);
|
||||
|
||||
if (overSlot != null && overSlot.isItemValid(draggedStack)) {
|
||||
|
||||
if (NEIClientConfig.canCheatItem(draggedStack)) {
|
||||
int contents = overSlot.getHasStack() ? overSlot.getStack().stackSize : 0;
|
||||
final int add = button == 0 ? draggedStack.stackSize : 1;
|
||||
|
||||
if (overSlot.getHasStack() && !NEIServerUtils.areStacksSameType(draggedStack, overSlot.getStack())) {
|
||||
contents = 0;
|
||||
}
|
||||
|
||||
final int total = Math.min(contents + add, Math.min(overSlot.getSlotStackLimit(), draggedStack.getMaxStackSize()));
|
||||
|
||||
if (total > contents) {
|
||||
NEIClientUtils.setSlotContents(overSlot.slotNumber, NEIServerUtils.copyStack(draggedStack, total), true);
|
||||
NEICPH.sendGiveItem(NEIServerUtils.copyStack(draggedStack, total), false, false);
|
||||
draggedStack.stackSize -= total - contents;
|
||||
}
|
||||
|
||||
if (draggedStack.stackSize == 0) {
|
||||
draggedStack = null;
|
||||
}
|
||||
|
||||
} else {
|
||||
draggedStack = null;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean handleSearchInputClick(int mouseX, int mouseY, int button)
|
||||
{
|
||||
|
||||
if (searchField.contains(mouseX, mouseY)) {
|
||||
final FluidStack fluidStack = StackInfo.getFluid(draggedStack);
|
||||
|
||||
if (fluidStack != null) {
|
||||
searchField.setText(SPECIAL_REGEX_CHARS.matcher(fluidStack.getLocalizedName()).replaceAll("\\\\$0"));
|
||||
} else {
|
||||
searchField.setText(SPECIAL_REGEX_CHARS.matcher(draggedStack.getDisplayName()).replaceAll("\\\\$0"));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseUp(int mousex, int mousey, int button) {
|
||||
ItemPanelSlot hoverSlot = getSlotMouseOver(mousex, mousey);
|
||||
|
||||
if (hoverSlot != null && hoverSlot.slotIndex == mouseDownSlot && draggedStack == null) {
|
||||
ItemStack item = hoverSlot.item;
|
||||
|
||||
if (NEIController.manager.window instanceof GuiRecipe || !NEIClientConfig.canCheatItem(item)) {
|
||||
|
||||
if (button == 0)
|
||||
GuiCraftingRecipe.openRecipeGui("item", item);
|
||||
else if (button == 1)
|
||||
@@ -403,7 +487,7 @@ public class ItemPanel extends Widget {
|
||||
return;
|
||||
}
|
||||
|
||||
NEIClientUtils.cheatItem(item, button, -1);
|
||||
NEIClientUtils.cheatItem(getDraggedStackWithQuantity(hoverSlot.slotIndex), button, -1);
|
||||
}
|
||||
|
||||
mouseDownSlot = -1;
|
||||
@@ -414,20 +498,23 @@ public class ItemPanel extends Widget {
|
||||
if (!contains(mousex, mousey))
|
||||
return false;
|
||||
|
||||
scroll(-i);
|
||||
grid.shiftPage(-i);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleKeyPress(int keyID, char keyChar) {
|
||||
|
||||
if (keyID == NEIClientConfig.getKeyBinding("gui.next")) {
|
||||
scroll(1);
|
||||
grid.shiftPage(1);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (keyID == NEIClientConfig.getKeyBinding("gui.prev")) {
|
||||
scroll(-1);
|
||||
grid.shiftPage(-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -437,53 +524,23 @@ public class ItemPanel extends Widget {
|
||||
return slot == null ? null : slot.item;
|
||||
}
|
||||
|
||||
public ItemPanelSlot getSlotMouseOver(int mousex, int mousey) {
|
||||
int index = firstIndex;
|
||||
for (int i = 0; i < rows * columns && index < realItems.size(); i++)
|
||||
if (validSlotMap[i]) {
|
||||
if (getSlotRect(i).contains(mousex, mousey))
|
||||
return new ItemPanelSlot(index);
|
||||
index++;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void scroll(int i) {
|
||||
if (itemsPerPage != 0) {
|
||||
int oldIndex = firstIndex;
|
||||
firstIndex += i * itemsPerPage;
|
||||
if (firstIndex >= realItems.size())
|
||||
firstIndex = 0;
|
||||
if (firstIndex < 0)
|
||||
if (oldIndex > 0)
|
||||
firstIndex = 0;
|
||||
else
|
||||
firstIndex = (realItems.size() - 1) / itemsPerPage * itemsPerPage;
|
||||
|
||||
calculatePage();
|
||||
}
|
||||
public ItemPanelSlot getSlotMouseOver(int mousex, int mousey)
|
||||
{
|
||||
return grid.getSlotMouseOver(mousex, mousey);
|
||||
}
|
||||
|
||||
public int getPage() {
|
||||
return page;
|
||||
return grid.page + 1;
|
||||
}
|
||||
|
||||
public int getNumPages() {
|
||||
return numPages;
|
||||
return grid.numPages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(int px, int py) {
|
||||
GuiContainer gui = NEIClientUtils.getGuiContainer();
|
||||
Rectangle4i rect = new Rectangle4i(px, py, 1, 1);
|
||||
try {
|
||||
GuiInfo.readLock.lock();
|
||||
if(GuiInfo.guiHandlers.stream().anyMatch(handler -> handler.hideItemPanelSlot(gui, rect.x, rect.y, rect.w, rect.h)))
|
||||
return false;
|
||||
} finally {
|
||||
GuiInfo.readLock.unlock();
|
||||
}
|
||||
return super.contains(px, py);
|
||||
public boolean contains(int px, int py)
|
||||
{
|
||||
return grid.contains(px, py);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
package codechicken.nei;
|
||||
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
import codechicken.nei.api.GuiInfo;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
import codechicken.nei.ItemPanel.ItemPanelSlot;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static codechicken.lib.gui.GuiDraw.drawRect;
|
||||
|
||||
public class ItemsGrid
|
||||
{
|
||||
protected static final int SLOT_SIZE = 18;
|
||||
|
||||
protected int width;
|
||||
protected int height;
|
||||
|
||||
protected int marginLeft;
|
||||
protected int marginTop;
|
||||
|
||||
protected ArrayList<ItemStack> realItems = new ArrayList<>();
|
||||
|
||||
protected int page;
|
||||
protected int perPage;
|
||||
|
||||
protected int firstIndex;
|
||||
protected int numPages;
|
||||
|
||||
protected int rows;
|
||||
protected int columns;
|
||||
|
||||
protected boolean[] validSlotMap;
|
||||
protected boolean[] invalidSlotMap;
|
||||
|
||||
public ArrayList<ItemStack> getItems()
|
||||
{
|
||||
return realItems;
|
||||
}
|
||||
|
||||
public ItemStack getItem(int idx)
|
||||
{
|
||||
return realItems.get(idx);
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
return realItems.size();
|
||||
}
|
||||
|
||||
public int indexOf(ItemStack stackA, boolean useNBT)
|
||||
{
|
||||
|
||||
for (int idx = 0; idx < realItems.size(); idx++) {
|
||||
if (StackInfo.equalItemAndNBT(stackA, realItems.get(idx), useNBT)) {
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public int getPage()
|
||||
{
|
||||
return page + 1;
|
||||
}
|
||||
|
||||
public int getPerPage()
|
||||
{
|
||||
return perPage;
|
||||
}
|
||||
|
||||
public int getNumPages()
|
||||
{
|
||||
return numPages;
|
||||
}
|
||||
|
||||
public int getRows()
|
||||
{
|
||||
return rows;
|
||||
}
|
||||
|
||||
public int getColumns()
|
||||
{
|
||||
return columns;
|
||||
}
|
||||
|
||||
public void setGridSize(int mleft, int mtop, int w, int h)
|
||||
{
|
||||
|
||||
//I don't like this big condition
|
||||
if (marginLeft != mleft || marginTop != mtop || width != w || height != h) {
|
||||
|
||||
marginLeft = mleft;
|
||||
marginTop = mtop;
|
||||
|
||||
width = Math.max(0, w);
|
||||
height = Math.max(0, h);
|
||||
|
||||
columns = width / SLOT_SIZE;
|
||||
rows = height / SLOT_SIZE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void shiftPage(int shift)
|
||||
{
|
||||
if (perPage == 0) {
|
||||
numPages = 0;
|
||||
page = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
numPages = (int) Math.ceil((float) realItems.size() / (float) perPage);
|
||||
|
||||
page += shift;
|
||||
|
||||
if (page >= numPages) {
|
||||
page = page - numPages;
|
||||
}
|
||||
|
||||
if (page < 0) {
|
||||
page = numPages + page;
|
||||
}
|
||||
|
||||
page = Math.max(0, Math.min(page, numPages - 1));
|
||||
}
|
||||
|
||||
public void refresh(GuiContainer gui)
|
||||
{
|
||||
updateGuiOverlapSlots(gui);
|
||||
shiftPage(0);
|
||||
}
|
||||
|
||||
private void updateGuiOverlapSlots(GuiContainer gui)
|
||||
{
|
||||
invalidSlotMap = new boolean[rows * columns];
|
||||
perPage = columns * rows;
|
||||
|
||||
checkGuiOverlap(gui, 0, columns - 2, 1);
|
||||
checkGuiOverlap(gui, columns - 1, 1, -1);
|
||||
|
||||
}
|
||||
|
||||
private void checkGuiOverlap(GuiContainer gui, int start, int end, int dir)
|
||||
{
|
||||
boolean validColumn = false;
|
||||
|
||||
for (int c = start; c != end && !validColumn; c += dir) {
|
||||
validColumn = true;
|
||||
|
||||
for (int r = 0; r < rows; r++) {
|
||||
final int idx = columns * r + c;
|
||||
if (!slotValid(gui, r, c) && idx >= 0 && idx < invalidSlotMap.length && !invalidSlotMap[idx]) {
|
||||
invalidSlotMap[idx] = true;
|
||||
validColumn = false;
|
||||
perPage--;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean slotValid(GuiContainer gui, int row, int column)
|
||||
{
|
||||
Rectangle4i rect = getSlotRect(row, column);
|
||||
|
||||
try {
|
||||
GuiInfo.readLock.lock();
|
||||
if (GuiInfo.guiHandlers.stream().anyMatch(handler -> handler.hideItemPanelSlot(gui, rect.x, rect.y, rect.w, rect.h))) {
|
||||
return false;
|
||||
}
|
||||
} finally {
|
||||
GuiInfo.readLock.unlock();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Rectangle4i getSlotRect(int i)
|
||||
{
|
||||
return getSlotRect(i / columns, i % columns);
|
||||
}
|
||||
|
||||
public Rectangle4i getSlotRect(int row, int column)
|
||||
{
|
||||
return new Rectangle4i(marginLeft + (width % SLOT_SIZE) / 2 + column * SLOT_SIZE, marginTop + row * SLOT_SIZE, SLOT_SIZE, SLOT_SIZE);
|
||||
}
|
||||
|
||||
public boolean isInvalidSlot(int idx)
|
||||
{
|
||||
return invalidSlotMap[idx];
|
||||
}
|
||||
|
||||
public void draw(int mousex, int mousey)
|
||||
{
|
||||
if (getPerPage() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemPanelSlot slot = getSlotMouseOver(mousex, mousey);
|
||||
|
||||
GuiContainerManager.enableMatrixStackLogging();
|
||||
|
||||
int idx = page * perPage;
|
||||
for (int i = 0; i < rows * columns && idx < size(); i++) {
|
||||
|
||||
if (!invalidSlotMap[i]) {
|
||||
drawItem(getSlotRect(i), idx, slot);
|
||||
idx ++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GuiContainerManager.disableMatrixStackLogging();
|
||||
}
|
||||
|
||||
protected void drawItem(Rectangle4i rect, int idx, ItemPanelSlot focus)
|
||||
{
|
||||
|
||||
if (focus != null && focus.slotIndex == idx) {
|
||||
drawRect(rect.x, rect.y, rect.w, rect.h, 0xee555555);//highlight
|
||||
}
|
||||
|
||||
GuiContainerManager.drawItem(rect.x + 1, rect.y + 1, getItem(idx));
|
||||
}
|
||||
|
||||
public ItemPanelSlot getSlotMouseOver(int mousex, int mousey)
|
||||
{
|
||||
if (!contains(mousex, mousey)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final int overRow = (int) ((mousey - marginTop) / SLOT_SIZE);
|
||||
final int overColumn = (int) ((mousex - marginLeft - (width % SLOT_SIZE) / 2) / SLOT_SIZE);
|
||||
final int slt = columns * overRow + overColumn;
|
||||
int idx = page * perPage + slt;
|
||||
|
||||
if (overRow >= rows || overColumn >= columns) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (int i = 0; i < slt; i++) {
|
||||
if (invalidSlotMap[i]) {
|
||||
idx--;
|
||||
}
|
||||
}
|
||||
|
||||
return idx < size()? new ItemPanelSlot(idx, realItems.get(idx)): null;
|
||||
}
|
||||
|
||||
public boolean contains(int px, int py)
|
||||
{
|
||||
|
||||
if (!(new Rectangle4i(marginLeft, marginTop, width, height)).contains(px, py)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final int r = (int) ((py - marginTop) / SLOT_SIZE);
|
||||
final int c = (int) ((px - marginLeft - (width % SLOT_SIZE) / 2) / SLOT_SIZE);
|
||||
final int slt = columns * r + c;
|
||||
|
||||
return r >= rows || c >= columns || !invalidSlotMap[slt];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -265,7 +265,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
GL11.glEnable(GL11.GL_DEPTH_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void postRenderObjects(GuiContainer gui, int mousex, int mousey) {
|
||||
if (!isHidden() && isEnabled()) {
|
||||
@@ -310,13 +310,13 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
VisiblityData visiblity = new VisiblityData();
|
||||
if (isHidden())
|
||||
visiblity.showNEI = false;
|
||||
|
||||
|
||||
if (isBookmarkPanelHidden())
|
||||
visiblity.showBookmarkPanel = false;
|
||||
|
||||
|
||||
if (gui.height - gui.ySize <= 40)
|
||||
visiblity.showSearchSection = false;
|
||||
|
||||
|
||||
if (gui.guiLeft - 4 < 76)
|
||||
visiblity.showWidgets = false;
|
||||
try {
|
||||
@@ -325,7 +325,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
} finally {
|
||||
GuiInfo.readLock.unlock();
|
||||
}
|
||||
|
||||
|
||||
visiblity.translateDependancies();
|
||||
|
||||
getLayoutStyle().layout(gui, visiblity);
|
||||
@@ -351,7 +351,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
this.icons[1] = new DrawableBuilder("nei:textures/nei_tabbed_sprites.png", 48, 0, 16, 16).build();
|
||||
this.icons[2] = new DrawableBuilder("nei:textures/nei_tabbed_sprites.png", 64, 0, 16, 16).build();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onButtonPress(boolean rightclick) {
|
||||
if (!rightclick) {
|
||||
@@ -367,7 +367,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addTooltips(List<String> tooltip) {
|
||||
tooltip.add(translate("inventory.options.tip"));
|
||||
@@ -380,9 +380,9 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
String controlKeyLocalization = translate(Minecraft.isRunningOnMac ? "key.ctrl.mac" : "key.ctrl");
|
||||
tooltip.add(modeColor + translate("inventory.options.tip.cheatmode." + cheatMode));
|
||||
tooltip.add(modeColor + translate("inventory.options.tip.cheatmode.disable", controlKeyLocalization));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getRenderLabel() {
|
||||
return translate("inventory.options");
|
||||
@@ -396,7 +396,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
this.icons[0] = new DrawableBuilder("nei:textures/nei_tabbed_sprites.png", 0, 0, 16, 16).build();
|
||||
this.icons[1] = new DrawableBuilder("nei:textures/nei_tabbed_sprites.png", 16, 0, 16, 16).build();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onButtonPress(boolean rightclick) {
|
||||
NEIClientConfig.toggleBooleanSetting("inventory.bookmarksEnabled");
|
||||
@@ -619,7 +619,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static void markItemsDirty() {
|
||||
// If anything has modified data this depends on, we'll need to reload the item list
|
||||
itemsLoaded = false;
|
||||
@@ -683,7 +683,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
if (visiblity.showBookmarkPanel) {
|
||||
addWidget(bookmarkPanel);
|
||||
bookmarkPanel.setVisible();
|
||||
}
|
||||
}
|
||||
|
||||
if (visiblity.showSearchSection) {
|
||||
addWidget(searchField);
|
||||
@@ -707,7 +707,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
if (canPerformAction("delete"))
|
||||
addWidget(delete);
|
||||
}
|
||||
|
||||
|
||||
if (!visiblity.showBookmarkPanel) {
|
||||
// Bookmarks or Subset/dropdown
|
||||
addWidget(dropDown);
|
||||
@@ -761,7 +761,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
|
||||
@Override
|
||||
public boolean shouldShowTooltip(GuiContainer gui) {
|
||||
return itemPanel.draggedStack == null;
|
||||
return itemPanel.draggedStack == null && bookmarkPanel.sortedStackIndex == -1;
|
||||
}
|
||||
|
||||
/** Note: this method isn't actually used by this mod, but NEI add-ons might need it. */
|
||||
@@ -799,16 +799,16 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
|
||||
public static void drawIcon(int x, int y, Image image) {
|
||||
final boolean isDrawableResource = image instanceof DrawableResource;
|
||||
|
||||
|
||||
if (!isDrawableResource)
|
||||
changeTexture("nei:textures/nei_sprites.png");
|
||||
|
||||
|
||||
GL11.glColor4f(1, 1, 1, 1);
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
|
||||
if(!isDrawableResource)
|
||||
drawTexturedModalRect(x, y, image.x, image.y, image.width, image.height);
|
||||
else
|
||||
else
|
||||
((DrawableResource)image).draw(x, y);
|
||||
GL11.glDisable(GL11.GL_BLEND);
|
||||
}
|
||||
@@ -884,4 +884,3 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -119,7 +119,7 @@ public class LayoutStyleMinecraft extends LayoutStyle
|
||||
bookmarkPanel.resize(gui);
|
||||
|
||||
more.w = more.h = less.w = less.h = 16;
|
||||
less.x = itemPanel.prev.x;
|
||||
less.x = itemPanel.pagePrev.x;
|
||||
more.x = gui.width - less.w - 2;
|
||||
more.y = less.y = gui.height - more.h - 2;
|
||||
|
||||
|
||||
@@ -48,10 +48,12 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class NEIClientConfig {
|
||||
private static boolean configLoaded;
|
||||
private static boolean enabledOverride;
|
||||
private static String worldPath;
|
||||
|
||||
public static Logger logger = LogManager.getLogger("NotEnoughItems");
|
||||
public static File configDir = new File(CommonUtils.getMinecraftDir(), "config/NEI/");
|
||||
@@ -59,17 +61,20 @@ public class NEIClientConfig {
|
||||
new File("saves/NEI/client.dat"),
|
||||
new ConfigFile(new File(configDir, "client.cfg")));
|
||||
public static ConfigSet world;
|
||||
public static final File bookmarkFile = new File(configDir, "bookmarks.ini");
|
||||
public static final File handlerFile = new File(configDir, "handlers.csv");
|
||||
public static final File serialHandlersFile = new File(configDir, "serialhandlers.cfg");
|
||||
public static final File heightHackHandlersFile = new File(configDir, "heighthackhandlers.cfg");
|
||||
public static final File handlerOrderingFile = new File(configDir, "handlerordering.csv");
|
||||
|
||||
@Deprecated
|
||||
public static File bookmarkFile;
|
||||
|
||||
// Set of handlers that need to be run in serial
|
||||
public static HashSet<String> serialHandlers = new HashSet<>();
|
||||
|
||||
// Set of handler ID of handlers that need the hack in GuiRecipe.startHeightHack().
|
||||
public static HashSet<String> heightHackHandlers = new HashSet<>();
|
||||
// Set of regexes matching handler ID of handlers that need the hack in GuiRecipe.startHeightHack().
|
||||
// We use regex here so that we can apply the height hack to entire mods with one entry.
|
||||
public static HashSet<Pattern> heightHackHandlerRegex = new HashSet<>();
|
||||
|
||||
// Map of handler ID to sort order.
|
||||
// Handlers will be sorted in ascending order, so smaller numbers show up earlier.
|
||||
@@ -117,7 +122,7 @@ public class NEIClientConfig {
|
||||
|
||||
tag.getTag("inventory.widgetsenabled").getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.widgetsenabled"));
|
||||
|
||||
|
||||
tag.getTag("inventory.hidden").getBooleanValue(false);
|
||||
tag.getTag("inventory.cheatmode").getIntValue(2);
|
||||
tag.getTag("inventory.lockmode").setComment("For those who can't help themselves.\nSet this to a mode and you will be unable to change it ingame").getIntValue(-1);
|
||||
@@ -163,6 +168,8 @@ public class NEIClientConfig {
|
||||
return isMouseScrollTransferEnabled();
|
||||
}
|
||||
});
|
||||
|
||||
tag.getTag("itemLoadingTimeout").getIntValue(500);
|
||||
|
||||
tag.getTag("command.creative").setDefaultValue("/gamemode {0} {1}");
|
||||
API.addOption(new OptionTextField("command.creative"));
|
||||
@@ -174,14 +181,31 @@ public class NEIClientConfig {
|
||||
API.addOption(new OptionTextField("command.rain"));
|
||||
tag.getTag("command.heal").setDefaultValue("");
|
||||
API.addOption(new OptionTextField("command.heal"));
|
||||
|
||||
|
||||
tag.getTag("inventory.worldSpecificBookmarks").setComment("Global or world specific bookmarks").getBooleanValue(false);
|
||||
API.addOption(new OptionToggleButton("inventory.worldSpecificBookmarks", true) {
|
||||
@Override
|
||||
public boolean onClick(int button) {
|
||||
super.onClick(button);
|
||||
initBookmarkFile(worldPath);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
tag.getTag("inventory.bookmarksEnabled").setComment("Enable/disable bookmarks").getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.bookmarksEnabled", true));
|
||||
tag.getTag("inventory.saveCurrentRecipeInBookmarksEnabled").setComment("Save Current Recipe in Bookmarks").getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.saveCurrentRecipeInBookmarksEnabled", true));
|
||||
tag.getTag("inventory.useNBTInBookmarks").setComment("Use NBT in Bookmarks").getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.useNBTInBookmarks", true));
|
||||
|
||||
tag.getTag("inventory.jei_style_tabs").setComment("Enable/disable JEI Style Tabs").getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButtonBoubs("inventory.jei_style_tabs", true));
|
||||
tag.getTag("inventory.jei_style_item_presence_overlay").setComment("Enable/disable JEI Style item presence overlay on ?-hover").getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.jei_style_item_presence_overlay", true));
|
||||
|
||||
tag.getTag("inventory.jei_style_recipe_catalyst").setComment("Enable/disable JEI Style Recipe Catalysts [experimental]").getBooleanValue(false);
|
||||
API.addOption(new OptionToggleButton("inventory.jei_style_recipe_catalyst", true));
|
||||
|
||||
|
||||
tag.getTag("inventory.creative_tab_style").setComment("Creative or JEI style tabs").getBooleanValue(false);
|
||||
API.addOption(new OptionToggleButton("inventory.creative_tab_style", true));
|
||||
|
||||
@@ -254,17 +278,22 @@ public class NEIClientConfig {
|
||||
return OptionList.getOptionList("nei.options");
|
||||
}
|
||||
|
||||
public static void loadWorld(String saveName) {
|
||||
public static void loadWorld(String worldPath) {
|
||||
NEIClientConfig.worldPath = worldPath;
|
||||
|
||||
setInternalEnabled(true);
|
||||
logger.debug("Loading "+(Minecraft.getMinecraft().isSingleplayer() ? "Local" : "Remote")+" World");
|
||||
bootNEI(ClientUtils.getWorld());
|
||||
|
||||
File saveDir = new File(CommonUtils.getMinecraftDir(), "saves/NEI/" + saveName);
|
||||
boolean newWorld = !saveDir.exists();
|
||||
if (newWorld)
|
||||
saveDir.mkdirs();
|
||||
final File specificDir = new File(CommonUtils.getMinecraftDir(), "saves/NEI/" + worldPath);
|
||||
final boolean newWorld = !specificDir.exists();
|
||||
|
||||
world = new ConfigSet(new File(saveDir, "NEI.dat"), new ConfigFile(new File(saveDir, "NEI.cfg")));
|
||||
if (newWorld) {
|
||||
specificDir.mkdirs();
|
||||
}
|
||||
|
||||
initBookmarkFile(worldPath);
|
||||
world = new ConfigSet(new File(specificDir, "NEI.dat"), new ConfigFile(new File(specificDir, "NEI.cfg")));
|
||||
onWorldLoad(newWorld);
|
||||
}
|
||||
|
||||
@@ -308,7 +337,6 @@ public class NEIClientConfig {
|
||||
GuiInfo.load();
|
||||
RecipeInfo.load();
|
||||
LayoutManager.load();
|
||||
ItemPanels.bookmarkPanel.loadBookmarks();
|
||||
NEIController.load();
|
||||
|
||||
configLoaded = true;
|
||||
@@ -337,6 +365,16 @@ public class NEIClientConfig {
|
||||
ItemSorter.loadConfig();
|
||||
}
|
||||
|
||||
private static void initBookmarkFile(String worldPath)
|
||||
{
|
||||
|
||||
if (!global.config.getTag("inventory.worldSpecificBookmarks").getBooleanValue()) {
|
||||
worldPath = "global";
|
||||
}
|
||||
|
||||
ItemPanels.bookmarkPanel.setBookmarkFile(worldPath);
|
||||
}
|
||||
|
||||
public static boolean isWorldSpecific(String setting) {
|
||||
if(world == null) return false;
|
||||
ConfigTag tag = world.config.getTag(setting, false);
|
||||
@@ -357,12 +395,21 @@ public class NEIClientConfig {
|
||||
public static boolean isBookmarkPanelHidden() {
|
||||
return !getBooleanSetting("inventory.bookmarksEnabled");
|
||||
}
|
||||
public static boolean saveCurrentRecipeInBookmarksEnabled() {
|
||||
return getBooleanSetting("inventory.saveCurrentRecipeInBookmarksEnabled");
|
||||
}
|
||||
public static boolean useNBTInBookmarks() {
|
||||
return getBooleanSetting("inventory.useNBTInBookmarks");
|
||||
}
|
||||
public static boolean areJEIStyleTabsVisible() {
|
||||
return getBooleanSetting("inventory.jei_style_tabs");
|
||||
}
|
||||
public static boolean isJEIStyleItemPresenceOverlayVisible() {
|
||||
return getBooleanSetting("inventory.jei_style_item_presence_overlay");
|
||||
}
|
||||
public static boolean areJEIStyleRecipeCatalystsVisible() {
|
||||
return getBooleanSetting("inventory.jei_style_recipe_catalyst");
|
||||
}
|
||||
public static boolean useCreativeTabStyle() {
|
||||
return getBooleanSetting("inventory.creative_tab_style");
|
||||
}
|
||||
@@ -370,7 +417,7 @@ public class NEIClientConfig {
|
||||
return enabledOverride && getBooleanSetting("inventory.widgetsenabled");
|
||||
}
|
||||
public static boolean loadHandlersFromJar() {
|
||||
return !getBooleanSetting("tools.handler_load_from_config");
|
||||
return !getBooleanSetting("tools.handler_load_from_config");
|
||||
}
|
||||
|
||||
public static void setEnabled(boolean flag) {
|
||||
@@ -406,6 +453,10 @@ public class NEIClientConfig {
|
||||
int i = getIntSetting("inventory.itemIDs");
|
||||
return i == 2 || (i == 1 && isEnabled() && !isHidden());
|
||||
}
|
||||
|
||||
public static int getItemLoadingTimeout() {
|
||||
return getIntSetting("itemLoadingTimeout");
|
||||
}
|
||||
|
||||
public static void toggleBooleanSetting(String setting) {
|
||||
ConfigTag tag = getSetting(setting);
|
||||
@@ -441,7 +492,7 @@ public class NEIClientConfig {
|
||||
public static boolean shouldInvertMouseScrollTransfer() {
|
||||
return !getBooleanSetting("inventory.invertMouseScrollTransfer");
|
||||
}
|
||||
|
||||
|
||||
public static boolean getMagnetMode() {
|
||||
return enabledActions.contains("magnet");
|
||||
}
|
||||
@@ -528,5 +579,5 @@ public class NEIClientConfig {
|
||||
if (file.isDirectory() && !saveFileNames.contains(file.getName()))
|
||||
ObfuscationRun.deleteDir(file, true);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import codechicken.lib.inventory.InventoryUtils;
|
||||
import codechicken.lib.util.LangProxy;
|
||||
import codechicken.nei.api.GuiInfo;
|
||||
import codechicken.nei.api.IInfiniteItemHandler;
|
||||
import codechicken.nei.api.INEIGuiHandler;
|
||||
import codechicken.nei.api.ItemInfo;
|
||||
import com.google.common.collect.Iterables;
|
||||
import net.minecraft.client.Minecraft;
|
||||
@@ -136,10 +135,7 @@ public class NEIClientUtils extends NEIServerUtils
|
||||
if (mode == 1 && stack.stackSize < stack.getMaxStackSize()) {
|
||||
giveStack(stack, stack.getMaxStackSize() - stack.stackSize);
|
||||
} else {
|
||||
int amount = getItemQuantity();
|
||||
if (amount == 0)
|
||||
amount = stack.getMaxStackSize();
|
||||
giveStack(stack, amount);
|
||||
giveStack(stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,7 +157,10 @@ public class NEIClientUtils extends NEIServerUtils
|
||||
final List<Iterable<Integer>> handlerSlots;
|
||||
try {
|
||||
GuiInfo.readLock.lock();
|
||||
handlerSlots = GuiInfo.guiHandlers.stream().map(handler -> handler.getItemSpawnSlots(gui, typestack)).collect(Collectors.toCollection(LinkedList::new));
|
||||
handlerSlots = GuiInfo.guiHandlers.stream()
|
||||
.map(handler -> handler.getItemSpawnSlots(gui, typestack))
|
||||
.filter(x -> x != null)
|
||||
.collect(Collectors.toCollection(LinkedList::new));
|
||||
} finally {
|
||||
GuiInfo.readLock.unlock();
|
||||
}
|
||||
|
||||
@@ -408,4 +408,8 @@ public class NEIServerUtils
|
||||
CompressedStreamTools.writeCompressed(tag, out);
|
||||
out.close();
|
||||
}
|
||||
|
||||
public static int divideCeil(int numerator, int denominator) {
|
||||
return (int) Math.ceil((float) numerator / denominator);
|
||||
}
|
||||
}
|
||||
@@ -63,8 +63,9 @@ public class SearchField extends TextField implements ItemFilterProvider
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTextColour() {
|
||||
if(ItemPanels.itemPanel.realItems.size() == 0) {
|
||||
public int getTextColour()
|
||||
{
|
||||
if (ItemPanels.itemPanel.getItems().isEmpty()) {
|
||||
return focused() ? 0xFFcc3300 : 0xFF993300;
|
||||
} else {
|
||||
return focused() ? 0xFFE0E0E0 : 0xFF909090;
|
||||
|
||||
@@ -18,8 +18,11 @@ import codechicken.nei.config.OptionKeyBind;
|
||||
import codechicken.nei.recipe.GuiCraftingRecipe;
|
||||
import codechicken.nei.recipe.GuiUsageRecipe;
|
||||
import codechicken.nei.recipe.ICraftingHandler;
|
||||
import codechicken.nei.recipe.IRecipeHandler;
|
||||
import codechicken.nei.recipe.IUsageHandler;
|
||||
import codechicken.nei.recipe.RecipeCatalysts;
|
||||
import codechicken.nei.recipe.RecipeInfo;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.inventory.Slot;
|
||||
@@ -29,6 +32,7 @@ import org.lwjgl.input.Keyboard;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This is the main class that handles item property configuration.
|
||||
@@ -284,4 +288,64 @@ public class API
|
||||
ItemInfo.itemVariants.put(item, variant);
|
||||
LayoutManager.markItemsDirty();
|
||||
}
|
||||
|
||||
public static void registerStackStringifyHandler(IStackStringifyHandler handler)
|
||||
{
|
||||
StackInfo.stackStringifyHandlers.add(handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an association between an ingredient and what it can craft. (i.e. Furnace ItemStack -> Smelting and Fuel Recipes)
|
||||
* Allows players to see what ingredient they need to craft in order to make recipes from a recipe category.
|
||||
* @param stack the ingredient that can craft recipes (like a furnace or crafting table)
|
||||
* @param handler the recipe category handled by the ingredient
|
||||
*/
|
||||
public static void addRecipeCatalyst(ItemStack stack, IRecipeHandler handler) {
|
||||
addRecipeCatalyst(Collections.singletonList(stack), handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an association between an ingredient and what it can craft. (i.e. Furnace ItemStack -> Smelting and Fuel Recipes)
|
||||
* Allows players to see what ingredient they need to craft in order to make recipes from a recipe category.
|
||||
* @param stacks the ingredients that can craft recipes (like a furnace or crafting table)
|
||||
* @param handler the recipe category handled by the ingredient
|
||||
*/
|
||||
public static void addRecipeCatalyst(List<ItemStack> stacks, IRecipeHandler handler) {
|
||||
String handlerID = handler.getOverlayIdentifier();
|
||||
if (handlerID != null) {
|
||||
addRecipeCatalyst(stacks, handler.getOverlayIdentifier());
|
||||
}
|
||||
else {
|
||||
NEIClientConfig.logger.warn(String.format("failed to add recipe catalyst, implement IRecipeHandler#getOverlayIdentifier for your handler %s", handler.getClass().getName()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an association between an ingredient and what it can craft. (i.e. Furnace ItemStack -> Smelting and Fuel Recipes)
|
||||
* Allows players to see what ingredient they need to craft in order to make recipes from a recipe category.
|
||||
* @param stack the ingredient that can craft recipes (like a furnace or crafting table)
|
||||
* @param handlerID recipe category identifier (see {@link IRecipeHandler#getOverlayIdentifier()})
|
||||
*/
|
||||
public static void addRecipeCatalyst(ItemStack stack, String handlerID) {
|
||||
addRecipeCatalyst(Collections.singletonList(stack), handlerID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an association between an ingredient and what it can craft. (i.e. Furnace ItemStack -> Smelting and Fuel Recipes)
|
||||
* Allows players to see what ingredient they need to craft in order to make recipes from a recipe category.
|
||||
* @param stacks the ingredients that can craft recipes (like a furnace or crafting table)
|
||||
* @param handlerID recipe category identifier (see {@link IRecipeHandler#getOverlayIdentifier()})
|
||||
*/
|
||||
public static void addRecipeCatalyst(List<ItemStack> stacks, String handlerID) {
|
||||
RecipeCatalysts.addRecipeCatalyst(stacks, handlerID);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void addRecipeCatalyst(ItemStack stack, Class<? extends IRecipeHandler> handler) {
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void addRecipeCatalyst(List<ItemStack> stacks, Class<? extends IRecipeHandler> handler) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,11 +3,11 @@ package codechicken.nei.api;
|
||||
import codechicken.nei.NEIChestGuiHandler;
|
||||
import codechicken.nei.NEICreativeGuiHandler;
|
||||
import codechicken.nei.NEIDummySlotHandler;
|
||||
import codechicken.nei.recipe.GuiRecipeCatalyst;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.client.gui.inventory.GuiContainerCreative;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
@@ -24,6 +24,7 @@ public class GuiInfo {
|
||||
API.registerNEIGuiHandler(new NEICreativeGuiHandler());
|
||||
API.registerNEIGuiHandler(new NEIChestGuiHandler());
|
||||
API.registerNEIGuiHandler(new NEIDummySlotHandler());
|
||||
API.registerNEIGuiHandler(new GuiRecipeCatalyst(null));
|
||||
customSlotGuis.add(GuiContainerCreative.class);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package codechicken.nei.api;
|
||||
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
public interface IStackStringifyHandler
|
||||
{
|
||||
|
||||
public NBTTagCompound convertItemStackToNBT(ItemStack stack, boolean saveStackSize);
|
||||
|
||||
public ItemStack convertNBTToItemStack(NBTTagCompound nbtTag);
|
||||
|
||||
public FluidStack getFluid(ItemStack stack);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package codechicken.nei.asm;
|
||||
|
||||
import codechicken.lib.asm.ASMHelper;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
|
||||
import static org.objectweb.asm.Opcodes.POP;
|
||||
import static org.objectweb.asm.Opcodes.PUTSTATIC;
|
||||
|
||||
public class GuiContainerManagerAPITransformer extends ClassVisitor {
|
||||
private final String tname;
|
||||
private boolean changed = false;
|
||||
|
||||
public GuiContainerManagerAPITransformer(int api, ClassVisitor cv, String tname) {
|
||||
super(api, cv);
|
||||
this.tname = tname;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodVisitor visitMethod(int access, String mname, String mdesc, String signature, String[] exceptions) {
|
||||
return new MethodVisitor(api, super.visitMethod(access, mname, mdesc, signature, exceptions)) {
|
||||
@Override
|
||||
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
|
||||
if (opcode == PUTSTATIC && "codechicken/nei/guihook/GuiContainerManager".equals(owner) && name.endsWith("Handlers") && desc.equals("Ljava/util/LinkedList;")) {
|
||||
ASMHelper.logger.warn("Found suspicious PUTSTATIC {} in {}#{}{}, replacing with POP!", name, tname, mname, mdesc);
|
||||
changed = true;
|
||||
super.visitInsn(POP);
|
||||
} else {
|
||||
super.visitFieldInsn(opcode, owner, name, desc);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public boolean isChanged() {
|
||||
return changed;
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,7 @@ public class NEITransformer implements IClassTransformer
|
||||
ASMInit.init();
|
||||
}
|
||||
|
||||
private final boolean paranoidMode = Boolean.getBoolean("nei.paranoid");
|
||||
private final ModularASMTransformer transformer = new ModularASMTransformer();
|
||||
private final Map<String, ASMBlock> asmblocks = ASMReader.loadResource("/assets/nei/asm/blocks.asm");
|
||||
|
||||
@@ -264,6 +265,14 @@ public class NEITransformer implements IClassTransformer
|
||||
}
|
||||
bytes = transformSubclasses(name, bytes);
|
||||
}
|
||||
if (paranoidMode && !tname.startsWith("codechicken.nei")) {
|
||||
ClassReader cr = new ClassReader(bytes);
|
||||
ClassWriter cw = new ClassWriter(0);
|
||||
GuiContainerManagerAPITransformer cv = new GuiContainerManagerAPITransformer(ASM5, cw, tname);
|
||||
cr.accept(cv, ClassReader.SKIP_DEBUG);
|
||||
if (cv.isChanged())
|
||||
bytes = cw.toByteArray();
|
||||
}
|
||||
|
||||
bytes = transformer.transform(name, bytes);
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL12;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.util.ArrayList;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
@@ -100,10 +101,12 @@ public class GuiItemIconDumper extends GuiScreen
|
||||
GL11.glEnable(GL12.GL_RESCALE_NORMAL);
|
||||
GL11.glColor4f(1, 1, 1, 1);
|
||||
|
||||
for(int i = 0; drawIndex < ItemPanels.itemPanel.realItems.size() && i < fit; drawIndex++, i++) {
|
||||
final ArrayList<ItemStack> items = ItemPanels.itemPanel.getItems();
|
||||
|
||||
for (int i = 0; drawIndex < items.size() && i < fit; drawIndex++, i++) {
|
||||
int x = i%cols * 18;
|
||||
int y = i/cols * 18;
|
||||
GuiContainerManager.drawItem(x+1, y+1, ItemPanels.itemPanel.realItems.get(drawIndex));
|
||||
GuiContainerManager.drawItem(x+1, y+1, items.get(drawIndex));
|
||||
}
|
||||
|
||||
GL11.glFlush();
|
||||
@@ -114,14 +117,19 @@ public class GuiItemIconDumper extends GuiScreen
|
||||
int rows = img.getHeight() / boxSize;
|
||||
int cols = img.getWidth() / boxSize;
|
||||
int fit = rows*cols;
|
||||
for(int i = 0; parseIndex < ItemPanels.itemPanel.realItems.size() && i < fit; parseIndex++, i++) {
|
||||
|
||||
final ArrayList<ItemStack> items = ItemPanels.itemPanel.getItems();
|
||||
|
||||
for(int i = 0; parseIndex < items.size() && i < fit; parseIndex++, i++) {
|
||||
int x = i%cols * boxSize;
|
||||
int y = i/cols * boxSize;
|
||||
exportImage(dir, img.getSubimage(x+borderSize, y+borderSize, iconSize, iconSize), ItemPanels.itemPanel.realItems.get(parseIndex));
|
||||
exportImage(dir, img.getSubimage(x+borderSize, y+borderSize, iconSize, iconSize), items.get(parseIndex));
|
||||
}
|
||||
|
||||
if(parseIndex >= ItemPanels.itemPanel.realItems.size())
|
||||
if (parseIndex >= items.size()) {
|
||||
returnScreen(new ChatComponentTranslation(opt.fullName()+".icon.dumped", "dumps/itempanel_icons"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static String cleanFileName(String name) {
|
||||
|
||||
@@ -8,17 +8,13 @@ import codechicken.nei.recipe.IRecipeHandler;
|
||||
import codechicken.nei.recipe.TemplateRecipeHandler;
|
||||
import codechicken.nei.util.NBTJson;
|
||||
import com.google.common.base.Objects;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.JsonToNBT;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.ChatComponentTranslation;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class HandlerDumper extends DataDumper
|
||||
|
||||
@@ -36,7 +36,7 @@ public class ItemPanelDumper extends DataDumper
|
||||
@Override
|
||||
public Iterable<String[]> dump(int mode) {
|
||||
LinkedList<String[]> list = new LinkedList<>();
|
||||
for (ItemStack stack : ItemPanels.itemPanel.realItems)
|
||||
for (ItemStack stack : ItemPanels.itemPanel.getItems())
|
||||
list.add(new String[]{
|
||||
Item.itemRegistry.getNameForObject(stack.getItem()),
|
||||
Integer.toString(Item.getIdFromItem(stack.getItem())),
|
||||
@@ -123,7 +123,7 @@ public class ItemPanelDumper extends DataDumper
|
||||
|
||||
public void dumpNBT(File file) throws IOException {
|
||||
NBTTagList list = new NBTTagList();
|
||||
for (ItemStack stack : ItemPanels.itemPanel.realItems)
|
||||
for (ItemStack stack : ItemPanels.itemPanel.getItems())
|
||||
list.appendTag(stack.writeToNBT(new NBTTagCompound()));
|
||||
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
@@ -134,7 +134,7 @@ public class ItemPanelDumper extends DataDumper
|
||||
|
||||
public void dumpJson(File file) throws IOException {
|
||||
PrintWriter p = new PrintWriter(file);
|
||||
for (ItemStack stack : ItemPanels.itemPanel.realItems) {
|
||||
for (ItemStack stack : ItemPanels.itemPanel.getItems()) {
|
||||
NBTTagCompound tag = stack.writeToNBT(new NBTTagCompound());
|
||||
tag.removeTag("Count");
|
||||
p.println(tag);
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
package codechicken.nei.drawable;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
|
||||
/*
|
||||
* 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
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package codechicken.nei.drawable;
|
||||
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.relauncher.SideOnly;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static codechicken.lib.gui.GuiDraw.drawMultilineTip;
|
||||
@@ -35,11 +36,11 @@ public class GuiContainerManager
|
||||
public GuiContainer window;
|
||||
|
||||
public static RenderItem drawItems = new RenderItem();
|
||||
public static LinkedList<IContainerTooltipHandler> tooltipHandlers = new LinkedList<>();
|
||||
public static LinkedList<IContainerInputHandler> inputHandlers = new LinkedList<>();
|
||||
public static LinkedList<IContainerDrawHandler> drawHandlers = new LinkedList<>();
|
||||
public static LinkedList<IContainerObjectHandler> objectHandlers = new LinkedList<>();
|
||||
public static LinkedList<IContainerSlotClickHandler> slotClickHandlers = new LinkedList<>();
|
||||
public static final LinkedList<IContainerTooltipHandler> tooltipHandlers = new HideousLinkedList<>(new CopyOnWriteArrayList<>());
|
||||
public static final LinkedList<IContainerInputHandler> inputHandlers = new HideousLinkedList<>(new CopyOnWriteArrayList<>());
|
||||
public static final LinkedList<IContainerDrawHandler> drawHandlers = new HideousLinkedList<>(new CopyOnWriteArrayList<>());
|
||||
public static final LinkedList<IContainerObjectHandler> objectHandlers = new HideousLinkedList<>(new CopyOnWriteArrayList<>());
|
||||
public static final LinkedList<IContainerSlotClickHandler> slotClickHandlers = new HideousLinkedList<>(new CopyOnWriteArrayList<>());
|
||||
|
||||
static {
|
||||
addSlotClickHandler(new DefaultSlotClickHandler());
|
||||
@@ -181,15 +182,29 @@ public class GuiContainerManager
|
||||
drawItem(i, j, itemstack, getFontRenderer(itemstack));
|
||||
}
|
||||
|
||||
public static void drawItem(int i, int j, ItemStack itemstack, boolean smallAmount) {
|
||||
drawItem(i, j, itemstack, getFontRenderer(itemstack), smallAmount);
|
||||
}
|
||||
|
||||
public static void drawItem(int i, int j, ItemStack itemstack, FontRenderer fontRenderer) {
|
||||
drawItem(i, j, itemstack, fontRenderer, false);
|
||||
}
|
||||
|
||||
private static int modelviewDepth = -1;
|
||||
private static final HashSet<String> stackTraces = new HashSet<>();
|
||||
|
||||
public static void drawItem(int i, int j, ItemStack itemstack, FontRenderer fontRenderer) {
|
||||
public static void drawItem(int i, int j, ItemStack itemstack, FontRenderer fontRenderer, boolean smallAmount) {
|
||||
GL11.glPushAttrib(GL11.GL_ENABLE_BIT);
|
||||
enable3DRender();
|
||||
float zLevel = drawItems.zLevel += 100F;
|
||||
try {
|
||||
drawItems.renderItemAndEffectIntoGUI(fontRenderer, renderEngine, itemstack, i, j);
|
||||
drawItems.renderItemOverlayIntoGUI(fontRenderer, renderEngine, itemstack, i, j);
|
||||
|
||||
if (!smallAmount) {
|
||||
drawItems.renderItemOverlayIntoGUI(fontRenderer, renderEngine, itemstack, i, j);
|
||||
} else if (itemstack.stackSize > 1) {
|
||||
drawBigStackSize(i, j, itemstack.stackSize);
|
||||
}
|
||||
|
||||
if (!checkMatrixStack())
|
||||
throw new IllegalStateException("Modelview matrix stack too deep");
|
||||
@@ -215,6 +230,28 @@ public class GuiContainerManager
|
||||
|
||||
enable2DRender();
|
||||
drawItems.zLevel = zLevel - 100;
|
||||
GL11.glPopAttrib();
|
||||
}
|
||||
|
||||
//copy from appeng.client.render.AppEngRenderItem
|
||||
protected static void drawBigStackSize(int offsetX, int offsetY, int amount)
|
||||
{
|
||||
final float scaleFactor = fontRenderer.getUnicodeFlag() ? 0.85f : 0.5f;
|
||||
final float inverseScaleFactor = 1.0f / scaleFactor;
|
||||
final String stackSize = String.valueOf( amount );
|
||||
|
||||
GL11.glDisable(GL11.GL_LIGHTING);
|
||||
GL11.glDisable(GL11.GL_DEPTH_TEST);
|
||||
GL11.glPushMatrix();
|
||||
GL11.glScaled(scaleFactor, scaleFactor, scaleFactor);
|
||||
|
||||
final int X = (int) ( ( (float) offsetX + 16.0f - fontRenderer.getStringWidth( stackSize ) * scaleFactor ) * inverseScaleFactor );
|
||||
final int Y = (int) ( ( (float) offsetY + 16.0f - 7.0f * scaleFactor ) * inverseScaleFactor );
|
||||
fontRenderer.drawStringWithShadow(stackSize, X, Y, 16777215);
|
||||
|
||||
GL11.glPopMatrix();
|
||||
GL11.glEnable(GL11.GL_LIGHTING);
|
||||
GL11.glEnable(GL11.GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
public static void enableMatrixStackLogging() {
|
||||
|
||||
@@ -0,0 +1,271 @@
|
||||
package codechicken.nei.guihook;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* A hideous LinkedList that is backed by an arbitrary list, for alternative characteristics while preserving
|
||||
* binary compatibility...
|
||||
* @param <E>
|
||||
*/
|
||||
final class HideousLinkedList<E> extends LinkedList<E> {
|
||||
private final List<E> backing;
|
||||
|
||||
HideousLinkedList(List<E> backing) {
|
||||
this.backing = backing;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return backing.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return backing.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
return backing.contains(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
return backing.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
return backing.toArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] toArray(T[] a) {
|
||||
return backing.toArray(a);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(E e) {
|
||||
return backing.add(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addFirst(E e) {
|
||||
backing.add(0, e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E getFirst() {
|
||||
if (backing.size() == 0) throw new NoSuchElementException();
|
||||
return(backing.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public E removeFirst() {
|
||||
E item = getFirst();
|
||||
backing.remove(0);
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLast(E e) {
|
||||
backing.add(backing.size(), e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E getLast() {
|
||||
if (backing.size() == 0) throw new NoSuchElementException();
|
||||
return backing.get(backing.size() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E removeLast() {
|
||||
E item = getLast();
|
||||
backing.remove(backing.size() - 1);
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E peek() {
|
||||
return backing.size() > 0 ? backing.get(0) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E peekFirst() {
|
||||
return backing.size() > 0 ? getFirst() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E peekLast() {
|
||||
return backing.size() > 0 ? getLast() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E poll() {
|
||||
return backing.size() > 0 ? removeFirst() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E pollFirst() {
|
||||
return poll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E pollLast() {
|
||||
return backing.size() > 0 ? removeLast() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void push(E e) {
|
||||
addFirst(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E pop() {
|
||||
return removeFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeFirstOccurrence(Object e) {
|
||||
return remove(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeLastOccurrence(Object e) {
|
||||
int idx = this.backing.lastIndexOf(e);
|
||||
if (idx != -1) {
|
||||
this.backing.remove(idx);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
return backing.remove(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
return backing.containsAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends E> c) {
|
||||
return backing.addAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(int index, Collection<? extends E> c) {
|
||||
return backing.addAll(index, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(Collection<?> c) {
|
||||
return backing.removeAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(Collection<?> c) {
|
||||
return backing.retainAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void replaceAll(UnaryOperator<E> operator) {
|
||||
backing.replaceAll(operator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sort(Comparator<? super E> c) {
|
||||
backing.sort(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
backing.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return backing.equals(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return backing.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E get(int index) {
|
||||
return backing.get(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E set(int index, E element) {
|
||||
return backing.set(index, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, E element) {
|
||||
backing.add(index, element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E remove(int index) {
|
||||
return backing.remove(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object o) {
|
||||
return backing.indexOf(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object o) {
|
||||
return backing.lastIndexOf(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator<E> listIterator() {
|
||||
return backing.listIterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator<E> listIterator(int index) {
|
||||
return backing.listIterator(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<E> subList(int fromIndex, int toIndex) {
|
||||
return backing.subList(fromIndex, toIndex);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spliterator<E> spliterator() {
|
||||
return backing.spliterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeIf(Predicate<? super E> filter) {
|
||||
return backing.removeIf(filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<E> stream() {
|
||||
return backing.stream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Stream<E> parallelStream() {
|
||||
return backing.parallelStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(Consumer<? super E> action) {
|
||||
backing.forEach(action);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
package codechicken.nei.recipe;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import codechicken.nei.util.NBTJson;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.PositionedStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BookmarkRecipeId
|
||||
{
|
||||
|
||||
public int position = -1;
|
||||
|
||||
public int recipetype = -1;
|
||||
|
||||
public String handlerName = null;
|
||||
|
||||
public List<NBTTagCompound> ingredients = new ArrayList<>();
|
||||
|
||||
|
||||
public BookmarkRecipeId(String handlerName, List<PositionedStack> stacks)
|
||||
{
|
||||
this.handlerName = handlerName;
|
||||
|
||||
for (PositionedStack pos : stacks) {
|
||||
final NBTTagCompound nbt = StackInfo.itemStackToNBT(getItemStackWithMinimumDamage(pos.items));
|
||||
if (nbt != null) {
|
||||
ingredients.add(nbt);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public BookmarkRecipeId(JsonObject json)
|
||||
{
|
||||
|
||||
if (json.get("handlerName") != null) {
|
||||
handlerName = json.get("handlerName").getAsString();
|
||||
}
|
||||
|
||||
if (json.get("ingredients") != null) {
|
||||
JsonArray arr = (JsonArray) json.get("ingredients");
|
||||
List<NBTTagCompound> ingredients = convertJsonArrayToIngredients(arr);
|
||||
|
||||
if (ingredients != null) {
|
||||
this.ingredients = ingredients;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean equalsIngredients(List<PositionedStack> stacks)
|
||||
{
|
||||
|
||||
if (ingredients.size() != stacks.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Short idx = 0;
|
||||
|
||||
for (PositionedStack pStack : stacks) {
|
||||
final NBTTagCompound tagCompoundA = StackInfo.itemStackToNBT(getItemStackWithMinimumDamage(pStack.items));
|
||||
final NBTTagCompound tagCompoundB = ingredients.get(idx);
|
||||
|
||||
if (tagCompoundB == null || !tagCompoundA.equals(tagCompoundB)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
idx++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public ItemStack getItemStackWithMinimumDamage(ItemStack[] stacks)
|
||||
{
|
||||
int damage = Short.MAX_VALUE;
|
||||
ItemStack result = stacks[0];
|
||||
|
||||
if (stacks.length > 1) {
|
||||
for (ItemStack stack : stacks) {
|
||||
if (stack.getItemDamage() < damage) {
|
||||
damage = stack.getItemDamage();
|
||||
result = stack;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result.copy();
|
||||
}
|
||||
|
||||
public JsonObject toJsonObject()
|
||||
{
|
||||
JsonObject json = new JsonObject();
|
||||
|
||||
if (handlerName != null) {
|
||||
json.add("handlerName", new JsonPrimitive(handlerName));
|
||||
json.add("ingredients", convertIngredientsToJsonArray(ingredients));
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
protected List<NBTTagCompound> convertJsonArrayToIngredients(JsonArray arr)
|
||||
{
|
||||
List<NBTTagCompound> ingredients = new ArrayList<>();
|
||||
|
||||
for (JsonElement elem : arr) {
|
||||
final NBTTagCompound nbt = (NBTTagCompound) NBTJson.toNbt(elem);
|
||||
|
||||
if (nbt == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ingredients.add(nbt);
|
||||
}
|
||||
|
||||
return ingredients;
|
||||
}
|
||||
|
||||
protected JsonArray convertIngredientsToJsonArray(List<NBTTagCompound> ingredients)
|
||||
{
|
||||
JsonArray arr = new JsonArray();
|
||||
|
||||
for (NBTTagCompound nbTag : ingredients) {
|
||||
arr.add(NBTJson.toJsonObject(nbTag));
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
public boolean equals(Object anObject)
|
||||
{
|
||||
if (this == anObject) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (anObject instanceof BookmarkRecipeId) {
|
||||
final BookmarkRecipeId anRecipeId = (BookmarkRecipeId) anObject;
|
||||
|
||||
if (!handlerName.equals(anRecipeId.handlerName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ingredients.size() != anRecipeId.ingredients.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int idx = 0; idx < ingredients.size(); idx++) {
|
||||
if (!ingredients.get(idx).equals(anRecipeId.ingredients.get(idx))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import net.minecraft.item.crafting.FurnaceRecipes;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static codechicken.nei.NEIClientUtils.translate;
|
||||
@@ -78,6 +77,11 @@ public class FuelRecipeHandler extends FurnaceRecipeHandler
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String specifyTransferRect() {
|
||||
return "fuel";
|
||||
}
|
||||
|
||||
public String getOverlayIdentifier() {
|
||||
return "fuel";
|
||||
}
|
||||
|
||||
@@ -115,6 +115,11 @@ public class FurnaceRecipeHandler extends TemplateRecipeHandler
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String specifyTransferRect() {
|
||||
return "smelting";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGuiTexture() {
|
||||
return "textures/gui/container/furnace.png";
|
||||
|
||||
@@ -6,6 +6,8 @@ import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import codechicken.nei.ItemPanels;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
@@ -46,9 +48,19 @@ public class GuiCraftingRecipe extends GuiRecipe
|
||||
handlers.sort(NEIClientConfig.HANDLER_COMPARATOR);
|
||||
|
||||
mc.displayGuiScreen(new GuiCraftingRecipe(prevscreen, handlers));
|
||||
|
||||
if (NEIClientConfig.saveCurrentRecipeInBookmarksEnabled() && !NEIClientUtils.shiftKey() && outputId.equals("item") && mc.currentScreen instanceof GuiRecipe) {
|
||||
GuiCraftingRecipe.openTargetRecipe((GuiRecipe)mc.currentScreen, (ItemStack)results[0]);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected static void openTargetRecipe(GuiRecipe currentScreen, ItemStack stackover)
|
||||
{
|
||||
currentScreen.openTargetRecipe(ItemPanels.bookmarkPanel.getBookmarkRecipeId(stackover));
|
||||
}
|
||||
|
||||
private GuiCraftingRecipe(GuiScreen prevgui, ArrayList<ICraftingHandler> handlers) {
|
||||
super(prevgui);
|
||||
currenthandlers = handlers;
|
||||
|
||||
@@ -35,6 +35,7 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
@@ -75,6 +76,7 @@ public abstract class GuiRecipe extends GuiContainer implements IGuiContainerOve
|
||||
|
||||
private final Rectangle area = new Rectangle();
|
||||
private final GuiRecipeTabs recipeTabs;
|
||||
private final GuiRecipeCatalyst guiRecipeCatalyst;
|
||||
private IRecipeHandler handler;
|
||||
private HandlerInfo handlerInfo;
|
||||
|
||||
@@ -83,6 +85,7 @@ public abstract class GuiRecipe extends GuiContainer implements IGuiContainerOve
|
||||
protected GuiRecipe(GuiScreen prevgui) {
|
||||
super(new ContainerRecipe());
|
||||
recipeTabs = new GuiRecipeTabs(this);
|
||||
guiRecipeCatalyst = new GuiRecipeCatalyst(this);
|
||||
slotcontainer = (ContainerRecipe) inventorySlots;
|
||||
|
||||
this.prevGui = prevgui;
|
||||
@@ -109,7 +112,11 @@ public abstract class GuiRecipe extends GuiContainer implements IGuiContainerOve
|
||||
private HeightHack() {
|
||||
trueHeight = height;
|
||||
|
||||
if (NEIClientConfig.heightHackHandlers.contains(handler.getHandlerId())) {
|
||||
boolean applyHeightHack =
|
||||
NEIClientConfig.heightHackHandlerRegex.stream()
|
||||
.map(pattern -> pattern.matcher(handler.getHandlerId()))
|
||||
.anyMatch(Matcher::matches);
|
||||
if (applyHeightHack) {
|
||||
// The old mods use the calculation ((height - 166) / 2) to compute the y-value of
|
||||
// the top edge of the NEI window.
|
||||
// guiTop is exactly that: the y-value of the top edge of the NEI window.
|
||||
@@ -193,20 +200,101 @@ public abstract class GuiRecipe extends GuiContainer implements IGuiContainerOve
|
||||
yShift = handlerInfo == null ? 0 : handlerInfo.getYShift();
|
||||
}
|
||||
|
||||
|
||||
public void setRecipePage(int idx) {
|
||||
setRecipePage(idx, 0);
|
||||
}
|
||||
|
||||
public void setRecipePage(int idx, int position) {
|
||||
recipetype = idx;
|
||||
if (recipetype < 0) recipetype = currenthandlers.size() - 1;
|
||||
else if (recipetype >= currenthandlers.size()) recipetype = 0;
|
||||
|
||||
handler = currenthandlers.get(recipetype);
|
||||
handlerInfo = getHandlerInfo(handler);
|
||||
page = 0;
|
||||
handlerInfo = GuiRecipeTab.getHandlerInfo(handler);
|
||||
page = Math.min(Math.max(0, position), handler.numRecipes() - 1) / getRecipesPerPage();
|
||||
recipeTabs.calcPageNumber();
|
||||
checkYShift();
|
||||
initOverlayButtons();
|
||||
}
|
||||
|
||||
public void openTargetRecipe(BookmarkRecipeId recipeId)
|
||||
{
|
||||
|
||||
if (recipeId == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (recipeId.recipetype == -1 || recipeId.position == -1) {
|
||||
recipeId.recipetype = 0;
|
||||
recipeId.position = 0;
|
||||
|
||||
if (recipeId.handlerName != null) {
|
||||
|
||||
for (int j = 0; j < currenthandlers.size(); j++) {
|
||||
IRecipeHandler localHandler = currenthandlers.get(j);
|
||||
HandlerInfo localHandlerInfo = GuiRecipeTab.getHandlerInfo(localHandler);
|
||||
|
||||
if (localHandlerInfo.getHandlerName().equals(recipeId.handlerName)) {
|
||||
recipeId.recipetype = j;
|
||||
|
||||
if (!recipeId.ingredients.isEmpty()) {
|
||||
for (int i = 0; i < localHandler.numRecipes(); i++) {
|
||||
|
||||
if (recipeId.equalsIngredients(localHandler.getIngredientStacks(i))) {
|
||||
recipeId.position = i;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
setRecipePage(recipeId.recipetype, recipeId.position);
|
||||
}
|
||||
|
||||
public List<PositionedStack> getFocusedRecipeIngredients()
|
||||
{
|
||||
final int recipesPerPage = getRecipesPerPage();
|
||||
|
||||
for (int idx = page * recipesPerPage; idx < handler.numRecipes() && idx < (page + 1) * recipesPerPage; idx++) {
|
||||
if (recipeInFocus(idx)) {
|
||||
return handler.getIngredientStacks(idx);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected boolean recipeInFocus(int idx)
|
||||
{
|
||||
final PositionedStack result = handler.getResultStack(idx);
|
||||
if (result != null && isMouseOver(result, idx)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final List<PositionedStack> stacks = handler.getOtherStacks(idx);
|
||||
for (PositionedStack stack : stacks) {
|
||||
if (isMouseOver(stack, idx)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getHandlerName()
|
||||
{
|
||||
return handlerInfo.getHandlerName();
|
||||
}
|
||||
|
||||
public IRecipeHandler getHandler() {
|
||||
return handler;
|
||||
}
|
||||
@@ -219,7 +307,6 @@ public abstract class GuiRecipe extends GuiContainer implements IGuiContainerOve
|
||||
return IntStream.range(minIndex, maxIndex).boxed().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void keyTyped(char c, int i) {
|
||||
if (i == Keyboard.KEY_ESCAPE) //esc
|
||||
@@ -354,21 +441,6 @@ public abstract class GuiRecipe extends GuiContainer implements IGuiContainerOve
|
||||
setRecipePage(--recipetype);
|
||||
}
|
||||
|
||||
public HandlerInfo getHandlerInfo(IRecipeHandler handler) {
|
||||
final String handlerID;
|
||||
if(handler instanceof TemplateRecipeHandler) {
|
||||
handlerID = (((TemplateRecipeHandler)handler).getOverlayIdentifier());
|
||||
} else {
|
||||
handlerID = null;
|
||||
}
|
||||
HandlerInfo info = GuiRecipeTab.getHandlerInfo(handler.getHandlerId(), handlerID);
|
||||
|
||||
if (info == null)
|
||||
return GuiRecipeTab.DEFAULT_HANDLER_INFO;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
private void overlayRecipe(int recipe) {
|
||||
final IRecipeOverlayRenderer renderer = handler.getOverlayRenderer(firstGui, recipe);
|
||||
final IOverlayHandler overlayHandler = handler.getOverlayHandler(firstGui, recipe);
|
||||
@@ -384,6 +456,7 @@ public abstract class GuiRecipe extends GuiContainer implements IGuiContainerOve
|
||||
}
|
||||
|
||||
public void refreshPage() {
|
||||
RecipeCatalysts.updatePosition(ySize - BG_TOP_HEIGHT - (GuiRecipeCatalyst.fullBorder * 2));
|
||||
refreshSlots();
|
||||
final int recipesPerPage = getRecipesPerPage();
|
||||
final boolean multiplepages = handler.numRecipes() > recipesPerPage;
|
||||
@@ -433,6 +506,13 @@ public abstract class GuiRecipe extends GuiContainer implements IGuiContainerOve
|
||||
PositionedStack result = handler.getResultStack(i);
|
||||
if (result != null)
|
||||
slotcontainer.addSlot(result, p.x, p.y);
|
||||
|
||||
List<PositionedStack> catalysts = RecipeCatalysts.getRecipeCatalysts(handler);
|
||||
for (PositionedStack catalyst : catalysts) {
|
||||
int xOffset = -GuiRecipeCatalyst.ingredientSize + 1;
|
||||
int yOffset = BG_TOP_Y + GuiRecipeCatalyst.fullBorder;
|
||||
slotcontainer.addSlot(catalyst, xOffset, yOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -517,6 +597,9 @@ public abstract class GuiRecipe extends GuiContainer implements IGuiContainerOve
|
||||
RenderHelper.enableGUIStandardItemLighting();
|
||||
OpenGlHelper.setLightmapTextureCoords(OpenGlHelper.lightmapTexUnit, 240f, 240f);
|
||||
recipeTabs.draw(mouseX, mouseY);
|
||||
if (NEIClientConfig.areJEIStyleRecipeCatalystsVisible()) {
|
||||
guiRecipeCatalyst.draw();
|
||||
}
|
||||
RenderHelper.disableStandardItemLighting();
|
||||
}
|
||||
|
||||
@@ -579,8 +662,12 @@ public abstract class GuiRecipe extends GuiContainer implements IGuiContainerOve
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private int getRecipesPerPage() {
|
||||
return getRecipesPerPage(handlerInfo);
|
||||
}
|
||||
|
||||
private int getRecipesPerPage(HandlerInfo handlerInfo) {
|
||||
if(handlerInfo != null)
|
||||
return Math.max(Math.min(((ySize - (buttonHeight*3)) / handlerInfo.getHeight()), handlerInfo.getMaxRecipesPerPage()), 1);
|
||||
else
|
||||
@@ -618,9 +705,7 @@ public abstract class GuiRecipe extends GuiContainer implements IGuiContainerOve
|
||||
@Override
|
||||
public boolean hideItemPanelSlot(GuiContainer gui, int x, int y, int w, int h) {
|
||||
// Because some of the handlers *cough avaritia* are oversized
|
||||
Rectangle rect = new Rectangle(area);
|
||||
|
||||
return rect.contains(x, y, w, h);
|
||||
return area.intersects(x, y, w, h);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
package codechicken.nei.recipe;
|
||||
|
||||
import codechicken.nei.api.INEIGuiAdapter;
|
||||
import codechicken.nei.drawable.GuiElementDuex;
|
||||
import codechicken.nei.drawable.GuiElementScalable;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import org.lwjgl.util.Rectangle;
|
||||
|
||||
public class GuiRecipeCatalyst extends INEIGuiAdapter {
|
||||
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;
|
||||
|
||||
private static final Rectangle catalystRect = new Rectangle();
|
||||
private static final Rectangle targetRect = new Rectangle();
|
||||
|
||||
public GuiRecipeCatalyst(GuiRecipe guiRecipe) {
|
||||
this.guiRecipe = guiRecipe;
|
||||
}
|
||||
|
||||
public void draw() {
|
||||
if (guiRecipe == null) return;
|
||||
int catalystsSize = RecipeCatalysts.getRecipeCatalysts(guiRecipe.getHandler()).size();
|
||||
if (catalystsSize == 0) return;
|
||||
|
||||
int availableHeight = RecipeCatalysts.getHeight();
|
||||
int columnCount = RecipeCatalysts.getColumnCount(availableHeight, catalystsSize);
|
||||
int rowCount = RecipeCatalysts.getRowCount(availableHeight, catalystsSize);
|
||||
int width, height, xPos, yPos;
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@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;
|
||||
|
||||
int availableHeight = RecipeCatalysts.getHeight();
|
||||
int columnCount = RecipeCatalysts.getColumnCount(availableHeight, catalystsSize);
|
||||
int rowCount = RecipeCatalysts.getRowCount(availableHeight, catalystsSize);
|
||||
int margin = 4;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -157,6 +157,24 @@ public abstract class GuiRecipeTab extends Widget {
|
||||
selected = handler == current;
|
||||
}
|
||||
|
||||
public static HandlerInfo getHandlerInfo(IRecipeHandler handler)
|
||||
{
|
||||
final String handlerID;
|
||||
|
||||
if (handler instanceof TemplateRecipeHandler) {
|
||||
handlerID = ((TemplateRecipeHandler) handler).getOverlayIdentifier();
|
||||
} else {
|
||||
handlerID = null;
|
||||
}
|
||||
|
||||
HandlerInfo info = getHandlerInfo(handler.getHandlerId(), handlerID);
|
||||
|
||||
if (info == null)
|
||||
return GuiRecipeTab.DEFAULT_HANDLER_INFO;
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
public static HandlerInfo getHandlerInfo(String name, String name2) {
|
||||
HandlerInfo res = handlerMap.get(name);
|
||||
if (res == null) res = handlerMap.get(name2);
|
||||
|
||||
@@ -28,11 +28,18 @@ public class GuiUsageRecipe extends GuiRecipe
|
||||
handlers = serialUsageHandlers.stream().map(h -> h.getUsageHandler(inputId, ingredients))
|
||||
.filter(h -> h.numRecipes() > 0)
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
|
||||
handlers.addAll(ItemList.forkJoinPool.submit(() -> usagehandlers.parallelStream()
|
||||
.map(h -> h.getUsageHandler(inputId, ingredients))
|
||||
.filter(h -> h.numRecipes() > 0)
|
||||
.collect(Collectors.toCollection(ArrayList::new))).get());
|
||||
|
||||
if (NEIClientConfig.areJEIStyleRecipeCatalystsVisible()) {
|
||||
handlers.addAll(ItemList.forkJoinPool.submit(() -> usagehandlers.parallelStream()
|
||||
.map(h -> h.getUsageAndCatalystHandler(inputId, ingredients))
|
||||
.filter(h -> h.numRecipes() > 0)
|
||||
.collect(Collectors.toCollection(ArrayList::new))).get());
|
||||
} else {
|
||||
handlers.addAll(ItemList.forkJoinPool.submit(() -> usagehandlers.parallelStream()
|
||||
.map(h -> h.getUsageHandler(inputId, ingredients))
|
||||
.filter(h -> h.numRecipes() > 0)
|
||||
.collect(Collectors.toCollection(ArrayList::new))).get());
|
||||
}
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
|
||||
@@ -16,7 +16,7 @@ import org.apache.logging.log4j.Level;
|
||||
public class HandlerInfo {
|
||||
public static int DEFAULT_HEIGHT = 65;
|
||||
public static int DEFAULT_WIDTH = 166;
|
||||
public static int DEFAULT_MAX_PER_PAGE = 2;
|
||||
public static int DEFAULT_MAX_PER_PAGE = 1;
|
||||
|
||||
private String handlerName;
|
||||
|
||||
|
||||
@@ -89,6 +89,15 @@ public interface IRecipeHandler
|
||||
* @return An instance of {@link IOverlayHandler} to be used for rendering the overlay of this specific recipe.
|
||||
*/
|
||||
public IOverlayHandler getOverlayHandler(GuiContainer gui, int recipe);
|
||||
/**
|
||||
* Simply works with the {@link codechicken.nei.api.DefaultOverlayRenderer}
|
||||
* If the current container has been registered with this identifier, the question mark appears and an overlay guide can be drawn.
|
||||
*
|
||||
* @return The overlay identifier of this recipe type.
|
||||
*/
|
||||
public default String getOverlayIdentifier() {
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @return The number of recipes that can fit on a page in the viewer (1 or 2)
|
||||
|
||||
@@ -15,5 +15,12 @@ public interface IUsageHandler extends IRecipeHandler
|
||||
* @param ingredients Objects representing the ingredients that matching recipes must contain.
|
||||
* @return An instance of {@link IUsageHandler} configured with a list of recipes that contain matching input
|
||||
*/
|
||||
public IUsageHandler getUsageHandler(String inputId, Object... ingredients);
|
||||
IUsageHandler getUsageHandler(String inputId, Object... ingredients);
|
||||
|
||||
/**
|
||||
* See {@link TemplateRecipeHandler#getUsageAndCatalystHandler} for implementation
|
||||
*/
|
||||
default IUsageHandler getUsageAndCatalystHandler(String inputId, Object... ingredients) {
|
||||
return getUsageHandler(inputId, ingredients);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package codechicken.nei.recipe;
|
||||
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIServerUtils;
|
||||
import codechicken.nei.PositionedStack;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class RecipeCatalysts {
|
||||
private static final Map<String, List<ItemStack>> recipeCatalystMap = new HashMap<>();
|
||||
private static Map<String, List<PositionedStack>> positionedRecipeCatalystMap = new HashMap<>();
|
||||
private static int heightCache;
|
||||
|
||||
public static void addRecipeCatalyst(List<ItemStack> stacks, String handlerID) {
|
||||
if (handlerID == null) return;
|
||||
if (recipeCatalystMap.containsKey(handlerID)) {
|
||||
recipeCatalystMap.get(handlerID).addAll(stacks);
|
||||
} else {
|
||||
// use ArrayList initializer to prevent UOE
|
||||
recipeCatalystMap.put(handlerID, new ArrayList<>(stacks));
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, List<PositionedStack>> getPositionedRecipeCatalystMap() {
|
||||
return positionedRecipeCatalystMap;
|
||||
}
|
||||
|
||||
public static List<PositionedStack> getRecipeCatalysts(IRecipeHandler handler) {
|
||||
return getRecipeCatalysts(handler.getOverlayIdentifier());
|
||||
}
|
||||
|
||||
public static List<PositionedStack> getRecipeCatalysts(String handlerID) {
|
||||
if (!NEIClientConfig.areJEIStyleTabsVisible() || !NEIClientConfig.areJEIStyleRecipeCatalystsVisible()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return positionedRecipeCatalystMap.getOrDefault(handlerID, Collections.emptyList());
|
||||
}
|
||||
|
||||
public static boolean containsCatalyst(IRecipeHandler handler, ItemStack candidate) {
|
||||
return containsCatalyst(handler.getOverlayIdentifier(), candidate);
|
||||
}
|
||||
|
||||
public static boolean containsCatalyst(String handlerID, ItemStack candidate) {
|
||||
return recipeCatalystMap.getOrDefault(handlerID, Collections.emptyList()).stream()
|
||||
.anyMatch(s -> NEIServerUtils.areStacksSameType(s, candidate));
|
||||
}
|
||||
|
||||
public static void updatePosition(int availableHeight) {
|
||||
if (availableHeight == heightCache) return;
|
||||
|
||||
Map<String, List<PositionedStack>> newMap = new HashMap<>();
|
||||
for (Map.Entry<String, List<ItemStack>> entry : recipeCatalystMap.entrySet()) {
|
||||
List<ItemStack> catalysts = entry.getValue();
|
||||
List<PositionedStack> newStacks = new ArrayList<>();
|
||||
int rowCount = getRowCount(availableHeight, catalysts.size());
|
||||
|
||||
for (int index = 0; index < catalysts.size(); index++) {
|
||||
ItemStack catalyst = catalysts.get(index);
|
||||
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 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);
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static boolean containsCatalyst(Class<? extends IRecipeHandler> handler, ItemStack candidate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,6 +10,9 @@ 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 net.minecraft.init.Blocks;
|
||||
import net.minecraft.init.Items;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@@ -119,5 +122,11 @@ public class RecipeInfo
|
||||
|
||||
API.registerRecipeHandler(new ProfilerRecipeHandler(true));
|
||||
API.registerUsageHandler(new ProfilerRecipeHandler(false));
|
||||
|
||||
API.addRecipeCatalyst(new ItemStack(Blocks.crafting_table), "crafting");
|
||||
API.addRecipeCatalyst(new ItemStack(Blocks.furnace), new FurnaceRecipeHandler());
|
||||
API.addRecipeCatalyst(new ItemStack(Items.brewing_stand), new BrewingRecipeHandler());
|
||||
API.addRecipeCatalyst(new ItemStack(Blocks.furnace), new FuelRecipeHandler());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,9 +5,12 @@ import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.NEIClientUtils;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.guihook.IContainerInputHandler;
|
||||
import codechicken.nei.PositionedStack;
|
||||
import net.minecraft.client.gui.inventory.GuiContainer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class RecipeItemInputHandler implements IContainerInputHandler
|
||||
{
|
||||
@Override
|
||||
@@ -23,9 +26,17 @@ public class RecipeItemInputHandler implements IContainerInputHandler
|
||||
if(keyCode == NEIClientConfig.getKeyBinding("gui.usage"))
|
||||
return GuiUsageRecipe.openRecipeGui("item", stackover.copy());
|
||||
|
||||
if(keyCode == NEIClientConfig.getKeyBinding("gui.bookmark")) {
|
||||
if (keyCode == NEIClientConfig.getKeyBinding("gui.bookmark")) {
|
||||
NEIClientConfig.logger.debug("Adding or removing {} from bookmarks", stackover.getDisplayName());
|
||||
ItemPanels.bookmarkPanel.addOrRemoveItem(stackover.copy());
|
||||
List<PositionedStack> ingredients = null;
|
||||
String handlerName = "";
|
||||
|
||||
if (gui instanceof GuiRecipe && NEIClientConfig.saveCurrentRecipeInBookmarksEnabled()) {
|
||||
ingredients = ((GuiRecipe) gui).getFocusedRecipeIngredients();
|
||||
handlerName = ((GuiRecipe) gui).getHandlerName();
|
||||
}
|
||||
|
||||
ItemPanels.bookmarkPanel.addOrRemoveItem(stackover.copy(), handlerName, ingredients);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -42,27 +53,32 @@ public class RecipeItemInputHandler implements IContainerInputHandler
|
||||
if (!(gui instanceof GuiRecipe))
|
||||
return false;
|
||||
|
||||
//disabled open recipe gui if hold shift (player have move recipe)
|
||||
if (button == 0 && ItemPanels.bookmarkPanel.getStackMouseOver(mousex, mousey) != null && NEIClientUtils.shiftKey()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(button == 0)
|
||||
return GuiCraftingRecipe.openRecipeGui("item", stackover.copy());
|
||||
|
||||
if(button == 1)
|
||||
return GuiUsageRecipe.openRecipeGui("item", stackover.copy());
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onKeyTyped(GuiContainer gui, char keyChar, int keyID)
|
||||
public void onKeyTyped(GuiContainer gui, char keyChar, int keyID)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMouseClicked(GuiContainer gui, int mousex, int mousey, int button)
|
||||
public void onMouseClicked(GuiContainer gui, int mousex, int mousey, int button)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMouseUp(GuiContainer gui, int mousex, int mousey, int button)
|
||||
public void onMouseUp(GuiContainer gui, int mousex, int mousey, int button)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -71,18 +87,18 @@ public class RecipeItemInputHandler implements IContainerInputHandler
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean mouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onMouseScrolled(GuiContainer gui, int mousex, int mousey, int scrolled)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onMouseDragged(GuiContainer gui, int mousex, int mousey, int button, long heldTime)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
package codechicken.nei.recipe;
|
||||
|
||||
import codechicken.nei.api.IStackStringifyHandler;
|
||||
import codechicken.nei.recipe.stackinfo.DefaultStackStringifyHandler;
|
||||
import codechicken.nei.recipe.stackinfo.GTFluidStackStringifyHandler;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class StackInfo
|
||||
{
|
||||
|
||||
public static final ArrayList<IStackStringifyHandler> stackStringifyHandlers = new ArrayList<>();
|
||||
|
||||
static {
|
||||
stackStringifyHandlers.add(new DefaultStackStringifyHandler());
|
||||
stackStringifyHandlers.add(new GTFluidStackStringifyHandler());
|
||||
}
|
||||
|
||||
public static NBTTagCompound itemStackToNBT(ItemStack stack)
|
||||
{
|
||||
return itemStackToNBT(stack, true);
|
||||
}
|
||||
|
||||
public static NBTTagCompound itemStackToNBT(ItemStack stack, boolean saveStackSize)
|
||||
{
|
||||
NBTTagCompound nbTag = null;
|
||||
|
||||
for (int i = stackStringifyHandlers.size() - 1; i >= 0 && nbTag == null; i--) {
|
||||
nbTag = stackStringifyHandlers.get(i).convertItemStackToNBT(stack, saveStackSize);
|
||||
}
|
||||
|
||||
return nbTag;
|
||||
}
|
||||
|
||||
public static ItemStack loadFromNBT(NBTTagCompound nbtTag)
|
||||
{
|
||||
ItemStack stack = null;
|
||||
|
||||
for (int i = stackStringifyHandlers.size() - 1; i >= 0 && stack == null; i--) {
|
||||
stack = stackStringifyHandlers.get(i).convertNBTToItemStack(nbtTag);
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
public static boolean equalItemAndNBT(ItemStack stackA, ItemStack stackB, boolean useNBT)
|
||||
{
|
||||
if (!stackA.isItemEqual(stackB)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (useNBT) {
|
||||
NBTTagCompound tagCompoundA = itemStackToNBT(stackA, false);
|
||||
NBTTagCompound tagCompoundB = itemStackToNBT(stackB, false);
|
||||
|
||||
return tagCompoundA == null && tagCompoundB == null || tagCompoundA != null && tagCompoundB != null && tagCompoundA.equals(tagCompoundB);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static FluidStack getFluid(ItemStack stack)
|
||||
{
|
||||
FluidStack fluid = null;
|
||||
|
||||
for (int i = stackStringifyHandlers.size() - 1; i >= 0 && fluid == null; i--) {
|
||||
fluid = stackStringifyHandlers.get(i).getFluid(stack);
|
||||
}
|
||||
|
||||
return fluid;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -442,6 +442,7 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
|
||||
*
|
||||
* @return The overlay identifier of this recipe type.
|
||||
*/
|
||||
@Override
|
||||
public String getOverlayIdentifier() {
|
||||
return null;
|
||||
}
|
||||
@@ -550,6 +551,35 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
|
||||
return handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* First look up {@link RecipeCatalysts} whether target ingredient is registered for it.
|
||||
* If so, load all recipes for this handler.
|
||||
* Fallback to {@link TemplateRecipeHandler#getUsageHandler}.
|
||||
*/
|
||||
public IUsageHandler getUsageAndCatalystHandler(String inputId, Object... ingredients) {
|
||||
TemplateRecipeHandler handler = newInstance();
|
||||
if (inputId.equals("item")) {
|
||||
ItemStack candidate = (ItemStack) ingredients[0];
|
||||
if (RecipeCatalysts.containsCatalyst(handler, candidate)) {
|
||||
for (RecipeTransferRect rect : transferRects) {
|
||||
if (specifyTransferRect() == null || Objects.equals(rect.outputId, specifyTransferRect())) {
|
||||
handler.loadCraftingRecipes(rect.outputId, rect.results);
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.getUsageHandler(inputId, ingredients);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this if you have multiple {@link RecipeTransferRect}s.
|
||||
* Used for {@link TemplateRecipeHandler#getUsageAndCatalystHandler}.
|
||||
*/
|
||||
public String specifyTransferRect() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public int numRecipes() {
|
||||
return arecipes.size();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package codechicken.nei.recipe.stackinfo;
|
||||
|
||||
import codechicken.nei.api.IStackStringifyHandler;
|
||||
import cpw.mods.fml.common.registry.GameData;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.fluids.FluidContainerRegistry;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.IFluidContainerItem;
|
||||
|
||||
public class DefaultStackStringifyHandler implements IStackStringifyHandler
|
||||
{
|
||||
|
||||
public NBTTagCompound convertItemStackToNBT(ItemStack stack, boolean saveStackSize)
|
||||
{
|
||||
final String strId = Item.itemRegistry.getNameForObject(stack.getItem());
|
||||
|
||||
if (strId == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final NBTTagCompound nbTag = new NBTTagCompound();
|
||||
nbTag.setString("strId", strId);
|
||||
nbTag.setInteger("Count", Math.max(saveStackSize? stack.stackSize: 1, 1));
|
||||
nbTag.setShort("Damage", (short)stack.getItemDamage());
|
||||
|
||||
if (stack.hasTagCompound()) {
|
||||
nbTag.setTag("tag", stack.getTagCompound());
|
||||
}
|
||||
|
||||
return nbTag;
|
||||
}
|
||||
|
||||
public ItemStack convertNBTToItemStack(NBTTagCompound nbtTag)
|
||||
{
|
||||
final String strId = nbtTag.getString("strId");
|
||||
|
||||
nbtTag = (NBTTagCompound)nbtTag.copy();
|
||||
nbtTag.setInteger("id", GameData.getItemRegistry().getId(strId)); //getObject
|
||||
|
||||
final ItemStack stack = ItemStack.loadItemStackFromNBT(nbtTag);
|
||||
|
||||
if (stack != null) {
|
||||
stack.stackSize = nbtTag.getInteger("Count");
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
|
||||
public FluidStack getFluid(ItemStack stack)
|
||||
{
|
||||
FluidStack fluidStack = FluidContainerRegistry.getFluidForFilledItem(stack);
|
||||
|
||||
if (fluidStack == null && stack.getItem() instanceof IFluidContainerItem) {
|
||||
fluidStack = ((IFluidContainerItem) stack.getItem()).getFluid(stack);
|
||||
}
|
||||
|
||||
return fluidStack;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package codechicken.nei.recipe.stackinfo;
|
||||
|
||||
import codechicken.nei.api.IStackStringifyHandler;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraftforge.fluids.Fluid;
|
||||
import net.minecraftforge.fluids.FluidRegistry;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class GTFluidStackStringifyHandler implements IStackStringifyHandler
|
||||
{
|
||||
|
||||
public static Class GTDisplayFluid = null;
|
||||
public static Method getFluidDisplayStack = null;
|
||||
public static Method getFluidFromDisplayStack = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
final Class gtUtility = Class.forName("gregtech.api.util.GT_Utility");
|
||||
|
||||
GTDisplayFluid = Class.forName("gregtech.common.items.GT_FluidDisplayItem");
|
||||
getFluidFromDisplayStack = gtUtility.getMethod("getFluidFromDisplayStack", ItemStack.class);
|
||||
getFluidDisplayStack = gtUtility.getMethod("getFluidDisplayStack", FluidStack.class, boolean.class);
|
||||
|
||||
} catch (Exception ignored) { /*Do nothing*/ }
|
||||
}
|
||||
|
||||
public NBTTagCompound convertItemStackToNBT(ItemStack stack, boolean saveStackSize)
|
||||
{
|
||||
|
||||
if (GTDisplayFluid != null && GTDisplayFluid.isInstance(stack.getItem())) {
|
||||
final FluidStack fluidStack = getFluid(stack);
|
||||
|
||||
if (fluidStack != null) {
|
||||
final NBTTagCompound nbTag = new NBTTagCompound();
|
||||
nbTag.setString("gtFluidName", fluidStack.getFluid().getName());
|
||||
nbTag.setInteger("Count", saveStackSize? fluidStack.amount: 1);
|
||||
return nbTag;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public ItemStack convertNBTToItemStack(NBTTagCompound nbtTag)
|
||||
{
|
||||
|
||||
if (getFluidDisplayStack != null && nbtTag.hasKey("gtFluidName")) {
|
||||
final String fluidName = nbtTag.getString("gtFluidName");
|
||||
final Fluid fluid = FluidRegistry.getFluid(fluidName);
|
||||
final int amount = nbtTag.getInteger("Count");
|
||||
|
||||
try {
|
||||
final Object obj = getFluidDisplayStack.invoke(null, new FluidStack(fluid, amount), true);
|
||||
|
||||
if (obj != null) {
|
||||
return (ItemStack) obj;
|
||||
}
|
||||
|
||||
} catch (Exception e) {}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public FluidStack getFluid(ItemStack stack)
|
||||
{
|
||||
|
||||
if (getFluidFromDisplayStack != null && GTDisplayFluid != null && GTDisplayFluid.isInstance(stack.getItem())) {
|
||||
try {
|
||||
final Object obj = getFluidFromDisplayStack.invoke(null, stack);
|
||||
|
||||
if (obj != null) {
|
||||
return (FluidStack) obj;
|
||||
}
|
||||
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,7 +34,11 @@ public class NBTJson {
|
||||
private static final Gson gson = new GsonBuilder().create();
|
||||
|
||||
public static String toJson(NBTTagCompound tag) {
|
||||
final String jsonString = toJsonObject(tag).toString();
|
||||
return toJson(toJsonObject(tag));
|
||||
}
|
||||
|
||||
public static String toJson(JsonElement json) {
|
||||
final String jsonString = json.toString();
|
||||
return gson.toJson(parser.parse(jsonString));
|
||||
}
|
||||
|
||||
@@ -50,6 +54,24 @@ public class NBTJson {
|
||||
root.add(nbtEntry.getKey(), toJsonObject(nbtEntry.getValue()));
|
||||
}
|
||||
return root;
|
||||
} else if (nbt instanceof NBTTagByte) {
|
||||
// Number (byte)
|
||||
return new JsonPrimitive(Byte.toString(((NBTTagByte) nbt).func_150290_f()) + 'B');
|
||||
} else if (nbt instanceof NBTTagShort) {
|
||||
// Number (short)
|
||||
return new JsonPrimitive(Short.toString(((NBTTagShort) nbt).func_150289_e()) + 'S');
|
||||
} else if (nbt instanceof NBTTagInt) {
|
||||
// Number (int)
|
||||
return new JsonPrimitive(((NBTTagInt) nbt).func_150287_d());
|
||||
} else if (nbt instanceof NBTTagLong) {
|
||||
// Number (long)
|
||||
return new JsonPrimitive(Long.toString(((NBTTagLong) nbt).func_150291_c()) + 'L');
|
||||
} else if (nbt instanceof NBTTagFloat) {
|
||||
// Number (float)
|
||||
return new JsonPrimitive(Float.toString(((NBTTagFloat) nbt).func_150288_h()) + 'F');
|
||||
} else if (nbt instanceof NBTTagDouble) {
|
||||
// Number (double)
|
||||
return new JsonPrimitive(Double.toString(((NBTTagDouble) nbt).func_150286_g()) + 'D');
|
||||
} else if (nbt instanceof NBTBase.NBTPrimitive) {
|
||||
// Number
|
||||
return new JsonPrimitive(((NBTBase.NBTPrimitive) nbt).func_150286_g());
|
||||
|
||||
@@ -208,6 +208,7 @@ gtPlusPlus.nei.GT_NEI_FluidReactor,GT++,gregtech:gt.blockmachines:998,,miscutils
|
||||
gtPlusPlus.nei.GT_NEI_MillingMachine,GT++,gregtech:gt.blockmachines:31027,,miscutils,TRUE,,,120,,2,,,,,,
|
||||
li.cil.oc.integration.nei.CallbackDocHandler,OpenComputers,OpenComputers:item:98,,OpenComputers,TRUE,,,120,,2,,,,,,
|
||||
li.cil.oc.integration.nei.ManualUsageHandler,OpenComputers,OpenComputers:item:98,,OpenComputers,TRUE,,,120,,2,,,,,,
|
||||
com.pam.harvestcraft.GardenRecipeHandler,Pam's Harvestcraft,harvestcraft:berrygarden,,harvestcraft,TRUE,,,100,,5,,,,,,
|
||||
tonius.neiintegration.mods.harvestcraft.RecipeHandlerApiary,Pam's Harvestcraft,harvestcraft:apiary,,harvestcraft,TRUE,,,70,,5,,,,,,There's only 1 though
|
||||
tonius.neiintegration.mods.harvestcraft.RecipeHandlerChurn,Pam's Harvestcraft,harvestcraft:churn,,harvestcraft,TRUE,,,65,,5,,,,,,Same as above
|
||||
tonius.neiintegration.mods.harvestcraft.RecipeHandlerOven,Pam's Harvestcraft,harvestcraft:oven,,harvestcraft,TRUE,,,65,,5,,,,,,
|
||||
@@ -449,3 +450,4 @@ neresources.nei.NEIEnchantmentHandler,Not Enough Resources,minecraft:anvil,,nere
|
||||
neresources.nei.NEIMobHandler,Not Enough Resources,minecraft:skull:4,,neresources,TRUE,,,130,166,2,,,,,,
|
||||
neresources.nei.NEIOreHandler,Not Enough Resources,minecraft:diamond_ore,,neresources,TRUE,,,65,166,5,,,,,,
|
||||
neresources.nei.NEIPlantHandler,Not Enough Resources,minecraft:wheat,,neresources,TRUE,,,130,166,2,,,,,,
|
||||
wanion.biggercraftingtables.nei.BigShapedRecipeHandler,Bigger Crafting Tables,minecraft:crafting_table,,biggercraftingtables,TRUE,,,130,,2,,,,,,
|
||||
|
@@ -108,6 +108,9 @@ nei.options.keys.world.creative=Gamemode
|
||||
nei.options.keys.world.creative.tip=Cycle Gamemode
|
||||
|
||||
nei.options.inventory=Inventory
|
||||
nei.options.inventory.worldSpecificBookmarks=World Specific Bookmarks
|
||||
nei.options.inventory.worldSpecificBookmarks.true=Yes
|
||||
nei.options.inventory.worldSpecificBookmarks.false=No
|
||||
nei.options.inventory.bookmarksEnabled=Bookmarks Panel Visibility
|
||||
nei.options.inventory.bookmarksEnabled.true=Visible
|
||||
nei.options.inventory.bookmarksEnabled.false=Hidden
|
||||
@@ -117,6 +120,15 @@ nei.options.inventory.jei_style_tabs.false=No [Weirdo]
|
||||
nei.options.inventory.jei_style_item_presence_overlay=JEI Style Item Overlay on ?-Hover
|
||||
nei.options.inventory.jei_style_item_presence_overlay.true=Yes
|
||||
nei.options.inventory.jei_style_item_presence_overlay.false=No
|
||||
nei.options.inventory.jei_style_recipe_catalyst=JEI Style Recipe Catalysts [experimental]
|
||||
nei.options.inventory.jei_style_recipe_catalyst.true=Yes
|
||||
nei.options.inventory.jei_style_recipe_catalyst.false=No
|
||||
nei.options.inventory.saveCurrentRecipeInBookmarksEnabled=Save Current Recipe in Bookmarks
|
||||
nei.options.inventory.saveCurrentRecipeInBookmarksEnabled.true=Enabled
|
||||
nei.options.inventory.saveCurrentRecipeInBookmarksEnabled.false=Disabled
|
||||
nei.options.inventory.useNBTInBookmarks=Use NBT in Bookmarks
|
||||
nei.options.inventory.useNBTInBookmarks.true=Yes
|
||||
nei.options.inventory.useNBTInBookmarks.false=No
|
||||
nei.options.inventory.creative_tab_style=Creative or JEI tab style
|
||||
nei.options.inventory.creative_tab_style.true=Creative
|
||||
nei.options.inventory.creative_tab_style.false=JEI
|
||||
|
||||
@@ -117,6 +117,12 @@ nei.options.inventory.jei_style_tabs.false=否 [不会吧]
|
||||
nei.options.inventory.jei_style_item_presence_overlay=JEI风格物品覆盖?-悬停
|
||||
nei.options.inventory.jei_style_item_presence_overlay.true=是
|
||||
nei.options.inventory.jei_style_item_presence_overlay.false=否
|
||||
nei.options.inventory.saveCurrentRecipeInBookmarksEnabled=保存书签中的当前合成表
|
||||
nei.options.inventory.saveCurrentRecipeInBookmarksEnabled.true=启用
|
||||
nei.options.inventory.saveCurrentRecipeInBookmarksEnabled.false=禁用
|
||||
nei.options.inventory.useNBTInBookmarks=在书签中启用NBT
|
||||
nei.options.inventory.useNBTInBookmarks.true=是
|
||||
nei.options.inventory.useNBTInBookmarks.false=否
|
||||
nei.options.inventory.creative_tab_style=创造模式/JEI标签页
|
||||
nei.options.inventory.creative_tab_style.true=创造模式
|
||||
nei.options.inventory.creative_tab_style.false=JEI
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 103 B |
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"repo": "https://github.com/GTNewHorizons/CodeChickenLib/releases/download/1.1.4.1/",
|
||||
"file": "CodeChickenLib-1.7.10-1.1.4.1.jar",
|
||||
"dev": "CodeChickenLib-1.7.10-1.1.4.1-dev.jar",
|
||||
"class": "codechicken.lib.asm.ASMHelper",
|
||||
"coreLib": true
|
||||
}
|
||||
Reference in new issue
Block a user