begin work

This commit is contained in:
GlodBlock committed 2022-05-10 17:57:38 +08:00
commit db2ad29b52
124 files changed
+11799

No files matched your search

+19
View File
@@ -0,0 +1,19 @@
# This is the universal Text Editor Configuration
# for all GTNewHorizons projects
# See: https://editorconfig.org/
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.{bat,ini}]
end_of_line = crlf
[*.{dtd,json,info,mcmeta,md,sh,svg,xml,xsd,xsl,yaml,yml}]
indent_size = 2
+8
View File
@@ -0,0 +1,8 @@
*.bat
.gradle/
.idea/
out/
*.iml
*.ipr
*.iws
run/
+3
View File
@@ -0,0 +1,3 @@
# Any Github changes require admin approval
/.github/** @GTNewHorizons/admin
+738
View File
@@ -0,0 +1,738 @@
//version: 1644894948
/*
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/GTNewHorizons/ExampleMod1.7.10/blob/main/build.gradle for updates.
*/
import org.gradle.internal.logging.text.StyledTextOutput
import org.gradle.internal.logging.text.StyledTextOutputFactory
import org.gradle.internal.logging.text.StyledTextOutput.Style
import com.github.jengelman.gradle.plugins.shadow.tasks.ConfigureShadowRelocation
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import java.util.concurrent.TimeUnit
buildscript {
repositories {
maven {
name 'forge'
url 'https://maven.minecraftforge.net'
}
maven {
name 'sonatype'
url 'https://oss.sonatype.org/content/repositories/snapshots/'
}
maven {
name 'Scala CI dependencies'
url 'https://repo1.maven.org/maven2/'
}
maven {
name 'jitpack'
url 'https://jitpack.io'
}
}
dependencies {
classpath 'com.github.GTNewHorizons:ForgeGradle:1.2.7'
}
}
plugins {
id 'java-library'
id 'idea'
id 'eclipse'
id 'scala'
id 'maven-publish'
id 'org.jetbrains.kotlin.jvm' version '1.5.30' apply false
id 'org.jetbrains.kotlin.kapt' version '1.5.30' apply false
id 'org.ajoberstar.grgit' version '4.1.1'
id 'com.github.johnrengelman.shadow' version '4.0.4'
id 'com.palantir.git-version' version '0.13.0' apply false
id 'de.undercouch.download' version '5.0.1'
id 'com.github.gmazzo.buildconfig' version '3.0.3' apply false
}
if (project.file('.git/HEAD').isFile()) {
apply plugin: 'com.palantir.git-version'
}
def out = services.get(StyledTextOutputFactory).create('an-output')
apply plugin: 'forge'
def projectJavaVersion = JavaLanguageVersion.of(8)
java {
toolchain {
languageVersion.set(projectJavaVersion)
}
}
idea {
module {
inheritOutputDirs = true
downloadJavadoc = true
downloadSources = true
}
}
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")
checkPropertyExists("autoUpdateBuildScript")
checkPropertyExists("minecraftVersion")
checkPropertyExists("forgeVersion")
checkPropertyExists("replaceGradleTokenInFile")
checkPropertyExists("gradleTokenModId")
checkPropertyExists("gradleTokenModName")
checkPropertyExists("gradleTokenVersion")
checkPropertyExists("gradleTokenGroupName")
checkPropertyExists("apiPackage")
checkPropertyExists("accessTransformersFile")
checkPropertyExists("usesMixins")
checkPropertyExists("mixinPlugin")
checkPropertyExists("mixinsPackage")
checkPropertyExists("coreModClass")
checkPropertyExists("containsMixinsAndOrCoreModOnly")
checkPropertyExists("usesShadowedDependencies")
checkPropertyExists("developmentEnvironmentUserName")
boolean noPublishedSources = project.findProperty("noPublishedSources") ? project.noPublishedSources.toBoolean() : false
String javaSourceDir = "src/main/java/"
String scalaSourceDir = "src/main/scala/"
String kotlinSourceDir = "src/main/kotlin/"
String targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/")
String targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/")
String targetPackageKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/")
if(!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) {
throw new GradleException("Could not resolve \"modGroup\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin)
}
if(apiPackage) {
targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/")
targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/")
targetPackageKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/")
if(!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) {
throw new GradleException("Could not resolve \"apiPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin)
}
}
if(accessTransformersFile) {
String targetFile = "src/main/resources/META-INF/" + accessTransformersFile
if(!getFile(targetFile).exists()) {
throw new GradleException("Could not resolve \"accessTransformersFile\"! Could not find " + targetFile)
}
}
if(usesMixins.toBoolean()) {
if(mixinsPackage.isEmpty() || mixinPlugin.isEmpty()) {
throw new GradleException("\"mixinPlugin\" requires \"mixinsPackage\" and \"mixinPlugin\" to be set!")
}
targetPackageJava = javaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/")
targetPackageScala = scalaSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/")
targetPackageKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinsPackage.toString().replaceAll("\\.", "/")
if(!(getFile(targetPackageJava).exists() || getFile(targetPackageScala).exists() || getFile(targetPackageKotlin).exists())) {
throw new GradleException("Could not resolve \"mixinsPackage\"! Could not find " + targetPackageJava + " or " + targetPackageScala + " or " + targetPackageKotlin)
}
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"
String targetFileKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + mixinPlugin.toString().replaceAll("\\.", "/") + ".kt"
if(!(getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists() || getFile(targetFileKotlin).exists())) {
throw new GradleException("Could not resolve \"mixinPlugin\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava + " or " + targetFileKotlin)
}
}
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"
String targetFileKotlin = kotlinSourceDir + modGroup.toString().replaceAll("\\.", "/") + "/" + coreModClass.toString().replaceAll("\\.", "/") + ".kt"
if(!(getFile(targetFileJava).exists() || getFile(targetFileScala).exists() || getFile(targetFileScalaJava).exists() || getFile(targetFileKotlin).exists())) {
throw new GradleException("Could not resolve \"coreModClass\"! Could not find " + targetFileJava + " or " + targetFileScala + " or " + targetFileScalaJava + " or " + targetFileKotlin)
}
}
configurations.all {
resolutionStrategy.cacheChangingModulesFor(0, TimeUnit.SECONDS)
// Make sure GregTech build won't time out
System.setProperty("org.gradle.internal.http.connectionTimeout", 120000 as String)
System.setProperty("org.gradle.internal.http.socketTimeout", 120000 as String)
}
// Fix Jenkins' Git: chmod a file should not be detected as a change and append a '.dirty' to the version
try {
'git config core.fileMode false'.execute()
}
catch (Exception ignored) {
out.style(Style.Failure).println("git isn't installed at all")
}
// Pulls version first from the VERSION env and then git tag
String identifiedVersion
String versionOverride = System.getenv("VERSION") ?: null
try {
identifiedVersion = versionOverride == null ? gitVersion() : versionOverride
}
catch (Exception ignored) {
out.style(Style.Failure).text(
'This mod must be version controlled by Git AND the repository must provide at least one tag,\n' +
'or the VERSION override must be set! ').style(Style.SuccessHeader).text('(Do NOT download from GitHub using the ZIP option, instead\n' +
'clone the repository, see ').style(Style.Info).text('https://gtnh.miraheze.org/wiki/Development').style(Style.SuccessHeader).println(' for details.)'
)
versionOverride = 'NO-GIT-TAG-SET'
identifiedVersion = versionOverride
}
version = minecraftVersion + '-' + identifiedVersion
ext {
modVersion = identifiedVersion
}
if(identifiedVersion == versionOverride) {
out.style(Style.Failure).text('Override version to ').style(Style.Identifier).text(modVersion).style(Style.Failure).println('!\7')
}
group = modGroup
if(project.hasProperty("customArchiveBaseName") && customArchiveBaseName) {
archivesBaseName = customArchiveBaseName
}
else {
archivesBaseName = modId
}
def arguments = []
def jvmArguments = []
if(usesMixins.toBoolean()) {
arguments += [
"--tweakClass org.spongepowered.asm.launch.MixinTweaker"
]
jvmArguments += [
"-Dmixin.debug.countInjections=true", "-Dmixin.debug.verbose=true", "-Dmixin.debug.export=true"
]
}
minecraft {
version = minecraftVersion + '-' + forgeVersion + '-' + minecraftVersion
runDir = 'run'
if (replaceGradleTokenInFile) {
replaceIn replaceGradleTokenInFile
if(gradleTokenModId) {
replace gradleTokenModId, modId
}
if(gradleTokenModName) {
replace gradleTokenModName, modName
}
if(gradleTokenVersion) {
replace gradleTokenVersion, modVersion
}
if(gradleTokenGroupName) {
replace gradleTokenGroupName, modGroup
}
}
clientIntellijRun {
args(arguments)
jvmArgs(jvmArguments)
if(developmentEnvironmentUserName) {
args("--username", developmentEnvironmentUserName)
}
}
serverIntellijRun {
args(arguments)
jvmArgs(jvmArguments)
}
}
if(file('addon.gradle').exists()) {
apply from: 'addon.gradle'
}
apply from: 'repositories.gradle'
configurations {
implementation.extendsFrom(shadowImplementation) // TODO: remove after all uses are refactored
implementation.extendsFrom(shadowCompile)
implementation.extendsFrom(shadeCompile)
}
repositories {
maven {
name 'Overmind forge repo mirror'
url 'https://gregtech.overminddl1.com/'
}
if(usesMixins.toBoolean()) {
maven {
name 'sponge'
url 'https://repo.spongepowered.org/repository/maven-public'
}
maven {
url 'https://jitpack.io'
}
}
}
dependencies {
if(usesMixins.toBoolean()) {
annotationProcessor('org.ow2.asm:asm-debug-all:5.0.3')
annotationProcessor('com.google.guava:guava:24.1.1-jre')
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('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'
exclude module: 'gson'
exclude module: 'commons-io'
exclude module: 'log4j-core'
}
compile('com.github.GTNewHorizons:SpongeMixins:1.5.0')
}
}
apply from: 'dependencies.gradle'
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()) {
getFile("/src/main/resources/mixins." + modId + ".json").text = """{
"required": true,
"minVersion": "0.7.11",
"package": "${modGroup}.${mixinsPackage}",
"plugin": "${modGroup}.${mixinPlugin}",
"refmap": "${mixingConfigRefMap}",
"target": "@env(DEFAULT)",
"compatibilityLevel": "JAVA_8"
}
"""
}
}
task relocateShadowJar(type: ConfigureShadowRelocation) {
target = tasks.shadowJar
prefix = modGroup + ".shadow"
}
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, project.configurations.shadowCompile]
dependsOn(relocateShadowJar)
}
jar {
project.configurations.shadeCompile.each { dep ->
from(project.zipTree(dep)) {
exclude 'META-INF', 'META-INF/**'
}
}
manifest {
attributes(getManifestAttributes())
}
if(usesShadowedDependencies.toBoolean()) {
dependsOn(shadowJar)
enabled = false
}
}
reobf {
if(usesMixins.toBoolean()) {
addExtraSrgFile mixinSrg
}
}
afterEvaluate {
if(usesMixins.toBoolean()) {
tasks.compileJava {
options.compilerArgs += [
"-AreobfSrgFile=${tasks.reobf.srg}",
"-AoutSrgFile=${mixinSrg}",
"-AoutRefMapFile=${refMap}",
// Elan: from what I understand they are just some linter configs so you get some warning on how to properly code
"-XDenableSunApiLintControl",
"-XDignore.symbol.file"
]
}
}
}
runClient {
if(developmentEnvironmentUserName) {
arguments += [
"--username",
developmentEnvironmentUserName
]
}
args(arguments)
jvmArgs(jvmArguments)
}
runServer {
args(arguments)
jvmArgs(jvmArguments)
}
tasks.withType(JavaExec).configureEach {
javaLauncher.set(
javaToolchains.launcherFor {
languageVersion = projectJavaVersion
}
)
}
processResources {
// 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 modVersion and minecraftVersion
expand "minecraftVersion": project.minecraft.version,
"modVersion": modVersion,
"modId": modId,
"modName": modName
}
if(usesMixins.toBoolean()) {
from refMap
}
// copy everything else that's not the mcmod.info
from(sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
}
}
def getManifestAttributes() {
def manifestAttributes = [:]
if(!containsMixinsAndOrCoreModOnly.toBoolean() && (usesMixins.toBoolean() || coreModClass)) {
manifestAttributes += ["FMLCorePluginContainsFMLMod": true]
}
if(accessTransformersFile) {
manifestAttributes += ["FMLAT" : accessTransformersFile.toString()]
}
if(coreModClass) {
manifestAttributes += ["FMLCorePlugin": modGroup + "." + coreModClass]
}
if(usesMixins.toBoolean()) {
manifestAttributes += [
"TweakClass" : "org.spongepowered.asm.launch.MixinTweaker",
"MixinConfigs" : "mixins." + modId + ".json",
"ForceLoadAsMod" : !containsMixinsAndOrCoreModOnly.toBoolean()
]
}
return manifestAttributes
}
task sourcesJar(type: Jar) {
from (sourceSets.main.allJava)
from (file("$projectDir/LICENSE"))
getArchiveClassifier().set('sources')
}
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")
manifest {
attributes(getManifestAttributes())
}
minimize() // This will only allow shading for actually used classes
configurations = [project.configurations.shadowImplementation, project.configurations.shadowCompile]
}
task relocateShadowDevJar(type: ConfigureShadowRelocation) {
target = tasks.shadowDevJar
prefix = modGroup + ".shadow"
}
task circularResolverJar(type: Jar) {
dependsOn(relocateShadowDevJar)
dependsOn(shadowDevJar)
enabled = false
}
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")
manifest {
attributes(getManifestAttributes())
}
if(usesShadowedDependencies.toBoolean()) {
dependsOn(circularResolverJar)
enabled = false
}
}
task apiJar(type: Jar) {
from (sourceSets.main.allJava) {
include modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + '/**'
}
from (sourceSets.main.output) {
include modGroup.toString().replaceAll("\\.", "/") + "/" + apiPackage.toString().replaceAll("\\.", "/") + '/**'
}
from (sourceSets.main.resources.srcDirs) {
include("LICENSE")
}
getArchiveClassifier().set('api')
}
artifacts {
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
}
// workaround variable hiding in pom processing
def projectConfigs = project.configurations
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 extra garbage from minecraft and minecraftDeps configuration
pom.withXml {
def badArtifacts = [:].withDefault {[] as Set<String>}
for (configuration in [projectConfigs.minecraft, projectConfigs.minecraftDeps]) {
for (dependency in configuration.allDependencies) {
badArtifacts[dependency.group == null ? "" : dependency.group] += dependency.name
}
}
// example for specifying extra stuff to ignore
// badArtifacts["org.example.group"] += "artifactName"
Node pomNode = asNode()
pomNode.dependencies.'*'.findAll() {
badArtifacts[it.groupId.text()].contains(it.artifactId.text())
}.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 (performBuildScriptUpdate(projectDir.toString())) return
print("Build script already up-to-date!")
}
}
if (isNewBuildScriptVersionAvailable(projectDir.toString())) {
if (autoUpdateBuildScript.toBoolean()) {
performBuildScriptUpdate(projectDir.toString())
} else {
out.style(Style.SuccessHeader).println("Build script update available! Run 'gradle updateBuildScript'")
}
}
static URL availableBuildScriptUrl() {
new URL("https://raw.githubusercontent.com/GTNewHorizons/ExampleMod1.7.10/main/build.gradle")
}
boolean performBuildScriptUpdate(String projectDir) {
if (isNewBuildScriptVersionAvailable(projectDir)) {
def buildscriptFile = getFile("build.gradle")
availableBuildScriptUrl().withInputStream { i -> buildscriptFile.withOutputStream { it << i } }
out.style(Style.Success).print("Build script updated. Please REIMPORT the project or RESTART your IDE!")
return true
}
return false
}
boolean isNewBuildScriptVersionAvailable(String projectDir) {
Map parameters = ["connectTimeout": 2000, "readTimeout": 2000]
String currentBuildScript = getFile("build.gradle").getText()
String currentBuildScriptHash = getVersionHash(currentBuildScript)
String availableBuildScript = availableBuildScriptUrl().newInputStream(parameters).getText()
String availableBuildScriptHash = getVersionHash(availableBuildScript)
boolean isUpToDate = currentBuildScriptHash.empty || availableBuildScriptHash.empty || currentBuildScriptHash == availableBuildScriptHash
return !isUpToDate
}
static String getVersionHash(String buildScriptContent) {
String versionLine = buildScriptContent.find("^//version: [a-z0-9]*")
if(versionLine != null) {
return versionLine.split(": ").last()
}
return ""
}
configure(updateBuildScript) {
group = 'forgegradle'
description = 'Updates the build script to the latest version'
}
// Deobfuscation
def deobf(String sourceURL) {
try {
URL url = new URL(sourceURL)
String fileName = url.getFile()
//get rid of directories:
int lastSlash = fileName.lastIndexOf("/")
if(lastSlash > 0) {
fileName = fileName.substring(lastSlash + 1)
}
//get rid of extension:
if(fileName.endsWith(".jar")) {
fileName = fileName.substring(0, fileName.lastIndexOf("."))
}
String hostName = url.getHost()
if(hostName.startsWith("www.")) {
hostName = hostName.substring(4)
}
List parts = Arrays.asList(hostName.split("\\."))
Collections.reverse(parts)
hostName = String.join(".", parts)
return deobf(sourceURL, hostName + "/" + fileName)
} catch(Exception e) {
return deobf(sourceURL, "deobf/" + String.valueOf(sourceURL.hashCode()))
}
}
// The method above is to be preferred. Use this method if the filename is not at the end of the URL.
def deobf(String sourceURL, String fileName) {
String cacheDir = System.getProperty("user.home") + "/.gradle/caches/"
String bon2Dir = cacheDir + "forge_gradle/deobf"
String bon2File = bon2Dir + "/BON2-2.5.0.jar"
String obfFile = cacheDir + "modules-2/files-2.1/" + fileName + ".jar"
String deobfFile = cacheDir + "modules-2/files-2.1/" + fileName + "-deobf.jar"
if(file(deobfFile).exists()) {
return files(deobfFile)
}
download.run {
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.run {
src sourceURL
dest obfFile
quiet true
overwrite false
}
exec {
commandLine 'java', '-jar', bon2File, '--inputJar', obfFile, '--outputJar', deobfFile, '--mcVer', '1.7.10', '--mappingsVer', 'stable_12', '--notch'
workingDir bon2Dir
standardOutput = new ByteArrayOutputStream()
}
return files(deobfFile)
}
// Helper methods
def checkPropertyExists(String propertyName) {
if (!project.hasProperty(propertyName)) {
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)
}
+14
View File
@@ -0,0 +1,14 @@
// Add your dependencies here
dependencies {
compile('com.github.GTNewHorizons:GT5-Unofficial:5.09.40.41:dev')
compile('com.github.GTNewHorizons:StructureLib:1.0.15:dev')
compile('com.github.GTNewHorizons:NotEnoughItems:2.2.12-GTNH:dev')
compile('net.industrial-craft:industrialcraft-2:2.2.828-experimental:dev')
compile('com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-beta-75-GTNH:dev')
compile('curse.maven:cofh-core-69162:2388751')
compile('com.github.GTNewHorizons:ExtraCells2:2.5.9:dev') {transitive = false}
compileOnly('com.github.GTNewHorizons:AppleCore:3.1.9:dev') {transitive = false}
compileOnly('com.github.GTNewHorizons:BuildCraft:7.1.27:dev') {transitive = false}
}
+71
View File
@@ -0,0 +1,71 @@
modName = FluidCraftForAE2
# This is a case-sensitive string to identify your mod. Convention is to use lower case.
modId = ae2fc
modGroup = com.glodblock.github
# WHY is there no version field?
# The build script relies on git to provide a version via tags. It is super easy and will enable you to always know the
# code base or your binary. Check out this tutorial: https://blog.mattclemente.com/2017/10/13/versioning-with-git-tags/
# Will update your build.gradle automatically whenever an update is available
autoUpdateBuildScript = false
minecraftVersion = 1.7.10
forgeVersion = 10.13.4.1614
# Select a username for testing your mod with breakpoints. You may leave this empty for a random user name each time you
# restart Minecraft in development. Choose this dependent on your mod:
# Do you need consistent player progressing (for example Thaumcraft)? -> Select a name
# Do you need to test how your custom blocks interacts with a player that is not the owner? -> leave name empty
developmentEnvironmentUserName = Developer
# Define a source file of your project with:
# public static final String VERSION = "GRADLETOKEN_VERSION";
# The string's content will be replaced with your mods version when compiled. You should use this to specify your mod's
# version in @Mod([...], version = VERSION, [...])
# Leave these properties empty to skip individual token replacements
replaceGradleTokenInFile = FluidCraft.java
gradleTokenModId = GRADLETOKEN_MODID
gradleTokenModName = GRADLETOKEN_MODNAME
gradleTokenVersion = GRADLETOKEN_VERSION
gradleTokenGroupName = GRADLETOKEN_GROUPNAME
# In case your mod provides an API for other mods to implement you may declare its package here. Otherwise, you can
# leave this property empty.
# Example value: apiPackage = api + modGroup = com.myname.mymodid -> com.myname.mymodid.api
apiPackage =
# Specify the configuration file for Forge's access transformers here. I must be placed into /src/main/resources/META-INF/
# Example value: mymodid_at.cfg
accessTransformersFile =
# Provides setup for Mixins if enabled. If you don't know what mixins are: Keep it disabled!
usesMixins = false
# Specify the location of your implementation of IMixinConfigPlugin. Leave it empty otherwise.
mixinPlugin =
# Specify the package that contains all of your Mixins. You may only place Mixins in this package or the build will fail!
mixinsPackage =
# Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin!
# This parameter is for legacy compatibility only
# Example value: coreModClass = asm.FMLPlugin + modGroup = com.myname.mymodid -> com.myname.mymodid.asm.FMLPlugin
coreModClass = coremod.FluidCraftCore
# If your project is only a consolidation of mixins or a core mod and does NOT contain a 'normal' mod ( = some class
# that is annotated with @Mod) you want this to be true. When in doubt: leave it on false!
containsMixinsAndOrCoreModOnly = false
# If enabled, you may use 'shadowCompile' for dependencies. They will be integrated in your jar. It is your
# responsibility check the licence and request permission for distribution, if required.
usesShadowedDependencies = false
# Optional parameter to customize the produced artifacts. Use this to preserver artifact naming when migrating older
# projects. New projects should not use this parameter.
#customArchiveBaseName =
# Optional parameter to prevent the source code from being published
# noPublishedSources =
systemProp.http.proxyHost=127.0.0.1
systemProp.http.proxyPort=7890
systemProp.https.proxyHost=127.0.0.1
systemProp.https.proxyPort=7890
Binary file not shown.
+5
View File
@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+164
View File
@@ -0,0 +1,164 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
+31
View File
@@ -0,0 +1,31 @@
// Add any additional repositories for your dependencies here
repositories {
maven {
name 'GTNH Maven'
url 'http://jenkins.usrv.eu:8081/nexus/content/groups/public/'
allowInsecureProtocol
}
maven {
name 'ic2'
url 'https://maven.ic2.player.to/'
metadataSources {
mavenPom()
artifact()
}
}
maven {
name 'gt'
url 'https://gregtech.overminddl1.com/'
}
maven {
url 'https://cursemaven.com'
content {
includeGroup 'curse.maven'
}
}
maven {
url 'https://jitpack.io'
}
}
@@ -0,0 +1,62 @@
package com.glodblock.github;
import com.glodblock.github.inventory.InventoryHandler;
import com.glodblock.github.loader.ChannelLoader;
import com.glodblock.github.loader.ListenerLoader;
import com.glodblock.github.loader.RenderLoader;
import com.glodblock.github.nei.recipes.DefaultExtractorLoader;
import com.glodblock.github.proxy.CommonProxy;
import com.glodblock.github.util.ModAndClassUtil;
import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLLoadCompleteEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.network.NetworkRegistry;
import net.minecraft.util.ResourceLocation;
@Mod(modid = FluidCraft.MODID, version = FluidCraft.VERSION)
public class FluidCraft {
public static final String MODID = "GRADLETOKEN_MODID";
public static final String VERSION = "GRADLETOKEN_VERSION";
public static final String MODNAME = "GRADLETOKEN_MODNAME";
@Mod.Instance(MODID)
public static FluidCraft INSTANCE;
@SidedProxy(clientSide = "com.glodblock.github.proxy.ClientProxy", serverSide = "com.glodblock.github.proxy.CommonProxy")
public static CommonProxy proxy;
@Mod.EventHandler
public static void preInit(FMLPreInitializationEvent event) {
(new ChannelLoader()).run();
proxy.preInit(event);
}
@Mod.EventHandler
public static void init(FMLInitializationEvent event) {
(new RenderLoader()).run();
(new ListenerLoader()).run();
ModAndClassUtil.init();
proxy.init(event);
}
@Mod.EventHandler
public static void postInit(FMLPostInitializationEvent event) {
NetworkRegistry.INSTANCE.registerGuiHandler(FluidCraft.INSTANCE, new InventoryHandler());
(new DefaultExtractorLoader()).run();
proxy.postInit(event);
}
@Mod.EventHandler
public void onLoadComplete(FMLLoadCompleteEvent event) {
}
public static ResourceLocation resource(String path) {
return new ResourceLocation(MODID, path);
}
}
@@ -0,0 +1,29 @@
package com.glodblock.github.client;
import com.glodblock.github.client.textures.FCPartsTexture;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.client.event.TextureStitchEvent;
import net.minecraftforge.common.MinecraftForge;
public class ClientHelper {
@SubscribeEvent
public void updateTextureSheet( final TextureStitchEvent.Pre ev )
{
if( ev.map.getTextureType() == 0 )
{
for( final FCPartsTexture cb : FCPartsTexture.values() )
{
cb.registerIcon( ev.map );
}
}
}
public static void register() {
ClientHelper handler = new ClientHelper();
MinecraftForge.EVENT_BUS.register(handler);
FMLCommonHandler.instance().bus().register(handler);
}
}
@@ -0,0 +1,163 @@
package com.glodblock.github.client.gui;
import appeng.api.config.ActionItems;
import appeng.api.config.ItemSubstitution;
import appeng.api.config.Settings;
import appeng.api.storage.ITerminalHost;
import appeng.client.gui.widgets.GuiImgButton;
import appeng.client.gui.widgets.GuiTabButton;
import appeng.container.slot.AppEngSlot;
import appeng.core.localization.GuiText;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.client.gui.container.FCBasePartContainer;
import com.glodblock.github.network.CPacketFluidPatternTermBtns;
import com.glodblock.github.util.Ae2Reflect;
import com.glodblock.github.util.ModAndClassUtil;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import org.lwjgl.input.Keyboard;
public class GuiBaseFluidPatternTerminal extends GuiFCBaseMonitor {
private static final String SUBSITUTION_DISABLE = "0";
private static final String SUBSITUTION_ENABLE = "1";
private static final String CRAFTMODE_CRFTING = "1";
private static final String CRAFTMODE_PROCESSING = "0";
public final FCBasePartContainer container;
private GuiTabButton tabCraftButton;
private GuiTabButton tabProcessButton;
private GuiImgButton substitutionsEnabledBtn;
private GuiImgButton substitutionsDisabledBtn;
private GuiImgButton encodeBtn;
private GuiImgButton clearBtn;
private GuiImgButton doubleBtn;
public GuiBaseFluidPatternTerminal(final InventoryPlayer inventoryPlayer, final ITerminalHost te )
{
super( inventoryPlayer, te, new FCBasePartContainer( inventoryPlayer, te ) );
this.container = (FCBasePartContainer) this.inventorySlots;
Ae2Reflect.setReservedSpace(this, 81);
}
@Override
protected void actionPerformed( final GuiButton btn )
{
super.actionPerformed( btn );
if( this.tabCraftButton == btn || this.tabProcessButton == btn )
{
FluidCraft.proxy.netHandler.sendToServer( new CPacketFluidPatternTermBtns( "PatternTerminal.CraftMode", this.tabProcessButton == btn ? CRAFTMODE_CRFTING : CRAFTMODE_PROCESSING ) );
}
else if( this.encodeBtn == btn )
{
FluidCraft.proxy.netHandler.sendToServer( new CPacketFluidPatternTermBtns( "PatternTerminal.Encode", isShiftKeyDown() ? "2" : "1" ) );
}
else if( this.clearBtn == btn )
{
FluidCraft.proxy.netHandler.sendToServer( new CPacketFluidPatternTermBtns( "PatternTerminal.Clear", "1" ) );
}
else if( this.substitutionsEnabledBtn == btn || this.substitutionsDisabledBtn == btn )
{
FluidCraft.proxy.netHandler.sendToServer( new CPacketFluidPatternTermBtns( "PatternTerminal.Substitute", this.substitutionsEnabledBtn == btn ? SUBSITUTION_DISABLE : SUBSITUTION_ENABLE ) );
}
else if (ModAndClassUtil.isDoubleButton && doubleBtn == btn)
{
FluidCraft.proxy.netHandler.sendToServer( new CPacketFluidPatternTermBtns( "PatternTerminal.Double", Keyboard.isKeyDown( Keyboard.KEY_LSHIFT ) ? "1": "0") );
}
}
@Override
@SuppressWarnings("unchecked")
public void initGui()
{
super.initGui();
this.tabCraftButton = new GuiTabButton( this.guiLeft + 173, this.guiTop + this.ySize - 177, new ItemStack( Blocks.crafting_table ), GuiText.CraftingPattern.getLocal(), itemRender );
this.buttonList.add( this.tabCraftButton );
this.tabProcessButton = new GuiTabButton( this.guiLeft + 173, this.guiTop + this.ySize - 177, new ItemStack( Blocks.furnace ), GuiText.ProcessingPattern.getLocal(), itemRender );
this.buttonList.add( this.tabProcessButton );
this.substitutionsEnabledBtn = new GuiImgButton( this.guiLeft + 84, this.guiTop + this.ySize - 163, Settings.ACTIONS, ItemSubstitution.ENABLED );
this.substitutionsEnabledBtn.setHalfSize( true );
this.buttonList.add( this.substitutionsEnabledBtn );
this.substitutionsDisabledBtn = new GuiImgButton( this.guiLeft + 84, this.guiTop + this.ySize - 163, Settings.ACTIONS, ItemSubstitution.DISABLED );
this.substitutionsDisabledBtn.setHalfSize( true );
this.buttonList.add( this.substitutionsDisabledBtn );
this.clearBtn = new GuiImgButton( this.guiLeft + 74, this.guiTop + this.ySize - 163, Settings.ACTIONS, ActionItems.CLOSE );
this.clearBtn.setHalfSize( true );
this.buttonList.add( this.clearBtn );
this.encodeBtn = new GuiImgButton( this.guiLeft + 147, this.guiTop + this.ySize - 142, Settings.ACTIONS, ActionItems.ENCODE );
this.buttonList.add( this.encodeBtn );
if (ModAndClassUtil.isDoubleButton) {
this.doubleBtn = new GuiImgButton( this.guiLeft + 74, this.guiTop + this.ySize - 153, Settings.ACTIONS, ActionItems.DOUBLE );
this.doubleBtn.setHalfSize( true );
this.buttonList.add( this.doubleBtn );
}
}
@Override
public void drawFG( final int offsetX, final int offsetY, final int mouseX, final int mouseY )
{
if( !this.container.isCraftingMode() )
{
this.tabCraftButton.visible = false;
this.tabProcessButton.visible = true;
if (ModAndClassUtil.isDoubleButton)
this.doubleBtn.visible = true;
}
else
{
this.tabCraftButton.visible = true;
this.tabProcessButton.visible = false;
if (ModAndClassUtil.isDoubleButton)
this.doubleBtn.visible = false;
}
if( this.container.substitute )
{
this.substitutionsEnabledBtn.visible = true;
this.substitutionsDisabledBtn.visible = false;
}
else
{
this.substitutionsEnabledBtn.visible = false;
this.substitutionsDisabledBtn.visible = true;
}
super.drawFG( offsetX, offsetY, mouseX, mouseY );
this.fontRendererObj.drawString( GuiText.PatternTerminal.getLocal(), 8, this.ySize - 96 + 2 - Ae2Reflect.getReservedSpace(this), 4210752 );
}
@Override
protected String getBackground()
{
if( this.container.isCraftingMode() )
{
return "guis/pattern.png";
}
return "guis/pattern2.png";
}
@Override
protected void repositionSlot( final AppEngSlot s )
{
if( s.isPlayerSide() )
{
s.yDisplayPosition = s.getY() + this.ySize - 78 - 5;
}
else
{
s.yDisplayPosition = s.getY() + this.ySize - 78 - 3;
}
}
}
@@ -0,0 +1,750 @@
package com.glodblock.github.client.gui;
import appeng.api.config.*;
import appeng.api.implementations.tiles.IViewCellStorage;
import appeng.api.storage.ITerminalHost;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.util.IConfigManager;
import appeng.api.util.IConfigurableObject;
import appeng.client.gui.AEBaseMEGui;
import appeng.client.gui.widgets.*;
import appeng.client.me.InternalSlotME;
import appeng.client.me.ItemRepo;
import appeng.client.me.SlotDisconnected;
import appeng.client.me.SlotME;
import appeng.container.AEBaseContainer;
import appeng.container.slot.*;
import appeng.core.AEConfig;
import appeng.core.AELog;
import appeng.core.localization.ButtonToolTips;
import appeng.core.localization.GuiText;
import appeng.core.sync.GuiBridge;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketInventoryAction;
import appeng.core.sync.packets.PacketSwitchGuis;
import appeng.core.sync.packets.PacketValueConfig;
import appeng.helpers.InventoryAction;
import appeng.integration.IntegrationRegistry;
import appeng.integration.IntegrationType;
import appeng.util.IConfigManagerHost;
import appeng.util.Platform;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.client.gui.container.FCBaseMonitorContain;
import com.glodblock.github.client.gui.container.FCBasePartContainer;
import com.glodblock.github.common.parts.PartFluidPatternTerminal;
import com.glodblock.github.network.CPacketInventoryAction;
import com.glodblock.github.network.CPacketSetTargetItem;
import com.glodblock.github.util.Ae2Reflect;
import com.glodblock.github.util.NameConst;
import com.google.common.base.Stopwatch;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class GuiFCBaseMonitor extends AEBaseMEGui implements ISortSource, IConfigManagerHost
{
public static int craftingGridOffsetX;
public static int craftingGridOffsetY;
private static String memoryText = "";
private final ItemRepo repo;
private final int offsetX = 9;
private final int lowerTextureOffset = 0;
private final IConfigManager configSrc;
private final boolean viewCell;
private final ItemStack[] myCurrentViewCells = new ItemStack[5];
private final FCBaseMonitorContain monitorableContainer;
private GuiTabButton craftingStatusBtn;
private GuiImgButton craftingStatusImgBtn;
private MEGuiTextField searchField;
private String myName;
private int perRow = 9;
private int reservedSpace = 0;
private boolean customSortOrder = true;
private int rows = 0;
private int maxRows = Integer.MAX_VALUE;
private int standardSize;
private GuiImgButton ViewBox;
private GuiImgButton SortByBox;
private GuiImgButton SortDirBox;
private GuiImgButton searchBoxSettings;
private GuiImgButton terminalStyleBox;
private GuiImgButton searchStringSave;
public GuiFCBaseMonitor(final InventoryPlayer inventoryPlayer, final ITerminalHost te )
{
this( inventoryPlayer, te, new FCBasePartContainer( inventoryPlayer, te ) );
}
public GuiFCBaseMonitor( final InventoryPlayer inventoryPlayer, final ITerminalHost te, final FCBasePartContainer c )
{
super( c );
final GuiScrollbar scrollbar = new GuiScrollbar();
this.setScrollBar( scrollbar );
this.repo = new ItemRepo( scrollbar, this );
this.xSize = 185;
this.ySize = 204;
if( te instanceof IViewCellStorage)
{
this.xSize += 33;
}
this.standardSize = this.xSize;
this.configSrc = ( (IConfigurableObject) this.inventorySlots ).getConfigManager();
( this.monitorableContainer = (FCBaseMonitorContain) this.inventorySlots ).setGui( this );
this.viewCell = te instanceof IViewCellStorage;
if( te instanceof PartFluidPatternTerminal)
{
this.myName = NameConst.GUI_FLUID_PATTERN_TERMINAL;
}
}
public void postUpdate( final List<IAEItemStack> list )
{
for( final IAEItemStack is : list )
{
this.repo.postUpdate( is );
}
this.repo.updateView();
this.setScrollBar();
}
private void setScrollBar()
{
this.getScrollBar().setTop( 18 ).setLeft( 175 ).setHeight( this.rows * 18 - 2 );
this.getScrollBar().setRange( 0, ( this.repo.size() + this.perRow - 1 ) / this.perRow - this.rows, Math.max( 1, this.rows / 6 ) );
}
@Override
protected void actionPerformed( final GuiButton btn )
{
if( btn == this.craftingStatusBtn || btn == this.craftingStatusImgBtn )
{
NetworkHandler.instance.sendToServer( new PacketSwitchGuis( GuiBridge.GUI_CRAFTING_STATUS ) );
}
if( btn instanceof GuiImgButton )
{
final boolean backwards = Mouse.isButtonDown( 1 );
final GuiImgButton iBtn = (GuiImgButton) btn;
if( iBtn.getSetting() != Settings.ACTIONS )
{
final Enum cv = iBtn.getCurrentValue();
final Enum next = Platform.rotateEnum( cv, backwards, iBtn.getSetting().getPossibleValues() );
if( btn == this.terminalStyleBox )
{
AEConfig.instance.settings.putSetting( iBtn.getSetting(), next );
}
else if( btn == this.searchBoxSettings )
{
AEConfig.instance.settings.putSetting( iBtn.getSetting(), next );
}
else if( btn == this.searchStringSave )
{
AEConfig.instance.preserveSearchBar = next == YesNo.YES;
}
else
{
try
{
NetworkHandler.instance.sendToServer( new PacketValueConfig( iBtn.getSetting().name(), next.name() ) );
}
catch( final IOException e )
{
AELog.debug( e );
}
}
iBtn.set( next );
if( next.getClass() == SearchBoxMode.class || next.getClass() == TerminalStyle.class )
{
this.reinitalize();
}
}
}
}
private void reinitalize()
{
this.buttonList.clear();
this.initGui();
}
@Override
public void initGui()
{
Keyboard.enableRepeatEvents( true );
this.maxRows = this.getMaxRows();
this.perRow = AEConfig.instance.getConfigManager().getSetting( Settings.TERMINAL_STYLE ) != TerminalStyle.FULL ? 9 : 9 + ( ( this.width - this.standardSize ) / 18 );
final boolean hasNEI = IntegrationRegistry.INSTANCE.isEnabled( IntegrationType.NEI );
final int NEI = hasNEI ? 0 : 0;
int top = hasNEI ? 22 : 0;
final int magicNumber = 114 + 1;
final int extraSpace = this.height - magicNumber - NEI - top - this.reservedSpace;
this.rows = (int) Math.floor( extraSpace / 18 );
if( this.rows > this.maxRows )
{
top += ( this.rows - this.maxRows ) * 18 / 2;
this.rows = this.maxRows;
}
if( hasNEI )
{
this.rows--;
}
if( this.rows < 3 )
{
this.rows = 3;
}
this.getMeSlots().clear();
for( int y = 0; y < this.rows; y++ )
{
for( int x = 0; x < this.perRow; x++ )
{
this.getMeSlots().add( new InternalSlotME( this.repo, x + y * this.perRow, this.offsetX + x * 18, 18 + y * 18 ) );
}
}
if( AEConfig.instance.getConfigManager().getSetting( Settings.TERMINAL_STYLE ) != TerminalStyle.FULL )
{
this.xSize = this.standardSize + ( ( this.perRow - 9 ) * 18 );
}
else
{
this.xSize = this.standardSize;
}
super.initGui();
// full size : 204
// extra slots : 72
// slot 18
this.ySize = magicNumber + this.rows * 18 + this.reservedSpace;
// this.guiTop = top;
final int unusedSpace = this.height - this.ySize;
this.guiTop = (int) Math.floor( unusedSpace / ( unusedSpace < 0 ? 3.8f : 2.0f ) );
int offset = this.guiTop + 8;
if( this.customSortOrder )
{
this.buttonList.add( this.SortByBox = new GuiImgButton( this.guiLeft - 18, offset, Settings.SORT_BY, this.configSrc.getSetting( Settings.SORT_BY ) ) );
offset += 20;
}
this.buttonList.add( this.ViewBox = new GuiImgButton( this.guiLeft - 18, offset, Settings.VIEW_MODE, this.configSrc.getSetting( Settings.VIEW_MODE ) ) );
offset += 20;
this.buttonList.add( this.SortDirBox = new GuiImgButton( this.guiLeft - 18, offset, Settings.SORT_DIRECTION, this.configSrc.getSetting( Settings.SORT_DIRECTION ) ) );
offset += 20;
this.buttonList.add( this.searchBoxSettings = new GuiImgButton( this.guiLeft - 18, offset, Settings.SEARCH_MODE, AEConfig.instance.settings.getSetting( Settings.SEARCH_MODE ) ) );
offset += 20;
this.buttonList.add( this.searchStringSave = new GuiImgButton( this.guiLeft - 18, offset, Settings.SAVE_SEARCH, AEConfig.instance.preserveSearchBar ? YesNo.YES : YesNo.NO ) );
offset += 20;
this.buttonList.add( this.terminalStyleBox = new GuiImgButton( this.guiLeft - 18, offset, Settings.TERMINAL_STYLE, AEConfig.instance.settings.getSetting( Settings.TERMINAL_STYLE ) ) );
offset += 20;
this.searchField = new MEGuiTextField( this.fontRendererObj, this.guiLeft + Math.max( 80, this.offsetX ), this.guiTop + 4, 90, 12 );
this.searchField.setEnableBackgroundDrawing( false );
this.searchField.setMaxStringLength( 25 );
this.searchField.setTextColor( 0xFFFFFF );
this.searchField.setVisible( true );
searchField.setMessage(ButtonToolTips.SearchStringTooltip.getLocal());
if( this.viewCell)
{
if (AEConfig.instance.getConfigManager().getSetting(Settings.CRAFTING_STATUS).equals(CraftingStatus.BUTTON)) {
this.buttonList.add(this.craftingStatusImgBtn = new GuiImgButton(this.guiLeft - 18, offset, Settings.CRAFTING_STATUS, AEConfig.instance.settings.getSetting(Settings.CRAFTING_STATUS)));
} else {
this.buttonList.add(this.craftingStatusBtn = new GuiTabButton(this.guiLeft + 170, this.guiTop - 4, 2 + 11 * 16, GuiText.CraftingStatus.getLocal(), itemRender));
this.craftingStatusBtn.setHideEdge( 13 ); // GuiTabButton implementation //
}
}
// Enum setting = AEConfig.INSTANCE.getSetting( "Terminal", SearchBoxMode.class, SearchBoxMode.AUTOSEARCH );
final Enum setting = AEConfig.instance.settings.getSetting( Settings.SEARCH_MODE );
this.searchField.setFocused( SearchBoxMode.AUTOSEARCH == setting || SearchBoxMode.NEI_AUTOSEARCH == setting );
if (AEConfig.instance.preserveSearchBar || this.isSubGui())
{
setSearchString(memoryText, false);
}
if( this.isSubGui() )
{
this.repo.updateView();
this.setScrollBar();
}
craftingGridOffsetX = Integer.MAX_VALUE;
craftingGridOffsetY = Integer.MAX_VALUE;
for( final Object s : this.inventorySlots.inventorySlots )
{
if( s instanceof AppEngSlot)
{
if( ( (Slot) s ).xDisplayPosition < 197 )
{
this.repositionSlot( (AppEngSlot) s );
}
}
if( s instanceof SlotCraftingMatrix || s instanceof SlotFakeCraftingMatrix)
{
final Slot g = (Slot) s;
if( g.xDisplayPosition > 0 && g.yDisplayPosition > 0 )
{
craftingGridOffsetX = Math.min( craftingGridOffsetX, g.xDisplayPosition );
craftingGridOffsetY = Math.min( craftingGridOffsetY, g.yDisplayPosition );
}
}
}
craftingGridOffsetX -= 25;
craftingGridOffsetY -= 6;
}
public void setSearchString(String memoryText, boolean updateView)
{
this.searchField.setText(memoryText);
this.repo.setSearchString(memoryText);
if (updateView)
{
this.repo.updateView();
this.setScrollBar();
}
}
@Override
public void drawFG( final int offsetX, final int offsetY, final int mouseX, final int mouseY )
{
this.fontRendererObj.drawString( this.getGuiDisplayName( GuiText.Terminal.getLocal() ), 8, 6, 4210752 );
this.fontRendererObj.drawString( GuiText.inventory.getLocal(), 8, this.ySize - 96 + 3, 4210752 );
}
@Override
protected void mouseClicked( final int xCoord, final int yCoord, final int btn )
{
final Enum searchMode = AEConfig.instance.settings.getSetting( Settings.SEARCH_MODE );
if( searchMode != SearchBoxMode.AUTOSEARCH && searchMode != SearchBoxMode.NEI_AUTOSEARCH )
{
this.searchField.mouseClicked( xCoord, yCoord, btn );
}
if( btn == 1 && this.searchField.isMouseIn( xCoord, yCoord ) )
{
setSearchString("", true);
}
super.mouseClicked( xCoord, yCoord, btn );
}
@Override
protected void handleMouseClick( final Slot slot, final int slotIdx, final int ctrlDown, final int mouseButton )
{
final EntityPlayer player = Minecraft.getMinecraft().thePlayer;
if( slot instanceof SlotFake)
{
final InventoryAction action = ctrlDown == 1 ? InventoryAction.SPLIT_OR_PLACE_SINGLE : InventoryAction.PICKUP_OR_SET_DOWN;
if( Ae2Reflect.getDragClick(this).size() > 1 )
{
return;
}
final PacketInventoryAction p = new PacketInventoryAction( action, slotIdx, 0 );
NetworkHandler.instance.sendToServer( p );
return;
}
if( slot instanceof SlotPatternTerm)
{
if( mouseButton == 6 )
{
return; // prevent weird double clicks..
}
try
{
NetworkHandler.instance.sendToServer( ( (SlotPatternTerm) slot ).getRequest( isShiftKeyDown() ) );
}
catch( final IOException e )
{
AELog.debug( e );
}
}
else if( slot instanceof SlotCraftingTerm )
{
if( mouseButton == 6 )
{
return; // prevent weird double clicks..
}
InventoryAction action = null;
if( isShiftKeyDown() )
{
action = InventoryAction.CRAFT_SHIFT;
}
else
{
// Craft stack on right-click, craft single on left-click
action = ( mouseButton == 1 ) ? InventoryAction.CRAFT_STACK : InventoryAction.CRAFT_ITEM;
}
final PacketInventoryAction p = new PacketInventoryAction( action, slotIdx, 0 );
NetworkHandler.instance.sendToServer( p );
return;
}
if( Keyboard.isKeyDown( Keyboard.KEY_SPACE ) )
{
if( this.enableSpaceClicking() && !( slot instanceof SlotPatternTerm ) )
{
IAEItemStack stack = null;
if( slot instanceof SlotME )
{
stack = ( (SlotME) slot ).getAEStack();
}
int slotNum = Ae2Reflect.getInventorySlots(this).size();
if( !( slot instanceof SlotME ) && slot != null )
{
slotNum = slot.slotNumber;
}
( (AEBaseContainer) this.inventorySlots ).setTargetStack( stack );
final PacketInventoryAction p = new PacketInventoryAction( InventoryAction.MOVE_REGION, slotNum, 0 );
NetworkHandler.instance.sendToServer( p );
return;
}
}
if( slot instanceof SlotDisconnected)
{
if( Ae2Reflect.getDragClick(this).size() > 1 )
{
return;
}
InventoryAction action = null;
switch( mouseButton )
{
case 0: // pickup / set-down.
{
ItemStack heldStack = player.inventory.getItemStack();
if (slot.getStack() == null && heldStack != null)
action = InventoryAction.SPLIT_OR_PLACE_SINGLE;
else if (slot.getStack() != null && (heldStack == null || heldStack.stackSize <= 1))
action = InventoryAction.PICKUP_OR_SET_DOWN;
}
break;
case 1:
action = ctrlDown == 1 ? InventoryAction.PICKUP_SINGLE : InventoryAction.SHIFT_CLICK;
break;
case 3: // creative dupe:
if( player.capabilities.isCreativeMode )
{
action = InventoryAction.CREATIVE_DUPLICATE;
}
break;
default:
case 4: // drop item:
case 6:
}
if( action != null )
{
final PacketInventoryAction p = new PacketInventoryAction( action, slot.getSlotIndex(), ( (SlotDisconnected) slot ).getSlot().getId() );
NetworkHandler.instance.sendToServer( p );
}
return;
}
if( slot instanceof SlotME )
{
InventoryAction action = null;
IAEItemStack stack = null;
switch( mouseButton )
{
case 0: // pickup / set-down.
action = ctrlDown == 1 ? InventoryAction.SPLIT_OR_PLACE_SINGLE : InventoryAction.PICKUP_OR_SET_DOWN;
stack = ( (SlotME) slot ).getAEStack();
if( stack != null && action == InventoryAction.PICKUP_OR_SET_DOWN && stack.getStackSize() == 0 && player.inventory.getItemStack() == null )
{
action = InventoryAction.AUTO_CRAFT;
}
break;
case 1:
action = ctrlDown == 1 ? InventoryAction.PICKUP_SINGLE : InventoryAction.SHIFT_CLICK;
stack = ( (SlotME) slot ).getAEStack();
break;
case 3: // creative dupe:
stack = ( (SlotME) slot ).getAEStack();
if( stack != null && stack.isCraftable() )
{
action = InventoryAction.AUTO_CRAFT;
}
else if( player.capabilities.isCreativeMode )
{
final IAEItemStack slotItem = ( (SlotME) slot ).getAEStack();
if( slotItem != null )
{
action = InventoryAction.CREATIVE_DUPLICATE;
}
}
break;
default:
case 4: // drop item:
case 6:
}
if (action == InventoryAction.AUTO_CRAFT) {
((AEBaseContainer) this.inventorySlots).setTargetStack( stack );
FluidCraft.proxy.netHandler.sendToServer(new CPacketInventoryAction(action, Ae2Reflect.getInventorySlots(this).size(), 0, stack));
}
else if( action != null )
{
( (AEBaseContainer) this.inventorySlots ).setTargetStack( stack );
final PacketInventoryAction p = new PacketInventoryAction( action, Ae2Reflect.getInventorySlots(this).size(), 0 );
NetworkHandler.instance.sendToServer( p );
}
return;
}
super.handleMouseClick( slot, slotIdx, ctrlDown, mouseButton );
}
@Override
public void onGuiClosed()
{
super.onGuiClosed();
Keyboard.enableRepeatEvents( false );
memoryText = this.searchField.getText();
}
@Override
public void drawBG( final int offsetX, final int offsetY, final int mouseX, final int mouseY )
{
this.bindTexture( this.getBackground() );
final int x_width = 197;
this.drawTexturedModalRect( offsetX, offsetY, 0, 0, x_width, 18 );
if( this.viewCell )
{
this.drawTexturedModalRect( offsetX + x_width, offsetY, x_width, 0, 46, 128 );
}
for( int x = 0; x < this.rows; x++ )
{
this.drawTexturedModalRect( offsetX, offsetY + 18 + x * 18, 0, 18, x_width, 18 );
}
this.drawTexturedModalRect( offsetX, offsetY + 16 + this.rows * 18 + this.lowerTextureOffset, 0, 106 - 18 - 18, x_width, 99 + this.reservedSpace - this.lowerTextureOffset );
if( this.viewCell )
{
boolean update = false;
for( int i = 0; i < 5; i++ )
{
if( this.myCurrentViewCells[i] != this.monitorableContainer.getCellViewSlot( i ).getStack() )
{
update = true;
this.myCurrentViewCells[i] = this.monitorableContainer.getCellViewSlot( i ).getStack();
}
}
if( update )
{
this.repo.setViewCell( this.myCurrentViewCells );
}
}
if( this.searchField != null )
{
this.searchField.drawTextBox();
}
}
protected String getBackground()
{
return "guis/terminal.png";
}
@Override
protected boolean isPowered()
{
return this.repo.hasPower();
}
int getMaxRows()
{
return AEConfig.instance.getConfigManager().getSetting( Settings.TERMINAL_STYLE ) == TerminalStyle.SMALL ? 6 : Integer.MAX_VALUE;
}
protected void repositionSlot( final AppEngSlot s )
{
s.yDisplayPosition = s.getY() + this.ySize - 78 - 5;
}
@Override
protected void keyTyped( final char character, final int key )
{
if( !this.checkHotbarKeys( key ) )
{
if( character == ' ' && this.searchField.getText().isEmpty() )
{
return;
}
if( this.searchField.textboxKeyTyped( character, key ) )
{
this.repo.setSearchString( this.searchField.getText() );
this.repo.updateView();
this.setScrollBar();
}
else
{
super.keyTyped( character, key );
}
}
}
@Override
public void updateScreen()
{
this.repo.setPower( this.monitorableContainer.isPowered() );
super.updateScreen();
}
@Override
public Enum getSortBy()
{
return this.configSrc.getSetting( Settings.SORT_BY );
}
@Override
public Enum getSortDir()
{
return this.configSrc.getSetting( Settings.SORT_DIRECTION );
}
@Override
public Enum getSortDisplay()
{
return this.configSrc.getSetting( Settings.VIEW_MODE );
}
@Override
public void updateSetting( final IConfigManager manager, final Enum settingName, final Enum newValue )
{
if( this.SortByBox != null )
{
this.SortByBox.set( this.configSrc.getSetting( Settings.SORT_BY ) );
}
if( this.SortDirBox != null )
{
this.SortDirBox.set( this.configSrc.getSetting( Settings.SORT_DIRECTION ) );
}
if( this.ViewBox != null )
{
this.ViewBox.set( this.configSrc.getSetting( Settings.VIEW_MODE ) );
}
this.repo.updateView();
}
int getReservedSpace()
{
return this.reservedSpace;
}
void setReservedSpace( final int reservedSpace )
{
this.reservedSpace = reservedSpace;
}
public boolean isCustomSortOrder()
{
return this.customSortOrder;
}
void setCustomSortOrder( final boolean customSortOrder )
{
this.customSortOrder = customSortOrder;
}
public int getStandardSize()
{
return this.standardSize;
}
void setStandardSize( final int standardSize )
{
this.standardSize = standardSize;
}
@Override
public void drawScreen( final int mouseX, final int mouseY, final float btn ) {
super.drawScreen(mouseX, mouseY, btn);
if (AEConfig.instance.preserveSearchBar && searchField != null)
handleTooltip(mouseX, mouseY, searchField.new TooltipProvider());
}
public boolean isOverSearchField(int x, int y)
{
return searchField.isMouseIn(x,y);
}
}
@@ -0,0 +1,257 @@
package com.glodblock.github.client.gui;
import appeng.api.AEApi;
import appeng.api.definitions.IDefinitions;
import appeng.api.definitions.IParts;
import appeng.api.storage.ITerminalHost;
import appeng.client.gui.AEBaseGui;
import appeng.client.gui.widgets.GuiNumberBox;
import appeng.client.gui.widgets.GuiTabButton;
import appeng.container.AEBaseContainer;
import appeng.container.implementations.ContainerCraftAmount;
import appeng.core.AEConfig;
import appeng.core.localization.GuiText;
import appeng.helpers.Reflected;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.common.parts.PartFluidPatternTerminal;
import com.glodblock.github.inventory.gui.GuiType;
import com.glodblock.github.loader.ItemAndBlockHolder;
import com.glodblock.github.network.CPacketCraftRequest;
import com.glodblock.github.network.CPacketSwitchGuis;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
public class GuiFluidCraftAmount extends AEBaseGui
{
private GuiNumberBox amountToCraft;
private GuiTabButton originalGuiBtn;
private GuiButton next;
private GuiButton plus1;
private GuiButton plus10;
private GuiButton plus100;
private GuiButton plus1000;
private GuiButton minus1;
private GuiButton minus10;
private GuiButton minus100;
private GuiButton minus1000;
private GuiType originalGui;
@Reflected
public GuiFluidCraftAmount(final InventoryPlayer inventoryPlayer, final ITerminalHost te )
{
super( new ContainerCraftAmount( inventoryPlayer, te ) );
}
@Override
public void initGui()
{
super.initGui();
final int a = AEConfig.instance.craftItemsByStackAmounts( 0 );
final int b = AEConfig.instance.craftItemsByStackAmounts( 1 );
final int c = AEConfig.instance.craftItemsByStackAmounts( 2 );
final int d = AEConfig.instance.craftItemsByStackAmounts( 3 );
this.buttonList.add( this.plus1 = new GuiButton( 0, this.guiLeft + 20, this.guiTop + 26, 22, 20, "+" + a ) );
this.buttonList.add( this.plus10 = new GuiButton( 0, this.guiLeft + 48, this.guiTop + 26, 28, 20, "+" + b ) );
this.buttonList.add( this.plus100 = new GuiButton( 0, this.guiLeft + 82, this.guiTop + 26, 32, 20, "+" + c ) );
this.buttonList.add( this.plus1000 = new GuiButton( 0, this.guiLeft + 120, this.guiTop + 26, 38, 20, "+" + d ) );
this.buttonList.add( this.minus1 = new GuiButton( 0, this.guiLeft + 20, this.guiTop + 75, 22, 20, "-" + a ) );
this.buttonList.add( this.minus10 = new GuiButton( 0, this.guiLeft + 48, this.guiTop + 75, 28, 20, "-" + b ) );
this.buttonList.add( this.minus100 = new GuiButton( 0, this.guiLeft + 82, this.guiTop + 75, 32, 20, "-" + c ) );
this.buttonList.add( this.minus1000 = new GuiButton( 0, this.guiLeft + 120, this.guiTop + 75, 38, 20, "-" + d ) );
this.buttonList.add( this.next = new GuiButton( 0, this.guiLeft + 128, this.guiTop + 51, 38, 20, GuiText.Next.getLocal() ) );
ItemStack myIcon = null;
final Object target = ( (AEBaseContainer) this.inventorySlots ).getTarget();
final IDefinitions definitions = AEApi.instance().definitions();
final IParts parts = definitions.parts();
if( target instanceof PartFluidPatternTerminal)
{
myIcon = new ItemStack(ItemAndBlockHolder.FLUID_TERMINAL, 1);
this.originalGui = GuiType.FLUID_PATTERN_TERMINAL;
}
if( this.originalGui != null && myIcon != null )
{
this.buttonList.add( this.originalGuiBtn = new GuiTabButton( this.guiLeft + 154, this.guiTop, myIcon, myIcon.getDisplayName(), itemRender ) );
}
this.amountToCraft = new GuiNumberBox( this.fontRendererObj, this.guiLeft + 62, this.guiTop + 57, 59, this.fontRendererObj.FONT_HEIGHT, Integer.class );
this.amountToCraft.setEnableBackgroundDrawing( false );
this.amountToCraft.setMaxStringLength( 16 );
this.amountToCraft.setTextColor( 0xFFFFFF );
this.amountToCraft.setVisible( true );
this.amountToCraft.setFocused( true );
this.amountToCraft.setText( "1" );
this.amountToCraft.setSelectionPos(0);
}
@Override
public void drawFG( final int offsetX, final int offsetY, final int mouseX, final int mouseY )
{
this.fontRendererObj.drawString( GuiText.SelectAmount.getLocal(), 8, 6, 4210752 );
}
@Override
public void drawBG( final int offsetX, final int offsetY, final int mouseX, final int mouseY )
{
this.next.displayString = isShiftKeyDown() ? GuiText.Start.getLocal() : GuiText.Next.getLocal();
this.bindTexture( "guis/craftAmt.png" );
this.drawTexturedModalRect( offsetX, offsetY, 0, 0, this.xSize, this.ySize );
try
{
Long.parseLong( this.amountToCraft.getText() );
this.next.enabled = this.amountToCraft.getText().length() > 0;
}
catch( final NumberFormatException e )
{
this.next.enabled = false;
}
this.amountToCraft.drawTextBox();
}
@Override
protected void keyTyped( final char character, final int key )
{
if( !this.checkHotbarKeys( key ) )
{
if( key == 28 )
{
this.actionPerformed( this.next );
}
if( ( key == 211 || key == 205 || key == 203 || key == 14 || character == '-' || Character.isDigit( character ) ) && this.amountToCraft.textboxKeyTyped( character, key ) )
{
try
{
String out = this.amountToCraft.getText();
boolean fixed = false;
while( out.startsWith( "0" ) && out.length() > 1 )
{
out = out.substring( 1 );
fixed = true;
}
if( fixed )
{
this.amountToCraft.setText( out );
}
if( out.isEmpty() )
{
out = "0";
}
final long result = Long.parseLong( out );
if( result < 0 )
{
this.amountToCraft.setText( "1" );
}
}
catch( final NumberFormatException e )
{
// :P
}
}
else
{
super.keyTyped( character, key );
}
}
}
@Override
protected void actionPerformed( final GuiButton btn )
{
super.actionPerformed( btn );
try
{
if( btn == this.originalGuiBtn )
{
FluidCraft.proxy.netHandler.sendToServer( new CPacketSwitchGuis( this.originalGui ) );
}
if( btn == this.next )
{
FluidCraft.proxy.netHandler.sendToServer( new CPacketCraftRequest( Integer.parseInt( this.amountToCraft.getText() ), isShiftKeyDown() ) );
}
}
catch( final NumberFormatException e )
{
// nope..
this.amountToCraft.setText( "1" );
}
final boolean isPlus = btn == this.plus1 || btn == this.plus10 || btn == this.plus100 || btn == this.plus1000;
final boolean isMinus = btn == this.minus1 || btn == this.minus10 || btn == this.minus100 || btn == this.minus1000;
if( isPlus || isMinus )
{
this.addQty( this.getQty( btn ) );
}
}
private void addQty( final int i )
{
try
{
String out = this.amountToCraft.getText();
boolean fixed = false;
while( out.startsWith( "0" ) && out.length() > 1 )
{
out = out.substring( 1 );
fixed = true;
}
if( fixed )
{
this.amountToCraft.setText( out );
}
if( out.isEmpty() )
{
out = "0";
}
long result = Integer.parseInt( out );
if( result == 1 && i > 1 )
{
result = 0;
}
result += i;
if( result < 1 )
{
result = 1;
}
out = Long.toString( result );
Integer.parseInt( out );
this.amountToCraft.setText( out );
}
catch( final NumberFormatException e )
{
// :P
}
}
protected String getBackground()
{
return "guis/craftAmt.png";
}
}
@@ -0,0 +1,531 @@
package com.glodblock.github.client.gui;
import appeng.api.AEApi;
import appeng.api.storage.ITerminalHost;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.client.gui.AEBaseGui;
import appeng.client.gui.widgets.GuiScrollbar;
import appeng.core.AELog;
import appeng.core.localization.GuiText;
import appeng.util.Platform;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.client.gui.container.ContainerFluidCraftConfirm;
import com.glodblock.github.common.parts.PartFluidPatternTerminal;
import com.glodblock.github.inventory.gui.GuiType;
import com.glodblock.github.network.CPacketFluidPatternTermBtns;
import com.glodblock.github.network.CPacketSwitchGuis;
import com.google.common.base.Joiner;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class GuiFluidCraftConfirm extends AEBaseGui {
private final ContainerFluidCraftConfirm ccc;
private final int rows = 5;
private final IItemList<IAEItemStack> storage = AEApi.instance().storage().createItemList();
private final IItemList<IAEItemStack> pending = AEApi.instance().storage().createItemList();
private final IItemList<IAEItemStack> missing = AEApi.instance().storage().createItemList();
private final List<IAEItemStack> visual = new ArrayList<IAEItemStack>();
private GuiType OriginalGui;
private GuiButton cancel;
private GuiButton start;
private GuiButton selectCPU;
private int tooltip = -1;
public GuiFluidCraftConfirm(final InventoryPlayer inventoryPlayer, final ITerminalHost te )
{
super( new ContainerFluidCraftConfirm( inventoryPlayer, te ) );
this.xSize = 238;
this.ySize = 206;
final GuiScrollbar scrollbar = new GuiScrollbar();
this.setScrollBar( scrollbar );
this.ccc = (ContainerFluidCraftConfirm) this.inventorySlots;
if( te instanceof PartFluidPatternTerminal)
{
this.OriginalGui = GuiType.FLUID_PATTERN_TERMINAL;
}
}
boolean isAutoStart()
{
return ( (ContainerFluidCraftConfirm) this.inventorySlots ).isAutoStart();
}
@Override
public void initGui()
{
super.initGui();
this.start = new GuiButton( 0, this.guiLeft + 162, this.guiTop + this.ySize - 25, 50, 20, GuiText.Start.getLocal() );
this.start.enabled = false;
this.buttonList.add( this.start );
this.selectCPU = new GuiButton( 0, this.guiLeft + ( 219 - 180 ) / 2, this.guiTop + this.ySize - 68, 180, 20, GuiText.CraftingCPU.getLocal() + ": " + GuiText.Automatic );
this.selectCPU.enabled = false;
this.buttonList.add( this.selectCPU );
if( this.OriginalGui != null )
{
this.cancel = new GuiButton( 0, this.guiLeft + 6, this.guiTop + this.ySize - 25, 50, 20, GuiText.Cancel.getLocal() );
}
this.buttonList.add( this.cancel );
}
@Override
public void drawScreen( final int mouseX, final int mouseY, final float btn )
{
this.updateCPUButtonText();
this.start.enabled = !( this.ccc.hasNoCPU() || this.isSimulation() );
this.selectCPU.enabled = !this.isSimulation();
final int gx = ( this.width - this.xSize ) / 2;
final int gy = ( this.height - this.ySize ) / 2;
this.tooltip = -1;
final int offY = 23;
int y = 0;
int x = 0;
for( int z = 0; z <= 4 * 5; z++ )
{
final int minX = gx + 9 + x * 67;
final int minY = gy + 22 + y * offY;
if( minX < mouseX && minX + 67 > mouseX )
{
if( minY < mouseY && minY + offY - 2 > mouseY )
{
this.tooltip = z;
break;
}
}
x++;
if( x > 2 )
{
y++;
x = 0;
}
}
super.drawScreen( mouseX, mouseY, btn );
}
private void updateCPUButtonText()
{
String btnTextText = GuiText.CraftingCPU.getLocal() + ": " + GuiText.Automatic.getLocal();
if( this.ccc.getSelectedCpu() >= 0 )// && status.selectedCpu < status.cpus.size() )
{
if( this.ccc.getName().length() > 0 )
{
final String name = this.ccc.getName().substring( 0, Math.min( 20, this.ccc.getName().length() ) );
btnTextText = GuiText.CraftingCPU.getLocal() + ": " + name;
}
else
{
btnTextText = GuiText.CraftingCPU.getLocal() + ": #" + this.ccc.getSelectedCpu();
}
}
if( this.ccc.hasNoCPU() )
{
btnTextText = GuiText.NoCraftingCPUs.getLocal();
}
this.selectCPU.displayString = btnTextText;
}
private boolean isSimulation()
{
return ( (ContainerFluidCraftConfirm) this.inventorySlots ).isSimulation();
}
@Override
public void drawFG( final int offsetX, final int offsetY, final int mouseX, final int mouseY )
{
final long BytesUsed = this.ccc.getUsedBytes();
final String byteUsed = NumberFormat.getInstance().format( BytesUsed );
final String Add = BytesUsed > 0 ? ( byteUsed + ' ' + GuiText.BytesUsed.getLocal() ) : GuiText.CalculatingWait.getLocal();
this.fontRendererObj.drawString( GuiText.CraftingPlan.getLocal() + " - " + Add, 8, 7, 4210752 );
String dsp = null;
if( this.isSimulation() )
{
dsp = GuiText.Simulation.getLocal();
}
else
{
dsp = this.ccc.getCpuAvailableBytes() > 0 ? ( GuiText.Bytes.getLocal() + ": " + this.ccc.getCpuAvailableBytes() + " : " + GuiText.CoProcessors.getLocal() + ": " + this.ccc.getCpuCoProcessors() ) : GuiText.Bytes.getLocal() + ": N/A : " + GuiText.CoProcessors.getLocal() + ": N/A";
}
final int offset = ( 219 - this.fontRendererObj.getStringWidth( dsp ) ) / 2;
this.fontRendererObj.drawString( dsp, offset, 165, 4210752 );
final int sectionLength = 67;
int x = 0;
int y = 0;
final int xo = 9;
final int yo = 22;
final int viewStart = this.getScrollBar().getCurrentScroll() * 3;
final int viewEnd = viewStart + 3 * this.rows;
String dspToolTip = "";
final List<String> lineList = new LinkedList<String>();
int toolPosX = 0;
int toolPosY = 0;
final int offY = 23;
for( int z = viewStart; z < Math.min( viewEnd, this.visual.size() ); z++ )
{
final IAEItemStack refStack = this.visual.get( z );// repo.getReferenceItem( z );
if( refStack != null )
{
GL11.glPushMatrix();
GL11.glScaled( 0.5, 0.5, 0.5 );
final IAEItemStack stored = this.storage.findPrecise( refStack );
final IAEItemStack pendingStack = this.pending.findPrecise( refStack );
final IAEItemStack missingStack = this.missing.findPrecise( refStack );
int lines = 0;
if( stored != null && stored.getStackSize() > 0 )
{
lines++;
}
if( pendingStack != null && pendingStack.getStackSize() > 0 )
{
lines++;
}
if( pendingStack != null && pendingStack.getStackSize() > 0 )
{
lines++;
}
final int negY = ( ( lines - 1 ) * 5 ) / 2;
int downY = 0;
if( stored != null && stored.getStackSize() > 0 )
{
String str = Long.toString( stored.getStackSize() );
if( stored.getStackSize() >= 10000 )
{
str = Long.toString( stored.getStackSize() / 1000 ) + 'k';
}
if( stored.getStackSize() >= 10000000 )
{
str = Long.toString( stored.getStackSize() / 1000000 ) + 'm';
}
str = GuiText.FromStorage.getLocal() + ": " + str;
final int w = 4 + this.fontRendererObj.getStringWidth( str );
this.fontRendererObj.drawString( str, (int) ( ( x * ( 1 + sectionLength ) + xo + sectionLength - 19 - ( w * 0.5 ) ) * 2 ), ( y * offY + yo + 6 - negY + downY ) * 2, 4210752 );
if( this.tooltip == z - viewStart )
{
lineList.add( GuiText.FromStorage.getLocal() + ": " + Long.toString( stored.getStackSize() ) );
}
downY += 5;
}
boolean red = false;
if( missingStack != null && missingStack.getStackSize() > 0 )
{
String str = Long.toString( missingStack.getStackSize() );
if( missingStack.getStackSize() >= 10000 )
{
str = Long.toString( missingStack.getStackSize() / 1000 ) + 'k';
}
if( missingStack.getStackSize() >= 10000000 )
{
str = Long.toString( missingStack.getStackSize() / 1000000 ) + 'm';
}
str = GuiText.Missing.getLocal() + ": " + str;
final int w = 4 + this.fontRendererObj.getStringWidth( str );
this.fontRendererObj.drawString( str, (int) ( ( x * ( 1 + sectionLength ) + xo + sectionLength - 19 - ( w * 0.5 ) ) * 2 ), ( y * offY + yo + 6 - negY + downY ) * 2, 4210752 );
if( this.tooltip == z - viewStart )
{
lineList.add( GuiText.Missing.getLocal() + ": " + Long.toString( missingStack.getStackSize() ) );
}
red = true;
downY += 5;
}
if( pendingStack != null && pendingStack.getStackSize() > 0 )
{
String str = Long.toString( pendingStack.getStackSize() );
if( pendingStack.getStackSize() >= 10000 )
{
str = Long.toString( pendingStack.getStackSize() / 1000 ) + 'k';
}
if( pendingStack.getStackSize() >= 10000000 )
{
str = Long.toString( pendingStack.getStackSize() / 1000000 ) + 'm';
}
str = GuiText.ToCraft.getLocal() + ": " + str;
final int w = 4 + this.fontRendererObj.getStringWidth( str );
this.fontRendererObj.drawString( str, (int) ( ( x * ( 1 + sectionLength ) + xo + sectionLength - 19 - ( w * 0.5 ) ) * 2 ), ( y * offY + yo + 6 - negY + downY ) * 2, 4210752 );
if( this.tooltip == z - viewStart )
{
lineList.add( GuiText.ToCraft.getLocal() + ": " + Long.toString( pendingStack.getStackSize() ) );
}
}
GL11.glPopMatrix();
final int posX = x * ( 1 + sectionLength ) + xo + sectionLength - 19;
final int posY = y * offY + yo;
final ItemStack is = refStack.copy().getItemStack();
if( this.tooltip == z - viewStart )
{
dspToolTip = Platform.getItemDisplayName( is );
if( lineList.size() > 0 )
{
addItemTooltip(is, lineList);
dspToolTip = dspToolTip + '\n' + Joiner.on( "\n" ).join( lineList );
}
toolPosX = x * ( 1 + sectionLength ) + xo + sectionLength - 8;
toolPosY = y * offY + yo;
}
this.drawItem( posX, posY, is );
if( red )
{
final int startX = x * ( 1 + sectionLength ) + xo;
final int startY = posY - 4;
drawRect( startX, startY, startX + sectionLength, startY + offY, 0x1AFF0000 );
}
x++;
if( x > 2 )
{
y++;
x = 0;
}
}
}
if( this.tooltip >= 0 && dspToolTip.length() > 0 )
{
this.drawTooltip( toolPosX, toolPosY + 10, 0, dspToolTip );
}
}
@Override
public void drawBG( final int offsetX, final int offsetY, final int mouseX, final int mouseY )
{
this.setScrollBar();
this.bindTexture( "guis/craftingreport.png" );
this.drawTexturedModalRect( offsetX, offsetY, 0, 0, this.xSize, this.ySize );
}
private void setScrollBar()
{
final int size = this.visual.size();
this.getScrollBar().setTop( 19 ).setLeft( 218 ).setHeight( 114 );
this.getScrollBar().setRange( 0, ( size + 2 ) / 3 - this.rows, 1 );
}
public void postUpdate( final List<IAEItemStack> list, final byte ref )
{
switch( ref )
{
case 0:
for( final IAEItemStack l : list )
{
this.handleInput( this.storage, l );
}
break;
case 1:
for( final IAEItemStack l : list )
{
this.handleInput( this.pending, l );
}
break;
case 2:
for( final IAEItemStack l : list )
{
this.handleInput( this.missing, l );
}
break;
}
for( final IAEItemStack l : list )
{
final long amt = this.getTotal( l );
if( amt <= 0 )
{
this.deleteVisualStack( l );
}
else
{
final IAEItemStack is = this.findVisualStack( l );
is.setStackSize( amt );
}
}
this.setScrollBar();
}
private void handleInput( final IItemList<IAEItemStack> s, final IAEItemStack l )
{
IAEItemStack a = s.findPrecise( l );
if( l.getStackSize() <= 0 )
{
if( a != null )
{
a.reset();
}
}
else
{
if( a == null )
{
s.add( l.copy() );
a = s.findPrecise( l );
}
if( a != null )
{
a.setStackSize( l.getStackSize() );
}
}
}
private long getTotal( final IAEItemStack is )
{
final IAEItemStack a = this.storage.findPrecise( is );
final IAEItemStack c = this.pending.findPrecise( is );
final IAEItemStack m = this.missing.findPrecise( is );
long total = 0;
if( a != null )
{
total += a.getStackSize();
}
if( c != null )
{
total += c.getStackSize();
}
if( m != null )
{
total += m.getStackSize();
}
return total;
}
private void deleteVisualStack( final IAEItemStack l )
{
final Iterator<IAEItemStack> i = this.visual.iterator();
while( i.hasNext() )
{
final IAEItemStack o = i.next();
if( o.equals( l ) )
{
i.remove();
return;
}
}
}
private IAEItemStack findVisualStack( final IAEItemStack l )
{
for( final IAEItemStack o : this.visual )
{
if( o.equals( l ) )
{
return o;
}
}
final IAEItemStack stack = l.copy();
this.visual.add( stack );
return stack;
}
@Override
protected void keyTyped( final char character, final int key )
{
if( !this.checkHotbarKeys( key ) )
{
if( key == 28 )
{
this.actionPerformed( this.start );
}
super.keyTyped( character, key );
}
}
@Override
protected void actionPerformed( final GuiButton btn )
{
super.actionPerformed( btn );
final boolean backwards = Mouse.isButtonDown( 1 );
if( btn == this.selectCPU )
{
FluidCraft.proxy.netHandler.sendToServer( new CPacketFluidPatternTermBtns( "Terminal.Cpu", backwards ? "Prev" : "Next" ) );
}
if( btn == this.cancel )
{
FluidCraft.proxy.netHandler.sendToServer( new CPacketSwitchGuis( this.OriginalGui ) );
}
if( btn == this.start )
{
try
{
FluidCraft.proxy.netHandler.sendToServer( new CPacketFluidPatternTermBtns( "Terminal.Start", "Start" ) );
}
catch( final Throwable e )
{
AELog.debug( e );
}
}
}
}
@@ -0,0 +1,33 @@
package com.glodblock.github.client.gui;
import appeng.client.gui.AEBaseGui;
import appeng.core.localization.GuiText;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.client.gui.container.ContainerFluidPacketDecoder;
import com.glodblock.github.common.tile.TileFluidPacketDecoder;
import com.glodblock.github.util.NameConst;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.util.ResourceLocation;
public class GuiFluidPacketDecoder extends AEBaseGui {
private static final ResourceLocation TEX_BG = FluidCraft.resource("textures/gui/fluid_packet_decoder.png");
public GuiFluidPacketDecoder(InventoryPlayer ipl, TileFluidPacketDecoder tile) {
super(new ContainerFluidPacketDecoder(ipl, tile));
}
@Override
public void drawBG(int offsetX, int offsetY, int mouseX, int mouseY) {
mc.getTextureManager().bindTexture(TEX_BG);
drawTexturedModalRect(offsetX, offsetY, 0, 0, 176, ySize);
}
@Override
public void drawFG(int offsetX, int offsetY, int mouseX, int mouseY) {
fontRendererObj.drawString(getGuiDisplayName(I18n.format(NameConst.GUI_FLUID_PACKET_DECODER)), 8, 6, 0x404040);
fontRendererObj.drawString(GuiText.inventory.getLocal(), 8, ySize - 94, 0x404040);
}
}
@@ -0,0 +1,136 @@
package com.glodblock.github.client.gui;
import appeng.api.storage.data.IAEItemStack;
import appeng.client.gui.AEBaseGui;
import appeng.client.render.AppEngRenderItem;
import appeng.core.localization.GuiText;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.client.gui.container.ContainerFluidPatternEncoder;
import com.glodblock.github.common.item.ItemFluidPacket;
import com.glodblock.github.common.tile.TileFluidPatternEncoder;
import com.glodblock.github.inventory.gui.MouseRegionManager;
import com.glodblock.github.inventory.slot.SlotFluid;
import com.glodblock.github.inventory.slot.SlotSingleItem;
import com.glodblock.github.network.CPacketEncodePattern;
import com.glodblock.github.util.Ae2Reflect;
import com.glodblock.github.util.NameConst;
import com.glodblock.github.util.Util;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fluids.FluidStack;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class GuiFluidPatternEncoder extends AEBaseGui {
private static final ResourceLocation TEX_BG = FluidCraft.resource("textures/gui/fluid_pattern_encoder.png");
private final ContainerFluidPatternEncoder cont;
private final MouseRegionManager mouseRegions = new MouseRegionManager(this, fontRendererObj);
private final AppEngRenderItem stackSizeRenderer = Ae2Reflect.getStackSizeRenderer(this);
public GuiFluidPatternEncoder(InventoryPlayer ipl, TileFluidPatternEncoder tile) {
super(new ContainerFluidPatternEncoder(ipl, tile));
this.cont = (ContainerFluidPatternEncoder)inventorySlots;
mouseRegions.addRegion(141, 38, 10, 10, new MouseRegionManager.Handler() {
@Override
public List<String> getTooltip() {
return Collections.singletonList(I18n.format(NameConst.TT_ENCODE_PATTERN));
}
@Override
public boolean onClick(int button) {
if (button == 0) {
if (cont.canEncodePattern()) {
FluidCraft.proxy.netHandler.sendToServer(new CPacketEncodePattern());
}
return true;
}
return false;
}
});
}
@Override
protected void mouseClicked(int xCoord, int yCoord, int btn) {
if (mouseRegions.onClick(xCoord, yCoord, btn)) {
super.mouseClicked(xCoord, yCoord, btn);
}
}
@Override
public void drawBG(int offsetX, int offsetY, int mouseX, int mouseY) {
mc.getTextureManager().bindTexture(TEX_BG);
drawTexturedModalRect(offsetX, offsetY, 0, 0, 176, ySize);
}
@Override
public void drawFG(int offsetX, int offsetY, int mouseX, int mouseY) {
fontRendererObj.drawString(getGuiDisplayName(I18n.format(NameConst.GUI_FLUID_PATTERN_ENCODER)), 8, 6, 0x404040);
fontRendererObj.drawString(GuiText.inventory.getLocal(), 8, ySize - 94, 0x404040);
mouseRegions.render(mouseX, mouseY);
}
@Override
public void func_146977_a( final Slot s )
{
this.drawSlot0( s );
}
public void drawSlot0(Slot slot) {
if (slot instanceof SlotFluid) {
IAEItemStack stack = ((SlotFluid)slot).getAeStack();
super.func_146977_a(new SlotSingleItem(slot));
if (stack == null) return;
IAEItemStack fake = stack.copy();
if (fake.getItemStack().getItem() instanceof ItemFluidPacket) {
if (ItemFluidPacket.getFluidStack(stack) != null && ItemFluidPacket.getFluidStack(stack).amount > 0)
fake.setStackSize(ItemFluidPacket.getFluidStack(stack).amount);
}
stackSizeRenderer.setAeStack(fake);
stackSizeRenderer.renderItemOverlayIntoGUI(fontRendererObj, mc.getTextureManager(), stack.getItemStack(), slot.xDisplayPosition, slot.yDisplayPosition);
} else {
super.func_146977_a(slot);
}
}
@Override
@SuppressWarnings({"unchecked", "rawtypes"})
protected void renderToolTip(ItemStack stack, int x, int y) {
List list;
if (stack.getItem() instanceof ItemFluidPacket) {
FluidStack fluid = ItemFluidPacket.getFluidStack(stack);
if (fluid != null) {
list = Arrays.asList(fluid.getLocalizedName(), String.format(EnumChatFormatting.GRAY + "%,d mB", fluid.amount));
}
else {
list = stack.getTooltip(this.mc.thePlayer, this.mc.gameSettings.advancedItemTooltips);
}
}
else {
list = stack.getTooltip(this.mc.thePlayer, this.mc.gameSettings.advancedItemTooltips);
}
for (int k = 0; k < list.size(); ++k)
{
if (k == 0)
{
list.set(k, stack.getRarity().rarityColor + (String)list.get(k));
}
else
{
list.set(k, EnumChatFormatting.GRAY + (String)list.get(k));
}
}
FontRenderer font = stack.getItem().getFontRenderer(stack);
drawHoveringText(list, x, y, (font == null ? fontRendererObj : font));
}
}
@@ -0,0 +1,73 @@
package com.glodblock.github.client.gui;
import appeng.api.storage.ITerminalHost;
import appeng.api.storage.data.IAEItemStack;
import appeng.client.gui.widgets.GuiTabButton;
import appeng.client.render.AppEngRenderItem;
import appeng.container.slot.SlotFake;
import appeng.util.item.AEItemStack;
import com.glodblock.github.client.gui.container.ContainerFluidPatternTerminal;
import com.glodblock.github.common.item.ItemFluidPacket;
import com.glodblock.github.inventory.InventoryHandler;
import com.glodblock.github.inventory.gui.GuiType;
import com.glodblock.github.inventory.slot.SlotSingleItem;
import com.glodblock.github.util.Ae2Reflect;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
public class GuiFluidPatternTerminal extends GuiBaseFluidPatternTerminal {
private GuiTabButton craftingStatusBtn;
private final AppEngRenderItem stackSizeRenderer = Ae2Reflect.getStackSizeRenderer(this);
public GuiFluidPatternTerminal(InventoryPlayer inventoryPlayer, ITerminalHost te) {
super(inventoryPlayer, te);
ContainerFluidPatternTerminal container = new ContainerFluidPatternTerminal(inventoryPlayer, te);
container.setGui(this);
this.inventorySlots = container;
Ae2Reflect.setGuiContainer(this, container);
}
@Override
public void initGui() {
super.initGui();
craftingStatusBtn = Ae2Reflect.getCraftingStatusButton(this);
}
@Override
public void func_146977_a( final Slot s )
{
if (drawSlot0(s))
super.func_146977_a( s );
}
public boolean drawSlot0(Slot slot) {
if (slot instanceof SlotFake && !this.container.isCraftingMode()) {
AEItemStack stack = AEItemStack.create(slot.getStack());
super.func_146977_a(new SlotSingleItem(slot));
if (stack == null) return true;
IAEItemStack fake = stack.copy();
if (fake.getItemStack().getItem() instanceof ItemFluidPacket) {
if (ItemFluidPacket.getFluidStack(stack) != null && ItemFluidPacket.getFluidStack(stack).amount > 0)
fake.setStackSize(ItemFluidPacket.getFluidStack(stack).amount);
}
else
return true;
stackSizeRenderer.setAeStack(fake);
stackSizeRenderer.renderItemOverlayIntoGUI(fontRendererObj, mc.getTextureManager(), stack.getItemStack(), slot.xDisplayPosition, slot.yDisplayPosition);
return false;
}
return true;
}
@Override
protected void actionPerformed(final GuiButton btn) {
if (btn == craftingStatusBtn) {
InventoryHandler.switchGui(GuiType.FLUID_PAT_TERM_CRAFTING_STATUS);
} else {
super.actionPerformed(btn);
}
}
}
@@ -0,0 +1,38 @@
package com.glodblock.github.client.gui;
import appeng.api.storage.ITerminalHost;
import appeng.client.gui.implementations.GuiCraftingStatus;
import appeng.client.gui.widgets.GuiTabButton;
import com.glodblock.github.inventory.InventoryHandler;
import com.glodblock.github.inventory.gui.GuiType;
import com.glodblock.github.loader.ItemAndBlockHolder;
import com.glodblock.github.util.Ae2Reflect;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
public class GuiFluidPatternTerminalCraftingStatus extends GuiCraftingStatus {
private GuiTabButton originalGuiBtn;
public GuiFluidPatternTerminalCraftingStatus(InventoryPlayer inventoryPlayer, ITerminalHost te) {
super(inventoryPlayer, te);
}
@Override
public void initGui() {
Ae2Reflect.rewriteIcon(this, new ItemStack(ItemAndBlockHolder.FLUID_TERMINAL, 1));
super.initGui();
originalGuiBtn = Ae2Reflect.getOriginalGuiButton(this);
}
@Override
protected void actionPerformed(final GuiButton btn) {
if (btn == originalGuiBtn) {
InventoryHandler.switchGui(GuiType.FLUID_PATTERN_TERMINAL);
} else {
super.actionPerformed(btn);
}
}
}
@@ -0,0 +1,9 @@
package com.glodblock.github.client.gui;
import appeng.api.storage.data.IAEFluidStack;
import java.util.Map;
public interface IFluidSyncContainer {
void receiveFluidSlots( final Map<Integer, IAEFluidStack> fluids );
}
@@ -0,0 +1,382 @@
package com.glodblock.github.client.gui.container;
import appeng.api.config.Upgrades;
import appeng.api.implementations.IUpgradeableHost;
import appeng.api.storage.data.IAEFluidStack;
import appeng.client.me.InternalSlotME;
import appeng.client.me.SlotME;
import appeng.container.implementations.ContainerUpgradeable;
import appeng.container.slot.*;
import appeng.util.Platform;
import appeng.util.item.AEFluidStack;
import com.glodblock.github.client.gui.IFluidSyncContainer;
import com.glodblock.github.inventory.IAEFluidTank;
import com.glodblock.github.util.Ae2Reflect;
import com.glodblock.github.util.FluidSyncHelper;
import com.glodblock.github.util.Util;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.ICrafting;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public abstract class ContainerFluidConfigurable extends ContainerUpgradeable implements IFluidSyncContainer
{
private FluidSyncHelper sync = null;
public ContainerFluidConfigurable(InventoryPlayer ip, IUpgradeableHost te )
{
super( ip, te );
}
public abstract IAEFluidTank getFluidConfigInventory();
private FluidSyncHelper getSynchHelper()
{
if( this.sync == null )
{
this.sync = new FluidSyncHelper( this.getFluidConfigInventory(), 0 );
}
return this.sync;
}
@Override
public ItemStack transferStackInSlot(final EntityPlayer p, final int idx )
{
if( Platform.isClient() )
{
return null;
}
boolean hasMETiles = false;
for( final Object is : this.inventorySlots )
{
if( is instanceof InternalSlotME)
{
hasMETiles = true;
break;
}
}
if( hasMETiles && Platform.isClient() )
{
return null;
}
final AppEngSlot clickSlot = (AppEngSlot) this.inventorySlots.get( idx ); // require AE SLots!
if( clickSlot instanceof SlotDisabled || clickSlot instanceof SlotInaccessible)
{
return null;
}
if( clickSlot != null && clickSlot.getHasStack() )
{
ItemStack tis = clickSlot.getStack();
if( tis == null )
{
return null;
}
final List<Slot> selectedSlots = new ArrayList<Slot>();
/**
* Gather a list of valid destinations.
*/
if( clickSlot.isPlayerSide() )
{
tis = this.transferStackToContainer( tis );
// target slots in the container...
for( final Object inventorySlot : this.inventorySlots )
{
final AppEngSlot cs = (AppEngSlot) inventorySlot;
if( !( cs.isPlayerSide() ) && !( cs instanceof SlotFake) && !( cs instanceof SlotCraftingMatrix) )
{
if( cs.isItemValid( tis ) )
{
selectedSlots.add( cs );
}
}
}
}
else
{
// target slots in the container...
for( final Object inventorySlot : this.inventorySlots )
{
final AppEngSlot cs = (AppEngSlot) inventorySlot;
if( ( cs.isPlayerSide() ) && !( cs instanceof SlotFake ) && !( cs instanceof SlotCraftingMatrix ) )
{
if( cs.isItemValid( tis ) )
{
selectedSlots.add( cs );
}
}
}
}
/**
* Handle Fake Slot Shift clicking.
*/
if( selectedSlots.isEmpty() && clickSlot.isPlayerSide() )
{
if( tis != null )
{
// target slots in the container...
for( final Object inventorySlot : this.inventorySlots )
{
final AppEngSlot cs = (AppEngSlot) inventorySlot;
final ItemStack destination = cs.getStack();
if( !( cs.isPlayerSide() ) && cs instanceof SlotFake )
{
if( Platform.isSameItemPrecise( destination, tis ) )
{
break;
}
else if( destination == null )
{
cs.putStack( tis.copy() );
cs.onSlotChanged();
this.detectAndSendChanges();
break;
}
}
}
}
}
if( tis != null )
{
// find partials..
for( final Slot d : selectedSlots )
{
if( d instanceof SlotDisabled || d instanceof SlotME)
{
continue;
}
if( d.isItemValid( tis ) )
{
if( d.getHasStack() )
{
final ItemStack t = d.getStack();
if( Platform.isSameItemPrecise( tis, t ) ) // t.isItemEqual(tis))
{
int maxSize = t.getMaxStackSize();
if( maxSize > d.getSlotStackLimit() )
{
maxSize = d.getSlotStackLimit();
}
int placeAble = maxSize - t.stackSize;
if( tis.stackSize < placeAble )
{
placeAble = tis.stackSize;
}
t.stackSize += placeAble;
tis.stackSize -= placeAble;
if( tis.stackSize <= 0 )
{
clickSlot.putStack( null );
d.onSlotChanged();
// if ( hasMETiles ) updateClient();
this.detectAndSendChanges();
this.detectAndSendChanges();
return null;
}
else
{
this.detectAndSendChanges();
}
}
}
}
}
// any match..
for( final Slot d : selectedSlots )
{
if( d instanceof SlotDisabled || d instanceof SlotME )
{
continue;
}
if( d.isItemValid( tis ) )
{
if( d.getHasStack() )
{
final ItemStack t = d.getStack();
if( Platform.isSameItemPrecise( t, tis ) )
{
int maxSize = t.getMaxStackSize();
if( d.getSlotStackLimit() < maxSize )
{
maxSize = d.getSlotStackLimit();
}
int placeAble = maxSize - t.stackSize;
if( tis.stackSize < placeAble )
{
placeAble = tis.stackSize;
}
t.stackSize += placeAble;
tis.stackSize -= placeAble;
if( tis.stackSize <= 0 )
{
clickSlot.putStack( null );
d.onSlotChanged();
// if ( worldEntity != null )
// worldEntity.markDirty();
// if ( hasMETiles ) updateClient();
this.detectAndSendChanges();
this.detectAndSendChanges();
return null;
}
else
{
this.detectAndSendChanges();
}
}
}
else
{
int maxSize = tis.getMaxStackSize();
if( maxSize > d.getSlotStackLimit() )
{
maxSize = d.getSlotStackLimit();
}
final ItemStack tmp = tis.copy();
if( tmp.stackSize > maxSize )
{
tmp.stackSize = maxSize;
}
tis.stackSize -= tmp.stackSize;
d.putStack( tmp );
if( tis.stackSize <= 0 )
{
clickSlot.putStack( null );
d.onSlotChanged();
// if ( worldEntity != null )
// worldEntity.markDirty();
// if ( hasMETiles ) updateClient();
this.detectAndSendChanges();
this.detectAndSendChanges();
return null;
}
else
{
this.detectAndSendChanges();
}
}
}
}
}
clickSlot.putStack( tis != null ? tis.copy() : null );
}
this.detectAndSendChanges();
return null;
}
protected ItemStack transferStackToContainer(ItemStack input )
{
FluidStack fs = Util.getFluidFromItem( input );
if( fs != null )
{
final IAEFluidTank t = this.getFluidConfigInventory();
final IAEFluidStack stack = AEFluidStack.create( fs );
for( int i = 0; i < t.getSlots(); ++i )
{
if( t.getFluidInSlot( i ) == null && this.isValidForConfig( i, stack ) )
{
t.setFluidInSlot( i, stack );
break;
}
}
}
return input;
}
protected boolean isValidForConfig( int slot, IAEFluidStack fs )
{
if( this.supportCapacity() )
{
// assumes 4 slots per upgrade
final int upgrades = Ae2Reflect.getUpgrade(this).getInstalledUpgrades( Upgrades.CAPACITY );
if( slot > 0 && upgrades < 1 )
{
return false;
}
if( slot > 4 && upgrades < 2 )
{
return false;
}
}
return true;
}
@Override
@SuppressWarnings("unchecked")
protected void standardDetectAndSendChanges()
{
if( Platform.isServer() )
{
this.getSynchHelper().sendDiff( this.crafters );
// clear out config items that are no longer valid (eg capacity upgrade removed)
final IAEFluidTank t = this.getFluidConfigInventory();
for( int i = 0; i < t.getSlots(); ++i )
{
if( t.getFluidInSlot( i ) != null && !this.isValidForConfig( i, t.getFluidInSlot( i ) ) )
{
t.setFluidInSlot( i, null );
}
}
}
super.standardDetectAndSendChanges();
}
@Override
public void addCraftingToCrafters( ICrafting listener )
{
super.addCraftingToCrafters( listener );
this.getSynchHelper().sendFull( Collections.singleton( listener ) );
}
@Override
public void receiveFluidSlots( Map<Integer, IAEFluidStack> fluids )
{
this.getSynchHelper().readPacket( fluids );
}
}
@@ -0,0 +1,436 @@
package com.glodblock.github.client.gui.container;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.config.SecurityPermissions;
import appeng.api.networking.IGrid;
import appeng.api.networking.crafting.ICraftingCPU;
import appeng.api.networking.crafting.ICraftingGrid;
import appeng.api.networking.crafting.ICraftingJob;
import appeng.api.networking.crafting.ICraftingLink;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.networking.security.IActionHost;
import appeng.api.networking.security.PlayerSource;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.ITerminalHost;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.container.AEBaseContainer;
import appeng.container.guisync.GuiSync;
import appeng.container.implementations.CraftingCPURecord;
import appeng.core.AELog;
import appeng.util.Platform;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.common.parts.PartFluidPatternTerminal;
import com.glodblock.github.inventory.InventoryHandler;
import com.glodblock.github.inventory.gui.GuiType;
import com.glodblock.github.network.SPacketMEInventoryUpdate;
import com.glodblock.github.util.Ae2Reflect;
import com.google.common.collect.ImmutableSet;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.ICrafting;
import net.minecraft.util.ChatComponentText;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.concurrent.Future;
public class ContainerFluidCraftConfirm extends AEBaseContainer {
private final ArrayList<CraftingCPURecord> cpus = new ArrayList<CraftingCPURecord>();
private Future<ICraftingJob> job;
private ICraftingJob result;
@GuiSync( 0 )
public long bytesUsed;
@GuiSync( 1 )
public long cpuBytesAvail;
@GuiSync( 2 )
public int cpuCoProcessors;
@GuiSync( 3 )
public boolean autoStart = false;
@GuiSync( 4 )
public boolean simulation = true;
@GuiSync( 5 )
public int selectedCpu = -1;
@GuiSync( 6 )
public boolean noCPU = true;
@GuiSync( 7 )
public String myName = "";
public ContainerFluidCraftConfirm(final InventoryPlayer ip, final ITerminalHost te )
{
super( ip, te );
}
public void cycleCpu( final boolean next )
{
if( next )
{
this.setSelectedCpu( this.getSelectedCpu() + 1 );
}
else
{
this.setSelectedCpu( this.getSelectedCpu() - 1 );
}
if( this.getSelectedCpu() < -1 )
{
this.setSelectedCpu( this.cpus.size() - 1 );
}
else if( this.getSelectedCpu() >= this.cpus.size() )
{
this.setSelectedCpu( -1 );
}
if( this.getSelectedCpu() == -1 )
{
this.setCpuAvailableBytes( 0 );
this.setCpuCoProcessors( 0 );
this.setName( "" );
}
else
{
this.setName(Ae2Reflect.getName(this.cpus.get(this.getSelectedCpu())));
this.setCpuAvailableBytes(Ae2Reflect.getSize(this.cpus.get(this.getSelectedCpu())));
this.setCpuCoProcessors(Ae2Reflect.getProcessors(this.cpus.get(this.getSelectedCpu())));
}
}
@Override
public void detectAndSendChanges()
{
if( Platform.isClient() )
{
return;
}
if (getGrid() == null)
return;
final ICraftingGrid cc = this.getGrid().getCache( ICraftingGrid.class );
final ImmutableSet<ICraftingCPU> cpuSet = cc.getCpus();
int matches = 0;
boolean changed = false;
for( final ICraftingCPU c : cpuSet )
{
boolean found = false;
for( final CraftingCPURecord ccr : this.cpus )
{
if( Ae2Reflect.getCPU(ccr) == c )
{
found = true;
}
}
final boolean matched = this.cpuMatches( c );
if( matched )
{
matches++;
}
if( found == !matched )
{
changed = true;
}
}
if( changed || this.cpus.size() != matches )
{
this.cpus.clear();
for( final ICraftingCPU c : cpuSet )
{
if( this.cpuMatches( c ) )
{
this.cpus.add( new CraftingCPURecord( c.getAvailableStorage(), c.getCoProcessors(), c ) );
}
}
this.sendCPUs();
}
this.setNoCPU( this.cpus.isEmpty() );
super.detectAndSendChanges();
if( this.getJob() != null && this.getJob().isDone() )
{
try
{
this.result = this.getJob().get();
if( !this.result.isSimulation() )
{
this.setSimulation( false );
if( this.isAutoStart() )
{
this.startJob();
return;
}
}
else
{
this.setSimulation( true );
}
final SPacketMEInventoryUpdate a = new SPacketMEInventoryUpdate( (byte) 0 );
final SPacketMEInventoryUpdate b = new SPacketMEInventoryUpdate( (byte) 1 );
final SPacketMEInventoryUpdate c = this.result.isSimulation() ? new SPacketMEInventoryUpdate( (byte) 2 ) : null;
final IItemList<IAEItemStack> plan = AEApi.instance().storage().createItemList();
this.result.populatePlan( plan );
this.setUsedBytes( this.result.getByteTotal() );
for( final IAEItemStack out : plan )
{
IAEItemStack o = out.copy();
o.reset();
o.setStackSize( out.getStackSize() );
final IAEItemStack p = out.copy();
p.reset();
p.setStackSize( out.getCountRequestable() );
final IStorageGrid sg = this.getGrid().getCache( IStorageGrid.class );
final IMEInventory<IAEItemStack> items = sg.getItemInventory();
IAEItemStack m = null;
if( c != null && this.result.isSimulation() )
{
m = o.copy();
o = items.extractItems( o, Actionable.SIMULATE, this.getActionSource() );
if( o == null )
{
o = m.copy();
o.setStackSize( 0 );
}
m.setStackSize( m.getStackSize() - o.getStackSize() );
}
if( o.getStackSize() > 0 )
{
a.appendItem( o );
}
if( p.getStackSize() > 0 )
{
b.appendItem( p );
}
if( c != null && m != null && m.getStackSize() > 0 )
{
c.appendItem( m );
}
}
for( final Object g : this.crafters )
{
if( g instanceof EntityPlayer)
{
FluidCraft.proxy.netHandler.sendTo( a, (EntityPlayerMP) g );
FluidCraft.proxy.netHandler.sendTo( b, (EntityPlayerMP) g );
if( c != null )
{
FluidCraft.proxy.netHandler.sendTo( c, (EntityPlayerMP) g );
}
}
}
}
catch( final Throwable e )
{
this.getPlayerInv().player.addChatMessage( new ChatComponentText( "Error: " + e.toString() ) );
AELog.debug( e );
this.setValidContainer( false );
this.result = null;
}
this.setJob( null );
}
this.verifyPermissions( SecurityPermissions.CRAFT, false );
}
private IGrid getGrid()
{
final IActionHost h = ( (IActionHost) this.getTarget() );
if (h == null || h.getActionableNode() == null)
return null;
return h.getActionableNode().getGrid();
}
private boolean cpuMatches( final ICraftingCPU c )
{
return c.getAvailableStorage() >= this.getUsedBytes() && !c.isBusy();
}
private void sendCPUs()
{
Collections.sort( this.cpus );
if( this.getSelectedCpu() >= this.cpus.size() )
{
this.setSelectedCpu( -1 );
this.setCpuAvailableBytes( 0 );
this.setCpuCoProcessors( 0 );
this.setName( "" );
}
else if( this.getSelectedCpu() != -1 )
{
this.setName(Ae2Reflect.getName(this.cpus.get(this.getSelectedCpu())));
this.setCpuAvailableBytes(Ae2Reflect.getSize(this.cpus.get(this.getSelectedCpu())));
this.setCpuCoProcessors(Ae2Reflect.getProcessors(this.cpus.get(this.getSelectedCpu())));
}
}
public void startJob()
{
GuiType originalGui = null;
final IActionHost ah = this.getActionHost();
if( ah instanceof PartFluidPatternTerminal)
{
originalGui = GuiType.FLUID_PATTERN_TERMINAL;
}
if( this.result != null && !this.isSimulation() && getGrid() != null)
{
final ICraftingGrid cc = this.getGrid().getCache( ICraftingGrid.class );
final ICraftingLink g = cc.submitJob( this.result, null, this.getSelectedCpu() == -1 ? null : Ae2Reflect.getCPU(this.cpus.get(this.getSelectedCpu())), true, this.getActionSrc() );
this.setAutoStart( false );
if( g != null && originalGui != null && this.getOpenContext() != null )
{
InventoryHandler.switchGui(originalGui);
}
}
}
private BaseActionSource getActionSrc()
{
return new PlayerSource( this.getPlayerInv().player, (IActionHost) this.getTarget() );
}
@Override
public void removeCraftingFromCrafters( final ICrafting c )
{
super.removeCraftingFromCrafters( c );
if( this.getJob() != null )
{
this.getJob().cancel( true );
this.setJob( null );
}
}
@Override
public void onContainerClosed( final EntityPlayer par1EntityPlayer )
{
super.onContainerClosed( par1EntityPlayer );
if( this.getJob() != null )
{
this.getJob().cancel( true );
this.setJob( null );
}
}
public World getWorld()
{
return this.getPlayerInv().player.worldObj;
}
public boolean isAutoStart()
{
return this.autoStart;
}
public void setAutoStart( final boolean autoStart )
{
this.autoStart = autoStart;
}
public long getUsedBytes()
{
return this.bytesUsed;
}
private void setUsedBytes( final long bytesUsed )
{
this.bytesUsed = bytesUsed;
}
public long getCpuAvailableBytes()
{
return this.cpuBytesAvail;
}
private void setCpuAvailableBytes( final long cpuBytesAvail )
{
this.cpuBytesAvail = cpuBytesAvail;
}
public int getCpuCoProcessors()
{
return this.cpuCoProcessors;
}
private void setCpuCoProcessors( final int cpuCoProcessors )
{
this.cpuCoProcessors = cpuCoProcessors;
}
public int getSelectedCpu()
{
return this.selectedCpu;
}
private void setSelectedCpu( final int selectedCpu )
{
this.selectedCpu = selectedCpu;
}
public String getName()
{
return this.myName;
}
private void setName( @Nonnull final String myName )
{
this.myName = myName;
}
public boolean hasNoCPU()
{
return this.noCPU;
}
private void setNoCPU( final boolean noCPU )
{
this.noCPU = noCPU;
}
public boolean isSimulation()
{
return this.simulation;
}
private void setSimulation( final boolean simulation )
{
this.simulation = simulation;
}
private Future<ICraftingJob> getJob()
{
return this.job;
}
public void setJob( final Future<ICraftingJob> job )
{
this.job = job;
}
}
@@ -0,0 +1,16 @@
package com.glodblock.github.client.gui.container;
import appeng.container.AEBaseContainer;
import appeng.container.slot.SlotNormal;
import com.glodblock.github.common.tile.TileFluidPacketDecoder;
import net.minecraft.entity.player.InventoryPlayer;
public class ContainerFluidPacketDecoder extends AEBaseContainer {
public ContainerFluidPacketDecoder(InventoryPlayer ipl, TileFluidPacketDecoder tile) {
super(ipl, tile);
addSlotToContainer(new SlotNormal(tile.getInventory(), 0, 80, 35));
bindPlayerInventory(ipl, 0, 84);
}
}
@@ -0,0 +1,226 @@
package com.glodblock.github.client.gui.container;
import appeng.api.AEApi;
import appeng.api.storage.data.IAEItemStack;
import appeng.container.AEBaseContainer;
import appeng.container.slot.SlotFake;
import appeng.container.slot.SlotRestrictedInput;
import appeng.helpers.InventoryAction;
import appeng.util.item.AEItemStack;
import com.glodblock.github.common.item.ItemFluidDrop;
import com.glodblock.github.common.item.ItemFluidEncodedPattern;
import com.glodblock.github.common.item.ItemFluidPacket;
import com.glodblock.github.common.tile.TileFluidPatternEncoder;
import com.glodblock.github.inventory.AeItemStackHandler;
import com.glodblock.github.inventory.AeStackInventory;
import com.glodblock.github.inventory.PatternConsumer;
import com.glodblock.github.inventory.slot.SlotFluid;
import com.glodblock.github.loader.ItemAndBlockHolder;
import com.glodblock.github.util.FluidPatternDetails;
import com.glodblock.github.util.Util;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidContainerItem;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class ContainerFluidPatternEncoder extends AEBaseContainer implements PatternConsumer {
private final TileFluidPatternEncoder tile;
public ContainerFluidPatternEncoder(InventoryPlayer ipl, TileFluidPatternEncoder tile) {
super(ipl, tile);
this.tile = tile;
AeItemStackHandler crafting = new AeItemStackHandler(tile.getCraftingSlots());
AeItemStackHandler output = new AeItemStackHandler(tile.getOutputSlots());
for (int y = 0; y < 3; y++) {
for (int x = 0; x < 3; x++) {
addSlotToContainer(new SlotFluidConvertingFake(crafting, y * 3 + x, 23 + x * 18, 17 + y * 18));
}
addSlotToContainer(new SlotFluidConvertingFake(output, y, 113, 17 + y * 18));
}
addSlotToContainer(new SlotRestrictedInput(
SlotRestrictedInput.PlacableItemType.BLANK_PATTERN, tile.getInventory(), 0, 138, 20, ipl));
addSlotToContainer(new SlotRestrictedInput(
SlotRestrictedInput.PlacableItemType.ENCODED_PATTERN, tile.getInventory(), 1, 138, 50, ipl));
bindPlayerInventory(ipl, 0, 84);
}
public TileFluidPatternEncoder getTile() {
return tile;
}
public boolean canEncodePattern() {
if (isNotPattern(tile.getInventory().getStackInSlot(0)) && isNotPattern(tile.getInventory().getStackInSlot(1))) {
return false;
}
find_input:
{
for (IAEItemStack stack : tile.getCraftingSlots()) {
if (stack != null && stack.getStackSize() > 0) {
break find_input;
}
}
return false;
}
for (IAEItemStack stack : tile.getOutputSlots()) {
if (stack != null && stack.getStackSize() > 0) {
return true;
}
}
return false;
}
private static boolean isNotPattern(ItemStack stack) {
return stack == null || !(AEApi.instance().definitions().materials().blankPattern().isSameAs(stack)
|| (stack.getItem() instanceof ItemFluidEncodedPattern));
}
public void encodePattern() {
if (canEncodePattern()) {
// if there is an encoded pattern, overwrite it; otherwise, consume a blank
if (tile.getInventory().getStackInSlot(1) == null) {
tile.getInventory().decrStackSize(0, 1); // this better work
}
ItemStack patternStack = new ItemStack(ItemAndBlockHolder.PATTERN);
FluidPatternDetails pattern = new FluidPatternDetails(patternStack);
pattern.setInputs(collectAeInventory(tile.getCraftingSlots()));
pattern.setOutputs(collectAeInventory(tile.getOutputSlots()));
tile.getInventory().setInventorySlotContents(1, pattern.writeToStack());
}
}
private static IAEItemStack[] collectAeInventory(AeStackInventory<IAEItemStack> inv) {
// see note at top of DensePatternDetails
List<IAEItemStack> acc = new ArrayList<>();
for (IAEItemStack stack : inv) {
if (stack != null) {
if (stack.getItem() instanceof ItemFluidPacket) {
IAEItemStack dropStack = ItemFluidDrop.newAeStack(ItemFluidPacket.getFluidStack(stack));
if (dropStack != null) {
acc.add(dropStack);
continue;
}
}
acc.add(stack);
}
}
return acc.toArray(new IAEItemStack[0]);
}
// adapted from ae2's AEBaseContainer#doAction
@Override
public void doAction(EntityPlayerMP player, InventoryAction action, int slotId, long id) {
Slot slot = getSlot(slotId);
if (slot instanceof SlotFluidConvertingFake) {
final ItemStack stack = player.inventory.getItemStack();
switch (action) {
case PICKUP_OR_SET_DOWN:
if (stack == null) {
slot.putStack(null);
} else {
((SlotFluidConvertingFake)slot).putConvertedStack(stack.copy());
}
break;
case PLACE_SINGLE:
if (stack != null) {
((SlotFluidConvertingFake)slot).putConvertedStack(Objects.requireNonNull(Util.copyStackWithSize(stack, 1)));
}
break;
case SPLIT_OR_PLACE_SINGLE:
ItemStack inSlot = slot.getStack();
if (inSlot != null) {
if (stack == null) {
slot.putStack(Util.copyStackWithSize(inSlot, Math.max(1, inSlot.stackSize - 1)));
} else if (stack.isItemEqual(inSlot)) {
slot.putStack(Util.copyStackWithSize(inSlot,
Math.min(inSlot.getMaxStackSize(), inSlot.stackSize + 1)));
} else {
((SlotFluidConvertingFake)slot).putConvertedStack(Objects.requireNonNull(Util.copyStackWithSize(stack, 1)));
}
} else if (stack != null) {
((SlotFluidConvertingFake)slot).putConvertedStack(Objects.requireNonNull(Util.copyStackWithSize(stack, 1)));
}
break;
}
} else {
super.doAction(player, action, slotId, id);
}
}
@Override
public void acceptPattern(IAEItemStack[] inputs, IAEItemStack[] outputs) {
copyStacks(inputs, tile.getCraftingSlots());
copyStacks(outputs, tile.getOutputSlots());
}
private static void copyStacks(IAEItemStack[] src, AeStackInventory<IAEItemStack> dest) {
int bound = Math.min(src.length, dest.getSlotCount());
for (int i = 0; i < bound; i++) {
dest.setStack(i, src[i]);
}
}
private static class SlotFluidConvertingFake extends SlotFake implements SlotFluid {
private final AeStackInventory<IAEItemStack> inv;
public SlotFluidConvertingFake(AeItemStackHandler inv, int idx, int x, int y) {
super(inv, idx, x, y);
this.inv = inv.getAeInventory();
}
@Override
public void putStack(ItemStack stack) {
inv.setStack(getSlotIndex(), AEItemStack.create(stack));
}
@Override
public void setAeStack(@Nullable IAEItemStack stack, boolean sync) {
inv.setStack(getSlotIndex(), stack);
}
public void putConvertedStack(ItemStack stack) {
if (stack == null) {
setAeStack(null, false);
return;
} else if (stack.getItem() instanceof IFluidContainerItem) {
FluidStack fluid = ((IFluidContainerItem) stack.getItem()).getFluid(stack);
if (fluid != null) {
fluid.amount *= stack.stackSize;
IAEItemStack aeStack = ItemFluidPacket.newAeStack(fluid);
if (aeStack != null) {
setAeStack(aeStack, false);
return;
}
}
} else if (FluidContainerRegistry.isContainer(stack)) {
FluidStack fluid = FluidContainerRegistry.getFluidForFilledItem(stack);
if (fluid != null) {
fluid.amount *= stack.stackSize;
IAEItemStack aeStack = ItemFluidPacket.newAeStack(fluid);
if (aeStack != null) {
setAeStack(aeStack, false);
return;
}
}
}
putStack(stack);
}
@Nullable
@Override
public IAEItemStack getAeStack() {
return inv.getStack(getSlotIndex());
}
}
}
@@ -0,0 +1,185 @@
package com.glodblock.github.client.gui.container;
import appeng.api.AEApi;
import appeng.api.definitions.IDefinitions;
import appeng.api.storage.ITerminalHost;
import appeng.api.storage.data.IAEItemStack;
import appeng.container.slot.SlotFakeCraftingMatrix;
import appeng.container.slot.SlotPatternOutputs;
import appeng.helpers.InventoryAction;
import appeng.util.item.AEItemStack;
import com.glodblock.github.common.item.ItemFluidDrop;
import com.glodblock.github.common.item.ItemFluidEncodedPattern;
import com.glodblock.github.common.item.ItemFluidPacket;
import com.glodblock.github.inventory.PatternConsumer;
import com.glodblock.github.loader.ItemAndBlockHolder;
import com.glodblock.github.util.FluidPatternDetails;
import com.glodblock.github.util.Util;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.IFluidContainerItem;
import java.util.ArrayList;
import java.util.List;
public class ContainerFluidPatternTerminal extends FCBasePartContainer implements PatternConsumer {
public ContainerFluidPatternTerminal(InventoryPlayer ip, ITerminalHost monitorable) {
super(ip, monitorable);
}
@Override
public void encode() {
if (!checkHasFluidPattern()) {
super.encode();
return;
}
ItemStack stack = this.patternSlotOUT.getStack();
if (stack == null) {
stack = this.patternSlotIN.getStack();
if (!isPattern(stack)) {
return;
}
if (stack.stackSize == 1) {
this.patternSlotIN.putStack(null);
} else {
stack.stackSize --;
}
encodeFluidPattern();
} else if (isPattern(stack)) {
encodeFluidPattern();
}
}
private static boolean isPattern(final ItemStack output) {
if (output == null) {
return false;
}
if (output.getItem() instanceof ItemFluidEncodedPattern) {
return true;
}
final IDefinitions defs = AEApi.instance().definitions();
return defs.items().encodedPattern().isSameAs(output) || defs.materials().blankPattern().isSameAs(output);
}
private boolean checkHasFluidPattern() {
if (this.craftingMode) {
return false;
}
boolean hasFluid = false, search = false;
for (Slot craftingSlot : this.craftingSlots) {
final ItemStack crafting = craftingSlot.getStack();
if (crafting == null) {
continue;
}
search = true;
if (crafting.getItem() instanceof ItemFluidPacket) {
hasFluid = true;
break;
}
}
if (!search) { // search=false -> inputs were empty
return false;
}
// `search` should be true at this point
for (Slot outputSlot : this.outputSlots) {
final ItemStack out = outputSlot.getStack();
if (out == null) {
continue;
}
search = false;
if (hasFluid) {
break;
} else if (out.getItem() instanceof ItemFluidPacket) {
hasFluid = true;
break;
}
}
return hasFluid && !search; // search=true -> outputs were empty
}
private void encodeFluidPattern() {
ItemStack patternStack = new ItemStack(ItemAndBlockHolder.PATTERN);
FluidPatternDetails pattern = new FluidPatternDetails(patternStack);
pattern.setInputs(collectInventory(craftingSlots));
pattern.setOutputs(collectInventory(outputSlots));
patternSlotOUT.putStack(pattern.writeToStack());
}
private static IAEItemStack[] collectInventory(Slot[] slots) {
// see note at top of FluidPatternDetails
List<IAEItemStack> acc = new ArrayList<>();
for (Slot slot : slots) {
ItemStack stack = slot.getStack();
if (stack == null) {
continue;
}
if (stack.getItem() instanceof ItemFluidPacket) {
IAEItemStack dropStack = ItemFluidDrop.newAeStack(ItemFluidPacket.getFluidStack(stack));
if (dropStack != null) {
acc.add(dropStack);
continue;
}
}
IAEItemStack aeStack = AEItemStack.create(stack);
acc.add(aeStack);
}
return acc.toArray(new IAEItemStack[0]);
}
@Override
public void acceptPattern(IAEItemStack[] inputs, IAEItemStack[] outputs) {
if (getPatternTerminal() != null) {
getPatternTerminal().onChangeCrafting(inputs, outputs);
}
}
@Override
public void doAction(EntityPlayerMP player, InventoryAction action, int slotId, long id) {
if (this.isCraftingMode()) {
super.doAction(player, action, slotId, id);
return;
}
if (slotId < 0 || slotId >= this.inventorySlots.size()) {
super.doAction(player, action, slotId, id);
return;
}
Slot slot = getSlot(slotId);
ItemStack stack = player.inventory.getItemStack();
if ((slot instanceof SlotFakeCraftingMatrix || slot instanceof SlotPatternOutputs) && stack != null
&& (stack.getItem() instanceof IFluidContainerItem || FluidContainerRegistry.isContainer(stack))) {
FluidStack fluid = null;
switch (action) {
case PICKUP_OR_SET_DOWN:
fluid = Util.getFluidFromItem(stack);
slot.putStack(ItemFluidPacket.newStack(fluid));
break;
case SPLIT_OR_PLACE_SINGLE:
fluid = Util.getFluidFromItem(Util.copyStackWithSize(stack, 1));
FluidStack origin = ItemFluidPacket.getFluidStack(slot.getStack());
if (fluid != null && fluid.equals(origin)) {
fluid.amount += origin.amount;
if (fluid.amount <= 0) fluid = null;
}
slot.putStack(ItemFluidPacket.newStack(fluid));
break;
}
if (fluid == null) {
super.doAction(player, action, slotId, id);
return;
}
return;
}
if (action == InventoryAction.SPLIT_OR_PLACE_SINGLE) {
if (stack == null && slot.getStack() != null && slot.getStack().getItem() instanceof ItemFluidPacket) {
return;
}
}
super.doAction(player, action, slotId, id);
}
}
@@ -0,0 +1,408 @@
package com.glodblock.github.client.gui.container;
import appeng.api.AEApi;
import appeng.api.config.*;
import appeng.api.implementations.guiobjects.IPortableCell;
import appeng.api.implementations.tiles.IMEChest;
import appeng.api.implementations.tiles.IViewCellStorage;
import appeng.api.networking.IGrid;
import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.energy.IEnergySource;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.networking.storage.IBaseMonitor;
import appeng.api.parts.IPart;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.IMEMonitorHandlerReceiver;
import appeng.api.storage.ITerminalHost;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.api.util.IConfigManager;
import appeng.api.util.IConfigurableObject;
import appeng.container.AEBaseContainer;
import appeng.container.guisync.GuiSync;
import appeng.container.slot.SlotRestrictedInput;
import appeng.core.AELog;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketValueConfig;
import appeng.helpers.WirelessTerminalGuiObject;
import appeng.me.helpers.ChannelPowerSrc;
import appeng.util.ConfigManager;
import appeng.util.IConfigManagerHost;
import appeng.util.Platform;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.network.SPacketMEInventoryUpdate;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.ICrafting;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.nio.BufferOverflowException;
public class FCBaseMonitorContain extends AEBaseContainer implements IConfigManagerHost, IConfigurableObject, IMEMonitorHandlerReceiver<IAEItemStack>
{
private final SlotRestrictedInput[] cellView = new SlotRestrictedInput[5];
private final IMEMonitor<IAEItemStack> monitor;
private final IItemList<IAEItemStack> items = AEApi.instance().storage().createItemList();
private final IConfigManager clientCM;
private final ITerminalHost host;
@GuiSync( 99 )
public boolean canAccessViewCells = false;
@GuiSync( 98 )
public boolean hasPower = false;
private IConfigManagerHost gui;
private IConfigManager serverCM;
private IGridNode networkNode;
public FCBaseMonitorContain(final InventoryPlayer ip, final ITerminalHost monitorable )
{
this( ip, monitorable, true );
}
protected FCBaseMonitorContain( final InventoryPlayer ip, final ITerminalHost monitorable, final boolean bindInventory )
{
super( ip, monitorable instanceof TileEntity ? (TileEntity) monitorable : null, monitorable instanceof IPart ? (IPart) monitorable : null );
this.host = monitorable;
this.clientCM = new ConfigManager( this );
this.clientCM.registerSetting( Settings.SORT_BY, SortOrder.NAME );
this.clientCM.registerSetting( Settings.VIEW_MODE, ViewItems.ALL );
this.clientCM.registerSetting( Settings.SORT_DIRECTION, SortDir.ASCENDING );
if( Platform.isServer() )
{
this.serverCM = monitorable.getConfigManager();
this.monitor = monitorable.getItemInventory();
if( this.monitor != null )
{
this.monitor.addListener( this, null );
this.setCellInventory( this.monitor );
if( monitorable instanceof IPortableCell)
{
this.setPowerSource( (IEnergySource) monitorable );
}
else if( monitorable instanceof IMEChest)
{
this.setPowerSource( (IEnergySource) monitorable );
}
else if( monitorable instanceof IGridHost)
{
final IGridNode node = ( (IGridHost) monitorable ).getGridNode( ForgeDirection.UNKNOWN );
if( node != null )
{
this.networkNode = node;
final IGrid g = node.getGrid();
if( g != null )
{
this.setPowerSource( new ChannelPowerSrc( this.networkNode, (IEnergySource) g.getCache( IEnergyGrid.class ) ) );
}
}
}
}
else
{
this.setValidContainer( false );
}
}
else
{
this.monitor = null;
}
this.canAccessViewCells = false;
if( monitorable instanceof IViewCellStorage)
{
for( int y = 0; y < 5; y++ )
{
this.cellView[y] = new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.VIEW_CELL, ( (IViewCellStorage) monitorable ).getViewCellStorage(), y, 206, y * 18 + 8, this.getInventoryPlayer() );
this.cellView[y].setAllowEdit( this.canAccessViewCells );
this.addSlotToContainer( this.cellView[y] );
}
}
if( bindInventory )
{
this.bindPlayerInventory( ip, 0, 0 );
}
}
public IGridNode getNetworkNode()
{
return this.networkNode;
}
@Override
public void detectAndSendChanges()
{
if( Platform.isServer() )
{
if( this.monitor != this.host.getItemInventory() )
{
this.setValidContainer( false );
}
for( final Settings set : this.serverCM.getSettings() )
{
final Enum<?> sideLocal = this.serverCM.getSetting( set );
final Enum<?> sideRemote = this.clientCM.getSetting( set );
if( sideLocal != sideRemote )
{
this.clientCM.putSetting( set, sideLocal );
for( final Object crafter : this.crafters )
{
try
{
NetworkHandler.instance.sendTo( new PacketValueConfig( set.name(), sideLocal.name() ), (EntityPlayerMP) crafter );
}
catch( final IOException e )
{
AELog.debug( e );
}
}
}
}
if( !this.items.isEmpty() )
{
final IItemList<IAEItemStack> monitorCache = this.monitor.getStorageList();
final SPacketMEInventoryUpdate piu = new SPacketMEInventoryUpdate();
for( final IAEItemStack is : this.items )
{
final IAEItemStack send = monitorCache.findPrecise( is );
if( send == null )
{
is.setStackSize( 0 );
piu.appendItem( is );
}
else
{
piu.appendItem( send );
}
}
if( !piu.isEmpty() )
{
this.items.resetStatus();
for( final Object c : this.crafters )
{
if( c instanceof EntityPlayer)
{
FluidCraft.proxy.netHandler.sendTo(piu, (EntityPlayerMP) c);
}
}
}
}
this.updatePowerStatus();
final boolean oldAccessible = this.canAccessViewCells;
this.canAccessViewCells =
this.host instanceof WirelessTerminalGuiObject
|| this.hasAccess( SecurityPermissions.BUILD, false );
if( this.canAccessViewCells != oldAccessible )
{
for( int y = 0; y < 5; y++ )
{
if( this.cellView[y] != null )
{
this.cellView[y].setAllowEdit( this.canAccessViewCells );
}
}
}
super.detectAndSendChanges();
}
}
protected void updatePowerStatus()
{
try
{
if( this.networkNode != null )
{
this.setPowered( this.networkNode.isActive() );
}
else if( this.getPowerSource() instanceof IEnergyGrid )
{
this.setPowered( ( (IEnergyGrid) this.getPowerSource() ).isNetworkPowered() );
}
else
{
this.setPowered( this.getPowerSource().extractAEPower( 1, Actionable.SIMULATE, PowerMultiplier.CONFIG ) > 0.8 );
}
}
catch( final Throwable t )
{
// :P
}
}
@Override
public void onUpdate( final String field, final Object oldValue, final Object newValue )
{
if( field.equals( "canAccessViewCells" ) )
{
for( int y = 0; y < 5; y++ )
{
if( this.cellView[y] != null )
{
this.cellView[y].setAllowEdit( this.canAccessViewCells );
}
}
}
super.onUpdate( field, oldValue, newValue );
}
@Override
public void addCraftingToCrafters( final ICrafting c )
{
super.addCraftingToCrafters( c );
this.queueInventory( c );
}
private void queueInventory( final ICrafting c )
{
if( Platform.isServer() && c instanceof EntityPlayer && this.monitor != null )
{
SPacketMEInventoryUpdate piu = new SPacketMEInventoryUpdate();
final IItemList<IAEItemStack> monitorCache = this.monitor.getStorageList();
for( final IAEItemStack send : monitorCache )
{
try
{
piu.appendItem( send );
}
catch( final BufferOverflowException boe )
{
FluidCraft.proxy.netHandler.sendTo( piu, (EntityPlayerMP) c );
piu = new SPacketMEInventoryUpdate();
piu.appendItem( send );
}
}
FluidCraft.proxy.netHandler.sendTo( piu, (EntityPlayerMP) c );
}
}
@Override
public void removeCraftingFromCrafters( final ICrafting c )
{
super.removeCraftingFromCrafters( c );
if( this.crafters.isEmpty() && this.monitor != null )
{
this.monitor.removeListener( this );
}
}
@Override
public void onContainerClosed( final EntityPlayer player )
{
super.onContainerClosed( player );
if( this.monitor != null )
{
this.monitor.removeListener( this );
}
}
@Override
public boolean isValid( final Object verificationToken )
{
return true;
}
@Override
public void postChange(final IBaseMonitor<IAEItemStack> monitor, final Iterable<IAEItemStack> change, final BaseActionSource source )
{
for( final IAEItemStack is : change )
{
this.items.add( is );
}
}
@Override
public void onListUpdate()
{
for( final Object c : this.crafters )
{
if( c instanceof ICrafting )
{
final ICrafting cr = (ICrafting) c;
this.queueInventory( cr );
}
}
}
@Override
public void updateSetting( final IConfigManager manager, final Enum settingName, final Enum newValue )
{
if( this.getGui() != null )
{
this.getGui().updateSetting( manager, settingName, newValue );
}
}
@Override
public IConfigManager getConfigManager()
{
if( Platform.isServer() )
{
return this.serverCM;
}
return this.clientCM;
}
public ItemStack[] getViewCells()
{
final ItemStack[] list = new ItemStack[this.cellView.length];
for( int x = 0; x < this.cellView.length; x++ )
{
list[x] = this.cellView[x].getStack();
}
return list;
}
public SlotRestrictedInput getCellViewSlot( final int index )
{
return this.cellView[index];
}
public boolean isPowered()
{
return this.hasPower;
}
private void setPowered( final boolean isPowered )
{
this.hasPower = isPowered;
}
private IConfigManagerHost getGui()
{
return this.gui;
}
public void setGui( @Nonnull final IConfigManagerHost gui )
{
this.gui = gui;
}
}
@@ -0,0 +1,625 @@
package com.glodblock.github.client.gui.container;
import appeng.api.AEApi;
import appeng.api.config.Actionable;
import appeng.api.definitions.IDefinitions;
import appeng.api.networking.security.MachineSource;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.ITerminalHost;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IItemList;
import appeng.container.ContainerNull;
import appeng.container.guisync.GuiSync;
import appeng.container.slot.*;
import appeng.core.sync.packets.PacketPatternSlot;
import appeng.helpers.IContainerCraftingPacket;
import appeng.items.storage.ItemViewCell;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.IAEAppEngInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.InventoryAdaptor;
import appeng.util.Platform;
import appeng.util.inv.AdaptorPlayerHand;
import appeng.util.item.AEItemStack;
import com.glodblock.github.common.item.ItemFluidPacket;
import com.glodblock.github.common.parts.PartFluidPatternTerminal;
import com.glodblock.github.util.Util;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.*;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.CraftingManager;
import net.minecraft.item.crafting.IRecipe;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.FluidStack;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;
public class FCBasePartContainer extends FCBaseMonitorContain implements IAEAppEngInventory, IOptionalSlotHost, IContainerCraftingPacket {
private final PartFluidPatternTerminal patternTerminal;
private final AppEngInternalInventory cOut = new AppEngInternalInventory( null, 1 );
private final IInventory crafting;
protected final SlotFakeCraftingMatrix[] craftingSlots = new SlotFakeCraftingMatrix[9];
protected final OptionalSlotFake[] outputSlots = new OptionalSlotFake[3];
protected final SlotPatternTerm craftSlot;
protected final SlotRestrictedInput patternSlotIN;
protected final SlotRestrictedInput patternSlotOUT;
@GuiSync( 97 )
public boolean craftingMode = true;
@GuiSync( 96 )
public boolean substitute = false;
public FCBasePartContainer(final InventoryPlayer ip, final ITerminalHost monitorable )
{
super( ip, monitorable, false );
this.patternTerminal = (PartFluidPatternTerminal) monitorable;
final IInventory patternInv = this.getPatternTerminal().getInventoryByName( "pattern" );
final IInventory output = this.getPatternTerminal().getInventoryByName( "output" );
this.crafting = this.getPatternTerminal().getInventoryByName( "crafting" );
for( int y = 0; y < 3; y++ )
{
for( int x = 0; x < 3; x++ )
{
this.addSlotToContainer( this.craftingSlots[x + y * 3] = new SlotFakeCraftingMatrix( this.crafting, x + y * 3, 18 + x * 18, -76 + y * 18 ) );
}
}
this.addSlotToContainer( this.craftSlot = new SlotPatternTerm( ip.player, this.getActionSource(), this.getPowerSource(), monitorable, this.crafting, patternInv, this.cOut, 110, -76 + 18, this, 2, this ) );
this.craftSlot.setIIcon( -1 );
for( int y = 0; y < 3; y++ )
{
this.addSlotToContainer( this.outputSlots[y] = new SlotPatternOutputs( output, this, y, 110, -76 + y * 18, 0, 0, 1 ) );
this.outputSlots[y].setRenderDisabled( false );
}
this.addSlotToContainer( this.patternSlotIN = new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.BLANK_PATTERN, patternInv, 0, 147, -72 - 9, this.getInventoryPlayer() ) );
this.addSlotToContainer( this.patternSlotOUT = new SlotRestrictedInput( SlotRestrictedInput.PlacableItemType.ENCODED_PATTERN, patternInv, 1, 147, -72 + 34, this.getInventoryPlayer() ) );
this.patternSlotOUT.setStackLimit( 1 );
this.bindPlayerInventory( ip, 0, 0 );
this.updateOrderOfOutputSlots();
}
private void updateOrderOfOutputSlots()
{
if( !this.isCraftingMode() )
{
this.craftSlot.xDisplayPosition = -9000;
for( int y = 0; y < 3; y++ )
{
this.outputSlots[y].xDisplayPosition = this.outputSlots[y].getX();
}
}
else
{
this.craftSlot.xDisplayPosition = this.craftSlot.getX();
for( int y = 0; y < 3; y++ )
{
this.outputSlots[y].xDisplayPosition = -9000;
}
}
}
@Override
public void putStackInSlot( final int par1, final ItemStack par2ItemStack )
{
super.putStackInSlot( par1, par2ItemStack );
this.getAndUpdateOutput();
}
@Override
public void putStacksInSlots( final ItemStack[] par1ArrayOfItemStack )
{
super.putStacksInSlots( par1ArrayOfItemStack );
this.getAndUpdateOutput();
}
private ItemStack getAndUpdateOutput()
{
final InventoryCrafting ic = new InventoryCrafting( this, 3, 3 );
for( int x = 0; x < ic.getSizeInventory(); x++ )
{
ic.setInventorySlotContents( x, this.crafting.getStackInSlot( x ) );
}
final ItemStack is = CraftingManager.getInstance().findMatchingRecipe( ic, this.getPlayerInv().player.worldObj );
this.cOut.setInventorySlotContents( 0, is );
return is;
}
@Override
public void saveChanges()
{
}
@Override
public void onChangeInventory(final IInventory inv, final int slot, final InvOperation mc, final ItemStack removedStack, final ItemStack newStack )
{
}
public void encodeAndMoveToInventory()
{
encode();
ItemStack output = this.patternSlotOUT.getStack();
if ( output != null )
{
if (!getPlayerInv().addItemStackToInventory( output )){
getPlayerInv().player.entityDropItem(output, 0);
}
this.patternSlotOUT.putStack( null );
}
}
public void encode()
{
ItemStack output = this.patternSlotOUT.getStack();
final ItemStack[] in = this.getInputs();
final ItemStack[] out = this.getOutputs();
// if there is no input, this would be silly.
if( in == null || out == null )
{
return;
}
// first check the output slots, should either be null, or a pattern
if( output != null && !this.isPattern( output ) )
{
return;
}// if nothing is there we should snag a new pattern.
else if( output == null )
{
output = this.patternSlotIN.getStack();
if (!this.isPattern( output ))
{
return; // no blanks.
}
// remove one, and clear the input slot.
output.stackSize--;
if( output.stackSize == 0 )
{
this.patternSlotIN.putStack( null );
}
// add a new encoded pattern.
for( final ItemStack encodedPatternStack : AEApi.instance().definitions().items().encodedPattern().maybeStack( 1 ).asSet() )
{
output = encodedPatternStack;
this.patternSlotOUT.putStack( output );
}
}
// encode the slot.
final NBTTagCompound encodedValue = new NBTTagCompound();
final NBTTagList tagIn = new NBTTagList();
final NBTTagList tagOut = new NBTTagList();
for( final ItemStack i : in )
{
tagIn.appendTag( this.createItemTag( i ) );
}
for( final ItemStack i : out )
{
tagOut.appendTag( this.createItemTag( i ) );
}
encodedValue.setTag( "in", tagIn );
encodedValue.setTag( "out", tagOut );
encodedValue.setBoolean( "crafting", this.isCraftingMode() );
encodedValue.setBoolean( "substitute", this.isSubstitute() );
output.setTagCompound( encodedValue );
}
private ItemStack[] getInputs()
{
final ItemStack[] input = new ItemStack[9];
boolean hasValue = false;
for( int x = 0; x < this.craftingSlots.length; x++ )
{
input[x] = this.craftingSlots[x].getStack();
if( input[x] != null )
{
hasValue = true;
}
}
if( hasValue )
{
return input;
}
return null;
}
private ItemStack[] getOutputs()
{
if( this.isCraftingMode() )
{
final ItemStack out = this.getAndUpdateOutput();
if( out != null && out.stackSize > 0 )
{
return new ItemStack[] { out };
}
}
else
{
final List<ItemStack> list = new ArrayList<>( 3 );
boolean hasValue = false;
for( final OptionalSlotFake outputSlot : this.outputSlots )
{
final ItemStack out = outputSlot.getStack();
if( out != null && out.stackSize > 0 )
{
list.add( out );
hasValue = true;
}
}
if( hasValue )
{
return list.toArray( new ItemStack[list.size()] );
}
}
return null;
}
private boolean isPattern( final ItemStack output )
{
if( output == null )
{
return false;
}
final IDefinitions definitions = AEApi.instance().definitions();
boolean isPattern = definitions.items().encodedPattern().isSameAs( output );
isPattern |= definitions.materials().blankPattern().isSameAs( output );
return isPattern;
}
private NBTBase createItemTag(final ItemStack i )
{
final NBTTagCompound c = new NBTTagCompound();
if( i != null )
{
i.writeToNBT( c );
}
return c;
}
@Override
public boolean isSlotEnabled( final int idx )
{
if( idx == 1 )
{
return Platform.isServer() ? !this.getPatternTerminal().isCraftingRecipe() : !this.isCraftingMode();
}
else if( idx == 2 )
{
return Platform.isServer() ? this.getPatternTerminal().isCraftingRecipe() : this.isCraftingMode();
}
else
{
return false;
}
}
public void craftOrGetItem( final PacketPatternSlot packetPatternSlot )
{
if( packetPatternSlot.slotItem != null && this.getCellInventory() != null )
{
final IAEItemStack out = packetPatternSlot.slotItem.copy();
InventoryAdaptor inv = new AdaptorPlayerHand( this.getPlayerInv().player );
final InventoryAdaptor playerInv = InventoryAdaptor.getAdaptor( this.getPlayerInv().player, ForgeDirection.UNKNOWN );
if( packetPatternSlot.shift )
{
inv = playerInv;
}
if( inv.simulateAdd( out.getItemStack() ) != null )
{
return;
}
final IAEItemStack extracted = Platform.poweredExtraction( this.getPowerSource(), this.getCellInventory(), out, this.getActionSource() );
final EntityPlayer p = this.getPlayerInv().player;
if( extracted != null )
{
inv.addItems( extracted.getItemStack() );
if( p instanceof EntityPlayerMP)
{
this.updateHeld( (EntityPlayerMP) p );
}
this.detectAndSendChanges();
return;
}
final InventoryCrafting ic = new InventoryCrafting( new ContainerNull(), 3, 3 );
final InventoryCrafting real = new InventoryCrafting( new ContainerNull(), 3, 3 );
for( int x = 0; x < 9; x++ )
{
ic.setInventorySlotContents( x, packetPatternSlot.pattern[x] == null ? null : packetPatternSlot.pattern[x].getItemStack() );
}
final IRecipe r = Platform.findMatchingRecipe( ic, p.worldObj );
if( r == null )
{
return;
}
final IMEMonitor<IAEItemStack> storage = this.getPatternTerminal().getItemInventory();
final IItemList<IAEItemStack> all = storage.getStorageList();
final ItemStack is = r.getCraftingResult( ic );
for( int x = 0; x < ic.getSizeInventory(); x++ )
{
if( ic.getStackInSlot( x ) != null )
{
final ItemStack pulled = Platform.extractItemsByRecipe( this.getPowerSource(), this.getActionSource(), storage, p.worldObj, r, is, ic, ic.getStackInSlot( x ), x, all, Actionable.MODULATE, ItemViewCell.createFilter( this.getViewCells() ) );
real.setInventorySlotContents( x, pulled );
}
}
final IRecipe rr = Platform.findMatchingRecipe( real, p.worldObj );
if( rr == r && Platform.isSameItemPrecise( rr.getCraftingResult( real ), is ) )
{
final SlotCrafting sc = new SlotCrafting( p, real, this.cOut, 0, 0, 0 );
sc.onPickupFromSlot( p, is );
for( int x = 0; x < real.getSizeInventory(); x++ )
{
final ItemStack failed = playerInv.addItems( real.getStackInSlot( x ) );
if( failed != null )
{
p.dropPlayerItemWithRandomChoice( failed, false );
}
}
inv.addItems( is );
if( p instanceof EntityPlayerMP )
{
this.updateHeld( (EntityPlayerMP) p );
}
this.detectAndSendChanges();
}
else
{
for( int x = 0; x < real.getSizeInventory(); x++ )
{
final ItemStack failed = real.getStackInSlot( x );
if( failed != null )
{
this.getCellInventory().injectItems( AEItemStack.create( failed ), Actionable.MODULATE, new MachineSource( this.getPatternTerminal() ) );
}
}
}
}
}
@Override
public void detectAndSendChanges()
{
super.detectAndSendChanges();
if( Platform.isServer() )
{
if( this.isCraftingMode() != this.getPatternTerminal().isCraftingRecipe() )
{
this.setCraftingMode( this.getPatternTerminal().isCraftingRecipe() );
this.updateOrderOfOutputSlots();
}
this.substitute = this.patternTerminal.isSubstitution();
}
}
@Override
public void onUpdate( final String field, final Object oldValue, final Object newValue )
{
super.onUpdate( field, oldValue, newValue );
if( field.equals( "craftingMode" ) )
{
this.getAndUpdateOutput();
this.updateOrderOfOutputSlots();
}
}
@Override
public void onSlotChange( final Slot s )
{
if( s == this.patternSlotOUT && Platform.isServer() )
{
for( final Object crafter : this.crafters )
{
final ICrafting icrafting = (ICrafting) crafter;
for( final Object g : this.inventorySlots )
{
if( g instanceof OptionalSlotFake || g instanceof SlotFakeCraftingMatrix )
{
final Slot sri = (Slot) g;
icrafting.sendSlotContents( this, sri.slotNumber, sri.getStack() );
}
}
( (EntityPlayerMP) icrafting ).isChangingQuantityOnly = false;
}
this.detectAndSendChanges();
}
}
public void clear()
{
for( final Slot s : this.craftingSlots )
{
s.putStack( null );
}
for( final Slot s : this.outputSlots )
{
s.putStack( null );
}
this.detectAndSendChanges();
this.getAndUpdateOutput();
}
@Override
public IInventory getInventoryByName( final String name )
{
if( name.equals( "player" ) )
{
return this.getInventoryPlayer();
}
return this.getPatternTerminal().getInventoryByName( name );
}
@Override
public boolean useRealItems()
{
return false;
}
public void toggleSubstitute()
{
this.substitute = !this.substitute;
this.detectAndSendChanges();
this.getAndUpdateOutput();
}
public boolean isCraftingMode()
{
return this.craftingMode;
}
private void setCraftingMode( final boolean craftingMode )
{
this.craftingMode = craftingMode;
}
public PartFluidPatternTerminal getPatternTerminal()
{
return this.patternTerminal;
}
private boolean isSubstitute()
{
return this.substitute;
}
public void setSubstitute( final boolean substitute )
{
this.substitute = substitute;
}
static boolean canDoubleStacks(SlotFake[] slots)
{
List<SlotFake> enabledSlots = Arrays.stream(slots).filter(SlotFake::isEnabled).collect(Collectors.toList());
long emptyStots = enabledSlots.stream().filter(s -> s.getStack() == null).count();
long fullSlots = enabledSlots.stream().filter(s-> s.getStack() != null && s.getStack().stackSize * 2 > 127).count();
return fullSlots <= emptyStots;
}
static void doubleStacksInternal(SlotFake[] slots)
{
List<ItemStack> overFlowStacks = new ArrayList<>();
List<SlotFake> enabledSlots = Arrays.stream(slots).filter(SlotFake::isEnabled).collect(Collectors.toList());
for (final Slot s : enabledSlots)
{
ItemStack st = s.getStack();
if (st == null)
continue;
if (Util.isFluidPacket(st)) {
FluidStack fluidStack = ItemFluidPacket.getFluidStack(st);
if (fluidStack != null) {
fluidStack = ItemFluidPacket.getFluidStack(st).copy();
if (fluidStack.amount < Integer.MAX_VALUE / 2)
fluidStack.amount *= 2;
}
s.putStack(ItemFluidPacket.newStack(fluidStack));
}
else if (st.stackSize * 2 > 127)
{
overFlowStacks.add(st.copy());
}
else
{
st.stackSize *= 2;
s.putStack(st);
}
}
Iterator<ItemStack> ow = overFlowStacks.iterator();
for (final Slot s : enabledSlots) {
if (!ow.hasNext())
break;
if (s.getStack() != null)
continue;
s.putStack(ow.next());
}
assert !ow.hasNext();
}
public void doubleStacks(boolean isShift)
{
if (!isCraftingMode() && canDoubleStacks(craftingSlots) && canDoubleStacks(outputSlots))
{
doubleStacksInternal(this.craftingSlots);
doubleStacksInternal(this.outputSlots);
if (isShift && !containsFluid(outputSlots) && !containsFluid(craftingSlots))
{
while (canDoubleStacks(craftingSlots) && canDoubleStacks(outputSlots))
{
doubleStacksInternal(this.craftingSlots);
doubleStacksInternal(this.outputSlots);
}
}
this.detectAndSendChanges();
}
}
static boolean containsFluid(SlotFake[] slots) {
List<SlotFake> enabledSlots = Arrays.stream(slots).filter(SlotFake::isEnabled).collect(Collectors.toList());
long fluid = enabledSlots.stream().filter(s -> Util.isFluidPacket(s.getStack())).count();
return fluid > 0;
}
}
@@ -0,0 +1,109 @@
package com.glodblock.github.client.render;
import com.glodblock.github.common.item.ItemFluidDrop;
import com.glodblock.github.loader.ItemAndBlockHolder;
import com.glodblock.github.util.RenderUtil;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ItemRenderer;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IIcon;
import net.minecraftforge.client.IItemRenderer;
import net.minecraftforge.client.MinecraftForgeClient;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import org.lwjgl.opengl.GL11;
import java.util.HashMap;
import java.util.Map;
@SideOnly(Side.CLIENT)
public class ItemDropRender implements IItemRenderer {
private final Map<String, Integer> colourCache = new HashMap<>();
public ItemDropRender() {
MinecraftForgeClient.registerItemRenderer(ItemAndBlockHolder.DROP, this);
}
@Override
public boolean handleRenderType(ItemStack item, ItemRenderType type) {
return type != ItemRenderType.FIRST_PERSON_MAP;
}
@Override
public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) {
return type == ItemRenderType.ENTITY;
}
@Override
public void renderItem(ItemRenderType type, ItemStack item, Object... data) {
IIcon shape = ItemAndBlockHolder.DROP.shape;
GL11.glEnable(GL11.GL_BLEND);
GL11.glEnable(GL11.GL_ALPHA_TEST);
if (type.equals(ItemRenderType.ENTITY)) {
GL11.glRotated(90.0D, 0.0D, 1.0D, 0.0D);
GL11.glTranslated(-0.5D, -0.6D, 0.0D);
}
Minecraft.getMinecraft().renderEngine.bindTexture(TextureMap.locationItemsTexture);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
FluidStack fluid = ItemFluidDrop.getFluidStack(item);
if (fluid != null) {
int RGB = getColour(fluid);
GL11.glColor3f((RGB >> 16 & 0xFF) / 255.0F, (RGB >> 8 & 0xFF) / 255.0F, (RGB & 0xFF) / 255.0F);
}
if (type.equals(ItemRenderType.INVENTORY)) {
RenderUtil.renderItemIcon(shape, 16.0D, 0.001D, 0.0F, 0.0F, -1.0F);
} else {
ItemRenderer.renderItemIn2D(Tessellator.instance, shape.getMaxU(), shape.getMinV(), shape.getMinU(), shape.getMaxV(), shape.getIconWidth(), shape.getIconHeight(), 0.0625F);
}
GL11.glDisable(GL11.GL_ALPHA_TEST);
GL11.glDisable(GL11.GL_BLEND);
}
public int getColour(FluidStack fluidStack) {
Fluid fluid = fluidStack.getFluid();
int colour = fluid.getColor(fluidStack);
return colour != 0xFFFFFF ? colour : getColour(fluid);
}
public int getColour(Fluid fluid) {
Integer cached = colourCache.get(fluid.getName());
if (cached != null) {
return cached;
}
int colour = fluid.getColor();
if (colour == 0xFFFFFF) {
TextureAtlasSprite sprite = Minecraft.getMinecraft().getTextureMapBlocks()
.getTextureExtry(fluid.getStillIcon().getIconName());
if (sprite != null && sprite.getFrameCount() > 0) {
int[][] image = sprite.getFrameTextureData(0);
int r = 0, g = 0, b = 0, count = 0;
for (int[] row : image) {
for (int pixel : row) {
if (((pixel >> 24) & 0xFF) > 127) { // is alpha above 50%?
r += (pixel >> 16) & 0xFF;
g += (pixel >> 8) & 0xFF;
b += pixel & 0xFF;
++count;
}
}
}
if (count > 0) {
// probably shouldn't need to mask each component by 0xFF
colour = ((r / count) << 16) | ((g / count) << 8) | (b / count);
}
}
}
colourCache.put(fluid.getName(), colour);
return colour;
}
}
@@ -0,0 +1,75 @@
package com.glodblock.github.client.render;
import com.glodblock.github.common.item.ItemFluidPacket;
import com.glodblock.github.loader.ItemAndBlockHolder;
import com.glodblock.github.util.RenderUtil;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ItemRenderer;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IIcon;
import net.minecraftforge.client.IItemRenderer;
import net.minecraftforge.client.MinecraftForgeClient;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import org.lwjgl.opengl.GL11;
@SideOnly(Side.CLIENT)
public class ItemPacketRender implements IItemRenderer {
public ItemPacketRender() {
MinecraftForgeClient.registerItemRenderer(ItemAndBlockHolder.PACKET, this);
}
@Override
public boolean handleRenderType(ItemStack item, ItemRenderType type) {
return type == ItemRenderType.INVENTORY;
}
@Override
public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item, ItemRendererHelper helper) {
return false;
}
@Override
public void renderItem(ItemRenderType type, ItemStack item, Object... data) {
if (item == null || item.getItem() == null || !(item.getItem() instanceof ItemFluidPacket))
return;
GL11.glEnable(GL11.GL_BLEND);
GL11.glEnable(GL11.GL_ALPHA_TEST);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
FluidStack fluid = ItemFluidPacket.getFluidStack(item);
int RGB = 0xFFFFFF;
if (fluid != null) {
RGB = fluid.getFluid().getColor(fluid);
}
IIcon icon = fluid == null ? FluidRegistry.WATER.getStillIcon() : fluid.getFluid().getStillIcon();
if (RGB != 0xFFFFFF) {
GL11.glColor3f((RGB >> 16 & 0xFF) / 255.0F, (RGB >> 8 & 0xFF) / 255.0F, (RGB & 0xFF) / 255.0F);
}
Tessellator tess = Tessellator.instance;
tess.startDrawingQuads();
// draw a simple rectangle for the inventory icon
final float x_min = icon.getMinU();
final float x_max = icon.getMaxU();
final float y_min = icon.getMinV();
final float y_max = icon.getMaxV();
tess.addVertexWithUV( 0, 16, 0, x_min, y_max);
tess.addVertexWithUV(16, 16, 0, x_max, y_max);
tess.addVertexWithUV(16, 0, 0, x_max, y_min);
tess.addVertexWithUV( 0, 0, 0, x_min, y_min);
tess.draw();
GL11.glDisable(GL11.GL_BLEND);
GL11.glDisable(GL11.GL_ALPHA_TEST);
}
}
@@ -0,0 +1,41 @@
package com.glodblock.github.client.render;
import appeng.client.render.BaseBlockRender;
import appeng.client.render.BlockRenderInfo;
import appeng.client.texture.ExtraBlockTextures;
import appeng.tile.misc.TileInterface;
import com.glodblock.github.client.textures.FCPartsTexture;
import com.glodblock.github.common.block.BlockFluidInterface;
import com.glodblock.github.common.tile.TileFluidInterface;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.util.IIcon;
import net.minecraft.world.IBlockAccess;
import net.minecraftforge.common.util.ForgeDirection;
public class RenderBlockFluidInterface extends BaseBlockRender<BlockFluidInterface, TileFluidInterface>
{
public RenderBlockFluidInterface()
{
super( false, 20 );
}
@Override
public boolean renderInWorld(final BlockFluidInterface block, final IBlockAccess world, final int x, final int y, final int z, final RenderBlocks renderer )
{
final TileInterface ti = block.getTileEntity( world, x, y, z );
final BlockRenderInfo info = block.getRendererInstance();
if( ti != null && ti.getForward() != ForgeDirection.UNKNOWN )
{
final IIcon side = FCPartsTexture.BlockFluidInterfaceAlternate_Arrow.getIcon();
info.setTemporaryRenderIcons( FCPartsTexture.BlockInterfaceAlternate.getIcon(), block.getIcon( 0, 0 ), side, side, side, side );
}
final boolean fz = super.renderInWorld( block, world, x, y, z, renderer );
info.setTemporaryRenderIcon( null );
return fz;
}
}
@@ -0,0 +1,50 @@
package com.glodblock.github.client.textures;
import com.glodblock.github.util.NameConst;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.util.IIcon;
import net.minecraft.util.ResourceLocation;
public enum FCPartsTexture {
PartFluidPatternTerminal_Bright("pattern_terminal_bright"), PartFluidPatternTerminal_Dark("pattern_terminal_dark"),
PartFluidPatternTerminal_Colored("pattern_terminal_medium"), PartTerminalBroad("terminal_broad"),
BlockFluidInterfaceAlternate_Arrow("fluid_interface_arrow"), BlockInterfaceAlternate("fluid_interface_a");
private final String name;
public net.minecraft.util.IIcon IIcon;
FCPartsTexture( final String name )
{
this.name = name;
}
public static ResourceLocation GuiTexture(final String string)
{
return null;
}
@SideOnly( Side.CLIENT )
public static IIcon getMissing()
{
return ( (TextureMap) Minecraft.getMinecraft().getTextureManager().getTexture( TextureMap.locationBlocksTexture ) ).getAtlasSprite( "missingno" );
}
public String getName()
{
return this.name;
}
public IIcon getIcon()
{
return this.IIcon;
}
public void registerIcon( final TextureMap map )
{
this.IIcon = map.registerIcon( NameConst.RES_KEY + this.name );
}
}
@@ -0,0 +1,24 @@
package com.glodblock.github.common.block;
import appeng.block.AEBaseItemBlock;
import com.glodblock.github.common.tile.TileFluidDiscretizer;
import com.glodblock.github.util.NameConst;
import cpw.mods.fml.common.registry.GameRegistry;
import net.minecraft.block.material.Material;
public class BlockFluidDiscretizer extends FCBaseBlock {
public BlockFluidDiscretizer() {
super(Material.iron, NameConst.BLOCK_FLUID_DISCRETIZER);
setFullBlock(true);
setOpaque(true);
setTileEntity(TileFluidDiscretizer.class);
}
public BlockFluidDiscretizer register() {
GameRegistry.registerBlock(this, AEBaseItemBlock.class, NameConst.BLOCK_FLUID_DISCRETIZER);
GameRegistry.registerTileEntity(TileFluidDiscretizer.class, NameConst.BLOCK_FLUID_DISCRETIZER);
return this;
}
}
@@ -0,0 +1,81 @@
package com.glodblock.github.common.block;
import appeng.api.util.IOrientable;
import appeng.block.AEBaseItemBlock;
import appeng.core.features.AEFeature;
import appeng.core.sync.GuiBridge;
import appeng.tile.misc.TileInterface;
import appeng.util.Platform;
import com.glodblock.github.client.render.RenderBlockFluidInterface;
import com.glodblock.github.common.tile.TileFluidInterface;
import com.glodblock.github.util.NameConst;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
import java.util.EnumSet;
public class BlockFluidInterface extends FCBaseBlock {
public BlockFluidInterface() {
super(Material.iron, NameConst.BLOCK_FLUID_INTERFACE);
setFullBlock(true);
setOpaque(true);
setTileEntity(TileFluidInterface.class);
setFeature( EnumSet.of( AEFeature.Core ) );
}
@Override
@SideOnly( Side.CLIENT )
protected RenderBlockFluidInterface getRenderer()
{
return new RenderBlockFluidInterface();
}
@Override
public boolean onActivated(final World w, final int x, final int y, final int z, final EntityPlayer p, final int side, final float hitX, final float hitY, final float hitZ )
{
if( p.isSneaking() )
{
return false;
}
final TileInterface tg = this.getTileEntity( w, x, y, z );
if( tg != null )
{
if( Platform.isServer() )
{
Platform.openGUI( p, tg, ForgeDirection.getOrientation( side ), GuiBridge.GUI_INTERFACE );
}
return true;
}
return false;
}
@Override
protected boolean hasCustomRotation()
{
return true;
}
@Override
protected void customRotateBlock(final IOrientable rotatable, final ForgeDirection axis )
{
if( rotatable instanceof TileInterface )
{
( (TileInterface) rotatable ).setSide( axis );
}
}
public BlockFluidInterface register() {
GameRegistry.registerBlock(this, AEBaseItemBlock.class, NameConst.BLOCK_FLUID_INTERFACE);
GameRegistry.registerTileEntity(TileFluidInterface.class, NameConst.BLOCK_FLUID_INTERFACE);
return this;
}
}
@@ -0,0 +1,45 @@
package com.glodblock.github.common.block;
import appeng.block.AEBaseItemBlock;
import com.glodblock.github.common.tile.TileFluidPacketDecoder;
import com.glodblock.github.inventory.InventoryHandler;
import com.glodblock.github.inventory.gui.GuiType;
import com.glodblock.github.util.BlockPos;
import com.glodblock.github.util.NameConst;
import cpw.mods.fml.common.registry.GameRegistry;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
public class BlockFluidPacketDecoder extends FCBaseBlock {
public BlockFluidPacketDecoder() {
super(Material.iron, NameConst.BLOCK_FLUID_PACKET_DECODER);
setFullBlock(true);
setOpaque(true);
setTileEntity(TileFluidPacketDecoder.class);
}
@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int facing, float hitX, float hitY, float hitZ) {
if (player.isSneaking()) {
return false;
}
TileFluidPacketDecoder tile = getTileEntity(world, x, y, z);
if (tile != null) {
if (!world.isRemote) {
InventoryHandler.openGui(player, world, new BlockPos(x, y, z), EnumFacing.getFront(facing), GuiType.FLUID_PACKET_DECODER);
}
return true;
}
return false;
}
public BlockFluidPacketDecoder register() {
GameRegistry.registerBlock(this, AEBaseItemBlock.class, NameConst.BLOCK_FLUID_PACKET_DECODER);
GameRegistry.registerTileEntity(TileFluidPacketDecoder.class, NameConst.BLOCK_FLUID_PACKET_DECODER);
return this;
}
}
@@ -0,0 +1,46 @@
package com.glodblock.github.common.block;
import appeng.block.AEBaseItemBlock;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.common.tile.TileFluidPatternEncoder;
import com.glodblock.github.inventory.InventoryHandler;
import com.glodblock.github.inventory.gui.GuiType;
import com.glodblock.github.util.BlockPos;
import com.glodblock.github.util.NameConst;
import cpw.mods.fml.common.registry.GameRegistry;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
public class BlockFluidPatternEncoder extends FCBaseBlock {
public BlockFluidPatternEncoder() {
super(Material.iron, NameConst.BLOCK_FLUID_PATTERN_ENCODER);
setFullBlock(true);
setOpaque(true);
setTileEntity(TileFluidPatternEncoder.class);
}
@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int facing, float hitX, float hitY, float hitZ) {
if (player.isSneaking()) {
return false;
}
TileFluidPatternEncoder tile = getTileEntity(world, x, y, z);
if (tile != null) {
if (!world.isRemote) {
InventoryHandler.openGui(player, world, new BlockPos(x, y, z), EnumFacing.getFront(facing), GuiType.FLUID_PATTERN_ENCODER);
}
return true;
}
return false;
}
public BlockFluidPatternEncoder register() {
GameRegistry.registerBlock(this, AEBaseItemBlock.class, NameConst.BLOCK_FLUID_PATTERN_ENCODER);
GameRegistry.registerTileEntity(TileFluidPatternEncoder.class, NameConst.BLOCK_FLUID_PATTERN_ENCODER);
return this;
}
}
@@ -0,0 +1,37 @@
package com.glodblock.github.common.block;
import appeng.block.AEBaseTileBlock;
import appeng.core.features.AEFeature;
import com.glodblock.github.FluidCraft;
import net.minecraft.block.material.Material;
import net.minecraft.tileentity.TileEntity;
import java.util.EnumSet;
public class FCBaseBlock extends AEBaseTileBlock {
public FCBaseBlock(Material mat, String name) {
super(mat);
this.setBlockName(name);
this.setBlockTextureName(FluidCraft.MODID + ":" + name);
}
@Override
public void setTileEntity( final Class<? extends TileEntity> clazz ) {
super.setTileEntity(clazz);
}
public void setOpaque(boolean opaque) {
this.isOpaque = opaque;
}
public void setFullBlock(boolean full) {
this.isFullSize = full;
}
@Override
public void setFeature( final EnumSet<AEFeature> f ) {
super.setFeature(f);
}
}
@@ -0,0 +1,142 @@
package com.glodblock.github.common.item;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.util.item.AEFluidStack;
import appeng.util.item.AEItemStack;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.loader.ItemAndBlockHolder;
import com.glodblock.github.util.NameConst;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.client.resources.I18n;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IIcon;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Objects;
public class ItemFluidDrop extends Item {
@SideOnly(Side.CLIENT)
public IIcon shape;
@Override
@SuppressWarnings("unchecked")
@SideOnly(Side.CLIENT)
public void getSubItems(Item item, CreativeTabs tab, List list) {
if (CreativeTabs.tabMisc.equals(tab)) {
list.add(newStack(new FluidStack(FluidRegistry.WATER, 1)));
list.add(newStack(new FluidStack(FluidRegistry.LAVA, 1)));
}
}
@Override
public String getItemStackDisplayName(ItemStack stack) {
FluidStack fluid = getFluidStack(stack);
return I18n.format("item.fluid_drop.name", fluid == null ? "???" : fluid.getLocalizedName());
}
@Override
@SuppressWarnings("unchecked")
@SideOnly(Side.CLIENT)
public void addInformation(ItemStack stack, EntityPlayer player, List tooltip, boolean flag) {
FluidStack fluid = getFluidStack(stack);
if (fluid != null) {
tooltip.add(String.format(EnumChatFormatting.GRAY + "%s, 1 mB", fluid.getLocalizedName()));
} else {
tooltip.add(EnumChatFormatting.RED + I18n.format(NameConst.TT_INVALID_FLUID));
}
}
@Override
@SideOnly(Side.CLIENT)
public void registerIcons(IIconRegister aIconRegister) {
super.registerIcons(aIconRegister);
shape = aIconRegister.registerIcon(NameConst.RES_KEY + NameConst.ITEM_FLUID_DROP);
}
public static ItemStack newStack(@Nullable FluidStack fluid) {
if (fluid == null || fluid.amount <= 0) {
return null;
}
ItemStack stack = new ItemStack(ItemAndBlockHolder.DROP, fluid.amount);
NBTTagCompound tag = new NBTTagCompound();
tag.setString("Fluid", fluid.getFluid().getName());
stack.setTagCompound(tag);
return stack;
}
public static FluidStack getFluidStack(ItemStack stack) {
if (stack == null|| stack.getItem() != ItemAndBlockHolder.DROP || !stack.hasTagCompound()) {
return null;
}
NBTTagCompound tag = Objects.requireNonNull(stack.getTagCompound());
if (!tag.hasKey("Fluid", Constants.NBT.TAG_STRING)) {
return null;
}
Fluid fluid = FluidRegistry.getFluid(tag.getString("Fluid").toLowerCase());
if (fluid == null) {
return null;
}
FluidStack fluidStack = new FluidStack(fluid, stack.stackSize);
if (tag.hasKey("FluidTag", Constants.NBT.TAG_COMPOUND)) {
fluidStack.tag = tag.getCompoundTag("FluidTag");
}
return fluidStack;
}
public static IAEFluidStack getAeFluidStack(@Nullable IAEItemStack stack) {
if (stack == null) {
return null;
}
IAEFluidStack fluidStack = AEFluidStack.create(getFluidStack(stack.getItemStack()));
if (fluidStack == null) {
return null;
}
fluidStack.setStackSize(stack.getStackSize());
return fluidStack;
}
public static IAEItemStack newAeStack(@Nullable FluidStack fluid) {
if (fluid == null || fluid.amount <= 0) {
return null;
}
IAEItemStack stack = AEItemStack.create(newStack(fluid));
if (stack == null) {
return null;
}
stack.setStackSize(fluid.amount);
return stack;
}
public static IAEItemStack newAeStack(@Nullable IAEFluidStack fluid) {
if (fluid == null || fluid.getStackSize() <= 0) {
return null;
}
IAEItemStack stack = AEItemStack.create(newStack(fluid.getFluidStack()));
if (stack == null) {
return null;
}
stack.setStackSize(fluid.getStackSize());
return stack;
}
public ItemFluidDrop register() {
GameRegistry.registerItem(this, NameConst.ITEM_FLUID_DROP, FluidCraft.MODID);
return this;
}
}
@@ -0,0 +1,31 @@
package com.glodblock.github.common.item;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.items.misc.ItemEncodedPattern;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.util.FluidPatternDetails;
import com.glodblock.github.util.NameConst;
import cpw.mods.fml.common.registry.GameRegistry;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
public class ItemFluidEncodedPattern extends ItemEncodedPattern {
public ItemFluidEncodedPattern() {
super();
this.setUnlocalizedName(NameConst.ITEM_FLUID_ENCODED_PATTERN);
this.setTextureName(FluidCraft.MODID + ":" + NameConst.ITEM_FLUID_ENCODED_PATTERN);
}
@Override
public ICraftingPatternDetails getPatternForItem(ItemStack is, World w) {
FluidPatternDetails pattern = new FluidPatternDetails(is);
return pattern.readFromStack() ? pattern : null;
}
public ItemFluidEncodedPattern register() {
GameRegistry.registerItem(this, NameConst.ITEM_FLUID_ENCODED_PATTERN, FluidCraft.MODID);
return this;
}
}
@@ -0,0 +1,110 @@
package com.glodblock.github.common.item;
import appeng.api.storage.data.IAEItemStack;
import appeng.util.item.AEItemStack;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.loader.ItemAndBlockHolder;
import com.glodblock.github.util.NameConst;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IIcon;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Objects;
public class ItemFluidPacket extends Item {
public ItemFluidPacket() {
setUnlocalizedName(NameConst.ITEM_FLUID_PACKET);
setMaxStackSize(1);
}
@Override
public String getItemStackDisplayName(ItemStack stack) {
FluidStack fluid = getFluidStack(stack);
return fluid != null ? String.format("%s, %,d mB", fluid.getLocalizedName(), fluid.amount)
: super.getItemStackDisplayName(stack);
}
@Override
@SuppressWarnings("unchecked")
public void addInformation(ItemStack stack, EntityPlayer player, List tooltip, boolean flags) {
FluidStack fluid = getFluidStack(stack);
if (fluid != null) {
for (String line : I18n.format(NameConst.TT_FLUID_PACKET).split("\\\\n")) {
tooltip.add(EnumChatFormatting.GRAY + line);
}
} else {
tooltip.add(EnumChatFormatting.RED + I18n.format(NameConst.TT_INVALID_FLUID));
}
}
public static FluidStack getFluidStack(ItemStack stack) {
if (stack == null || !stack.hasTagCompound()) {
return null;
}
FluidStack fluid = FluidStack.loadFluidStackFromNBT(Objects.requireNonNull(stack.getTagCompound()).getCompoundTag("FluidStack"));
return (fluid != null && fluid.amount > 0) ? fluid : null;
}
public static FluidStack getFluidStack(@Nullable IAEItemStack stack) {
return stack != null ? getFluidStack(stack.getItemStack()) : null;
}
public static ItemStack newStack(@Nullable FluidStack fluid) {
if (fluid == null || fluid.amount == 0) {
return null;
}
ItemStack stack = new ItemStack(ItemAndBlockHolder.PACKET);
NBTTagCompound tag = new NBTTagCompound();
NBTTagCompound fluidTag = new NBTTagCompound();
fluid.writeToNBT(fluidTag);
tag.setTag("FluidStack", fluidTag);
stack.setTagCompound(tag);
return stack;
}
@Nullable
public static IAEItemStack newAeStack(@Nullable FluidStack fluid) {
return AEItemStack.create(newStack(fluid));
}
@Override
public int getSpriteNumber() {
return 0;
}
@Override
@SideOnly(Side.CLIENT)
public void registerIcons(IIconRegister aIconRegister) {
}
@SideOnly(Side.CLIENT)
public IIcon getIconFromDamage(int p_77617_1_) {
return FluidRegistry.WATER.getStillIcon();
}
@Override
@SideOnly(Side.CLIENT)
public int getColorFromItemStack(ItemStack aStack, int aRenderPass) {
Fluid tFluid = FluidRegistry.getFluid(aStack.getItemDamage());
return tFluid == null ? 16777215 : tFluid.getColor();
}
public ItemFluidPacket register() {
GameRegistry.registerItem(this, NameConst.ITEM_FLUID_PACKET, FluidCraft.MODID);
return this;
}
}
@@ -0,0 +1,53 @@
package com.glodblock.github.common.item;
import appeng.api.AEApi;
import appeng.api.parts.IPartItem;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.common.parts.PartFluidPatternTerminal;
import com.glodblock.github.util.NameConst;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import javax.annotation.Nullable;
public class ItemPartFluidPatternTerminal extends Item implements IPartItem {
public ItemPartFluidPatternTerminal() {
this.setMaxStackSize(64);
this.setUnlocalizedName(NameConst.ITEM_PART_FLUID_PATTERN_TERMINAL);
AEApi.instance().partHelper().setItemBusRenderer(this);
}
@Nullable
@Override
public PartFluidPatternTerminal createPartFromItemStack(ItemStack is) {
return new PartFluidPatternTerminal(is);
}
@Override
public boolean onItemUse(ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float xOffset, float yOffset, float zOffset) {
return AEApi.instance().partHelper().placeBus(player.getHeldItem(), x, y, z, side, player, world);
}
public ItemPartFluidPatternTerminal register() {
GameRegistry.registerItem(this, NameConst.ITEM_PART_FLUID_PATTERN_TERMINAL, FluidCraft.MODID);
return this;
}
@Override
public void registerIcons(IIconRegister _iconRegister) {
}
@Override
@SideOnly(Side.CLIENT)
public int getSpriteNumber() {
return 0;
}
}
@@ -0,0 +1,507 @@
package com.glodblock.github.common.parts;
import appeng.api.config.Settings;
import appeng.api.config.SortDir;
import appeng.api.config.SortOrder;
import appeng.api.config.ViewItems;
import appeng.api.implementations.IPowerChannelState;
import appeng.api.implementations.tiles.IViewCellStorage;
import appeng.api.networking.GridFlags;
import appeng.api.networking.events.MENetworkBootingStatusChange;
import appeng.api.networking.events.MENetworkEventSubscribe;
import appeng.api.networking.events.MENetworkPowerStatusChange;
import appeng.api.parts.IPartCollisionHelper;
import appeng.api.parts.IPartRenderHelper;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.ITerminalHost;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.util.IConfigManager;
import appeng.client.texture.CableBusTextures;
import appeng.core.sync.GuiBridge;
import appeng.me.GridAccessException;
import appeng.parts.AEBasePart;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.IAEAppEngInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.ConfigManager;
import appeng.util.IConfigManagerHost;
import appeng.util.Platform;
import com.glodblock.github.client.textures.FCPartsTexture;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.IIcon;
import net.minecraft.util.MathHelper;
import net.minecraft.util.Vec3;
import net.minecraftforge.common.util.ForgeDirection;
import java.io.IOException;
import java.util.List;
public abstract class FCBasePart extends AEBasePart implements IPowerChannelState, ITerminalHost, IConfigManagerHost, IViewCellStorage, IAEAppEngInventory {
protected static final int POWERED_FLAG = 4;
protected static final int CHANNEL_FLAG = 16;
private static final int BOOTING_FLAG = 8;
private byte spin = 0; // 0-3
private int clientFlags = 0; // sent as byte.
private float opacity = -1;
private final IConfigManager cm = new ConfigManager( this );
private final AppEngInternalInventory viewCell = new AppEngInternalInventory( this, 5 );
public FCBasePart( final ItemStack is )
{
this( is, false );
}
protected FCBasePart( final ItemStack is, final boolean requireChannel )
{
super( is );
if( requireChannel )
{
this.getProxy().setFlags( GridFlags.REQUIRE_CHANNEL );
this.getProxy().setIdlePowerUsage( 1.0 / 2.0 );
}
else
{
this.getProxy().setIdlePowerUsage( 1.0 / 16.0 ); // lights drain a little bit.
}
this.cm.registerSetting( Settings.SORT_BY, SortOrder.NAME );
this.cm.registerSetting( Settings.VIEW_MODE, ViewItems.ALL );
this.cm.registerSetting( Settings.SORT_DIRECTION, SortDir.ASCENDING );
}
@MENetworkEventSubscribe
public final void bootingRender( final MENetworkBootingStatusChange c )
{
if( !this.isLightSource() )
{
this.getHost().markForUpdate();
}
}
@MENetworkEventSubscribe
public final void powerRender( final MENetworkPowerStatusChange c )
{
this.getHost().markForUpdate();
}
@Override
public final void getBoxes( final IPartCollisionHelper bch )
{
bch.addBox( 2, 2, 14, 14, 14, 16 );
bch.addBox( 4, 4, 13, 12, 12, 14 );
}
@Override
public void onNeighborChanged()
{
this.opacity = -1;
this.getHost().markForUpdate();
}
@Override
public void getDrops(final List<ItemStack> drops, final boolean wrenched )
{
super.getDrops( drops, wrenched );
for( final ItemStack is : this.viewCell )
{
if( is != null )
{
drops.add( is );
}
}
}
@Override
public IConfigManager getConfigManager()
{
return this.cm;
}
@Override
public void readFromNBT( final NBTTagCompound data )
{
super.readFromNBT( data );
if( data.hasKey( "opacity" ) )
{
this.opacity = data.getFloat( "opacity" );
}
this.spin = data.getByte( "spin" );
this.cm.readFromNBT( data );
this.viewCell.readFromNBT( data, "viewCell" );
}
@Override
public void writeToNBT( final NBTTagCompound data )
{
super.writeToNBT( data );
data.setFloat( "opacity", this.opacity );
data.setByte( "spin", this.getSpin() );
this.cm.writeToNBT( data );
this.viewCell.writeToNBT( data, "viewCell" );
}
public GuiBridge getGui(final EntityPlayer player )
{
return GuiBridge.GUI_ME;
}
@Override
public void writeToStream( final ByteBuf data ) throws IOException
{
super.writeToStream( data );
this.clientFlags = this.getSpin() & 3;
try
{
if( this.getProxy().getEnergy().isNetworkPowered() )
{
this.clientFlags = this.getClientFlags() | FCBasePart.POWERED_FLAG;
}
if( this.getProxy().getPath().isNetworkBooting() )
{
this.clientFlags = this.getClientFlags() | FCBasePart.BOOTING_FLAG;
}
if( this.getProxy().getNode().meetsChannelRequirements() )
{
this.clientFlags = this.getClientFlags() | FCBasePart.CHANNEL_FLAG;
}
}
catch( final GridAccessException e )
{
// um.. nothing.
}
data.writeByte( (byte) this.getClientFlags() );
}
@Override
public boolean readFromStream( final ByteBuf data ) throws IOException
{
super.readFromStream( data );
final int oldFlags = this.getClientFlags();
this.clientFlags = data.readByte();
this.spin = (byte) ( this.getClientFlags() & 3 );
return this.getClientFlags() != oldFlags;
}
@Override
public final int getLightLevel()
{
return this.blockLight( this.isPowered() ? ( this.isLightSource() ? 15 : 9 ) : 0 );
}
public boolean onPartActivate0(final EntityPlayer player, final Vec3 pos )
{
final TileEntity te = this.getTile();
if( !player.isSneaking() && Platform.isWrench( player, player.inventory.getCurrentItem(), te.xCoord, te.yCoord, te.zCoord ) )
{
if( Platform.isServer() )
{
if( this.getSpin() > 3 )
{
this.spin = 0;
}
switch( this.getSpin() )
{
case 0:
this.spin = 1;
break;
case 1:
this.spin = 3;
break;
case 2:
this.spin = 0;
break;
case 3:
this.spin = 2;
break;
}
this.getHost().markForUpdate();
this.saveChanges();
}
return true;
}
else
{
return super.onPartActivate( player, pos );
}
}
@Override
public boolean onPartActivate( final EntityPlayer player, final Vec3 pos )
{
if( !onPartActivate0( player, pos ) )
{
if( !player.isSneaking() )
{
if( Platform.isClient() )
{
return true;
}
Platform.openGUI( player, this.getHost().getTile(), this.getSide(), this.getGui( player ) );
return true;
}
}
return false;
}
@Override
public final void onPlacement( final EntityPlayer player, final ItemStack held, final ForgeDirection side )
{
super.onPlacement( player, held, side );
final byte rotation = (byte) ( MathHelper.floor_double( ( player.rotationYaw * 4F ) / 360F + 2.5D ) & 3 );
if( side == ForgeDirection.UP )
{
this.spin = rotation;
}
else if( side == ForgeDirection.DOWN )
{
this.spin = rotation;
}
}
private int blockLight(final int emit )
{
if( this.opacity < 0 )
{
final TileEntity te = this.getTile();
this.opacity = 255 - te.getWorldObj().getBlockLightOpacity( te.xCoord + this.getSide().offsetX, te.yCoord + this.getSide().offsetY, te.zCoord + this.getSide().offsetZ );
}
return (int) ( emit * ( this.opacity / 255.0f ) );
}
@Override
public final boolean isPowered()
{
try
{
if( Platform.isServer() )
{
return this.getProxy().getEnergy().isNetworkPowered();
}
else
{
return ( ( this.getClientFlags() & FCBasePart.POWERED_FLAG ) == FCBasePart.POWERED_FLAG );
}
}
catch( final GridAccessException e )
{
return false;
}
}
@Override
public IMEMonitor<IAEItemStack> getItemInventory()
{
try
{
return this.getProxy().getStorage().getItemInventory();
}
catch( final GridAccessException e )
{
// err nope?
}
return null;
}
@Override
public IMEMonitor<IAEFluidStack> getFluidInventory()
{
try
{
return this.getProxy().getStorage().getFluidInventory();
}
catch( final GridAccessException e )
{
// err nope?
}
return null;
}
@Override
public void updateSetting( final IConfigManager manager, final Enum settingName, final Enum newValue )
{
}
@Override
public IInventory getViewCellStorage()
{
return this.viewCell;
}
@Override
public void onChangeInventory(final IInventory inv, final int slot, final InvOperation mc, final ItemStack removedStack, final ItemStack newStack )
{
this.getHost().markForSave();
}
@Override
public final boolean isActive()
{
if( !this.isLightSource() )
{
return ( ( this.getClientFlags() & ( FCBasePart.CHANNEL_FLAG | FCBasePart.POWERED_FLAG ) ) == ( FCBasePart.CHANNEL_FLAG | FCBasePart.POWERED_FLAG ) );
}
else
{
return this.isPowered();
}
}
public final int getClientFlags()
{
return this.clientFlags;
}
public final byte getSpin()
{
return this.spin;
}
@Override
@SideOnly( Side.CLIENT )
public void renderInventory(final IPartRenderHelper rh, final RenderBlocks renderer )
{
rh.setBounds( 2, 2, 14, 14, 14, 16 );
final IIcon sideTexture = CableBusTextures.PartMonitorSides.getIcon();
final IIcon backTexture = CableBusTextures.PartMonitorBack.getIcon();
rh.setTexture( sideTexture, sideTexture, backTexture, FCPartsTexture.PartTerminalBroad.getIcon(), sideTexture, sideTexture );
rh.renderInventoryBox( renderer );
rh.setInvColor( this.getColor().whiteVariant );
rh.renderInventoryFace( this.getFrontBright().getIcon(), ForgeDirection.SOUTH, renderer );
rh.setInvColor( this.getColor().mediumVariant );
rh.renderInventoryFace( this.getFrontDark().getIcon(), ForgeDirection.SOUTH, renderer );
rh.setInvColor( this.getColor().blackVariant );
rh.renderInventoryFace( this.getFrontColored().getIcon(), ForgeDirection.SOUTH, renderer );
rh.setBounds( 4, 4, 13, 12, 12, 14 );
rh.renderInventoryBox( renderer );
}
@Override
@SideOnly( Side.CLIENT )
public void renderStatic( final int x, final int y, final int z, final IPartRenderHelper rh, final RenderBlocks renderer )
{
this.setRenderCache( rh.useSimplifiedRendering( x, y, z, this, this.getRenderCache() ) );
final IIcon sideTexture = CableBusTextures.PartMonitorSides.getIcon();
final IIcon backTexture = CableBusTextures.PartMonitorBack.getIcon();
rh.setTexture( sideTexture, sideTexture, backTexture, FCPartsTexture.PartTerminalBroad.getIcon(), sideTexture, sideTexture );
rh.setBounds( 2, 2, 14, 14, 14, 16 );
rh.renderBlock( x, y, z, renderer );
if( this.getLightLevel() > 0 )
{
final int l = 13;
Tessellator.instance.setBrightness( l << 20 | l << 4 );
}
renderer.uvRotateBottom = renderer.uvRotateEast = renderer.uvRotateNorth = renderer.uvRotateSouth = renderer.uvRotateTop = renderer.uvRotateWest = this.getSpin();
Tessellator.instance.setColorOpaque_I( this.getColor().whiteVariant );
rh.renderFace( x, y, z, this.getFrontBright().getIcon(), ForgeDirection.SOUTH, renderer );
Tessellator.instance.setColorOpaque_I( this.getColor().mediumVariant );
rh.renderFace( x, y, z, this.getFrontDark().getIcon(), ForgeDirection.SOUTH, renderer );
Tessellator.instance.setColorOpaque_I( this.getColor().blackVariant );
rh.renderFace( x, y, z, this.getFrontColored().getIcon(), ForgeDirection.SOUTH, renderer );
renderer.uvRotateBottom = renderer.uvRotateEast = renderer.uvRotateNorth = renderer.uvRotateSouth = renderer.uvRotateTop = renderer.uvRotateWest = 0;
final IIcon sideStatusTexture = CableBusTextures.PartMonitorSidesStatus.getIcon();
rh.setTexture( sideStatusTexture, sideStatusTexture, backTexture, this.getItemStack().getIconIndex(), sideStatusTexture, sideStatusTexture );
rh.setBounds( 4, 4, 13, 12, 12, 14 );
rh.renderBlock( x, y, z, renderer );
final boolean hasChan = ( this.getClientFlags() & ( FCBasePart.POWERED_FLAG | FCBasePart.CHANNEL_FLAG ) ) == ( FCBasePart.POWERED_FLAG | FCBasePart.CHANNEL_FLAG );
final boolean hasPower = ( this.getClientFlags() & FCBasePart.POWERED_FLAG ) == FCBasePart.POWERED_FLAG;
if( hasChan )
{
final int l = 14;
Tessellator.instance.setBrightness( l << 20 | l << 4 );
Tessellator.instance.setColorOpaque_I( this.getColor().blackVariant );
}
else if( hasPower )
{
final int l = 9;
Tessellator.instance.setBrightness( l << 20 | l << 4 );
Tessellator.instance.setColorOpaque_I( this.getColor().whiteVariant );
}
else
{
Tessellator.instance.setBrightness( 0 );
Tessellator.instance.setColorOpaque_I( 0x000000 );
}
final IIcon sideStatusLightTexture = CableBusTextures.PartMonitorSidesStatusLights.getIcon();
rh.renderFace( x, y, z, sideStatusLightTexture, ForgeDirection.EAST, renderer );
rh.renderFace( x, y, z, sideStatusLightTexture, ForgeDirection.WEST, renderer );
rh.renderFace( x, y, z, sideStatusLightTexture, ForgeDirection.UP, renderer );
rh.renderFace( x, y, z, sideStatusLightTexture, ForgeDirection.DOWN, renderer );
}
/**
* The texture used for the bright front layer.
* <p>
* The final texture can overlap any of the the texture in no particular order.
*/
public abstract FCPartsTexture getFrontBright();
/**
* The texture used for the colored (medium) front layer.
* <p>
* The final texture can overlap any of the the texture in no particular order.
*/
public abstract FCPartsTexture getFrontColored();
/**
* The texture used for the dark front layer.
* <p>
* The final texture can overlap any of the the texture in no particular order.
*/
public abstract FCPartsTexture getFrontDark();
/**
* Should the part emit light. This actually only affects the light level, light source use a level of 15 and non
* light source 9.
*/
public abstract boolean isLightSource();
}
@@ -0,0 +1,288 @@
package com.glodblock.github.common.parts;
import appeng.api.config.SecurityPermissions;
import appeng.api.implementations.ICraftingPatternItem;
import appeng.api.networking.IGridHost;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.storage.data.IAEItemStack;
import appeng.core.sync.GuiBridge;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.Platform;
import com.glodblock.github.client.textures.FCPartsTexture;
import com.glodblock.github.common.item.ItemFluidDrop;
import com.glodblock.github.common.item.ItemFluidEncodedPattern;
import com.glodblock.github.common.item.ItemFluidPacket;
import com.glodblock.github.inventory.InventoryHandler;
import com.glodblock.github.inventory.gui.GuiType;
import com.glodblock.github.util.BlockPos;
import com.glodblock.github.util.FluidPatternDetails;
import com.glodblock.github.util.Util;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ChatComponentText;
import net.minecraft.util.Vec3;
import java.util.List;
import java.util.Objects;
public class PartFluidPatternTerminal extends FCBasePart {
private static final FCPartsTexture FRONT_BRIGHT_ICON = FCPartsTexture.PartFluidPatternTerminal_Bright;
private static final FCPartsTexture FRONT_DARK_ICON = FCPartsTexture.PartFluidPatternTerminal_Colored;
private static final FCPartsTexture FRONT_COLORED_ICON = FCPartsTexture.PartFluidPatternTerminal_Dark;
private final AppEngInternalInventory crafting = new AppEngInternalInventory( this, 9 );
private final AppEngInternalInventory output = new AppEngInternalInventory( this, 3 );
private final AppEngInternalInventory pattern = new AppEngInternalInventory( this, 2 );
private boolean craftingMode = true;
private boolean substitute = false;
public PartFluidPatternTerminal(ItemStack is) {
super(is, true);
}
@Override
public void getDrops(final List<ItemStack> drops, final boolean wrenched )
{
for( final ItemStack is : this.pattern )
{
if( is != null )
{
drops.add( is );
}
}
}
@Override
public boolean onPartActivate( final EntityPlayer player, final Vec3 pos ) {
TileEntity te = this.getTile();
BlockPos tePos = new BlockPos(te);
if (Platform.isWrench(player, player.inventory.getCurrentItem(), tePos.getX(), tePos.getY(), tePos.getZ())) {
return super.onPartActivate(player, pos);
}
if (Platform.isServer()) {
if (Util.hasPermission(player, SecurityPermissions.INJECT, (IGridHost) this) || Util.hasPermission(player, SecurityPermissions.EXTRACT, (IGridHost) this)) {
InventoryHandler.openGui(player, te.getWorldObj(), tePos, Objects.requireNonNull(Util.from(getSide())), GuiType.FLUID_PATTERN_TERMINAL);
}
else {
player.addChatComponentMessage(new ChatComponentText("You don't have permission to view."));
}
}
return true;
}
@Override
public void readFromNBT( final NBTTagCompound data )
{
super.readFromNBT( data );
this.setCraftingRecipe( data.getBoolean( "craftingMode" ) );
this.setSubstitution( data.getBoolean( "substitute" ) );
this.pattern.readFromNBT( data, "pattern" );
this.output.readFromNBT( data, "outputList" );
this.crafting.readFromNBT( data, "craftingGrid" );
}
@Override
public void writeToNBT( final NBTTagCompound data )
{
super.writeToNBT( data );
data.setBoolean( "craftingMode", this.craftingMode );
data.setBoolean( "substitute", this.substitute );
this.pattern.writeToNBT( data, "pattern" );
this.output.writeToNBT( data, "outputList" );
this.crafting.writeToNBT( data, "craftingGrid" );
}
@Override
public GuiBridge getGui(final EntityPlayer p )
{
int x = (int) p.posX;
int y = (int) p.posY;
int z = (int) p.posZ;
if( this.getHost().getTile() != null )
{
x = this.getTile().xCoord;
y = this.getTile().yCoord;
z = this.getTile().zCoord;
}
if( GuiBridge.GUI_PATTERN_TERMINAL.hasPermissions( this.getHost().getTile(), x, y, z, this.getSide(), p ) )
{
return GuiBridge.GUI_PATTERN_TERMINAL;
}
return GuiBridge.GUI_ME;
}
public void onChangeInventory0(final IInventory inv, final int slot, final InvOperation mc, final ItemStack removedStack, final ItemStack newStack )
{
if( inv == this.pattern && slot == 1 )
{
final ItemStack is = this.pattern.getStackInSlot( 1 );
if( is != null && is.getItem() instanceof ICraftingPatternItem)
{
final ICraftingPatternItem pattern = (ICraftingPatternItem) is.getItem();
final ICraftingPatternDetails details = pattern.getPatternForItem( is, this.getHost().getTile().getWorldObj() );
if( details != null )
{
this.setCraftingRecipe( details.isCraftable() );
this.setSubstitution( details.canSubstitute() );
for( int x = 0; x < this.crafting.getSizeInventory() && x < details.getInputs().length; x++ )
{
final IAEItemStack item = details.getInputs()[x];
this.crafting.setInventorySlotContents( x, item == null ? null : item.getItemStack() );
}
for( int x = 0; x < this.output.getSizeInventory() && x < details.getOutputs().length; x++ )
{
final IAEItemStack item = details.getOutputs()[x];
this.output.setInventorySlotContents( x, item == null ? null : item.getItemStack() );
}
}
}
}
else if( inv == this.crafting )
{
this.fixCraftingRecipes();
}
this.getHost().markForSave();
}
@Override
public void onChangeInventory(final IInventory inv, final int slot, final InvOperation mc, final ItemStack removedStack, final ItemStack newStack )
{
if (inv == this.pattern && slot == 1) {
final ItemStack is = inv.getStackInSlot(1);
if (is != null && is.getItem() instanceof ItemFluidEncodedPattern) {
final ItemFluidEncodedPattern pattern = (ItemFluidEncodedPattern) is.getItem();
final ICraftingPatternDetails details = pattern.getPatternForItem( is, this.getHost().getTile().getWorldObj() );
if( details != null )
{
this.setCraftingRecipe( details.isCraftable() );
this.setSubstitution( details.canSubstitute() );
for( int x = 0; x < this.crafting.getSizeInventory() && x < details.getInputs().length; x++ )
{
final IAEItemStack item = details.getInputs()[x];
if (item != null && item.getItem() instanceof ItemFluidDrop) {
ItemStack packet = ItemFluidPacket.newStack(ItemFluidDrop.getFluidStack(item.getItemStack()));
this.crafting.setInventorySlotContents(x, packet);
}
else this.crafting.setInventorySlotContents( x, item == null ? null : item.getItemStack() );
}
for( int x = 0; x < this.output.getSizeInventory() && x < details.getOutputs().length; x++ )
{
final IAEItemStack item = details.getOutputs()[x];
if (item != null && item.getItem() instanceof ItemFluidDrop) {
ItemStack packet = ItemFluidPacket.newStack(ItemFluidDrop.getFluidStack(item.getItemStack()));
this.output.setInventorySlotContents(x, packet);
}
else this.output.setInventorySlotContents( x, item == null ? null : item.getItemStack() );
}
}
this.getHost().markForSave();
return;
}
}
onChangeInventory0(inv, slot, mc, removedStack, newStack);
}
private void fixCraftingRecipes()
{
if( this.craftingMode )
{
for( int x = 0; x < this.crafting.getSizeInventory(); x++ )
{
final ItemStack is = this.crafting.getStackInSlot( x );
if( is != null )
{
is.stackSize = 1;
}
}
}
}
public boolean isCraftingRecipe()
{
return this.craftingMode;
}
public void setCraftingRecipe( final boolean craftingMode )
{
this.craftingMode = craftingMode;
this.fixCraftingRecipes();
}
public boolean isSubstitution()
{
return this.substitute;
}
public void setSubstitution( boolean canSubstitute )
{
this.substitute = canSubstitute;
}
public void onChangeCrafting(IAEItemStack[] newCrafting, IAEItemStack[] newOutput) {
IInventory crafting = this.getInventoryByName("crafting");
IInventory output = this.getInventoryByName("output");
if (crafting instanceof AppEngInternalInventory && output instanceof AppEngInternalInventory) {
for (int x = 0; x < crafting.getSizeInventory() && x < newCrafting.length; x++) {
final IAEItemStack item = newCrafting[x];
crafting.setInventorySlotContents(x, item == null ? null: item.getItemStack());
}
for (int x = 0; x < output.getSizeInventory() && x < newOutput.length; x++) {
final IAEItemStack item = newOutput[x];
output.setInventorySlotContents(x, item == null ? null : item.getItemStack());
}
}
}
@Override
public IInventory getInventoryByName( final String name )
{
if( name.equals( "crafting" ) )
{
return this.crafting;
}
if( name.equals( "output" ) )
{
return this.output;
}
if( name.equals( "pattern" ) )
{
return this.pattern;
}
return super.getInventoryByName( name );
}
@Override
public FCPartsTexture getFrontBright() {
return FRONT_BRIGHT_ICON;
}
@Override
public FCPartsTexture getFrontColored() {
return FRONT_COLORED_ICON;
}
@Override
public FCPartsTexture getFrontDark() {
return FRONT_DARK_ICON;
}
@Override
public boolean isLightSource() {
return false;
}
}
@@ -0,0 +1,295 @@
package com.glodblock.github.common.tile;
import appeng.api.config.Actionable;
import appeng.api.networking.GridFlags;
import appeng.api.networking.crafting.ICraftingGrid;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.events.*;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.networking.security.MachineSource;
import appeng.api.networking.storage.IBaseMonitor;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.storage.*;
import appeng.api.storage.data.IAEFluidStack;
import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
import appeng.helpers.IPriorityHost;
import appeng.me.GridAccessException;
import appeng.me.cache.CraftingGridCache;
import appeng.me.storage.MEInventoryHandler;
import appeng.tile.grid.AENetworkTile;
import appeng.util.Platform;
import com.glodblock.github.common.item.ItemFluidDrop;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class TileFluidDiscretizer extends AENetworkTile implements IPriorityHost, ICellContainer {
private final BaseActionSource ownActionSource = new MachineSource(this);
private final FluidDiscretizingInventory fluidDropInv = new FluidDiscretizingInventory();
private final FluidCraftingInventory fluidCraftInv = new FluidCraftingInventory();
private boolean prevActiveState = false;
public TileFluidDiscretizer() {
super();
getProxy().setIdlePowerUsage(3D);
getProxy().setFlags(GridFlags.REQUIRE_CHANNEL);
}
@Override
public boolean canBeRotated() {
return false;
//based
}
@Override
@SuppressWarnings("rawtypes")
public List<IMEInventoryHandler> getCellArray(StorageChannel channel) {
/*conflict = !checkDiscreatizer();
if (conflict) return Collections.emptyList();*/
if (getProxy().isActive()) {
if (channel == StorageChannel.ITEMS) {
return Collections.singletonList(fluidDropInv.invHandler);
} else if (channel == StorageChannel.FLUIDS) {
return Collections.singletonList(fluidCraftInv.invHandler);
}
}
return Collections.emptyList();
}
@Override
public int getPriority() {
return Integer.MAX_VALUE;
}
@Override
public void setPriority(int newValue) {
//do nothing
}
@Override
public void blinkCell(int slot) {
//do nothing
}
@Override
public void gridChanged() {
IMEMonitor<IAEFluidStack> fluidGrid = getFluidGrid();
if (fluidGrid != null) {
fluidGrid.addListener(fluidDropInv, fluidGrid);
}
}
@Override
public void saveChanges(IMEInventory cellInventory) {
markDirty();
}
private IMEMonitor<IAEFluidStack> getFluidGrid() {
try {
return getProxy().getGrid().<IStorageGrid>getCache(IStorageGrid.class).getFluidInventory();
} catch (GridAccessException e) {
return null;
}
}
private IEnergyGrid getEnergyGrid() {
try {
return getProxy().getGrid().getCache(IEnergyGrid.class);
} catch (GridAccessException e) {
return null;
}
}
private void updateState() {
boolean isActive = getProxy().isActive();
if (isActive != prevActiveState) {
prevActiveState = isActive;
try {
getProxy().getGrid().postEvent(new MENetworkCellArrayUpdate());
} catch (GridAccessException e) {
// NO-OP
}
}
}
@MENetworkEventSubscribe
public void onPowerUpdate(MENetworkPowerStatusChange event) {
updateState();
}
@MENetworkEventSubscribe
public void onChannelUpdate(MENetworkChannelsChanged event) {
updateState();
}
@MENetworkEventSubscribe
public void onStorageUpdate(MENetworkStorageEvent event) {
updateState();
}
private boolean checkDiscreatizer() {
int amount = getProxy().getNode().getGrid().getMachines(this.getClass()).size();
return amount <= 1;
}
private class FluidDiscretizingInventory implements IMEInventory<IAEItemStack>, IMEMonitorHandlerReceiver<IAEFluidStack> {
private final MEInventoryHandler<IAEItemStack> invHandler = new MEInventoryHandler<>(this, getChannel());
private List<IAEItemStack> itemCache = null;
FluidDiscretizingInventory() {
invHandler.setPriority(Integer.MAX_VALUE);
}
@Override
public IAEItemStack injectItems(IAEItemStack request, Actionable type, BaseActionSource src) {
/*if (conflict) return request;*/
IAEFluidStack fluidStack = ItemFluidDrop.getAeFluidStack(request);
if (fluidStack == null) {
return request;
}
IMEMonitor<IAEFluidStack> fluidGrid = getFluidGrid();
if (fluidGrid == null) {
return request;
}
IEnergyGrid energyGrid = getEnergyGrid();
if (energyGrid == null) {
return request;
}
if (type == Actionable.SIMULATE) {
return ItemFluidDrop.newAeStack(fluidGrid.injectItems(fluidStack.copy(), Actionable.SIMULATE, src));
}
else {
return ItemFluidDrop.newAeStack(Platform.poweredInsert(energyGrid, fluidGrid, fluidStack, ownActionSource));
}
}
@Override
public IAEItemStack extractItems(IAEItemStack request, Actionable mode, BaseActionSource src) {
/*if (conflict) return null;*/
IAEFluidStack fluidStack = ItemFluidDrop.getAeFluidStack(request);
if (fluidStack == null) {
return null;
}
IMEMonitor<IAEFluidStack> fluidGrid = getFluidGrid();
if (fluidGrid == null) {
return null;
}
IEnergyGrid energyGrid = getEnergyGrid();
if (energyGrid == null) {
return null;
}
if (mode == Actionable.SIMULATE) {
return ItemFluidDrop.newAeStack(fluidGrid.extractItems(fluidStack.copy(), Actionable.SIMULATE, src));
}
else {
return ItemFluidDrop.newAeStack(Platform.poweredExtraction(energyGrid, fluidGrid, fluidStack, ownActionSource));
}
}
@Override
public IItemList<IAEItemStack> getAvailableItems(IItemList<IAEItemStack> out) {
/*if (conflict) return out;*/
if (itemCache == null) {
itemCache = new ArrayList<>();
IMEMonitor<IAEFluidStack> fluidGrid = getFluidGrid();
if (fluidGrid != null) {
for (IAEFluidStack fluid : fluidGrid.getStorageList()) {
IAEItemStack stack = ItemFluidDrop.newAeStack(fluid);
if (stack != null) {
itemCache.add(stack);
}
}
}
}
for (IAEItemStack stack : itemCache) {
out.addStorage(stack);
}
return out;
}
@Override
public StorageChannel getChannel() {
return StorageChannel.ITEMS;
}
@Override
public boolean isValid(Object verificationToken) {
IMEMonitor<IAEFluidStack> fluidGrid = getFluidGrid();
return fluidGrid != null && fluidGrid == verificationToken /*&& !conflict*/;
}
@Override
public void postChange(IBaseMonitor<IAEFluidStack> monitor, Iterable<IAEFluidStack> change, BaseActionSource actionSource) {
itemCache = null;
try {
List<IAEItemStack> mappedChanges = new ArrayList<>();
for (IAEFluidStack fluidStack : change) {
IAEItemStack itemStack = ItemFluidDrop.newAeStack(fluidStack);
if (itemStack != null) {
mappedChanges.add(itemStack);
}
}
getProxy().getGrid().<IStorageGrid>getCache(IStorageGrid.class)
.postAlterationOfStoredItems(getChannel(), mappedChanges, ownActionSource);
} catch (GridAccessException e) {
// NO-OP
}
}
@Override
public void onListUpdate() {
// NO-OP
}
}
private class FluidCraftingInventory implements IMEInventory<IAEFluidStack> {
private final MEInventoryHandler<IAEFluidStack> invHandler = new MEInventoryHandler<>(this, getChannel());
FluidCraftingInventory() {
invHandler.setPriority(Integer.MAX_VALUE);
}
@Override
@SuppressWarnings("rawtypes")
public IAEFluidStack injectItems(IAEFluidStack input, Actionable type, BaseActionSource src) {
/*if (conflict) return null;*/
ICraftingGrid craftingGrid;
try {
craftingGrid = getProxy().getGrid().getCache(ICraftingGrid.class);
} catch (GridAccessException e) {
return null;
}
if (craftingGrid instanceof CraftingGridCache) {
IAEStack remaining = ((CraftingGridCache)craftingGrid).injectItems(
ItemFluidDrop.newAeStack(input), type, ownActionSource);
if (remaining instanceof IAEItemStack) {
return ItemFluidDrop.getAeFluidStack((IAEItemStack) remaining);
}
}
return null;
}
@Override
public IAEFluidStack extractItems(IAEFluidStack request, Actionable mode, BaseActionSource src) {
return null;
}
@Override
public IItemList<IAEFluidStack> getAvailableItems(IItemList<IAEFluidStack> out) {
return out;
}
@Override
public StorageChannel getChannel() {
return StorageChannel.FLUIDS;
}
}
}
@@ -0,0 +1,81 @@
package com.glodblock.github.common.tile;
import appeng.api.config.Actionable;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.networking.security.MachineSource;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.data.IAEFluidStack;
import appeng.me.GridAccessException;
import appeng.tile.misc.TileInterface;
import appeng.util.Platform;
import appeng.util.item.AEFluidStack;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;
public class TileFluidInterface extends TileInterface implements IFluidHandler
{
private final BaseActionSource ownActionSource = new MachineSource(this);
private IMEMonitor<IAEFluidStack> getFluidGrid() {
try {
return getProxy().getGrid().<IStorageGrid>getCache(IStorageGrid.class).getFluidInventory();
} catch (GridAccessException e) {
return null;
}
}
private IEnergyGrid getEnergyGrid() {
try {
return getProxy().getGrid().getCache(IEnergyGrid.class);
} catch (GridAccessException e) {
return null;
}
}
@Override
public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
IMEMonitor<IAEFluidStack> fluidGrid = getFluidGrid();
IEnergyGrid energyGrid = getEnergyGrid();
if (energyGrid == null || fluidGrid == null || resource == null)
return 0;
int ori = resource.amount;
IAEFluidStack remove;
if (doFill) {
remove = Platform.poweredInsert(energyGrid, fluidGrid, AEFluidStack.create(resource), ownActionSource);
} else {
remove = fluidGrid.injectItems(AEFluidStack.create(resource), Actionable.SIMULATE, ownActionSource);
}
return remove == null ? ori : (int) (ori - remove.getStackSize());
}
@Override
public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) {
return null;
}
@Override
public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) {
return null;
}
@Override
public boolean canFill(ForgeDirection from, Fluid fluid) {
return true;
}
@Override
public boolean canDrain(ForgeDirection from, Fluid fluid) {
return false;
}
@Override
public FluidTankInfo[] getTankInfo(ForgeDirection from) {
return new FluidTankInfo[]{new FluidTankInfo(null, 0)};
}
}
@@ -0,0 +1,102 @@
package com.glodblock.github.common.tile;
import appeng.api.networking.GridFlags;
import appeng.api.networking.IGridNode;
import appeng.api.networking.energy.IEnergyGrid;
import appeng.api.networking.security.BaseActionSource;
import appeng.api.networking.security.MachineSource;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.networking.ticking.IGridTickable;
import appeng.api.networking.ticking.TickRateModulation;
import appeng.api.networking.ticking.TickingRequest;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.data.IAEFluidStack;
import appeng.helpers.Reflected;
import appeng.me.GridAccessException;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.grid.AENetworkTile;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.IAEAppEngInventory;
import appeng.tile.inventory.InvOperation;
import appeng.util.Platform;
import appeng.util.item.AEFluidStack;
import com.glodblock.github.common.item.ItemFluidPacket;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fluids.FluidStack;
public class TileFluidPacketDecoder extends AENetworkTile implements IGridTickable, IAEAppEngInventory {
private final AppEngInternalInventory inventory = new AppEngInternalInventory(this, 1);
private final BaseActionSource ownActionSource = new MachineSource(this);
@Reflected
public TileFluidPacketDecoder() {
getProxy().setIdlePowerUsage(1D);
getProxy().setFlags(GridFlags.REQUIRE_CHANNEL);
}
public IInventory getInventory() {
return inventory;
}
@Override
public boolean canBeRotated() {
return false;
}
@Override
public TickingRequest getTickingRequest(IGridNode node) {
return new TickingRequest(5, 120, false, true);
}
@Override
public TickRateModulation tickingRequest(IGridNode node, int ticksSinceLastCall) {
ItemStack stack = inventory.getStackInSlot(0);
if (stack == null || !(stack.getItem() instanceof ItemFluidPacket)) {
return TickRateModulation.SLEEP;
}
FluidStack fluid = ItemFluidPacket.getFluidStack(stack);
if (fluid == null || fluid.amount <= 0) {
inventory.setInventorySlotContents(0, null);
return TickRateModulation.SLEEP;
}
IAEFluidStack aeFluid = AEFluidStack.create(fluid);
IEnergyGrid energyGrid = node.getGrid().getCache(IEnergyGrid.class);
IMEMonitor<IAEFluidStack> fluidGrid = node.getGrid().<IStorageGrid>getCache(IStorageGrid.class).getFluidInventory();
IAEFluidStack remaining = Platform.poweredInsert(energyGrid, fluidGrid, aeFluid, ownActionSource);
if (remaining != null) {
if (remaining.getStackSize() == aeFluid.getStackSize()) {
return TickRateModulation.SLOWER;
}
inventory.setInventorySlotContents(0, ItemFluidPacket.newStack(remaining.getFluidStack()));
return TickRateModulation.FASTER;
} else {
inventory.setInventorySlotContents(0, null);
return TickRateModulation.SLEEP;
}
}
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removedStack, ItemStack newStack) {
try {
getProxy().getTick().alertDevice(getProxy().getNode());
} catch (GridAccessException e) {
// NO-OP
}
}
@TileEvent( TileEventType.WORLD_NBT_WRITE )
public NBTTagCompound writeToNBTEvent(NBTTagCompound data) {
inventory.writeToNBT(data, "Inventory");
return data;
}
@TileEvent( TileEventType.WORLD_NBT_READ )
public void readFromNBTEvent(NBTTagCompound data) {
inventory.readFromNBT(data, "Inventory");
}
}
@@ -0,0 +1,77 @@
package com.glodblock.github.common.tile;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.tile.AEBaseTile;
import appeng.tile.TileEvent;
import appeng.tile.events.TileEventType;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.inventory.IAEAppEngInventory;
import appeng.tile.inventory.InvOperation;
import com.glodblock.github.inventory.AeStackInventory;
import com.glodblock.github.inventory.AeStackInventoryImpl;
import com.glodblock.github.util.BlockPos;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import java.util.List;
public class TileFluidPatternEncoder extends AEBaseTile implements IAEAppEngInventory {
private final AppEngInternalInventory patternInv = new AppEngInternalInventory(this, 2);
private final AeStackInventoryImpl<IAEItemStack> crafting = new AeStackInventoryImpl<>(StorageChannel.ITEMS, 9, this);
private final AeStackInventoryImpl<IAEItemStack> output = new AeStackInventoryImpl<>(StorageChannel.ITEMS, 3, this);
public IInventory getInventory() {
return patternInv;
}
public AeStackInventory<IAEItemStack> getCraftingSlots() {
return crafting;
}
public AeStackInventory<IAEItemStack> getOutputSlots() {
return output;
}
@Override
public boolean canBeRotated() {
return false;
}
@Override
public void getDrops(final World w, final int x, final int y, final int z, final List<ItemStack> drops ) {
getDrops(w, new BlockPos(x, y, z), drops);
}
public void getDrops(World world, BlockPos pos, List<ItemStack> drops) {
for (ItemStack stack : patternInv) {
if (stack != null) {
drops.add(stack);
}
}
}
@TileEvent( TileEventType.WORLD_NBT_READ )
public void readFromNBTEvent(NBTTagCompound data) {
patternInv.readFromNBT(data, "Inventory");
crafting.readFromNbt(data, "CraftingSlots");
output.readFromNbt(data, "OutputSlots");
}
@TileEvent( TileEventType.WORLD_NBT_WRITE )
public NBTTagCompound writeToNBTEvent(NBTTagCompound data) {
patternInv.writeToNBT(data, "Inventory");
crafting.writeToNbt(data, "CraftingSlots");
output.writeToNbt(data, "OutputSlots");
return data;
}
@Override
public void onChangeInventory(IInventory inv, int slot, InvOperation mc, ItemStack removedStack, ItemStack newStack) {
}
}
@@ -0,0 +1,59 @@
package com.glodblock.github.coremod;
import com.glodblock.github.coremod.transform.CraftingCpuTransformer;
import com.glodblock.github.coremod.transform.CraftingTreeNodeTransformer;
import com.glodblock.github.coremod.transform.DualityInterfaceTransformer;
import net.minecraft.launchwrapper.IClassTransformer;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
public class FCClassTransformer implements IClassTransformer {
@Override
public byte[] transform(String name, String transformedName, byte[] code) {
Transform tform;
switch (transformedName) {
case "appeng.crafting.CraftingTreeNode":
tform = CraftingTreeNodeTransformer.INSTANCE;
break;
case "appeng.me.cluster.implementations.CraftingCPUCluster":
tform = CraftingCpuTransformer.INSTANCE;
break;
case "appeng.helpers.DualityInterface":
tform = DualityInterfaceTransformer.INSTANCE;
break;
/*case "appeng.container.implementations.ContainerInterfaceTerminal":
tform = ContainerInterfaceTerminalTransformer.INSTANCE;
break;*/ //unfinished
default:
return code;
}
System.out.println("[FCAE2] Transforming class: " + transformedName);
return tform.transformClass(code);
}
public interface Transform {
byte[] transformClass(byte[] code);
}
public static abstract class ClassMapper implements Transform {
@Override
public byte[] transformClass(byte[] code) {
ClassReader reader = new ClassReader(code);
ClassWriter writer = new ClassWriter(reader, getWriteFlags());
reader.accept(getClassMapper(writer), 0);
return writer.toByteArray();
}
protected int getWriteFlags() {
return 0;
}
protected abstract ClassVisitor getClassMapper(ClassVisitor downstream);
}
}
@@ -0,0 +1,40 @@
package com.glodblock.github.coremod;
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
import javax.annotation.Nullable;
import java.util.Map;
@IFMLLoadingPlugin.MCVersion("1.7.10")
@IFMLLoadingPlugin.TransformerExclusions("com.glodblock.github.coremod")
public class FluidCraftCore implements IFMLLoadingPlugin {
@Override
public String[] getASMTransformerClass() {
return new String[] { FluidCraftCore.class.getPackage().getName() + ".FCClassTransformer" };
}
@Nullable
@Override
public String getModContainerClass() {
return null;
}
@Nullable
@Override
public String getSetupClass() {
return null;
}
@Override
public void injectData(Map<String, Object> data) {
// NO-OP
}
@Nullable
@Override
public String getAccessTransformerClass() {
return null;
}
}
@@ -0,0 +1,87 @@
package com.glodblock.github.coremod.hooker;
import appeng.api.networking.IGridNode;
import appeng.api.networking.IMachineSet;
import appeng.api.storage.data.IAEItemStack;
import appeng.me.MachineSet;
import appeng.tile.misc.TileInterface;
import appeng.util.InventoryAdaptor;
import com.glodblock.github.common.item.ItemFluidDrop;
import com.glodblock.github.common.item.ItemFluidPacket;
import com.glodblock.github.inventory.FluidConvertingInventoryAdaptor;
import com.glodblock.github.inventory.FluidConvertingInventoryCrafting;
import com.glodblock.github.loader.ItemAndBlockHolder;
import com.glodblock.github.util.Ae2Reflect;
import com.glodblock.github.util.SetBackedMachineSet;
import com.glodblock.github.util.Util;
import com.google.common.collect.Sets;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.util.ForgeDirection;
import javax.annotation.Nullable;
import java.util.HashSet;
import java.util.Set;
public class CoreModHooks {
public static InventoryCrafting wrapCraftingBuffer(InventoryCrafting inv) {
return new FluidConvertingInventoryCrafting(Ae2Reflect.getCraftContainer(inv), Ae2Reflect.getCraftWidth(inv), inv.getSizeInventory()/Ae2Reflect.getCraftWidth(inv));
}
public static IAEItemStack wrapFluidPacketStack(IAEItemStack stack) {
if (stack.getItem() == ItemAndBlockHolder.PACKET) {
IAEItemStack dropStack = ItemFluidDrop.newAeStack(ItemFluidPacket.getFluidStack(stack.getItemStack()));
if (dropStack != null) {
return dropStack;
}
}
return stack;
}
@Nullable
public static InventoryAdaptor wrapInventory(@Nullable TileEntity tile, ForgeDirection face) {
return tile != null ? FluidConvertingInventoryAdaptor.wrap(tile, Util.from(face)) : null;
}
public static long getCraftingByteCost(IAEItemStack stack) {
return stack.getItem() instanceof ItemFluidDrop
? (long)Math.ceil(stack.getStackSize() / 1000D) : stack.getStackSize();
}
public static IAEItemStack[] flattenFluidPackets(IAEItemStack[] stacks) {
for (int i = 0; i < stacks.length; i++) {
if (stacks[i].getItem() instanceof ItemFluidPacket) {
stacks[i] = ItemFluidDrop.newAeStack(ItemFluidPacket.getFluidStack(stacks[i]));
}
}
return stacks;
}
/*public static IMachineSet getMachines(IGrid grid, Class<? extends IGridHost> c) {
if (c == TileInterface.class) {
return unionMachineSets(grid.getMachines(c), grid.getMachines(TileDualInterface.class));
} else if (c == PartInterface.class) {
return unionMachineSets(grid.getMachines(c), grid.getMachines(PartDualInterface.class));
} else {
return grid.getMachines(c);
}
}*/ //unfinished
private static IMachineSet unionMachineSets(IMachineSet a, IMachineSet b) {
if (a.isEmpty()) {
return b;
} else if (b.isEmpty()) {
return a;
} else if (a instanceof MachineSet && b instanceof MachineSet) {
return new SetBackedMachineSet(TileInterface.class, Sets.union((MachineSet)a, (MachineSet)b));
} else {
Set<IGridNode> union = new HashSet<>();
a.forEach(union::add);
b.forEach(union::add);
return new SetBackedMachineSet(TileInterface.class, union);
}
}
}
@@ -0,0 +1,58 @@
package com.glodblock.github.coremod.transform;
import com.glodblock.github.coremod.FCClassTransformer;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class ContainerInterfaceTerminalTransformer extends FCClassTransformer.ClassMapper {
public static final ContainerInterfaceTerminalTransformer INSTANCE = new ContainerInterfaceTerminalTransformer();
private ContainerInterfaceTerminalTransformer() {
// NO-OP
}
@Override
protected ClassVisitor getClassMapper(ClassVisitor downstream) {
return new TransformContainerInterfaceTerminal(Opcodes.ASM5, downstream);
}
private static class TransformContainerInterfaceTerminal extends ClassVisitor {
TransformContainerInterfaceTerminal(int api, ClassVisitor cv) {
super(api, cv);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
if (name.equals("detectAndSendChanges") || name.equals("func_75142_b") || name.equals("regenList")) {
return new TransformDetectAndSendChanges(api, super.visitMethod(access, name, desc, signature, exceptions));
}
return super.visitMethod(access, name, desc, signature, exceptions);
}
}
private static class TransformDetectAndSendChanges extends MethodVisitor {
TransformDetectAndSendChanges(int api, MethodVisitor mv) {
super(api, mv);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
if (opcode == Opcodes.INVOKEINTERFACE
&& owner.equals("appeng/api/networking/IGrid") && name.equals("getMachines")) {
super.visitMethodInsn(Opcodes.INVOKESTATIC,
"com/glodblock/github/coremod/hooker/CoreModHooks",
"getMachines",
"(Lappeng/api/networking/IGrid;Ljava/lang/Class;)Lappeng/api/networking/IMachineSet;",
false);
} else {
super.visitMethodInsn(opcode, owner, name, desc, itf);
}
}
}
}
@@ -0,0 +1,86 @@
package com.glodblock.github.coremod.transform;
import com.glodblock.github.coremod.FCClassTransformer;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class CraftingCpuTransformer extends FCClassTransformer.ClassMapper {
public static final CraftingCpuTransformer INSTANCE = new CraftingCpuTransformer();
private CraftingCpuTransformer() {
// NO-OP
}
@Override
protected ClassVisitor getClassMapper(ClassVisitor downstream) {
return new TransformCraftingCPUCluster(Opcodes.ASM5, downstream);
}
private static class TransformCraftingCPUCluster extends ClassVisitor {
TransformCraftingCPUCluster(int api, ClassVisitor cv) {
super(api, cv);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
if (name.equals("executeCrafting")) {
return new TransformExecuteCrafting(api, super.visitMethod(access, name, desc, signature, exceptions));
}
return super.visitMethod(access, name, desc, signature, exceptions);
}
}
private static class TransformExecuteCrafting extends MethodVisitor {
private boolean gotInventory = false;
TransformExecuteCrafting(int api, MethodVisitor mv) {
super(api, mv);
}
@Override
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
if (opcode == Opcodes.GETFIELD
&& owner.equals("appeng/me/cluster/implementations/CraftingCPUCluster") && name.equals("inventory")) {
gotInventory = true;
}
super.visitFieldInsn(opcode, owner, name, desc);
}
@Override
public void visitLineNumber(int line, Label start) {
gotInventory = false;
super.visitLineNumber(line, start);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
super.visitMethodInsn(opcode, owner, name, desc, itf);
if (gotInventory) {
if (opcode == Opcodes.INVOKESTATIC
&& owner.equals("appeng/util/item/AEItemStack") && name.equals("create")) {
gotInventory = false;
super.visitMethodInsn(Opcodes.INVOKESTATIC,
"com/glodblock/github/coremod/hooker/CoreModHooks",
"wrapFluidPacketStack",
"(Lappeng/api/storage/data/IAEItemStack;)Lappeng/api/storage/data/IAEItemStack;",
false);
}
} else if (opcode == Opcodes.INVOKESPECIAL
&& owner.equals("net/minecraft/inventory/InventoryCrafting") && name.equals("<init>")) {
super.visitMethodInsn(Opcodes.INVOKESTATIC,
"com/glodblock/github/coremod/hooker/CoreModHooks",
"wrapCraftingBuffer",
"(Lnet/minecraft/inventory/InventoryCrafting;)Lnet/minecraft/inventory/InventoryCrafting;",
false);
}
}
}
}
@@ -0,0 +1,77 @@
package com.glodblock.github.coremod.transform;
import com.glodblock.github.coremod.FCClassTransformer;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class CraftingTreeNodeTransformer extends FCClassTransformer.ClassMapper {
public static final CraftingTreeNodeTransformer INSTANCE = new CraftingTreeNodeTransformer();
private CraftingTreeNodeTransformer() {
// NO-OP
}
@Override
protected ClassVisitor getClassMapper(ClassVisitor downstream) {
return new TransformCraftingTreeNode(Opcodes.ASM5, downstream);
}
private static class TransformCraftingTreeNode extends ClassVisitor {
TransformCraftingTreeNode(int api, ClassVisitor cv) {
super(api, cv);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
if (name.equals("request")) {
return new TransformRequest(api, super.visitMethod(access, name, desc, signature, exceptions));
}
return super.visitMethod(access, name, desc, signature, exceptions);
}
}
private static class TransformRequest extends MethodVisitor {
private boolean writingBytes = false;
TransformRequest(int api, MethodVisitor mv) {
super(api, mv);
}
@Override
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
if (opcode == Opcodes.GETFIELD && owner.equals("appeng/crafting/CraftingTreeNode") && name.equals("bytes")) {
writingBytes = true;
}
super.visitFieldInsn(opcode, owner, name, desc);
}
@Override
public void visitLineNumber(int line, Label start) {
writingBytes = false; // no write here
super.visitLineNumber(line, start);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
if (writingBytes && opcode == Opcodes.INVOKEINTERFACE
&& owner.equals("appeng/api/storage/data/IAEItemStack") && name.equals("getStackSize")) {
writingBytes = false;
super.visitMethodInsn(Opcodes.INVOKESTATIC,
"com/glodblock/github/coremod/hooker/CoreModHooks",
"getCraftingByteCost",
"(Lappeng/api/storage/data/IAEItemStack;)J",
false);
} else {
super.visitMethodInsn(opcode, owner, name, desc, itf);
}
}
}
}
@@ -0,0 +1,62 @@
package com.glodblock.github.coremod.transform;
import com.glodblock.github.coremod.FCClassTransformer;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class DualityInterfaceTransformer extends FCClassTransformer.ClassMapper {
public static final DualityInterfaceTransformer INSTANCE = new DualityInterfaceTransformer();
private DualityInterfaceTransformer() {
// NO-OP
}
@Override
protected ClassVisitor getClassMapper(ClassVisitor downstream) {
return new TransformDualityInterface(Opcodes.ASM5, downstream);
}
private static class TransformDualityInterface extends ClassVisitor {
TransformDualityInterface(int api, ClassVisitor cv) {
super(api, cv);
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
switch (name) {
case "pushItemsOut":
case "pushPattern":
case "isBusy":
return new TransformInvAdaptorCalls(api, super.visitMethod(access, name, desc, signature, exceptions));
default:
return super.visitMethod(access, name, desc, signature, exceptions);
}
}
}
private static class TransformInvAdaptorCalls extends MethodVisitor {
TransformInvAdaptorCalls(int api, MethodVisitor mv) {
super(api, mv);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
if (opcode == Opcodes.INVOKESTATIC && owner.equals("appeng/util/InventoryAdaptor") && name.equals("getAdaptor")) {
super.visitMethodInsn(Opcodes.INVOKESTATIC,
"com/glodblock/github/coremod/hooker/CoreModHooks",
"wrapInventory",
"(Lnet/minecraft/tileentity/TileEntity;Lnet/minecraftforge/common/util/ForgeDirection;)Lappeng/util/InventoryAdaptor;",
false);
} else {
super.visitMethodInsn(opcode, owner, name, desc, itf);
}
}
}
}
@@ -0,0 +1,411 @@
package com.glodblock.github.inventory;
import appeng.api.storage.data.IAEFluidStack;
import appeng.core.AELog;
import appeng.util.Platform;
import appeng.util.item.AEFluidStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidTank;
import java.util.Objects;
public class AEFluidInventory implements IAEFluidTank
{
private final IAEFluidStack[] fluids;
private final IAEFluidInventory handler;
private final int capacity;
private FluidTankInfo[] props = null;
public AEFluidInventory( final IAEFluidInventory handler, final int slots, final int capcity )
{
this.fluids = new IAEFluidStack[slots];
this.handler = handler;
this.capacity = capcity;
}
public AEFluidInventory( final IAEFluidInventory handler, final int slots )
{
this( handler, slots, Integer.MAX_VALUE );
}
@Override
public void setFluidInSlot( final int slot, final IAEFluidStack fluid )
{
if( slot >= 0 && slot < this.getSlots() )
{
if( Objects.equals( this.fluids[slot], fluid ) )
{
if( fluid != null && fluid.getStackSize() != this.fluids[slot].getStackSize() )
{
this.fluids[slot].setStackSize( Math.min( fluid.getStackSize(), this.capacity ) );
this.onContentChanged( slot );
}
}
else
{
if( fluid == null )
{
this.fluids[slot] = null;
}
else
{
this.fluids[slot] = fluid.copy();
this.fluids[slot].setStackSize( Math.min( fluid.getStackSize(), this.capacity ) );
}
this.onContentChanged( slot );
}
}
}
private void onContentChanged( final int slot )
{
if( this.handler != null && Platform.isServer() )
{
this.handler.onFluidInventoryChanged( this, slot );
}
}
@Override
public IAEFluidStack getFluidInSlot( final int slot )
{
if( slot >= 0 && slot < this.getSlots() )
{
return this.fluids[slot];
}
return null;
}
@Override
public int getSlots()
{
return this.fluids.length;
}
@Override
public FluidTankInfo[] getTankInfo(ForgeDirection from)
{
if( this.props == null )
{
this.props = new FluidTankInfo[this.getSlots()];
for( int i = 0; i < this.getSlots(); ++i )
{
this.props[i] = new FluidTankInfo(new FluidTankPropertiesWrapper( i ));
}
}
return this.props;
}
public int fill( final int slot, final FluidStack resource, final boolean doFill )
{
if( resource == null || resource.amount <= 0 )
{
return 0;
}
final IAEFluidStack fluid = this.fluids[slot];
if( fluid != null && !fluid.getFluidStack().isFluidEqual( resource ) )
{
return 0;
}
int amountToStore = this.capacity;
if( fluid != null )
{
amountToStore -= fluid.getStackSize();
}
amountToStore = Math.min( amountToStore, resource.amount );
if( doFill )
{
if( fluid == null )
{
this.setFluidInSlot( slot, AEFluidStack.create( resource ) );
}
else
{
fluid.setStackSize( fluid.getStackSize() + amountToStore );
this.onContentChanged( slot );
}
}
return amountToStore;
}
public FluidStack drain( final int slot, final FluidStack resource, final boolean doDrain )
{
final IAEFluidStack fluid = this.fluids[slot];
if(fluid == null || !fluid.getFluidStack().equals(resource))
{
return null;
}
return this.drain( slot, resource.amount, doDrain );
}
public FluidStack drain( final int slot, final int maxDrain, boolean doDrain )
{
final IAEFluidStack fluid = this.fluids[slot];
if( fluid == null || maxDrain <= 0 )
{
return null;
}
int drained = maxDrain;
if( fluid.getStackSize() < drained )
{
drained = (int) fluid.getStackSize();
}
FluidStack stack = new FluidStack( fluid.getFluid(), drained );
if( doDrain )
{
fluid.setStackSize( fluid.getStackSize() - drained );
if( fluid.getStackSize() <= 0 )
{
this.fluids[slot] = null;
}
this.onContentChanged( slot );
}
return stack;
}
@Override
public int fill(ForgeDirection from, final FluidStack fluid, final boolean doFill )
{
if( fluid == null || fluid.amount <= 0 )
{
return 0;
}
final FluidStack insert = fluid.copy();
int totalFillAmount = 0;
for( int slot = 0; slot < this.getSlots(); ++slot )
{
int fillAmount = this.fill( slot, insert, doFill );
totalFillAmount += fillAmount;
insert.amount -= fillAmount;
if( insert.amount <= 0 )
{
break;
}
}
return totalFillAmount;
}
@Override
public FluidStack drain(ForgeDirection from, final FluidStack fluid, final boolean doDrain )
{
if( fluid == null || fluid.amount <= 0 )
{
return null;
}
final FluidStack resource = fluid.copy();
FluidStack totalDrained = null;
for( int slot = 0; slot < this.getSlots(); ++slot )
{
FluidStack drain = this.drain( slot, resource, doDrain );
if( drain != null )
{
if( totalDrained == null )
{
totalDrained = drain;
}
else
{
totalDrained.amount += drain.amount;
}
resource.amount -= drain.amount;
if( resource.amount <= 0 )
{
break;
}
}
}
return totalDrained;
}
@Override
public FluidStack drain( ForgeDirection from, final int maxDrain, final boolean doDrain )
{
if( maxDrain == 0 )
{
return null;
}
FluidStack totalDrained = null;
int toDrain = maxDrain;
for( int slot = 0; slot < this.getSlots(); ++slot )
{
if( totalDrained == null )
{
totalDrained = this.drain( slot, toDrain, doDrain );
if( totalDrained != null )
{
toDrain -= totalDrained.amount;
}
}
else
{
FluidStack copy = totalDrained.copy();
copy.amount = toDrain;
FluidStack drain = this.drain( slot, copy, doDrain );
if( drain != null )
{
totalDrained.amount += drain.amount;
toDrain -= drain.amount;
}
}
if( toDrain <= 0 )
{
break;
}
}
return totalDrained;
}
@Override
public boolean canFill(ForgeDirection from, Fluid fluid) {
return fill(from, new FluidStack(fluid, 1), false) == 1;
}
@Override
public boolean canDrain(ForgeDirection from, Fluid fluid) {
return drain(from, new FluidStack(fluid, 1), false) != null;
}
public void writeToNBT( final NBTTagCompound data, final String name )
{
final NBTTagCompound c = new NBTTagCompound();
this.writeToNBT( c );
data.setTag( name, c );
}
private void writeToNBT( final NBTTagCompound target )
{
for( int x = 0; x < this.fluids.length; x++ )
{
try
{
final NBTTagCompound c = new NBTTagCompound();
if( this.fluids[x] != null )
{
this.fluids[x].writeToNBT( c );
}
target.setTag( "#" + x, c );
}
catch( final Exception ignored )
{
}
}
}
public void readFromNBT( final NBTTagCompound data, final String name )
{
final NBTTagCompound c = data.getCompoundTag( name );
if( c != null )
{
this.readFromNBT( c );
}
}
private void readFromNBT( final NBTTagCompound target )
{
for( int x = 0; x < this.fluids.length; x++ )
{
try
{
final NBTTagCompound c = target.getCompoundTag( "#" + x );
if( c != null )
{
this.fluids[x] = AEFluidStack.loadFluidStackFromNBT( c );
}
}
catch( final Exception e )
{
AELog.debug( e );
}
}
}
private class FluidTankPropertiesWrapper implements IFluidTank
{
private final int slot;
public FluidTankPropertiesWrapper( final int slot )
{
this.slot = slot;
}
@Override
public FluidStack getFluid()
{
return AEFluidInventory.this.fluids[this.slot] == null ? null : AEFluidInventory.this.fluids[this.slot].getFluidStack();
}
@Override
public int getFluidAmount() {
return getFluid() == null ? 0 : getFluid().amount;
}
@Override
public int getCapacity()
{
return Math.min( AEFluidInventory.this.capacity, Integer.MAX_VALUE );
}
@Override
public FluidTankInfo getInfo() {
return null;
}
@Override
public int fill(FluidStack resource, boolean doFill) {
if (resource == null || (getFluid() != null && !resource.equals(getFluid()))) return 0;
int acc = 0;
if (getFluid() == null) {
acc = Math.min(resource.amount, getCapacity());
}
if (getFluid() != null) {
acc = Math.max(resource.amount, getCapacity() - getFluid().amount);
}
if (doFill) {
if (getFluid() == null)
AEFluidInventory.this.setFluidInSlot(this.slot, AEFluidStack.create(new FluidStack(resource.getFluid(), acc)));
else getFluid().amount += acc;
}
return acc;
}
@Override
public FluidStack drain(int maxDrain, boolean doDrain) {
if (getFluid() == null) return null;
FluidStack remove = new FluidStack(getFluid().getFluid(), 1);
int amt = Math.min(maxDrain, getFluid().amount);
remove.amount = amt;
if (doDrain) {
if (amt == getFluid().amount) {
AEFluidInventory.this.setFluidInSlot(this.slot, null);
}
else getFluid().amount -= amt;
}
return remove;
}
}
}
@@ -0,0 +1,90 @@
package com.glodblock.github.inventory;
import appeng.api.storage.data.IAEFluidStack;
import appeng.util.Platform;
import appeng.util.item.AEFluidStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTank;
import net.minecraftforge.fluids.FluidTankInfo;
public class AEFluidTank extends FluidTank implements IAEFluidTank
{
private final IAEFluidInventory host;
public AEFluidTank( IAEFluidInventory host, int capacity )
{
super( capacity );
this.host = host;
if( host instanceof TileEntity) {
this.tile = (TileEntity) host;
}
}
protected void onContentsChanged()
{
if( this.host != null && Platform.isServer() )
{
this.host.onFluidInventoryChanged( this, 0 );
}
}
@Override
public void setFluidInSlot( int slot, IAEFluidStack fluid )
{
if( slot == 0 )
{
this.setFluid( fluid == null ? null : fluid.getFluidStack() );
this.onContentsChanged();
}
}
@Override
public IAEFluidStack getFluidInSlot(int slot )
{
if( slot == 0 )
{
return AEFluidStack.create( this.getFluid() );
}
return null;
}
@Override
public int getSlots()
{
return 1;
}
@Override
public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
return super.fill(resource, doFill);
}
@Override
public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) {
if (resource == null || !resource.equals(this.getFluid())) return null;
return super.drain(resource.amount, doDrain);
}
@Override
public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) {
return super.drain(maxDrain, doDrain);
}
@Override
public boolean canFill(ForgeDirection from, Fluid fluid) {
return super.fill(new FluidStack(fluid, 1), false) == 1;
}
@Override
public boolean canDrain(ForgeDirection from, Fluid fluid) {
return drain(ForgeDirection.UNKNOWN, new FluidStack(fluid, 1), false) != null;
}
@Override
public FluidTankInfo[] getTankInfo(ForgeDirection from) {
return new FluidTankInfo[]{super.getInfo()};
}
}
@@ -0,0 +1,84 @@
package com.glodblock.github.inventory;
import appeng.api.storage.data.IAEItemStack;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
public class AeItemStackHandler implements IInventory {
private final AeStackInventory<IAEItemStack> inv;
public AeItemStackHandler(AeStackInventory<IAEItemStack> inv) {
this.inv = inv;
}
public AeStackInventory<IAEItemStack> getAeInventory() {
return inv;
}
@Override
public int getSizeInventory() {
return inv.getSlotCount();
}
public ItemStack getStackInSlot(int slot) {
IAEItemStack stack = inv.getStack(slot);
return stack != null ? stack.getItemStack() : null;
}
@Override
public ItemStack decrStackSize(int p_70298_1_, int p_70298_2_) {
return null;
}
@Override
public ItemStack getStackInSlotOnClosing(int p_70304_1_) {
return null;
}
@Override
public void setInventorySlotContents(int p_70299_1_, ItemStack p_70299_2_) {
}
@Override
public String getInventoryName() {
return "AeItemStackHandler";
}
@Override
public boolean hasCustomInventoryName() {
return false;
}
@Override
public int getInventoryStackLimit() {
return 64;
}
@Override
public void markDirty() {
}
@Override
public boolean isUseableByPlayer(EntityPlayer p_70300_1_) {
return false;
}
@Override
public void openInventory() {
}
@Override
public void closeInventory() {
}
@Override
public boolean isItemValidForSlot(int p_94041_1_, ItemStack p_94041_2_) {
return false;
}
}
@@ -0,0 +1,19 @@
package com.glodblock.github.inventory;
import appeng.api.storage.data.IAEStack;
import javax.annotation.Nullable;
import java.util.stream.Stream;
public interface AeStackInventory<T extends IAEStack<T>> extends Iterable<T> {
int getSlotCount();
@Nullable
T getStack(int slot);
void setStack(int slot, @Nullable T stack);
Stream<T> stream();
}
@@ -0,0 +1,102 @@
package com.glodblock.github.inventory;
import appeng.api.storage.StorageChannel;
import appeng.api.storage.data.IAEStack;
import appeng.tile.inventory.IAEAppEngInventory;
import appeng.util.item.AEFluidStack;
import appeng.util.item.AEItemStack;
import com.glodblock.github.util.ObjectArrayIterator;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraftforge.common.util.Constants;
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.Iterator;
import java.util.stream.Stream;
public class AeStackInventoryImpl <T extends IAEStack<T>> implements AeStackInventory<T> {
private final StorageChannel channel;
private final T[] inv;
private final IAEAppEngInventory owner;
@SuppressWarnings("unchecked")
public AeStackInventoryImpl(StorageChannel channel, int slotCount, @Nullable IAEAppEngInventory owner) {
this.channel = channel;
this.inv = (T[])new IAEStack[slotCount];
this.owner = owner;
}
public AeStackInventoryImpl(StorageChannel channel, int slotCount) {
this(channel, slotCount, null);
}
@Override
public int getSlotCount() {
return inv.length;
}
@Override
@Nullable
public T getStack(int slot) {
return inv[slot];
}
@Override
public void setStack(int slot, @Nullable T stack) {
inv[slot] = stack;
if (owner != null) {
owner.saveChanges();
}
}
@Override
public Iterator<T> iterator() {
return new ObjectArrayIterator<>(inv);
}
@Override
public Stream<T> stream() {
return Arrays.stream(inv);
}
public void writeToNbt(NBTTagCompound tag) {
NBTTagList stacksTag = new NBTTagList();
for (T stack : inv) {
if (stack == null) {
stacksTag.appendTag(new NBTTagCompound());
} else {
NBTTagCompound stackTag = new NBTTagCompound();
stack.writeToNBT(stackTag);
stacksTag.appendTag(stackTag);
}
}
tag.setTag("Contents", stacksTag);
}
public void writeToNbt(NBTTagCompound parentTag, String key) {
NBTTagCompound tag = new NBTTagCompound();
writeToNbt(tag);
parentTag.setTag(key, tag);
}
@SuppressWarnings("unchecked")
public void readFromNbt(NBTTagCompound tag) {
NBTTagList stacksTag = tag.getTagList("Contents", Constants.NBT.TAG_COMPOUND);
for (int i = 0; i < inv.length; i++) {
NBTTagCompound stackTag = stacksTag.getCompoundTagAt(i);
if (channel == StorageChannel.ITEMS) {
inv[i] = stackTag == null ? null : (T) AEItemStack.loadItemStackFromNBT(stackTag);
}
else {
inv[i] = stackTag == null ? null : (T) AEFluidStack.loadFluidStackFromNBT(stackTag);
}
}
}
public void readFromNbt(NBTTagCompound parentTag, String key) {
readFromNbt(parentTag.getCompoundTag(key));
}
}
@@ -0,0 +1,161 @@
package com.glodblock.github.inventory;
import appeng.api.config.FuzzyMode;
import appeng.util.InventoryAdaptor;
import appeng.util.inv.IInventoryDestination;
import appeng.util.inv.ItemSlot;
import com.glodblock.github.common.item.ItemFluidPacket;
import com.glodblock.github.common.tile.TileFluidInterface;
import com.glodblock.github.util.Ae2Reflect;
import com.glodblock.github.util.Util;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.util.ForgeDirection;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidTankInfo;
import net.minecraftforge.fluids.IFluidHandler;
import javax.annotation.Nullable;
import java.util.Collections;
import java.util.Iterator;
public class FluidConvertingInventoryAdaptor extends InventoryAdaptor {
public static InventoryAdaptor wrap(TileEntity capProvider, EnumFacing face) {
// sometimes i wish 1.7.10 has cap system.
ForgeDirection f = Util.from(face);
TileEntity inter = capProvider.getWorldObj().getTileEntity(capProvider.xCoord + f.offsetX, capProvider.yCoord + f.offsetY, capProvider.zCoord + f.offsetZ);
if (!(inter instanceof TileFluidInterface)) return InventoryAdaptor.getAdaptor(capProvider, f);
IInventory item = capProvider instanceof IInventory ? (IInventory) capProvider : null;
IFluidHandler fluid = capProvider instanceof IFluidHandler ? (IFluidHandler) capProvider : null;
return new FluidConvertingInventoryAdaptor(item, fluid, face);
}
private final InventoryAdaptor invItems;
private final IFluidHandler invFluids;
private final ForgeDirection side;
public FluidConvertingInventoryAdaptor(@Nullable IInventory invItems, @Nullable IFluidHandler invFluids, EnumFacing facing) {
this.invItems = invItems != null ? InventoryAdaptor.getAdaptor(invItems, Util.from(facing)) : null;
this.invFluids = invFluids;
this.side = Util.from(facing);
}
@Override
public ItemStack addItems(ItemStack toBeAdded) {
if (toBeAdded.getItem() instanceof ItemFluidPacket) {
if (invFluids != null) {
FluidStack fluid = ItemFluidPacket.getFluidStack(toBeAdded);
if (fluid != null) {
int filled = invFluids.fill(side, fluid, true);
if (filled > 0) {
fluid.amount -= filled;
return ItemFluidPacket.newStack(fluid);
}
}
}
return toBeAdded;
}
return invItems != null ? invItems.addItems(toBeAdded) : toBeAdded;
}
@Override
public ItemStack simulateAdd(ItemStack toBeSimulated) {
if (toBeSimulated.getItem() instanceof ItemFluidPacket) {
if (invFluids != null) {
FluidStack fluid = ItemFluidPacket.getFluidStack(toBeSimulated);
if (fluid != null) {
int filled = invFluids.fill(side, fluid, false);
if (filled > 0) {
fluid.amount -= filled;
return ItemFluidPacket.newStack(fluid);
}
}
}
return toBeSimulated;
}
return invItems != null ? invItems.simulateAdd(toBeSimulated) : toBeSimulated;
}
@Override
public ItemStack removeItems(int amount, ItemStack filter, IInventoryDestination destination) {
return invItems != null ? invItems.removeItems(amount, filter, destination) : null;
}
@Override
public ItemStack simulateRemove(int amount, ItemStack filter, IInventoryDestination destination) {
return invItems != null ? invItems.simulateRemove(amount, filter, destination) : null;
}
@Override
public ItemStack removeSimilarItems(int amount, ItemStack filter, FuzzyMode fuzzyMode, IInventoryDestination destination) {
return invItems != null ? invItems.removeSimilarItems(amount, filter, fuzzyMode, destination) : null;
}
@Override
public ItemStack simulateSimilarRemove(int amount, ItemStack filter, FuzzyMode fuzzyMode, IInventoryDestination destination) {
return invItems != null ? invItems.simulateSimilarRemove(amount, filter, fuzzyMode, destination) : null;
}
@Override
public boolean containsItems() {
if (invFluids != null) {
for (FluidTankInfo tank : invFluids.getTankInfo(side)) {
FluidStack fluid = tank.fluid;
if (fluid != null && fluid.amount > 0) {
return true;
}
}
}
return invItems != null && invItems.containsItems();
}
public boolean hasSlots() {
return (invFluids != null && invFluids.getTankInfo(side).length > 0)
|| (invItems != null);
}
@Override
public Iterator<ItemSlot> iterator() {
return new SlotIterator(
invFluids != null ? invFluids.getTankInfo(side) : new FluidTankInfo[0],
invItems != null ? invItems.iterator() : Collections.emptyIterator());
}
private static class SlotIterator implements Iterator<ItemSlot> {
private final FluidTankInfo[] tanks;
private final Iterator<ItemSlot> itemSlots;
private int nextSlotIndex = 0;
SlotIterator(FluidTankInfo[] tanks, Iterator<ItemSlot> itemSlots) {
this.tanks = tanks;
this.itemSlots = itemSlots;
}
@Override
public boolean hasNext() {
return nextSlotIndex < tanks.length || itemSlots.hasNext();
}
@Override
public ItemSlot next() {
if (nextSlotIndex < tanks.length) {
FluidStack fluid = tanks[nextSlotIndex].fluid;
ItemSlot slot = new ItemSlot();
slot.setSlot(nextSlotIndex++);
slot.setItemStack(fluid != null ? ItemFluidPacket.newStack(fluid) : null);
Ae2Reflect.setItemSlotExtractable(slot, false);
return slot;
} else {
ItemSlot slot = itemSlots.next();
slot.setSlot(nextSlotIndex++);
return slot;
}
}
}
}
@@ -0,0 +1,32 @@
package com.glodblock.github.inventory;
import com.glodblock.github.common.item.ItemFluidDrop;
import com.glodblock.github.common.item.ItemFluidPacket;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
public class FluidConvertingInventoryCrafting extends InventoryCrafting {
public FluidConvertingInventoryCrafting(Container container, int width, int height) {
super(container, width, height);
}
@Override
public void setInventorySlotContents(int index, ItemStack stack) {
if (stack.getItem() instanceof ItemFluidDrop) {
FluidStack fluid = ItemFluidDrop.getFluidStack(stack);
if (fluid != null) {
super.setInventorySlotContents(index, ItemFluidPacket.newStack(new FluidStack(fluid, stack.stackSize)));
} else {
// wtf?
super.setInventorySlotContents(index, ItemFluidPacket.newStack(new FluidStack(FluidRegistry.WATER, 1000)));
}
} else {
super.setInventorySlotContents(index, stack);
}
}
}
@@ -0,0 +1,7 @@
package com.glodblock.github.inventory;
@FunctionalInterface
public interface IAEFluidInventory
{
void onFluidInventoryChanged( final IAEFluidTank inv, final int slot );
}
@@ -0,0 +1,13 @@
package com.glodblock.github.inventory;
import appeng.api.storage.data.IAEFluidStack;
import net.minecraftforge.fluids.IFluidHandler;
public interface IAEFluidTank extends IFluidHandler {
void setFluidInSlot( final int slot, final IAEFluidStack fluid );
IAEFluidStack getFluidInSlot( final int slot );
int getSlots();
}
@@ -0,0 +1,51 @@
package com.glodblock.github.inventory;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.inventory.gui.GuiType;
import com.glodblock.github.network.CPacketSwitchGuis;
import com.glodblock.github.util.BlockPos;
import cpw.mods.fml.common.network.IGuiHandler;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import javax.annotation.Nullable;
public class InventoryHandler implements IGuiHandler {
public static void switchGui(GuiType guiType) {
FluidCraft.proxy.netHandler.sendToServer(new CPacketSwitchGuis(guiType));
}
public static void openGui(EntityPlayer player, World world, BlockPos pos, EnumFacing face, GuiType guiType) {
player.openGui(FluidCraft.INSTANCE,
(guiType.ordinal() << 3) | face.ordinal(), world, pos.getX(), pos.getY(), pos.getZ());
}
@Nullable
@Override
public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) {
int faceOrd = id & 0x7;
if (faceOrd > EnumFacing.values().length) {
return null;
}
EnumFacing face = EnumFacing.getFront(faceOrd);
GuiType type = GuiType.getByOrdinal(id >>> 3);
return type != null ? type.guiFactory.createServerGui(player, world, x, y, z, face) : null;
}
@SideOnly(Side.CLIENT)
@Nullable
@Override
public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) {
int faceOrd = id & 0x7;
if (faceOrd > EnumFacing.values().length) {
return null;
}
EnumFacing face = EnumFacing.getFront(faceOrd);
GuiType type = GuiType.getByOrdinal(id >>> 3);
return type != null ? type.guiFactory.createClientGui(player, world, x, y, z, face) : null;
}
}
@@ -0,0 +1,9 @@
package com.glodblock.github.inventory;
import appeng.api.storage.data.IAEItemStack;
public interface PatternConsumer {
void acceptPattern(IAEItemStack[] inputs, IAEItemStack[] outputs);
}
@@ -0,0 +1,20 @@
package com.glodblock.github.inventory.gui;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import javax.annotation.Nullable;
public interface GuiFactory {
@Nullable
Object createServerGui(EntityPlayer player, World world, int x, int y, int z, EnumFacing face);
@SideOnly(Side.CLIENT)
@Nullable
Object createClientGui(EntityPlayer player, World world, int x, int y, int z, EnumFacing face);
}
@@ -0,0 +1,107 @@
package com.glodblock.github.inventory.gui;
import appeng.api.storage.ITerminalHost;
import appeng.container.implementations.ContainerCraftAmount;
import appeng.container.implementations.ContainerCraftingStatus;
import com.glodblock.github.client.gui.*;
import com.glodblock.github.client.gui.container.ContainerFluidCraftConfirm;
import com.glodblock.github.client.gui.container.ContainerFluidPacketDecoder;
import com.glodblock.github.client.gui.container.ContainerFluidPatternEncoder;
import com.glodblock.github.client.gui.container.ContainerFluidPatternTerminal;
import com.glodblock.github.common.parts.PartFluidPatternTerminal;
import com.glodblock.github.common.tile.TileFluidPacketDecoder;
import com.glodblock.github.common.tile.TileFluidPatternEncoder;
import com.google.common.collect.ImmutableList;
import net.minecraft.entity.player.EntityPlayer;
import javax.annotation.Nullable;
import java.util.List;
public enum GuiType {
FLUID_PAT_TERM_CRAFTING_STATUS(new PartGuiFactory<PartFluidPatternTerminal>(PartFluidPatternTerminal.class) {
@Override
protected Object createServerGui(EntityPlayer player, PartFluidPatternTerminal inv) {
return new ContainerCraftingStatus(player.inventory, inv);
}
@Override
protected Object createClientGui(EntityPlayer player, PartFluidPatternTerminal inv) {
return new GuiFluidPatternTerminalCraftingStatus(player.inventory, inv);
}
}),
FLUID_PATTERN_TERMINAL(new PartGuiFactory<ITerminalHost>(ITerminalHost.class) {
@Override
protected Object createServerGui(EntityPlayer player, ITerminalHost inv) {
return new ContainerFluidPatternTerminal(player.inventory, inv);
}
@Override
protected Object createClientGui(EntityPlayer player, ITerminalHost inv) {
return new GuiFluidPatternTerminal(player.inventory, inv);
}
}),
FLUID_PATTERN_ENCODER(new TileGuiFactory<TileFluidPatternEncoder>(TileFluidPatternEncoder.class) {
@Override
protected Object createServerGui(EntityPlayer player, TileFluidPatternEncoder inv) {
return new ContainerFluidPatternEncoder(player.inventory, inv);
}
@Override
protected Object createClientGui(EntityPlayer player, TileFluidPatternEncoder inv) {
return new GuiFluidPatternEncoder(player.inventory, inv);
}
}),
FLUID_CRAFTING_CONFIRM(new PartGuiFactory<PartFluidPatternTerminal>(PartFluidPatternTerminal.class) {
@Override
protected Object createServerGui(EntityPlayer player, PartFluidPatternTerminal inv) {
return new ContainerFluidCraftConfirm(player.inventory, inv);
}
@Override
protected Object createClientGui(EntityPlayer player, PartFluidPatternTerminal inv) {
return new GuiFluidCraftConfirm(player.inventory, inv);
}
}),
FLUID_CRAFTING_AMOUNT(new PartGuiFactory<PartFluidPatternTerminal>(PartFluidPatternTerminal.class) {
@Override
protected Object createServerGui(EntityPlayer player, PartFluidPatternTerminal inv) {
return new ContainerCraftAmount(player.inventory, inv);
}
@Override
protected Object createClientGui(EntityPlayer player, PartFluidPatternTerminal inv) {
return new GuiFluidCraftAmount(player.inventory, inv);
}
}),
FLUID_PACKET_DECODER(new TileGuiFactory<TileFluidPacketDecoder>(TileFluidPacketDecoder.class) {
@Override
protected Object createServerGui(EntityPlayer player, TileFluidPacketDecoder inv) {
return new ContainerFluidPacketDecoder(player.inventory, inv);
}
@Override
protected Object createClientGui(EntityPlayer player, TileFluidPacketDecoder inv) {
return new GuiFluidPacketDecoder(player.inventory, inv);
}
});
public static final List<GuiType> VALUES = ImmutableList.copyOf(values());
@Nullable
public static GuiType getByOrdinal(int ordinal) {
return ordinal < 0 || ordinal >= VALUES.size() ? null : VALUES.get(ordinal);
}
public final GuiFactory guiFactory;
GuiType(GuiFactory guiFactory) {
this.guiFactory = guiFactory;
}
}
@@ -0,0 +1,84 @@
package com.glodblock.github.inventory.gui;
import com.glodblock.github.util.Ae2Reflect;
import net.minecraft.client.audio.PositionedSoundRecord;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.util.ResourceLocation;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class MouseRegionManager {
private final GuiContainer gui;
private final List<Region> regions = new ArrayList<>();
private final FontRenderer font;
public MouseRegionManager(GuiContainer gui, FontRenderer font) {
this.gui = gui;
this.font = font;
}
public void addRegion(int x, int y, int width, int height, Handler handler) {
regions.add(new Region(x, y, width, height, handler));
}
public boolean onClick(int mX, int mY, int button) {
mX -= Ae2Reflect.getGuiLeft(gui);
mY -= Ae2Reflect.getGuiTop(gui);
for (Region region : regions) {
if (region.containsMouse(mX, mY) && region.handler.onClick(button)) {
gui.mc.getSoundHandler().playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), 1F));
return false;
}
}
return true;
}
public void render(int mX, int mY) {
mX -= Ae2Reflect.getGuiLeft(gui);
mY -= Ae2Reflect.getGuiTop(gui);
for (Region region : regions) {
if (region.containsMouse(mX, mY)) {
List<String> tooltip = region.handler.getTooltip();
if (tooltip != null) {
return;
}
}
}
}
private static class Region {
private final int x, y, width, height;
private final Handler handler;
Region(int x, int y, int width, int height, Handler handler) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.handler = handler;
}
boolean containsMouse(int mX, int mY) {
return mX >= x && mX < x + width && mY >= y && mY < y + height;
}
}
public interface Handler {
@Nullable
default List<String> getTooltip() {
return null;
}
default boolean onClick(int button) {
return false;
}
}
}
@@ -0,0 +1,28 @@
package com.glodblock.github.inventory.gui;
import appeng.api.parts.IPart;
import appeng.api.parts.IPartHost;
import com.glodblock.github.util.Util;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import javax.annotation.Nullable;
public abstract class PartGuiFactory<T> extends TileGuiFactory<T> {
PartGuiFactory(Class<T> invClass) {
super(invClass);
}
@Nullable
@Override
protected T getInventory(TileEntity tile, EnumFacing face) {
if (tile instanceof IPartHost) {
IPart part = ((IPartHost)tile).getPart(Util.from(face));
if (invClass.isInstance(part)) {
return invClass.cast(part);
}
}
return null;
}
}
@@ -0,0 +1,66 @@
package com.glodblock.github.inventory.gui;
import appeng.container.AEBaseContainer;
import appeng.container.ContainerOpenContext;
import com.glodblock.github.util.Util;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import javax.annotation.Nullable;
public abstract class TileGuiFactory<T> implements GuiFactory {
protected final Class<T> invClass;
TileGuiFactory(Class<T> invClass) {
this.invClass = invClass;
}
@Nullable
protected T getInventory(TileEntity tile, EnumFacing face) {
return invClass.isInstance(tile) ? invClass.cast(tile) : null;
}
@Nullable
@Override
public Object createServerGui(EntityPlayer player, World world, int x, int y, int z, EnumFacing face) {
TileEntity tile = world.getTileEntity(x, y, z);
if (tile == null) {
return null;
}
T inv = getInventory(tile, face);
if (inv == null) {
return null;
}
Object gui = createServerGui(player, inv);
if (gui instanceof AEBaseContainer) {
ContainerOpenContext ctx = new ContainerOpenContext(inv);
ctx.setWorld(world);
ctx.setX(x);
ctx.setY(y);
ctx.setZ(z);
ctx.setSide(Util.from(face));
((AEBaseContainer)gui).setOpenContext(ctx);
}
return gui;
}
@Nullable
protected abstract Object createServerGui(EntityPlayer player, T inv);
@Nullable
@Override
public Object createClientGui(EntityPlayer player, World world, int x, int y, int z, EnumFacing face) {
TileEntity tile = world.getTileEntity(x, y, z);
if (tile == null) {
return null;
}
T inv = getInventory(tile, face);
return inv != null ? createClientGui(player, inv) : null;
}
@Nullable
protected abstract Object createClientGui(EntityPlayer player, T inv);
}
@@ -0,0 +1,15 @@
package com.glodblock.github.inventory.slot;
import appeng.api.storage.data.IAEItemStack;
import javax.annotation.Nullable;
public interface SlotFluid {
@Nullable
IAEItemStack getAeStack();
void setAeStack(@Nullable IAEItemStack stack, boolean sync);
}
@@ -0,0 +1,102 @@
package com.glodblock.github.inventory.slot;
import com.glodblock.github.util.Util;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
public class SlotSingleItem extends Slot {
private final Slot delegate;
public SlotSingleItem(Slot delegate) {
super(delegate.inventory, delegate.getSlotIndex(), delegate.xDisplayPosition, delegate.yDisplayPosition);
this.delegate = delegate;
}
@Override
public ItemStack getStack() {
ItemStack stack = delegate.getStack();
return stack == null ? null : Util.copyStackWithSize(stack, 1);
}
// delegated
@Override
public void onSlotChange(ItemStack p_75220_1_, ItemStack p_75220_2_) {
delegate.onSlotChange(p_75220_1_, p_75220_2_);
}
@Override
public void onPickupFromSlot(EntityPlayer thePlayer, ItemStack stack) {
delegate.onPickupFromSlot(thePlayer, stack);
}
@Override
public boolean isItemValid(ItemStack stack) {
return delegate.isItemValid(stack);
}
@Override
public boolean getHasStack() {
return delegate.getHasStack();
}
@Override
public void putStack(ItemStack stack) {
delegate.putStack(stack);
}
@Override
public void onSlotChanged() {
delegate.onSlotChanged();
}
@Override
public int getSlotStackLimit() {
return delegate.getSlotStackLimit();
}
@Override
public ItemStack decrStackSize(int amount) {
return delegate.decrStackSize(amount);
}
@Override
public boolean isSlotInInventory(IInventory inv, int slotIn) {
return delegate.isSlotInInventory(inv, slotIn);
}
@Override
public boolean canTakeStack(EntityPlayer playerIn) {
return delegate.canTakeStack(playerIn);
}
@Override
@SideOnly(Side.CLIENT)
public boolean func_111238_b() {
return delegate.func_111238_b();
}
@Override
@SideOnly(Side.CLIENT)
public ResourceLocation getBackgroundIconTexture() {
return delegate.getBackgroundIconTexture();
}
@Override
@SideOnly(Side.CLIENT)
public void setBackgroundIconTexture(ResourceLocation texture) {
delegate.setBackgroundIconTexture(texture);
}
@Override
public int getSlotIndex() {
return delegate.getSlotIndex();
}
}
@@ -0,0 +1,22 @@
package com.glodblock.github.loader;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.network.*;
import cpw.mods.fml.relauncher.Side;
public class ChannelLoader implements Runnable {
@Override
public void run() {
int id = 0;
FluidCraft.proxy.netHandler.registerMessage(new CPacketSwitchGuis.Handler(), CPacketSwitchGuis.class, id ++, Side.SERVER);
FluidCraft.proxy.netHandler.registerMessage(new CPacketFluidPatternTermBtns.Handler(), CPacketFluidPatternTermBtns.class, id ++, Side.SERVER);
FluidCraft.proxy.netHandler.registerMessage(new CPacketEncodePattern.Handler(), CPacketEncodePattern.class, id ++, Side.SERVER);
FluidCraft.proxy.netHandler.registerMessage(new SPacketMEInventoryUpdate.Handler(), SPacketMEInventoryUpdate.class, id ++, Side.CLIENT);
FluidCraft.proxy.netHandler.registerMessage(new CPacketCraftRequest.Handler(), CPacketCraftRequest.class, id ++, Side.SERVER);
FluidCraft.proxy.netHandler.registerMessage(new CPacketInventoryAction.Handler(), CPacketInventoryAction.class, id ++, Side.SERVER);
FluidCraft.proxy.netHandler.registerMessage(new CPacketSetTargetItem.Handler(), CPacketSetTargetItem.class, id ++, Side.SERVER);
FluidCraft.proxy.netHandler.registerMessage(new CPacketSwitchGuis.Handler(), CPacketSwitchGuis.class, id ++, Side.CLIENT);
FluidCraft.proxy.netHandler.registerMessage(new SPacketFluidSlot.Handler(), SPacketFluidSlot.class, id ++, Side.SERVER);
FluidCraft.proxy.netHandler.registerMessage(new CPacketTransferRecipe.Handler(), CPacketTransferRecipe.class, id ++, Side.SERVER);
}
}
@@ -0,0 +1,24 @@
package com.glodblock.github.loader;
import com.glodblock.github.common.block.BlockFluidDiscretizer;
import com.glodblock.github.common.block.BlockFluidInterface;
import com.glodblock.github.common.block.BlockFluidPacketDecoder;
import com.glodblock.github.common.block.BlockFluidPatternEncoder;
import com.glodblock.github.common.item.ItemFluidDrop;
import com.glodblock.github.common.item.ItemFluidEncodedPattern;
import com.glodblock.github.common.item.ItemFluidPacket;
import com.glodblock.github.common.item.ItemPartFluidPatternTerminal;
public class ItemAndBlockHolder {
public static ItemFluidDrop DROP = new ItemFluidDrop().register();
public static ItemFluidEncodedPattern PATTERN = new ItemFluidEncodedPattern().register();
public static ItemPartFluidPatternTerminal FLUID_TERMINAL = new ItemPartFluidPatternTerminal().register();
public static ItemFluidPacket PACKET = new ItemFluidPacket().register();
public static BlockFluidDiscretizer DISCRETIZER = new BlockFluidDiscretizer().register();
public static BlockFluidPatternEncoder ENCODER = new BlockFluidPatternEncoder().register();
public static BlockFluidPacketDecoder DECODER = new BlockFluidPacketDecoder().register();
public static BlockFluidInterface INTERFACE = new BlockFluidInterface().register();
}
@@ -0,0 +1,12 @@
package com.glodblock.github.loader;
import com.glodblock.github.client.ClientHelper;
public class ListenerLoader implements Runnable {
@Override
public void run() {
ClientHelper.register();
}
}
@@ -0,0 +1,14 @@
package com.glodblock.github.loader;
import com.glodblock.github.client.render.ItemDropRender;
import com.glodblock.github.client.render.ItemPacketRender;
public class RenderLoader implements Runnable {
@Override
public void run() {
new ItemDropRender();
new ItemPacketRender();
}
}
@@ -0,0 +1,50 @@
package com.glodblock.github.nei;
import codechicken.nei.api.IOverlayHandler;
import codechicken.nei.recipe.IRecipeHandler;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.client.gui.GuiFluidPatternTerminal;
import com.glodblock.github.nei.object.OrderStack;
import com.glodblock.github.nei.recipes.FluidRecipe;
import com.glodblock.github.network.CPacketTransferRecipe;
import net.minecraft.client.gui.inventory.GuiContainer;
import java.util.HashSet;
import java.util.List;
public class FluidPatternTerminalRecipeTransferHandler implements IOverlayHandler {
public static final FluidPatternTerminalRecipeTransferHandler INSTANCE = new FluidPatternTerminalRecipeTransferHandler();
public static final HashSet<String> notOtherSet = new HashSet<>();
public static final HashSet<String> craftSet = new HashSet<>();
static {
notOtherSet.add("smelting");
notOtherSet.add("brewing");
craftSet.add("crafting");
craftSet.add("crafting2x2");
}
@Override
public void overlayRecipe(GuiContainer firstGui, IRecipeHandler recipe, int recipeIndex, boolean shift) {
if (isCorrectGui(firstGui)) {
List<OrderStack<?>> in = FluidRecipe.getPackageInputs(recipe, recipeIndex);
List<OrderStack<?>> out = FluidRecipe.getPackageOutputs(recipe, recipeIndex, !notUseOther(recipe));
boolean craft = shouldCraft(recipe);
FluidCraft.proxy.netHandler.sendToServer(new CPacketTransferRecipe(in, out, craft));
}
}
private boolean isCorrectGui(GuiContainer firstGui) {
return firstGui instanceof GuiFluidPatternTerminal;
}
private boolean notUseOther(IRecipeHandler recipeHandler) {
return notOtherSet.contains(recipeHandler.getOverlayIdentifier());
}
private boolean shouldCraft(IRecipeHandler recipeHandler) {
return craftSet.contains(recipeHandler.getOverlayIdentifier());
}
}
@@ -0,0 +1,27 @@
package com.glodblock.github.nei;
import codechicken.nei.api.API;
import codechicken.nei.api.IConfigureNEI;
import com.glodblock.github.FluidCraft;
import com.glodblock.github.client.gui.GuiFluidPatternTerminal;
import com.glodblock.github.nei.recipes.FluidRecipe;
public class NEI_FC_Config implements IConfigureNEI {
@Override
public void loadConfig() {
for (String identifier : FluidRecipe.getSupportRecipes()) {
API.registerGuiOverlayHandler(GuiFluidPatternTerminal.class, FluidPatternTerminalRecipeTransferHandler.INSTANCE, identifier);
}
}
@Override
public String getName() {
return FluidCraft.MODNAME;
}
@Override
public String getVersion() {
return FluidCraft.VERSION;
}
}
@@ -0,0 +1,9 @@
package com.glodblock.github.nei.object;
import net.minecraftforge.fluids.FluidStack;
public interface IFluidDummy {
FluidStack getFluidStack();
}
@@ -0,0 +1,13 @@
package com.glodblock.github.nei.object;
import codechicken.nei.PositionedStack;
import java.util.List;
public interface IRecipeExtractor {
List<OrderStack<?>> getInputIngredients(List<PositionedStack> rawInputs);
List<OrderStack<?>> getOutputIngredients(List<PositionedStack> rawOutputs);
}
@@ -0,0 +1,9 @@
package com.glodblock.github.nei.object;
public class IllegalOrderStackID extends RuntimeException {
public IllegalOrderStackID(int id) {
super("Illegal type id: " + id);
}
}
@@ -0,0 +1,106 @@
package com.glodblock.github.nei.object;
import codechicken.nei.PositionedStack;
import com.glodblock.github.util.Util;
import cpw.mods.fml.common.network.ByteBufUtils;
import io.netty.buffer.ByteBuf;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.oredict.OreDictionary;
import javax.annotation.Nullable;
public class OrderStack<T> {
private final T RealStack;
private final int index;
public final static int ITEM = 1;
public final static int FLUID = 2;
public final static int CUSTOM = 3;
public OrderStack(T stack, int order) {
if (stack == null || order < 0)
throw new IllegalArgumentException("Trying to create a null or negative order stack!");
this.RealStack = stack;
this.index = order;
}
public T getStack() {
return RealStack;
}
public int getIndex() {
return index;
}
public static OrderStack<ItemStack> pack(PositionedStack stack, int index) {
if (stack != null && stack.items != null && stack.items.length > 0) {
if (Items.feather.getDamage(stack.items[0]) == OreDictionary.WILDCARD_VALUE) {
ItemStack tmp = stack.items[0].copy();
tmp.setItemDamage(0);
return new OrderStack<>(tmp, index);
}
else return new OrderStack<>(stack.items[0].copy(), index);
}
return null;
}
public static OrderStack<?> packFluid(PositionedStack stack, int index) {
if (stack != null && stack.items != null && stack.items.length > 0) {
FluidStack fluid = Util.getFluidFromItem(stack.items[0]);
if (fluid != null) return new OrderStack<>(fluid.copy(), index);
else return pack(stack, index);
}
return null;
}
protected void customNBTWriter(NBTTagCompound buf) {
}
protected T customNBTReader(NBTTagCompound buf) {
return null;
}
public final void writeToNBT(NBTTagCompound buf) {
if (RealStack instanceof ItemStack) {
NBTTagCompound tmp = new NBTTagCompound();
tmp.setByte("t", (byte) ITEM);
((ItemStack) RealStack).writeToNBT(tmp);
buf.setTag(index + ":", tmp);
}
else if (RealStack instanceof FluidStack) {
NBTTagCompound tmp = new NBTTagCompound();
tmp.setByte("t", (byte) FLUID);
((FluidStack) RealStack).writeToNBT(tmp);
buf.setTag(index + ":", tmp);
}
else {
NBTTagCompound tmp = new NBTTagCompound();
tmp.setByte("t", (byte) CUSTOM);
customNBTWriter(tmp);
buf.setTag(index + ":", tmp);
}
}
public static OrderStack<?> readFromNBT(NBTTagCompound buf, @Nullable OrderStack<?> dummy, int index) {
if (!buf.hasKey(index + ":")) return null;
NBTTagCompound info = buf.getCompoundTag(index + ":");
byte id = info.getByte("t");
switch (id) {
case ITEM:
return new OrderStack<>(ItemStack.loadItemStackFromNBT(info), index);
case FLUID:
return new OrderStack<>(FluidStack.loadFluidStackFromNBT(info), index);
case CUSTOM:
if (dummy == null) throw new IllegalOrderStackID(id);
return new OrderStack<>(dummy.customNBTReader(buf), index);
default:
throw new IllegalOrderStackID(id);
}
}
}
@@ -0,0 +1,24 @@
package com.glodblock.github.nei.recipes;
import com.glodblock.github.nei.recipes.extractor.GregTech5RecipeExtractor;
import com.glodblock.github.nei.recipes.extractor.VanillaRecipeExtractor;
import com.glodblock.github.util.ModAndClassUtil;
import gregtech.api.util.GT_Recipe;
public class DefaultExtractorLoader implements Runnable {
@Override
public void run() {
FluidRecipe.addRecipeMap("smelting", new VanillaRecipeExtractor(false));
FluidRecipe.addRecipeMap("brewing", new VanillaRecipeExtractor(false));
FluidRecipe.addRecipeMap("crafting", new VanillaRecipeExtractor(true));
FluidRecipe.addRecipeMap("crafting2x2", new VanillaRecipeExtractor(true));
if (ModAndClassUtil.GT5) {
for (GT_Recipe.GT_Recipe_Map tMap : GT_Recipe.GT_Recipe_Map.sMappings) {
FluidRecipe.addRecipeMap(tMap.mNEIName, new GregTech5RecipeExtractor(tMap.mNEIName.equals("gt.recipe.scanner") || tMap.mNEIName.equals("gt.recipe.fakeAssemblylineProcess")));
}
}
}
}
@@ -0,0 +1,42 @@
package com.glodblock.github.nei.recipes;
import codechicken.nei.PositionedStack;
import codechicken.nei.recipe.IRecipeHandler;
import com.glodblock.github.nei.object.IRecipeExtractor;
import com.glodblock.github.nei.object.OrderStack;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
public final class FluidRecipe {
private static final HashMap<String, IRecipeExtractor> IdentifierMap = new HashMap<>();
public static void addRecipeMap(String recipeIdentifier, IRecipeExtractor extractor) {
IdentifierMap.put(recipeIdentifier, extractor);
}
public static List<OrderStack<?>> getPackageInputs(IRecipeHandler recipe, int index) {
if (recipe == null || !IdentifierMap.containsKey(recipe.getOverlayIdentifier())) return new ArrayList<>();
IRecipeExtractor extractor = IdentifierMap.get(recipe.getOverlayIdentifier());
if (extractor == null) return new ArrayList<>();
List<PositionedStack> tmp = new ArrayList<>(recipe.getIngredientStacks(index));
return extractor.getInputIngredients(tmp);
}
public static List<OrderStack<?>> getPackageOutputs(IRecipeHandler recipe, int index, boolean useOther) {
if (recipe == null || !IdentifierMap.containsKey(recipe.getOverlayIdentifier())) return new ArrayList<>();
IRecipeExtractor extractor = IdentifierMap.get(recipe.getOverlayIdentifier());
if (extractor == null) return new ArrayList<>();
List<PositionedStack> tmp = new ArrayList<>(Collections.singleton(recipe.getResultStack(index)));
if (useOther) tmp.addAll(recipe.getOtherStacks(index));
return extractor.getOutputIngredients(tmp);
}
public static List<String> getSupportRecipes() {
return new ArrayList<>(IdentifierMap.keySet());
}
}
@@ -0,0 +1,94 @@
package com.glodblock.github.nei.recipes.extractor;
import codechicken.nei.PositionedStack;
import com.glodblock.github.nei.object.IRecipeExtractor;
import com.glodblock.github.nei.object.OrderStack;
import gregtech.common.items.GT_FluidDisplayItem;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class GregTech5RecipeExtractor implements IRecipeExtractor {
boolean r;
public GregTech5RecipeExtractor(boolean removeSpecial) {
r = removeSpecial;
}
@Override
public List<OrderStack<?>> getInputIngredients(List<PositionedStack> rawInputs) {
List<PositionedStack> compressed = compress(rawInputs);
if (r) compressed.remove(compressed.size() - 1);
List<OrderStack<?>> tmp = new LinkedList<>();
for (int i = 0; i < compressed.size(); i ++) {
if (compressed.get(i) == null) continue;
ItemStack item = compressed.get(i).items[0];
OrderStack<?> stack;
if (item.getItem() instanceof GT_FluidDisplayItem) {
NBTTagCompound aNBT = item.getTagCompound();
int amt = (int) aNBT.getLong("mFluidDisplayAmount");
if (amt <= 0) continue;
stack = new OrderStack<>(new FluidStack(FluidRegistry.getFluid(item.getItemDamage()), amt), i);
tmp.add(stack);
} else {
stack = OrderStack.pack(compressed.get(i), i);
if (stack != null) tmp.add(stack);
}
}
return tmp;
}
@Override
public List<OrderStack<?>> getOutputIngredients(List<PositionedStack> rawOutputs) {
List<PositionedStack> compressed = compress(rawOutputs);
if (r) compressed.remove(compressed.size() - 1);
List<OrderStack<?>> tmp = new LinkedList<>();
for (int i = 0; i < compressed.size(); i ++) {
if (compressed.get(i) == null) continue;
ItemStack item = compressed.get(i).items[0];
OrderStack<?> stack;
if (item.getItem() instanceof GT_FluidDisplayItem) {
NBTTagCompound aNBT = item.getTagCompound();
int amt = (int) aNBT.getLong("mFluidDisplayAmount");
if (amt <= 0) continue;
stack = new OrderStack<>(new FluidStack(FluidRegistry.getFluid(item.getItemDamage()), amt), i);
tmp.add(stack);
} else {
stack = OrderStack.pack(compressed.get(i), i);
if (stack != null) tmp.add(stack);
}
}
return tmp;
}
private List<PositionedStack> compress(List<PositionedStack> list) {
List<PositionedStack> comp = new LinkedList<>();
for (PositionedStack positionedStack : list) {
if (positionedStack == null) continue;
ItemStack currentStack = positionedStack.items[0];
if (currentStack.stackSize == 0) continue;
boolean find = false;
for (PositionedStack storedStack : comp) {
if (storedStack == null) continue;
ItemStack firstStack = storedStack.items[0];
boolean areItemStackEqual = firstStack.isItemEqual(currentStack) && ItemStack.areItemStackTagsEqual(firstStack, currentStack);
if (areItemStackEqual && (firstStack.stackSize + currentStack.stackSize) <= firstStack.getMaxStackSize()) {
find = true;
storedStack.items[0].stackSize = firstStack.stackSize + currentStack.stackSize;
}
}
if (!find) {
comp.add(positionedStack.copy());
}
}
return comp.stream().filter(Objects::nonNull).collect(Collectors.toList());
}
}
@@ -0,0 +1,46 @@
package com.glodblock.github.nei.recipes.extractor;
import codechicken.nei.PositionedStack;
import com.glodblock.github.nei.object.IRecipeExtractor;
import com.glodblock.github.nei.object.OrderStack;
import java.util.LinkedList;
import java.util.List;
public class VanillaRecipeExtractor implements IRecipeExtractor {
private boolean c;
public VanillaRecipeExtractor(boolean isCraft) {
c = isCraft;
}
@Override
public List<OrderStack<?>> getInputIngredients(List<PositionedStack> rawInputs) {
List<OrderStack<?>> tmp = new LinkedList<>();
for (int i = 0; i < rawInputs.size(); i ++) {
if (rawInputs.get(i) == null) continue;
final int col = (rawInputs.get(i).relx - 25) / 18;
final int row = (rawInputs.get(i).rely - 6) / 18;
int index = col + row * 3;
OrderStack<?> stack = OrderStack.pack(rawInputs.get(i), c ? index : i);
if (stack != null) tmp.add(stack);
}
return tmp;
}
@Override
public List<OrderStack<?>> getOutputIngredients(List<PositionedStack> rawOutputs) {
List<OrderStack<?>> tmp = new LinkedList<>();
for (int i = 0; i < rawOutputs.size(); i ++) {
if (rawOutputs.get(i) == null) continue;
final int col = (rawOutputs.get(i).relx - 25) / 18;
final int row = (rawOutputs.get(i).rely - 6) / 18;
int index = col + row * 3;
OrderStack<?> stack = OrderStack.pack(rawOutputs.get(i), c ? index : i);
if (stack != null) tmp.add(stack);
}
return tmp;
}
}
@@ -0,0 +1,118 @@
package com.glodblock.github.network;
import appeng.api.networking.IGrid;
import appeng.api.networking.IGridHost;
import appeng.api.networking.IGridNode;
import appeng.api.networking.crafting.ICraftingGrid;
import appeng.api.networking.crafting.ICraftingJob;
import appeng.container.ContainerOpenContext;
import appeng.container.implementations.ContainerCraftAmount;
import appeng.core.AELog;
import com.glodblock.github.client.gui.container.ContainerFluidCraftConfirm;
import com.glodblock.github.inventory.InventoryHandler;
import com.glodblock.github.inventory.gui.GuiType;
import com.glodblock.github.util.BlockPos;
import com.glodblock.github.util.Util;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.common.util.ForgeDirection;
import javax.annotation.Nullable;
import java.util.Objects;
import java.util.concurrent.Future;
public class CPacketCraftRequest implements IMessage {
private long amount;
private boolean heldShift;
public CPacketCraftRequest() {
}
public CPacketCraftRequest( final int craftAmt, final boolean shift ) {
amount = craftAmt;
heldShift = shift;
}
@Override
public void toBytes(ByteBuf buf) {
buf.writeLong(amount);
buf.writeBoolean(heldShift);
}
@Override
public void fromBytes(ByteBuf buf) {
amount = buf.readLong();
heldShift = buf.readBoolean();
}
public static class Handler implements IMessageHandler<CPacketCraftRequest, IMessage> {
@Nullable
@Override
public IMessage onMessage(CPacketCraftRequest message, MessageContext ctx) {
if( ctx.getServerHandler().playerEntity.openContainer instanceof ContainerCraftAmount)
{
EntityPlayerMP player = ctx.getServerHandler().playerEntity;
final ContainerCraftAmount cca = (ContainerCraftAmount) ctx.getServerHandler().playerEntity.openContainer;
final Object target = cca.getTarget();
if( target instanceof IGridHost)
{
final IGridHost gh = (IGridHost) target;
final IGridNode gn = gh.getGridNode( ForgeDirection.UNKNOWN );
if( gn == null )
{
return null;
}
final IGrid g = gn.getGrid();
if( g == null || cca.getItemToCraft() == null )
{
return null;
}
cca.getItemToCraft().setStackSize( message.amount );
Future<ICraftingJob> futureJob = null;
try
{
final ICraftingGrid cg = g.getCache( ICraftingGrid.class );
futureJob = cg.beginCraftingJob( cca.getWorld(), cca.getGrid(), cca.getActionSrc(), cca.getItemToCraft(), null );
final ContainerOpenContext context = cca.getOpenContext();
if( context != null )
{
final TileEntity te = context.getTile();
InventoryHandler.openGui(player, player.worldObj, new BlockPos(te), Objects.requireNonNull(Util.from(context.getSide())), GuiType.FLUID_CRAFTING_CONFIRM);
if( player.openContainer instanceof ContainerFluidCraftConfirm)
{
final ContainerFluidCraftConfirm ccc = (ContainerFluidCraftConfirm) player.openContainer;
ccc.setAutoStart( message.heldShift );
ccc.setJob( futureJob );
cca.detectAndSendChanges();
}
}
}
catch( final Throwable e )
{
if( futureJob != null )
{
futureJob.cancel( true );
}
AELog.debug( e );
}
}
}
return null;
}
}
}
@@ -0,0 +1,38 @@
package com.glodblock.github.network;
import com.glodblock.github.client.gui.container.ContainerFluidPatternEncoder;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayerMP;
import javax.annotation.Nullable;
public class CPacketEncodePattern implements IMessage {
@Override
public void toBytes(ByteBuf buf) {
// NO-OP
}
@Override
public void fromBytes(ByteBuf buf) {
// NO-OP
}
public static class Handler implements IMessageHandler<CPacketEncodePattern, IMessage> {
@Nullable
@Override
public IMessage onMessage(CPacketEncodePattern message, MessageContext ctx) {
EntityPlayerMP player = ctx.getServerHandler().playerEntity;
if (player.openContainer instanceof ContainerFluidPatternEncoder) {
((ContainerFluidPatternEncoder)player.openContainer).encodePattern();
}
return null;
}
}
}
@@ -0,0 +1,95 @@
package com.glodblock.github.network;
import com.glodblock.github.client.gui.container.ContainerFluidCraftConfirm;
import com.glodblock.github.client.gui.container.ContainerFluidPatternTerminal;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import io.netty.buffer.ByteBuf;
import net.minecraft.inventory.Container;
public class CPacketFluidPatternTermBtns implements IMessage {
private String Name = "";
private String Value = "";
public CPacketFluidPatternTermBtns( final String name, final String value ) {
Name = name;
Value = value;
}
public CPacketFluidPatternTermBtns() {
// NO-OP
}
@Override
public void fromBytes(ByteBuf buf) {
int leName = buf.readInt();
int leVal = buf.readInt();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < leName; i ++) {
sb.append(buf.readChar());
}
Name = sb.toString();
sb = new StringBuilder();
for (int i = 0; i < leVal; i ++) {
sb.append(buf.readChar());
}
Value = sb.toString();
}
@Override
public void toBytes(ByteBuf buf) {
buf.writeInt(Name.length());
buf.writeInt(Value.length());
for (int i = 0; i < Name.length(); i ++) {
buf.writeChar(Name.charAt(i));
}
for (int i = 0; i < Value.length(); i ++) {
buf.writeChar(Value.charAt(i));
}
}
public static class Handler implements IMessageHandler<CPacketFluidPatternTermBtns, IMessage> {
@Override
public IMessage onMessage(CPacketFluidPatternTermBtns message, MessageContext ctx) {
String Name = message.Name;
String Value = message.Value;
final Container c = ctx.getServerHandler().playerEntity.openContainer;
if( Name.startsWith( "PatternTerminal." ) && c instanceof ContainerFluidPatternTerminal)
{
final ContainerFluidPatternTerminal cpt = (ContainerFluidPatternTerminal) c;
switch (Name) {
case "PatternTerminal.CraftMode":
cpt.getPatternTerminal().setCraftingRecipe(Value.equals("1"));
break;
case "PatternTerminal.Encode":
if (Value.equals("2"))
cpt.encodeAndMoveToInventory();
else
cpt.encode();
break;
case "PatternTerminal.Clear":
cpt.clear();
break;
case "PatternTerminal.Substitute":
cpt.getPatternTerminal().setSubstitution(Value.equals("1"));
break;
case "PatternTerminal.Double":
cpt.doubleStacks(Value.equals("1"));
break;
}
} else if(Name.equals( "Terminal.Cpu" ) && c instanceof ContainerFluidCraftConfirm) {
final ContainerFluidCraftConfirm qk = (ContainerFluidCraftConfirm) c;
qk.cycleCpu( Value.equals( "Next" ) );
}
else if( Name.equals( "Terminal.Start" ) && c instanceof ContainerFluidCraftConfirm ) {
final ContainerFluidCraftConfirm qk = (ContainerFluidCraftConfirm) c;
qk.startJob();
}
return null;
}
}
}
@@ -0,0 +1,124 @@
package com.glodblock.github.network;
import appeng.api.storage.data.IAEItemStack;
import appeng.container.AEBaseContainer;
import appeng.container.ContainerOpenContext;
import appeng.container.implementations.ContainerCraftAmount;
import appeng.core.sync.GuiBridge;
import appeng.helpers.InventoryAction;
import appeng.util.Platform;
import appeng.util.item.AEItemStack;
import com.glodblock.github.inventory.InventoryHandler;
import com.glodblock.github.inventory.gui.GuiType;
import com.glodblock.github.util.BlockPos;
import com.glodblock.github.util.Util;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.tileentity.TileEntity;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.Objects;
public class CPacketInventoryAction implements IMessage {
private InventoryAction action;
private int slot;
private long id;
private IAEItemStack stack;
private boolean isEmpty;
public CPacketInventoryAction() {
}
public CPacketInventoryAction( final InventoryAction action, final int slot, final int id ) {
this.action = action;
this.slot = slot;
this.id = id;
this.stack = null;
this.isEmpty = true;
}
public CPacketInventoryAction(final InventoryAction action, final int slot, final int id , IAEItemStack stack) {
this.action = action;
this.slot = slot;
this.id = id;
this.stack = stack;
this.isEmpty = stack == null;
}
@Override
public void toBytes(ByteBuf buf) {
buf.writeInt(action.ordinal());
buf.writeInt(slot);
buf.writeLong(id);
buf.writeBoolean(isEmpty);
if (!isEmpty) {
try {
stack.writeToPacket(buf);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public void fromBytes(ByteBuf buf) {
action = InventoryAction.values()[buf.readInt()];
slot = buf.readInt();
id = buf.readLong();
isEmpty = buf.readBoolean();
if (!isEmpty) {
try {
stack = AEItemStack.loadItemStackFromPacket(buf);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static class Handler implements IMessageHandler<CPacketInventoryAction, IMessage> {
@Nullable
@Override
public IMessage onMessage(CPacketInventoryAction message, MessageContext ctx) {
final EntityPlayerMP sender = ctx.getServerHandler().playerEntity;
if( sender.openContainer instanceof AEBaseContainer )
{
final AEBaseContainer baseContainer = (AEBaseContainer) sender.openContainer;
if( message.action == InventoryAction.AUTO_CRAFT )
{
final ContainerOpenContext context = baseContainer.getOpenContext();
if( context != null )
{
final TileEntity te = context.getTile();
InventoryHandler.openGui( sender, te.getWorldObj(), new BlockPos(te), Objects.requireNonNull(Util.from(baseContainer.getOpenContext().getSide())), GuiType.FLUID_CRAFTING_AMOUNT );
if( sender.openContainer instanceof ContainerCraftAmount )
{
final ContainerCraftAmount cca = (ContainerCraftAmount) sender.openContainer;
if( baseContainer.getTargetStack() != null )
{
cca.getCraftingItem().putStack( baseContainer.getTargetStack().getItemStack() );
cca.setItemToCraft( baseContainer.getTargetStack() );
}
cca.detectAndSendChanges();
}
}
}
else
{
baseContainer.doAction( sender, message.action, message.slot, message.id );
}
}
return null;
}
}
}
@@ -0,0 +1,56 @@
package com.glodblock.github.network;
import appeng.api.storage.data.IAEItemStack;
import appeng.container.AEBaseContainer;
import appeng.util.item.AEItemStack;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import io.netty.buffer.ByteBuf;
import net.minecraft.inventory.Container;
import java.io.IOException;
public class CPacketSetTargetItem implements IMessage {
private IAEItemStack stack;
public CPacketSetTargetItem() {
}
public CPacketSetTargetItem(IAEItemStack stack) {
this.stack = stack;
}
@Override
public void toBytes(ByteBuf buf) {
try {
stack.writeToPacket(buf);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void fromBytes(ByteBuf buf) {
try {
stack = AEItemStack.loadItemStackFromPacket(buf);
} catch (IOException e) {
e.printStackTrace();
}
}
public static class Handler implements IMessageHandler<CPacketSetTargetItem, IMessage> {
@Override
public IMessage onMessage(CPacketSetTargetItem message, MessageContext ctx) {
Container c = ctx.getServerHandler().playerEntity.openContainer;
if (c instanceof AEBaseContainer) {
((AEBaseContainer) c).setTargetStack(message.stack);
}
return null;
}
}
}
@@ -0,0 +1,68 @@
package com.glodblock.github.network;
import appeng.container.AEBaseContainer;
import appeng.container.ContainerOpenContext;
import com.glodblock.github.inventory.InventoryHandler;
import com.glodblock.github.inventory.gui.GuiType;
import com.glodblock.github.util.BlockPos;
import com.glodblock.github.util.Util;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.Container;
import net.minecraft.tileentity.TileEntity;
import javax.annotation.Nullable;
import java.util.Objects;
public class CPacketSwitchGuis implements IMessage {
private GuiType guiType;
public CPacketSwitchGuis(GuiType guiType) {
this.guiType = guiType;
}
public CPacketSwitchGuis() {
// NO-OP
}
@Override
public void fromBytes(ByteBuf byteBuf) {
guiType = GuiType.getByOrdinal(byteBuf.readByte());
}
@Override
public void toBytes(ByteBuf byteBuf) {
byteBuf.writeByte(guiType != null ? guiType.ordinal() : 0);
}
public static class Handler implements IMessageHandler<CPacketSwitchGuis, IMessage> {
@Nullable
@Override
public IMessage onMessage(CPacketSwitchGuis message, MessageContext ctx) {
if (message.guiType == null) {
return null;
}
EntityPlayerMP player = ctx.getServerHandler().playerEntity;
Container cont = player.openContainer;
if (!(cont instanceof AEBaseContainer)) {
return null;
}
ContainerOpenContext context = ((AEBaseContainer)cont).getOpenContext();
if (context == null) {
return null;
}
TileEntity te = context.getTile();
if (te == null) {
return null;
}
InventoryHandler.openGui(player, player.worldObj, new BlockPos(te), Objects.requireNonNull(Util.from(context.getSide())), message.guiType);
return null;
}
}
}
@@ -0,0 +1,128 @@
package com.glodblock.github.network;
import com.glodblock.github.client.gui.container.ContainerFluidPatternTerminal;
import com.glodblock.github.common.item.ItemFluidPacket;
import com.glodblock.github.nei.object.OrderStack;
import cpw.mods.fml.common.network.ByteBufUtils;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import io.netty.buffer.ByteBuf;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fluids.FluidStack;
import javax.annotation.Nullable;
import java.util.LinkedList;
import java.util.List;
public class CPacketTransferRecipe implements IMessage {
private List<OrderStack<?>> inputs;
private List<OrderStack<?>> outputs;
private boolean isCraft;
private final static int MAX_INDEX = 16;
public CPacketTransferRecipe(){
}
public CPacketTransferRecipe(List<OrderStack<?>> IN, List<OrderStack<?>> OUT, boolean craft) {
this.inputs = IN;
this.outputs = OUT;
this.isCraft = craft;
}
//I should use GZIP to compress the message, but i'm too lazy.
//NBT to ByteBuf has a compress stream
@Override
public void toBytes(ByteBuf buf) {
buf.writeBoolean(isCraft);
NBTTagCompound nbt_m = new NBTTagCompound();
NBTTagCompound nbt_i = new NBTTagCompound();
NBTTagCompound nbt_o = new NBTTagCompound();
for (OrderStack<?> stack : inputs) {
stack.writeToNBT(nbt_i);
}
for (OrderStack<?> stack : outputs) {
stack.writeToNBT(nbt_o);
}
nbt_m.setTag("i", nbt_i);
nbt_m.setTag("o", nbt_o);
ByteBufUtils.writeTag(buf, nbt_m);
}
@Override
public void fromBytes(ByteBuf buf) {
isCraft = buf.readBoolean();
inputs = new LinkedList<>();
outputs = new LinkedList<>();
NBTTagCompound nbt_m = ByteBufUtils.readTag(buf);
NBTTagCompound nbt_i = nbt_m.getCompoundTag("i");
NBTTagCompound nbt_o = nbt_m.getCompoundTag("o");
for (int i = 0; i < MAX_INDEX; i ++) {
OrderStack<?> tmp = OrderStack.readFromNBT(nbt_i, null, i);
if (tmp != null) inputs.add(tmp);
}
for (int i = 0; i < MAX_INDEX; i ++) {
OrderStack<?> tmp = OrderStack.readFromNBT(nbt_o, null, i);
if (tmp != null) outputs.add(tmp);
}
}
public static class Handler implements IMessageHandler<CPacketTransferRecipe, IMessage> {
@Nullable
@Override
public IMessage onMessage(CPacketTransferRecipe message, MessageContext ctx) {
Container c = ctx.getServerHandler().playerEntity.openContainer;
if (c instanceof ContainerFluidPatternTerminal) {
ContainerFluidPatternTerminal cf = (ContainerFluidPatternTerminal) c;
cf.getPatternTerminal().setCraftingRecipe(message.isCraft);
IInventory inputSlot = cf.getInventoryByName("crafting");
IInventory outputSlot = cf.getInventoryByName("output");
for (int i = 0; i < inputSlot.getSizeInventory(); i ++) {
inputSlot.setInventorySlotContents(i, null);
}
for (int i = 0; i < outputSlot.getSizeInventory(); i ++) {
outputSlot.setInventorySlotContents(i, null);
}
for (OrderStack<?> stack : message.inputs) {
if (stack != null) {
int index = stack.getIndex();
ItemStack stack1;
if (stack.getStack() instanceof ItemStack) {
stack1 = ((ItemStack) stack.getStack()).copy();
}
else if (stack.getStack() instanceof FluidStack) {
stack1 = ItemFluidPacket.newStack((FluidStack) stack.getStack());
}
else throw new UnsupportedOperationException("Trying to get an unsupported item!");
if (index < inputSlot.getSizeInventory())
inputSlot.setInventorySlotContents(index, stack1);
}
}
for (OrderStack<?> stack : message.outputs) {
if (stack != null) {
int index = stack.getIndex();
ItemStack stack1;
if (stack.getStack() instanceof ItemStack) {
stack1 = ((ItemStack) stack.getStack()).copy();
}
else if (stack.getStack() instanceof FluidStack) {
stack1 = ItemFluidPacket.newStack((FluidStack) stack.getStack());
}
else throw new UnsupportedOperationException("Trying to get an unsupported item!");
if (index < outputSlot.getSizeInventory())
outputSlot.setInventorySlotContents(index, stack1);
}
}
c.onCraftMatrixChanged(inputSlot);
c.onCraftMatrixChanged(outputSlot);
}
return null;
}
}
}
@@ -0,0 +1,68 @@
package com.glodblock.github.network;
import appeng.api.storage.data.IAEFluidStack;
import appeng.util.item.AEFluidStack;
import com.glodblock.github.client.gui.IFluidSyncContainer;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import io.netty.buffer.ByteBuf;
import net.minecraft.inventory.Container;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class SPacketFluidSlot implements IMessage {
private Map<Integer, IAEFluidStack> list;
public SPacketFluidSlot() {
}
public SPacketFluidSlot(Map<Integer, IAEFluidStack> data) {
this.list = data;
}
@Override
public void fromBytes(ByteBuf buf) {
int size = buf.readInt();
this.list = new HashMap<>();
try {
for (int i = 0; i < size; i ++) {
int id = buf.readInt();
IAEFluidStack fluid = AEFluidStack.loadFluidStackFromPacket(buf);
list.put(id, fluid);
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void toBytes(ByteBuf buf) {
buf.writeInt(list.size());
try {
for (Map.Entry<Integer, IAEFluidStack> fs : list.entrySet()) {
buf.writeInt(fs.getKey());
fs.getValue().writeToPacket(buf);
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static class Handler implements IMessageHandler<SPacketFluidSlot, IMessage> {
@Override
public IMessage onMessage(SPacketFluidSlot message, MessageContext ctx) {
final Container c = ctx.getServerHandler().playerEntity.openContainer;
if( c instanceof IFluidSyncContainer)
{
( (IFluidSyncContainer) c ).receiveFluidSlots( message.list );
}
return null;
}
}
}
@@ -0,0 +1,84 @@
package com.glodblock.github.network;
import appeng.api.storage.data.IAEItemStack;
import appeng.util.item.AEItemStack;
import com.glodblock.github.client.gui.GuiFCBaseMonitor;
import com.glodblock.github.client.gui.GuiFluidCraftConfirm;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import io.netty.buffer.ByteBuf;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import java.io.IOException;
import java.nio.BufferOverflowException;
import java.util.LinkedList;
import java.util.List;
public class SPacketMEInventoryUpdate implements IMessage {
private List<IAEItemStack> list;
private byte ref;
public SPacketMEInventoryUpdate() {
ref = 0;
list = new LinkedList<>();
}
public SPacketMEInventoryUpdate(byte b) {
this.ref = b;
list = new LinkedList<>();
}
@Override
public void fromBytes(ByteBuf buf) {
long amount = buf.readLong();
ref = buf.readByte();
list = new LinkedList<>();
try {
for (int i = 0; i < amount; i ++) {
list.add(AEItemStack.loadItemStackFromPacket(buf));
}
} catch (IOException io) {
io.printStackTrace();
}
}
@Override
public void toBytes(ByteBuf buf) {
buf.writeLong(list.size());
buf.writeByte(ref);
try {
for (IAEItemStack itemStack : list) {
itemStack.writeToPacket(buf);
}
} catch (IOException io) {
io.printStackTrace();
}
}
public void appendItem( final IAEItemStack is ) throws BufferOverflowException {
list.add(is);
}
public boolean isEmpty() {
return this.list.isEmpty();
}
public static class Handler implements IMessageHandler<SPacketMEInventoryUpdate, IMessage> {
@Override
public IMessage onMessage(SPacketMEInventoryUpdate message, MessageContext ctx) {
final GuiScreen gs = Minecraft.getMinecraft().currentScreen;
if( gs instanceof GuiFCBaseMonitor)
{
( (GuiFCBaseMonitor) gs ).postUpdate(message.list);
}
else if ( gs instanceof GuiFluidCraftConfirm) {
( (GuiFluidCraftConfirm) gs ).postUpdate( message.list, message.ref );
}
return null;
}
}
}
@@ -0,0 +1,23 @@
package com.glodblock.github.proxy;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
public class ClientProxy extends CommonProxy {
@Override
public void preInit(FMLPreInitializationEvent event){
super.preInit(event);
}
@Override
public void init(FMLInitializationEvent event){
super.init(event);
}
@Override
public void postInit(FMLPostInitializationEvent event){
super.postInit(event);
}
}
@@ -0,0 +1,20 @@
package com.glodblock.github.proxy;
import com.glodblock.github.FluidCraft;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.network.simpleimpl.SimpleNetworkWrapper;
public class CommonProxy {
public final SimpleNetworkWrapper netHandler = NetworkRegistry.INSTANCE.newSimpleChannel(FluidCraft.MODID);
public void preInit(FMLPreInitializationEvent event){}
public void init(FMLInitializationEvent event){}
public void postInit(FMLPostInitializationEvent event){}
}
@@ -0,0 +1,237 @@
package com.glodblock.github.util;
import appeng.api.implementations.IUpgradeableHost;
import appeng.api.networking.crafting.ICraftingCPU;
import appeng.client.gui.AEBaseGui;
import appeng.client.gui.implementations.GuiCraftingStatus;
import appeng.client.gui.widgets.GuiTabButton;
import appeng.client.render.AppEngRenderItem;
import appeng.container.implementations.ContainerUpgradeable;
import appeng.container.implementations.CraftingCPURecord;
import appeng.helpers.MultiCraftingTracker;
import appeng.util.inv.ItemSlot;
import com.glodblock.github.client.gui.GuiBaseFluidPatternTerminal;
import com.glodblock.github.client.gui.GuiFCBaseMonitor;
import com.glodblock.github.client.gui.container.ContainerFluidPatternTerminal;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Set;
public class Ae2Reflect {
private static final Field fInventory_container;
private static final Field fInventory_width;
private static final Field fInventory_stackList;
private static final Field fAEContainer_upgradeable;
private static final Method mItemSlot_setExtractable;
private static final Method mTracker_isBusy;
private static final Method mTracker_cancel;
static {
try {
fInventory_container = reflectField(InventoryCrafting.class, "eventHandler");
fInventory_width = reflectField(InventoryCrafting.class, "inventoryWidth");
fInventory_stackList = reflectField(InventoryCrafting.class, "stackList");
fAEContainer_upgradeable = reflectField(ContainerUpgradeable.class, "upgradeable");
mItemSlot_setExtractable = reflectMethod(ItemSlot.class, "setExtractable", boolean.class);
mTracker_isBusy = reflectMethod(MultiCraftingTracker.class, "isBusy", int.class);
mTracker_cancel = reflectMethod(MultiCraftingTracker.class, "cancel");
} catch (Exception e) {
throw new IllegalStateException("Failed to initialize AE2 reflection hacks!", e);
}
}
public static Method reflectMethod(Class<?> owner, String name, Class<?>... paramTypes) throws NoSuchMethodException {
Method m = owner.getDeclaredMethod(name, paramTypes);
m.setAccessible(true);
return m;
}
public static Field reflectField(Class<?> owner, String name) throws NoSuchFieldException {
Field f = owner.getDeclaredField(name);
f.setAccessible(true);
return f;
}
@SuppressWarnings("unchecked")
public static <T> T readField(Object owner, Field field) {
try {
return (T)field.get(owner);
} catch (Exception e) {
throw new IllegalStateException("Failed to read field: " + field);
}
}
public static void writeField(Object owner, Field field, Object value) {
try {
field.set(owner, value);
} catch (Exception e) {
throw new IllegalStateException("Failed to write field: " + field);
}
}
public static void doCancel(MultiCraftingTracker mct) {
try {
mTracker_cancel.invoke(mct);
} catch (Exception e) {
throw new IllegalStateException("Failed to invoke method: " + mTracker_cancel, e);
}
}
public static boolean getBusy(MultiCraftingTracker mct, int slot) {
try {
return (boolean) mTracker_isBusy.invoke(mct, slot);
} catch (Exception e) {
throw new IllegalStateException("Failed to invoke method: " + mTracker_isBusy, e);
}
}
public static IUpgradeableHost getUpgrade(ContainerUpgradeable container) {
return Ae2Reflect.readField(container, fAEContainer_upgradeable);
}
public static Container getCraftContainer(InventoryCrafting inv) {
return Ae2Reflect.readField(inv, fInventory_container);
}
public static int getCraftWidth(InventoryCrafting inv) {
return Ae2Reflect.readField(inv, fInventory_width);
}
public static ItemStack[] getCraftStackList(InventoryCrafting inv) {
return Ae2Reflect.readField(inv, fInventory_stackList);
}
public static void setItemSlotExtractable(ItemSlot slot, boolean extractable) {
try {
mItemSlot_setExtractable.invoke(slot, extractable);
} catch (Exception e) {
throw new IllegalStateException("Failed to invoke method: " + mItemSlot_setExtractable, e);
}
}
private static final Field fAEBaseGui_stackSizeRenderer;
private static final Field fGuiCraftingStatus_originalGuiBtn;
private static final Field fGuiPatternTerm_container;
private static final Field fGuiCPUStatus_icon;
private static final Field fGuiMEMonitorable_monitorableContainer;
private static final Field fGuiMEMonitorable_configSrc;
private static final Field fGuiMEMonitorable_craftingStatusBtn;
private static final Field fGuiContainer_guiLeft;
private static final Field fGuiContainer_guiTop;
private static final Field fCPU_cpu;
private static final Field fCPU_myName;
private static final Field fCPU_processors;
private static final Field fCPU_size;
private static final Field fGui_drag;
private static final Method mGuiPatternTerm_inventorySlots;
private static final Method mGuiPatternTerm_reservedSpace;
private static final Method mGuiPatternTerm_reservedSpaceSetter;
static {
try {
fAEBaseGui_stackSizeRenderer = Ae2Reflect.reflectField(AEBaseGui.class, "aeRenderItem");
fGuiCraftingStatus_originalGuiBtn = Ae2Reflect.reflectField(GuiCraftingStatus.class, "originalGuiBtn");
fGuiPatternTerm_container = Ae2Reflect.reflectField(GuiBaseFluidPatternTerminal.class, "container");
fGuiMEMonitorable_monitorableContainer = Ae2Reflect.reflectField(GuiFCBaseMonitor.class, "monitorableContainer");
fGuiMEMonitorable_configSrc = Ae2Reflect.reflectField(GuiFCBaseMonitor.class, "configSrc");
fGuiMEMonitorable_craftingStatusBtn = Ae2Reflect.reflectField(GuiFCBaseMonitor.class, "craftingStatusBtn");
fGuiCPUStatus_icon = Ae2Reflect.reflectField(GuiCraftingStatus.class, "myIcon");
fGuiContainer_guiLeft = Ae2Reflect.reflectField(GuiContainer.class, "guiLeft");
fGuiContainer_guiTop = Ae2Reflect.reflectField(GuiContainer.class, "guiTop");
fCPU_cpu = Ae2Reflect.reflectField(CraftingCPURecord.class, "cpu");
fCPU_myName = Ae2Reflect.reflectField(CraftingCPURecord.class, "myName");
fCPU_processors = Ae2Reflect.reflectField(CraftingCPURecord.class, "processors");
fCPU_size = Ae2Reflect.reflectField(CraftingCPURecord.class, "size");
fGui_drag = Ae2Reflect.reflectField(AEBaseGui.class, "drag_click");
mGuiPatternTerm_inventorySlots = Ae2Reflect.reflectMethod(AEBaseGui.class, "getInventorySlots");
mGuiPatternTerm_reservedSpace = Ae2Reflect.reflectMethod(GuiFCBaseMonitor.class, "getReservedSpace");
mGuiPatternTerm_reservedSpaceSetter = Ae2Reflect.reflectMethod(GuiFCBaseMonitor.class, "setReservedSpace", int.class);
} catch (Exception e) {
throw new IllegalStateException("Failed to initialize AE2 reflection hacks!", e);
}
}
@SuppressWarnings("unchecked")
public static List<Slot> getInventorySlots(AEBaseGui gui) {
try {
return (List<Slot>) mGuiPatternTerm_inventorySlots.invoke(gui);
} catch (Exception e) {
throw new IllegalStateException("Failed to invoke method: " + mGuiPatternTerm_inventorySlots, e);
}
}
public static void rewriteIcon(GuiCraftingStatus gui, ItemStack icon) {
Ae2Reflect.writeField(gui, fGuiCPUStatus_icon, icon);
}
public static Set<Slot> getDragClick(AEBaseGui gui) {
return Ae2Reflect.readField(gui, fGui_drag);
}
public static ICraftingCPU getCPU(CraftingCPURecord cpu) {
return Ae2Reflect.readField(cpu, fCPU_cpu);
}
public static String getName(CraftingCPURecord cpu) {
return Ae2Reflect.readField(cpu, fCPU_myName);
}
public static int getProcessors(CraftingCPURecord cpu) {
return Ae2Reflect.readField(cpu, fCPU_processors);
}
public static long getSize(CraftingCPURecord cpu) {
return Ae2Reflect.readField(cpu, fCPU_size);
}
public static int getGuiLeft(GuiContainer gui) {
return Ae2Reflect.readField(gui, fGuiContainer_guiLeft);
}
public static int getGuiTop(GuiContainer gui) {
return Ae2Reflect.readField(gui, fGuiContainer_guiTop);
}
public static void setReservedSpace(GuiFCBaseMonitor gui, int size) {
try {
mGuiPatternTerm_reservedSpaceSetter.invoke(gui, size);
} catch (Exception e) {
throw new IllegalStateException("Failed to invoke method: " + mGuiPatternTerm_reservedSpaceSetter, e);
}
}
public static int getReservedSpace(GuiFCBaseMonitor gui) {
try {
return (int) mGuiPatternTerm_reservedSpace.invoke(gui);
} catch (Exception e) {
throw new IllegalStateException("Failed to invoke method: " + mGuiPatternTerm_reservedSpace, e);
}
}
public static AppEngRenderItem getStackSizeRenderer(AEBaseGui gui) {
return Ae2Reflect.readField(gui, fAEBaseGui_stackSizeRenderer);
}
public static GuiTabButton getOriginalGuiButton(GuiCraftingStatus gui) {
return Ae2Reflect.readField(gui, fGuiCraftingStatus_originalGuiBtn);
}
public static void setGuiContainer(GuiBaseFluidPatternTerminal instance, ContainerFluidPatternTerminal container) {
Ae2Reflect.writeField(instance, fGuiPatternTerm_container, container);
Ae2Reflect.writeField(instance, fGuiMEMonitorable_monitorableContainer, container);
Ae2Reflect.writeField(instance, fGuiMEMonitorable_configSrc, container.getConfigManager());
}
public static GuiTabButton getCraftingStatusButton(GuiFCBaseMonitor gui) {
return Ae2Reflect.readField(gui, fGuiMEMonitorable_craftingStatusBtn);
}
}
@@ -0,0 +1,46 @@
package com.glodblock.github.util;
import net.minecraft.tileentity.TileEntity;
import javax.annotation.Nonnull;
public class BlockPos {
private final int x;
private final int y;
private final int z;
public BlockPos(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public BlockPos(@Nonnull TileEntity te) {
this.x = te.xCoord;
this.y = te.yCoord;
this.z = te.zCoord;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getZ() {
return z;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof BlockPos) {
BlockPos pos = (BlockPos) obj;
return pos.x == x && pos.y == y && pos.z == z;
}
return false;
}
}
@@ -0,0 +1,199 @@
package com.glodblock.github.util;
import appeng.api.networking.crafting.ICraftingPatternDetails;
import appeng.api.storage.data.IAEItemStack;
import appeng.util.item.AEItemStack;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.world.World;
import net.minecraftforge.common.util.Constants;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class FluidPatternDetails implements ICraftingPatternDetails, Comparable<FluidPatternDetails>{
private final ItemStack patternStack;
private IAEItemStack patternStackAe;
private IAEItemStack[] inputs = null, inputsCond = null, outputs = null, outputsCond = null;
private int priority = 0;
public FluidPatternDetails(ItemStack stack) {
this.patternStack = stack;
this.patternStackAe = Objects.requireNonNull(AEItemStack.create(stack)); // s2g
}
@Override
public ItemStack getPattern() {
return patternStack;
}
@Override
public int getPriority() {
return priority;
}
@Override
public void setPriority(int priority) {
this.priority = priority;
}
@Override
public boolean isCraftable() {
return false;
}
@Override
public boolean canSubstitute() {
return false;
}
@Override
public IAEItemStack[] getInputs() {
return checkInitialized(inputs);
}
@Override
public IAEItemStack[] getCondensedInputs() {
return checkInitialized(inputsCond);
}
public boolean setInputs(IAEItemStack[] inputs) {
for (IAEItemStack stack : inputs) { // see note at top of class
if (stack == null) {
return false;
}
}
IAEItemStack[] condensed = condenseStacks(inputs);
if (condensed.length == 0) {
return false;
}
this.inputs = inputs;
this.inputsCond = condensed;
return true;
}
@Override
public IAEItemStack[] getOutputs() {
return checkInitialized(outputs);
}
@Override
public IAEItemStack[] getCondensedOutputs() {
return checkInitialized(outputsCond);
}
public boolean setOutputs(IAEItemStack[] outputs) {
for (IAEItemStack stack : outputs) { // see note at top of class
if (stack == null) {
return false;
}
}
IAEItemStack[] condensed = condenseStacks(outputs);
if (condensed.length == 0) {
return false;
}
this.outputs = outputs;
this.outputsCond = condensed;
return true;
}
private static IAEItemStack[] condenseStacks(IAEItemStack[] stacks) {
// AE item stacks are equivalent iff they are of the same item type (not accounting for stack size)
// thus, it's not the semantically-correct definition of "equal" but it's useful for matching item types
Map<IAEItemStack, IAEItemStack> accMap = new HashMap<>();
for (IAEItemStack stack : stacks) {
if (stack != null) {
IAEItemStack acc = accMap.get(stack);
if (acc == null) {
accMap.put(stack, stack.copy());
} else {
acc.add(stack);
}
}
}
return accMap.values().toArray(new IAEItemStack[0]);
}
@Override
public ItemStack getOutput(InventoryCrafting craftingInv, World world) {
throw new IllegalStateException("Not a crafting recipe!");
}
@Override
public boolean isValidItemForSlot(int slotIndex, ItemStack itemStack, World world) {
throw new IllegalStateException("Not a crafting recipe!");
}
private static <T> T checkInitialized(@Nullable T value) {
if (value == null) {
throw new IllegalStateException("Pattern is not initialized!");
}
return value;
}
@Override
public int hashCode() {
return patternStackAe.hashCode();
}
@Override
public boolean equals(Object obj) {
// ae2 null-checks the pattern stack here for some reason, but doesn't null-check in hashCode()
// this is inconsistent, so i've just decided to assert non-null in the constructor, which is to say that
// the pattern stack can never be null here
return obj instanceof FluidPatternDetails && patternStackAe.equals(((FluidPatternDetails)obj).patternStackAe);
}
@Override
public int compareTo(FluidPatternDetails o) {
return Integer.compare(o.priority, this.priority);
}
public ItemStack writeToStack() {
NBTTagCompound tag = new NBTTagCompound();
tag.setTag("Inputs", writeStackArray(checkInitialized(inputs)));
tag.setTag("Outputs", writeStackArray(checkInitialized(outputs)));
patternStack.setTagCompound(tag);
patternStackAe = Objects.requireNonNull(AEItemStack.create(patternStack));
return patternStack;
}
public static NBTTagList writeStackArray(IAEItemStack[] stacks) {
NBTTagList listTag = new NBTTagList();
for (IAEItemStack stack : stacks) {
if (stack != null) {
// see note at top of class
NBTTagCompound stackTag = new NBTTagCompound();
stack.writeToNBT(stackTag);
listTag.appendTag(stackTag);
}
}
return listTag;
}
public boolean readFromStack() {
if (!patternStack.hasTagCompound()) {
return false;
}
NBTTagCompound tag = Objects.requireNonNull(patternStack.getTagCompound());
// may be possible to enter a partially-correct state if setInputs succeeds but setOutputs failed
// but outside code should treat it as completely incorrect and not attempt to make calls
return setInputs(readStackArray(tag.getTagList("Inputs", Constants.NBT.TAG_COMPOUND), 9))
&& setOutputs(readStackArray(tag.getTagList("Outputs", Constants.NBT.TAG_COMPOUND), 3));
}
public static IAEItemStack[] readStackArray(NBTTagList listTag, int maxCount) {
// see note at top of class
IAEItemStack[] stacks = new IAEItemStack[Math.min(listTag.tagCount(), maxCount)];
for (int i = 0; i < stacks.length; i++) {
stacks[i] = AEItemStack.loadItemStackFromNBT(listTag.getCompoundTagAt(i));
}
return stacks;
}
}
Loaded 100 of 124 files, more files were not shown because too many files have changed in this diff. Show more