Compare commits

..

4 Commits

Author SHA1 Message Date
serenibyss 2054c2afe3 fix 2024-01-03 23:48:58 -06:00
serenibyss 69650e2bef power cost improvements from eff + unbreaking 2024-01-03 23:46:41 -06:00
serenibyss 1a576705fe annihilation plane performance improvement 2024-01-03 23:26:50 -06:00
serenibyss 27a3f70f0b fortune enchantable 2024-01-03 23:21:32 -06:00
209 changed files with 2810 additions and 6160 deletions
+19 -17
View File
@@ -1,23 +1,25 @@
name: Build
name: Build mod
on: [push]
on: [ push, pull_request, workflow_dispatch ]
jobs:
build:
name: Build mod
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up OpenJDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'adopt' # You can choose other OpenJDK distributions.
- name: Update Build Script (Before Build)
run: ./gradlew updateBuildScript
- name: Build with Gradle
run: ./gradlew build
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: AE2-UEL
path: build/libs/*.jar # Make sure this path matches the location of your build artifacts
- uses: actions/checkout@v2
- name: Set up JDK 1.8
uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: '8'
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
run: ./gradlew -Pnet.minecraftforge.gradle.disableUpdateChecker=true build
- name: Upload artifacts
uses: actions/upload-artifact@v2
with:
name: appliedenergistics2
path: build/libs
-82
View File
@@ -1,82 +0,0 @@
# Publishes built jars to distribution platforms
name: Publish
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+' # any semver tag, e.g. 1.2.3
env:
# type of release
RELEASE_TYPE: "release"
jobs:
Publish:
runs-on: ubuntu-latest
permissions:
contents: write # needed to create GitHub releases
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Check for Duplicate Tags
run: |
if git rev-parse -q --verify "refs/tags/${{ github.ref }}" >/dev/null; then
echo "Tag already exists. A version bump is required."
exit 1
fi
- name: Setup Java
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '17'
- name: Build Project
uses: gradle/gradle-build-action@v2
with:
arguments: 'build --build-cache --daemon' # use the daemon here so the rest of the process is faster
generate-job-summary: false
gradle-home-cache-includes: |
caches
jdks
notifications
wrapper
- name: Publish to GitHub
uses: softprops/action-gh-release@v1
with:
files: "build/libs/*.jar"
generate_release_notes: true
fail_on_unmatched_files: true
- name: Publish to Maven
uses: gradle/gradle-build-action@v2
env:
MAVEN_USER: "${{secrets.MAVEN_USER}}"
MAVEN_PASSWORD: "${{secrets.MAVEN_PASSWORD}}"
with:
arguments: 'publish --daemon'
generate-job-summary: false
gradle-home-cache-includes: |
caches
jdks
notifications
wrapper
- name: Publish to Curseforge
uses: gradle/gradle-build-action@v2
env:
CURSEFORGE_API_KEY: "${{secrets.CURSEFORGE_API_KEY}}"
CURSEFORGE_PROJECT_ID: "${{secrets.CURSEFORGE_PROJECT_ID}}"
RELEASE_TYPE: "${{env.RELEASE_TYPE}}"
with:
arguments: 'curseforge --daemon'
generate-job-summary: false
gradle-home-cache-includes: |
caches
jdks
notifications
wrapper
-39
View File
@@ -1,39 +0,0 @@
# Updates the Gradle Cache when relevant files change
name: Update Gradle Cache
on:
workflow_dispatch:
push:
branches:
- master
paths:
- "gradle**" # covers gradle folder, gradle.properties, gradlew
- "build.gradle*"
- "settings.gradle*"
- "src/main/resources/*_at.cfg" # access transformers
jobs:
Update_Cache:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Setup Java
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: '17'
- name: Update Cache
uses: gradle/gradle-build-action@v2
with:
arguments: 'test --build-cache --no-daemon' # disable daemon since only one gradle operation will happen
generate-job-summary: false
gradle-home-cache-includes: |
caches
jdks
notifications
wrapper
cache-write-only: true
+25 -76
View File
@@ -1,83 +1,32 @@
.nopublish
# exclude all
/*
### Windows ###
# include important folders
# need gradle
!gradle/
!gradlew
!gradlew.bat
!build.gradle
!gradle.properties
!settings.gradle
!.travis.yml
thumbs.db
*.db
# include markdowns
!README.md
!LICENSE
### Java ###
# include sourcecode
!src/
*.class
# include git important files
!.gitmodules
!.gitignore
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# code format to reduce noise in git commits
!codeformat/
# Package Files #
*.war
*.ear
*.txt
# Github specific files and directories
!.github/
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
### Eclipse ###
*.pydevproject
.metadata
.gradle
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.settings/
.loadpath
/eclipse
# Eclipse Core
.project
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# JDT-specific (Eclipse Java Development Tools)
.classpath
# Java annotation processor (APT)
.factorypath
# PDT-specific
.buildpath
# sbteclipse plugin
.target
# TeXlipse plugin
.texlipse
### Intellij IDEA ###
*.iml
*.ipr
*.iws
.idea/
.idea_modules/
/classes/
/out/
/build/
# Linux
*~
run/
logs/
# Explicit ignores
Thumbs.db
+33
View File
@@ -0,0 +1,33 @@
sudo: required
dist: trusty
language: java
jdk:
- oraclejdk8
- openjdk8
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
- rm -f $HOME/.gradle/caches/minecraft/ForgeVersion.json
- rm -f $HOME/.gradle/caches/minecraft/ForgeVersion.json.etag
- rm -fr $HOME/.gradle/caches/minecraft/deobfedDeps
- rm -f $HOME/.gradle/caches/*/fileHashes/fileHashes.bin
- rm -f $HOME/.gradle/caches/*/fileHashes/fileHashes.lock
cache:
directories:
- '$HOME/.m2/repository'
- '$HOME/.sonar/cache'
- '$HOME/.gradle/wrapper'
- '$HOME/.gradle/caches'
addons:
sonarcloud:
organization: "appliedenergistics"
install: "./gradlew setupCIWorkspace"
script:
- "./gradlew build"
- "./gradlew test"
- "./gradlew sonarqube"
+141 -341
View File
@@ -1,4 +1,3 @@
//version: 1704659416
/*
* DO NOT CHANGE THIS FILE!
* Also, you may replace this file at any time if there is an update available.
@@ -20,24 +19,23 @@ import static org.gradle.internal.logging.text.StyledTextOutput.Style
plugins {
id 'java'
id 'java-library'
id 'base'
id 'eclipse'
id 'maven-publish'
id 'org.jetbrains.gradle.plugin.idea-ext' version '1.1.7'
id 'com.gtnewhorizons.retrofuturagradle' version '1.3.25'
id 'net.darkhax.curseforgegradle' version '1.1.17' apply false
id 'com.modrinth.minotaur' version '2.8.6' apply false
id 'com.gtnewhorizons.retrofuturagradle' version '1.3.19'
id 'net.darkhax.curseforgegradle' version '1.0.14' apply false
id 'com.modrinth.minotaur' version '2.8.0' apply false
id 'com.diffplug.spotless' version '6.13.0' apply false
id 'com.palantir.git-version' version '3.0.0' apply false
id 'com.github.johnrengelman.shadow' version '8.1.1' apply false
id 'org.jetbrains.kotlin.jvm' version '1.8.0' apply false
id 'org.jetbrains.kotlin.kapt' version '1.8.0' apply false
id 'com.google.devtools.ksp' version '1.8.0-1.0.9' apply false
}
if (verifySettingsGradle()) {
throw new GradleException("Settings has been updated, please re-run task.")
}
def out = services.get(StyledTextOutputFactory).create('an-output')
// Project properties
// Required properties: we don't know how to handle these being missing gracefully
@@ -52,72 +50,31 @@ checkPropertyExists("mixinsPackage")
checkPropertyExists("coreModClass")
checkPropertyExists("containsMixinsAndOrCoreModOnly")
// Optional properties: we can assume some default behavior if these are missing
propertyDefaultIfUnset("modVersion", "")
propertyDefaultIfUnset("includeMCVersionJar", false)
propertyDefaultIfUnset("autoUpdateBuildScript", false)
propertyDefaultIfUnset("modArchivesBaseName", project.modId)
propertyDefaultIfUnsetWithEnvVar("developmentEnvironmentUserName", "Developer", "DEV_USERNAME")
propertyDefaultIfUnset("generateGradleTokenClass", "")
propertyDefaultIfUnset("gradleTokenModId", "")
propertyDefaultIfUnset("gradleTokenModName", "")
propertyDefaultIfUnset("gradleTokenVersion", "")
propertyDefaultIfUnset("useSrcApiPath", false)
propertyDefaultIfUnset("includeWellKnownRepositories", true)
propertyDefaultIfUnset("includeCommonDevEnvMods", true)
propertyDefaultIfUnset("noPublishedSources", false)
propertyDefaultIfUnset("forceEnableMixins", false)
propertyDefaultIfUnsetWithEnvVar("enableCoreModDebug", false, "CORE_MOD_DEBUG")
propertyDefaultIfUnset("generateMixinConfig", true)
propertyDefaultIfUnset("usesShadowedDependencies", false)
propertyDefaultIfUnset("minimizeShadowedDependencies", true)
propertyDefaultIfUnset("relocateShadowedDependencies", true)
propertyDefaultIfUnset("separateRunDirectories", false)
propertyDefaultIfUnset("versionDisplayFormat", '$MOD_NAME \u2212 $VERSION')
propertyDefaultIfUnsetWithEnvVar("modrinthProjectId", "", "MODRINTH_PROJECT_ID")
propertyDefaultIfUnset("modrinthRelations", "")
propertyDefaultIfUnsetWithEnvVar("curseForgeProjectId", "", "CURSEFORGE_PROJECT_ID")
propertyDefaultIfUnset("curseForgeRelations", "")
propertyDefaultIfUnsetWithEnvVar("releaseType", "release", "RELEASE_TYPE")
propertyDefaultIfUnset("generateDefaultChangelog", false)
propertyDefaultIfUnset("customMavenPublishUrl", "")
propertyDefaultIfUnset("mavenArtifactGroup", getDefaultArtifactGroup())
propertyDefaultIfUnset("enableModernJavaSyntax", false)
propertyDefaultIfUnset("enableSpotless", false)
propertyDefaultIfUnset("enableJUnit", false)
propertyDefaultIfUnsetWithEnvVar("deploymentDebug", false, "DEPLOYMENT_DEBUG")
// Project property assertions
final String javaSourceDir = 'src/main/java/'
final String scalaSourceDir = 'src/main/scala/'
final String kotlinSourceDir = 'src/main/kotlin/'
// If Kotlin is supported, add the path here
final String modGroupPath = modGroup.toString().replace('.' as char, '/' as char)
final String apiPackagePath = apiPackage.toString().replace('.' as char, '/' as char)
String targetPackageJava = javaSourceDir + modGroupPath
String targetPackageScala = scalaSourceDir + modGroupPath
String targetPackageKotlin = kotlinSourceDir + modGroupPath
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 Kotlin is supported, add the path here
if (!getFile(targetPackageJava).exists() && !getFile(targetPackageScala).exists()) {
throw new GradleException("Could not resolve \"modGroup\"! Could not find ${targetPackageJava} or ${targetPackageScala}")
}
if (apiPackage) {
final String endApiPath = modGroupPath + '/' + apiPackagePath
if (useSrcApiPath) {
targetPackageJava = 'src/api/java/' + endApiPath
targetPackageScala = 'src/api/scala/' + endApiPath
targetPackageKotlin = 'src/api/kotlin/' + endApiPath
} else {
targetPackageJava = javaSourceDir + endApiPath
targetPackageScala = scalaSourceDir + endApiPath
targetPackageKotlin = kotlinSourceDir + endApiPath
}
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}")
targetPackageJava = 'src/api/java/' + modGroupPath + '/api'
targetPackageScala = 'src/api/java/' + modGroupPath + '/api'
if (!getFile(targetPackageJava).exists() && !getFile(targetPackageScala).exists()) {
throw new GradleException("Could not resolve \"apiPackage\"! Could not find ${targetPackageJava} or ${targetPackageScala}")
}
}
@@ -139,9 +96,8 @@ if (usesMixins.toBoolean()) {
final String mixinPackagePath = mixinsPackage.toString().replaceAll('\\.', '/')
targetPackageJava = javaSourceDir + modGroupPath + '/' + mixinPackagePath
targetPackageScala = scalaSourceDir + modGroupPath + '/' + mixinPackagePath
targetPackageKotlin = kotlinSourceDir + modGroupPath + '/' + mixinPackagePath
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}")
if (!getFile(targetPackageJava).exists()) {
throw new GradleException("Could not resolve \"mixinsPackage\"! Could not find ${targetPackageJava} or ${targetPackageScala}")
}
}
@@ -150,105 +106,13 @@ if (coreModClass) {
String targetFileJava = javaSourceDir + modGroupPath + '/' + coreModPath + '.java'
String targetFileScala = scalaSourceDir + modGroupPath + '/' + coreModPath + '.scala'
String targetFileScalaJava = scalaSourceDir + modGroupPath + '/' + coreModPath + '.java'
String targetFileKotlin = kotlinSourceDir + modGroupPath + '/' + coreModPath + '.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}")
if (!getFile(targetFileJava).exists() && !getFile(targetFileScala).exists() && !getFile(targetFileScalaJava).exists()) {
throw new GradleException("Could not resolve \"coreModClass\"! Could not find " + targetFileJava)
}
}
// Plugin application
// Scala
if (getFile('src/main/scala').exists()) {
apply plugin: 'scala'
}
if (getFile('src/main/kotlin').exists()) {
apply plugin: 'org.jetbrains.kotlin.jvm'
}
// Kotlin
pluginManager.withPlugin('org.jetbrains.kotlin.jvm') {
kotlin {
jvmToolchain(8)
}
def disabledKotlinTaskList = [
"kaptGenerateStubsMcLauncherKotlin",
"kaptGenerateStubsPatchedMcKotlin",
"kaptGenerateStubsInjectedTagsKotlin",
"compileMcLauncherKotlin",
"compilePatchedMcKotlin",
"compileInjectedTagsKotlin",
"kaptMcLauncherKotlin",
"kaptPatchedMcKotlin",
"kaptInjectedTagsKotlin",
"kspMcLauncherKotlin",
"kspPatchedMcKotlin",
"kspInjectedTagsKotlin",
]
tasks.configureEach { task ->
if (task.name in disabledKotlinTaskList) {
task.enabled = false
}
}
}
// Spotless
//noinspection GroovyAssignabilityCheck
project.extensions.add(com.diffplug.blowdryer.Blowdryer, 'Blowdryer', com.diffplug.blowdryer.Blowdryer) // make Blowdryer available in plugin application
if (enableSpotless.toBoolean()) {
apply plugin: 'com.diffplug.spotless'
// Spotless auto-formatter
// See https://github.com/diffplug/spotless/tree/main/plugin-gradle
// Can be locally toggled via spotless:off/spotless:on comments
spotless {
encoding 'UTF-8'
format 'misc', {
target '.gitignore'
trimTrailingWhitespace()
indentWithSpaces(4)
endWithNewline()
}
java {
target 'src/main/java/**/*.java', 'src/test/java/**/*.java' // exclude api as they are not our files
def orderFile = project.file('spotless.importorder')
if (!orderFile.exists()) {
orderFile = Blowdryer.file('spotless.importorder')
}
def formatFile = project.file('spotless.eclipseformat.xml')
if (!formatFile.exists()) {
formatFile = Blowdryer.file('spotless.eclipseformat.xml')
}
toggleOffOn()
importOrderFile(orderFile)
removeUnusedImports()
endWithNewline()
//noinspection GroovyAssignabilityCheck
eclipse('4.19.0').configFile(formatFile)
}
kotlin {
target 'src/*/kotlin/**/*.kt'
toggleOffOn()
ktfmt('0.39')
trimTrailingWhitespace()
indentWithSpaces(4)
endWithNewline()
}
scala {
target 'src/*/scala/**/*.scala'
scalafmt('3.7.1')
}
}
}
// Git version checking, also checking for if this is a submodule
if (project.file('.git/HEAD').isFile() || project.file('.git').isFile()) {
apply plugin: 'com.palantir.git-version'
@@ -259,9 +123,6 @@ if (usesShadowedDependencies.toBoolean()) {
apply plugin: 'com.github.johnrengelman.shadow'
}
// Configure Java
java {
toolchain {
if (enableModernJavaSyntax.toBoolean()) {
@@ -303,11 +164,8 @@ tasks.withType(ScalaCompile).configureEach {
// Allow others using this buildscript to have custom gradle code run
if (getFile('addon.gradle').exists()) {
apply from: 'addon.gradle'
} else if (getFile('addon.gradle.kts').exists()) {
apply from: 'addon.gradle.kts'
}
// Configure Minecraft
// Try to gather mod version from git tags if version is not manually specified
@@ -323,24 +181,23 @@ if (!modVersion) {
}
}
if (includeMCVersionJar.toBoolean()){
if (includeMCVersionJar.toBoolean()) {
version = "${minecraftVersion}-${modVersion}"
}
else {
} else {
version = modVersion
}
group = modGroup
base {
archivesName = modArchivesBaseName
}
archivesBaseName = modArchivesBaseName
minecraft {
mcVersion = minecraftVersion
username = developmentEnvironmentUserName.toString()
useDependencyAccessTransformers = true
setMcpMappingChannel("stable")
setMcpMappingVersion("39")
// Automatic token injection with RetroFuturaGradle
if (gradleTokenModId) {
injectedTags.put gradleTokenModId, modId
@@ -352,30 +209,22 @@ minecraft {
injectedTags.put gradleTokenVersion, modVersion
}
injectedTags.put("VERSION", project.version)
injectedTags.put("AEVERSION", aeversion)
injectedTags.put("AECHANNEL", aechannel)
injectedTags.put("AEBUILD", aebuild)
// JVM arguments
extraRunJvmArguments.add("-ea:${modGroup}")
if (usesMixins.toBoolean()) {
extraRunJvmArguments.addAll([
'-Dmixin.hotSwap=true',
'-Dmixin.checks.interfaces=true',
'-Dmixin.debug.export=true'
'-Dmixin.hotSwap=true',
'-Dmixin.checks.interfaces=true',
'-Dmixin.debug.export=true'
])
}
if (enableCoreModDebug.toBoolean()) {
extraRunJvmArguments.addAll([
'-Dlegacy.debugClassLoading=true',
'-Dlegacy.debugClassLoadingFiner=true',
'-Dlegacy.debugClassLoadingSave=true'
])
}
}
if (coreModClass) {
for (runTask in ['runClient', 'runServer']) {
tasks.named(runTask).configure {
extraJvmArgs.add("-Dfml.coreMods.load=${modGroup}.${coreModClass}")
}
if (coreModClass) {
extraRunJvmArguments.add("-Dfml.coreMods.load=${modGroup}.${coreModClass}")
}
}
@@ -387,6 +236,17 @@ tasks.named('processIdeaSettings').configure {
dependsOn('injectTags')
}
tasks.register("generateMcModInfo") {
}
tasks.register("generatePackMcMeta") {
}
tasks.named('processIdeaSettings').configure {
dependsOn('injectTags')
}
// Repositories
@@ -403,63 +263,46 @@ repositories.configureEach { repo ->
// Allow adding custom repositories to the buildscript
if (getFile('repositories.gradle').exists()) {
apply from: 'repositories.gradle'
} else if (getFile('repositories.gradle.kts').exists()) {
apply from: 'repositories.gradle.kts'
}
repositories {
if (includeWellKnownRepositories.toBoolean() || includeCommonDevEnvMods.toBoolean()) {
exclusiveContent {
forRepository {
//noinspection ForeignDelegate
maven {
name = 'Curse Maven'
url = 'https://www.cursemaven.com'
// url = 'https://beta.cursemaven.com'
}
}
filter {
includeGroup 'curse.maven'
}
}
exclusiveContent {
forRepository {
//noinspection ForeignDelegate
maven {
name = 'Modrinth'
url = 'https://api.modrinth.com/maven'
}
}
filter {
includeGroup 'maven.modrinth'
}
}
maven {
name 'Cleanroom Maven'
url 'https://maven.cleanroommc.com'
}
maven {
name 'BlameJared Maven'
url 'https://maven.blamejared.com'
}
maven {
name 'GTNH Maven'
url 'https://nexus.gtnewhorizons.com/repository/public/'
}
}
if (usesMixins.toBoolean() || forceEnableMixins.toBoolean()) {
// need to add this here even if we did not above
if (!includeWellKnownRepositories.toBoolean()) {
exclusiveContent {
forRepository {
//noinspection ForeignDelegate
maven {
name 'Cleanroom Maven'
url 'https://maven.cleanroommc.com'
name = 'Curse Maven'
url = 'https://www.cursemaven.com'
}
}
filter {
includeGroup 'curse.maven'
}
}
mavenLocal() // Must be last for caching to work
exclusiveContent {
forRepository {
//noinspection ForeignDelegate
maven {
name = 'Modrinth'
url = 'https://api.modrinth.com/maven'
}
}
filter {
includeGroup 'maven.modrinth'
}
}
maven {
name 'Cleanroom Maven'
url 'https://maven.cleanroommc.com'
}
maven {
name 'BlameJared Maven'
url 'https://maven.blamejared.com'
}
gradlePluginPortal()
mavenCentral()
mavenLocal()
}
// Dependencies
// Configure dependency configurations
@@ -475,31 +318,32 @@ configurations {
}
}
String mixinProviderSpec = 'zone.rong:mixinbooter:8.9'
dependencies {
if (usesMixins.toBoolean()) {
if (usesMixins.toBoolean() || forceEnableMixins.toBoolean()) {
implementation 'zone.rong:mixinbooter:7.0'
String mixin = 'org.spongepowered:mixin:0.8.3'
if (usesMixins.toBoolean()) {
mixin = modUtils.enableMixins(mixin, "mixins.${modId}.refmap.json")
}
api(mixin) {
transitive = false
}
annotationProcessor(mixin) {
transitive = false
}
annotationProcessor 'org.ow2.asm:asm-debug-all:5.2'
// should use 24.1.1 but 30.0+ has a vulnerability fix
annotationProcessor 'com.google.guava:guava:30.0-jre'
// should use 2.8.6 but 2.8.9+ has a vulnerability fix
annotationProcessor 'com.google.code.gson:gson:2.8.9'
mixinProviderSpec = modUtils.enableMixins(mixinProviderSpec, "mixins.${modId}.refmap.json")
api (mixinProviderSpec) {
transitive = false
}
annotationProcessor(mixinProviderSpec) {
transitive = false
}
} else if (forceEnableMixins.toBoolean()) {
runtimeOnly(mixinProviderSpec)
}
if (enableJUnit.toBoolean()) {
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.1'
testImplementation 'org.hamcrest:hamcrest:2.2'
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
if (enableModernJavaSyntax.toBoolean()) {
@@ -520,11 +364,8 @@ dependencies {
testCompileOnly "me.eigenraven.java8unsupported:java-8-unsupported-shim:1.0.0"
}
compileOnlyApi 'org.jetbrains:annotations:24.1.0'
annotationProcessor 'org.jetbrains:annotations:24.1.0'
patchedMinecraft('net.minecraft:launchwrapper:1.17.2') {
transitive = false
}
compileOnlyApi 'org.jetbrains:annotations:23.0.0'
annotationProcessor 'org.jetbrains:annotations:23.0.0'
if (includeCommonDevEnvMods.toBoolean()) {
implementation 'mezz.jei:jei_1.12.2:4.16.1.302'
@@ -533,20 +374,11 @@ dependencies {
}
}
pluginManager.withPlugin('org.jetbrains.kotlin.kapt') {
if (usesMixins.toBoolean()) {
dependencies {
kapt(mixinProviderSpec)
}
}
}
if (getFile('dependencies.gradle').exists()) {
apply from: 'dependencies.gradle'
} else if (getFile('dependencies.gradle.kts').exists()) {
apply from: 'dependencies.gradle.kts'
if (getFile('gradle/scripts/dependencies.gradle').exists()) {
apply from: 'gradle/scripts/dependencies.gradle'
}
apply from: 'gradle/scripts/optional.gradle'
// Test configuration
@@ -580,7 +412,6 @@ test {
}
}
// Resource processing and jar building
processResources {
@@ -633,20 +464,20 @@ tasks.register('generateAssets') {
mcmodInfoFile.text = """[{
"modid": "\${modid}",
"name": "\${modname}",
"description": "An example mod for Minecraft 1.12.2 with Forge",
"description": "A Mod about Matter, Energy and using them to conquer the world..",
"version": "\${version}",
"mcversion": "\${mcversion}",
"logoFile": "",
"url": "",
"authorList": [],
"credits": "",
"logoFile": "assets/appliedenergistics2/meta/logo.png",
"url": "https://github.com/PrototypeTrousers/Applied-Energistics-2",
"authorList": ["AlgorithmX2"],
"credits": "AlgorithmX2",
"dependencies": []
}]
"""
}
// mixins.{modid}.json
if (usesMixins.toBoolean() && generateMixinConfig.toBoolean()) {
if (usesMixins.toBoolean()) {
def mixinConfigFile = getFile("src/main/resources/mixins.${modId}.json")
if (!mixinConfigFile.exists()) {
def mixinConfigRefmap = "mixins.${modId}.refmap.json"
@@ -683,49 +514,26 @@ jar {
}
}
if (useSrcApiPath && apiPackage) {
from sourceSets.api.output
dependsOn apiClasses
from sourceSets.api.output
dependsOn apiClasses
include "${modGroupPath}/**"
include "assets/**"
include "mcmod.info"
include "pack.mcmeta"
if (accessTransformersFile) {
include "META-INF/${accessTransformersFile}"
}
}
}
// Configure default run tasks
if (separateRunDirectories.toBoolean()) {
runClient {
workingDir = file('run/client')
}
runServer {
workingDir = file('run/server')
}
// specify which files are really included, can control which APIs should be in
include "appeng/**"
include "assets/**"
include "mcmod.info"
include "pack.mcmeta"
include "META-INF/appliedenergistics2_at.cfg"
}
// Create API library jar
tasks.register('apiJar', Jar) {
archiveClassifier.set 'api'
if (useSrcApiPath) {
from(sourceSets.api.java) {
include "${modGroupPath}/${apiPackagePath}/**"
}
from(sourceSets.api.output) {
include "${modGroupPath}/${apiPackagePath}/**"
}
} else {
from(sourceSets.main.java) {
include "${modGroupPath}/${apiPackagePath}/**"
}
from(sourceSets.api.java) {
include "${modGroupPath}/${apiPackagePath}/**"
}
from(sourceSets.main.output) {
include "${modGroupPath}/${apiPackagePath}/**"
}
from(sourceSets.api.output) {
include "${modGroupPath}/${apiPackagePath}/**"
}
}
@@ -758,7 +566,7 @@ if (usesShadowedDependencies.toBoolean()) {
finalizedBy(tasks.shadowJar)
}
tasks.named('reobfJar', ReobfuscatedJar) {
inputJar.set(tasks.named('shadowJar', ShadowJar).flatMap({it.archiveFile}))
inputJar.set(tasks.named('shadowJar', ShadowJar).flatMap({ it.archiveFile }))
}
AdhocComponentWithVariants javaComponent = (AdhocComponentWithVariants) project.components.findByName('java')
javaComponent.withVariantsFromConfiguration(configurations.shadowRuntimeElements) {
@@ -893,7 +701,7 @@ tasks.register('generateChangelog') {
.collect { ['--', it] }).flatten())
if (changelog) {
changelog = "Changes since ${lastTag}:\n${{("\n" + changelog).replaceAll("\n", "\n* ")}}"
changelog = "Changes since ${lastTag}:\n${{ ("\n" + changelog).replaceAll("\n", "\n* ") }}"
}
def f = getFile('build/changelog.md')
changelog = changelog ?: 'There have been no changes.'
@@ -919,7 +727,7 @@ if (cfApiKey.isPresent() || deploymentDebug.toBoolean()) {
def changelogFile = getChangelog()
def changelogRaw = changelogFile.exists() ? changelogFile.getText('UTF-8') : ""
mainFile.displayName = versionDisplayFormat.replace('$MOD_NAME', modName).replace('$VERSION', modVersion)
mainFile.displayName = "${modName}: ${modVersion}"
mainFile.releaseType = getReleaseType()
mainFile.changelog = changelogRaw
mainFile.changelogType = 'markdown'
@@ -935,12 +743,6 @@ if (cfApiKey.isPresent() || deploymentDebug.toBoolean()) {
}
String[] parts = dep.split(':')
String type = parts[0], slug = parts[1]
def types = [
'req' : 'requiredDependency', 'required': 'requiredDependency',
'opt' : 'optionalDependency', 'optional': 'optionalDependency',
'embed' : 'embeddedLibrary', 'embedded': 'embeddedLibrary',
'incomp': 'incompatible', 'fail' : 'incompatible']
if (types.containsKey(type)) type = types[type]
if (!(type in ['requiredDependency', 'embeddedLibrary', 'optionalDependency', 'tool', 'incompatible'])) {
throw new Exception('Invalid Curseforge dependency type: ' + type)
}
@@ -965,7 +767,6 @@ if (modrinthApiKey.isPresent() || deploymentDebug.toBoolean()) {
modrinth {
token = modrinthApiKey.getOrElse('debug_token')
projectId = modrinthProjectId
versionName = versionDisplayFormat.replace('$MOD_NAME', modName).replace('$VERSION', modVersion)
changelog = changelogFile.exists() ? changelogFile.getText('UTF-8') : ""
versionType = getReleaseType()
versionNumber = modVersion
@@ -983,7 +784,7 @@ if (modrinthApiKey.isPresent() || deploymentDebug.toBoolean()) {
}
String[] parts = dep.split(':')
String[] qual = parts[0].split('-')
addModrinthDep(qual[0], qual.length > 1 ? qual[1] : 'project', parts[1])
addModrinthDep(qual[0], qual[1], parts[1])
}
}
tasks.modrinth.dependsOn(build)
@@ -992,17 +793,9 @@ if (modrinthApiKey.isPresent() || deploymentDebug.toBoolean()) {
def addModrinthDep(String scope, String type, String name) {
com.modrinth.minotaur.dependencies.Dependency dep
def types = [
'req' : 'required',
'opt' : 'optional',
'embed' : 'embedded',
'incomp': 'incompatible', 'fail': 'incompatible']
if (types.containsKey(scope)) scope = types[scope]
if (!(scope in ['required', 'optional', 'incompatible', 'embedded'])) {
throw new Exception('Invalid modrinth dependency scope: ' + scope)
}
types = ['proj': 'project', '': 'project', 'p': 'project', 'ver': 'version', 'v': 'version']
if (types.containsKey(type)) type = types[type]
switch (type) {
case 'project':
dep = new ModDependency(name, scope)
@@ -1030,8 +823,8 @@ if (customMavenPublishUrl) {
}
// providers is not available here, use System for getting env vars
groupId = System.getenv('ARTIFACT_GROUP_ID') ?: project.mavenArtifactGroup
artifactId = System.getenv('ARTIFACT_ID') ?: project.modArchivesBaseName
groupId = System.getenv('ARTIFACT_GROUP_ID') ?: project.group
artifactId = System.getenv('ARTIFACT_ID') ?: project.name
version = System.getenv('RELEASE_VERSION') ?: publishedVersion
}
}
@@ -1069,6 +862,7 @@ def getReleaseType() {
* Next, if 'generateDefaultChangelog' option is enabled, use that.
* Otherwise, try to use a CHANGELOG.md file at root directory.
*/
def getChangelog() {
def final changelogEnv = providers.environmentVariable('CHANGELOG_LOCATION')
if (changelogEnv.isPresent()) {
@@ -1083,7 +877,7 @@ def getChangelog() {
// Buildscript updating
def buildscriptGradleVersion = '8.5'
def buildscriptGradleVersion = '8.1.1'
tasks.named('wrapper', Wrapper).configure {
gradleVersion = buildscriptGradleVersion
@@ -1118,18 +912,29 @@ static URL availableBuildScriptUrl() {
new URL("https://raw.githubusercontent.com/GregTechCEu/Buildscripts/master/build.gradle")
}
static URL availableSettingsGradleUrl() {
static URL exampleSettingsGradleUrl() {
new URL("https://raw.githubusercontent.com/GregTechCEu/Buildscripts/master/settings.gradle")
}
boolean verifySettingsGradle() {
def settingsFile = getFile("settings.gradle")
if (!settingsFile.exists()) {
println("Downloading default settings.gradle")
exampleSettingsGradleUrl().withInputStream { i -> settingsFile.withOutputStream { it << i } }
return true
}
return false
}
boolean performBuildScriptUpdate() {
if (isNewBuildScriptVersionAvailable()) {
def buildscriptFile = getFile("build.gradle")
def settingsFile = getFile("settings.gradle")
availableBuildScriptUrl().withInputStream { i -> buildscriptFile.withOutputStream { it << i } }
availableSettingsGradleUrl().withInputStream { i -> settingsFile.withOutputStream { it << i } }
def out = services.get(StyledTextOutputFactory).create('buildscript-update-output')
out.style(Style.Success).print("Build script updated. Please REIMPORT the project or RESTART your IDE!")
if (verifySettingsGradle()) {
throw new GradleException("Settings has been updated, please re-run task.")
}
return true
}
return false
@@ -1176,11 +981,6 @@ tasks.register('faq') {
// Helpers
def getDefaultArtifactGroup() {
def lastIndex = project.modGroup.lastIndexOf('.')
return lastIndex < 0 ? project.modGroup : project.modGroup.substring(0, lastIndex)
}
def getFile(String relativePath) {
return new File(projectDir, relativePath)
}
@@ -1224,4 +1024,4 @@ def getLastTag() {
def githubTag = providers.environmentVariable('GITHUB_TAG')
return runShell('git describe --abbrev=0 --tags ' +
(githubTag.isPresent() ? runShell('git rev-list --tags --skip=1 --max-count=1') : ''))
}
}
-52
View File
@@ -1,52 +0,0 @@
//file:noinspection DependencyNotationArgument
// TODO remove when fixed in RFG ^
/*
* Add your dependencies here. Common configurations:
* - implementation("group:name:version:classifier"): if you need this for internal implementation details of the mod.
* Available at compiletime and runtime for your environment.
*
* - compileOnlyApi("g:n:v:c"): if you need this for internal implementation details of the mod.
* Available at compiletime but not runtime for your environment.
*
* - annotationProcessor("g:n:v:c"): mostly for java compiler plugins, if you know you need this, use it, otherwise don't worry
*
* - testCONFIG("g:n:v:c"): replace CONFIG by one of the above, same as above but for the test sources instead of main
*
* You can exclude transitive dependencies (dependencies of the chosen dependency) by appending { transitive = false } if needed.
*
* To add a mod with CurseMaven, replace '("g:n:v:c")' in the above with 'rfg.deobf("curse.maven:project_slug-project_id:file_id")'
* Example: implementation rfg.deobf("curse.maven:gregtech-ce-unofficial-557242:4527757")
*
* To shadow a dependency, use 'shadowImplementation'. For more info, see https://github.com/GregTechCEu/Buildscripts/blob/master/docs/shadow.md
*
* For more details, see https://docs.gradle.org/8.0.1/userguide/java_library_plugin.html#sec:java_library_configurations_graph
*/
dependencies {
// Mods always in-game
implementation rfg.deobf("curse.maven:gregtechceu-557242:4429261") // GTCEu
implementation rfg.deobf("curse.maven:codechicken-lib-1-8-242818:2779848") // CCL 3.2.3.358
implementation rfg.deobf("curse.maven:baubles-227083:2518667") // Baubles
implementation rfg.deobf("curse.maven:industrial-craft-242638:2547175") // IC2
implementation rfg.deobf("curse.maven:forestry-59751:2684780") // Forestry
// Mods only in code by default
compileOnly "curse.maven:chisel-235279:2915375"
compileOnly "curse.maven:hwyla-253449:2568751"
compileOnly "curse.maven:recipe-stages-280554:3405072"
compileOnly "curse.maven:item-stages-280316:2696769"
compileOnly "curse.maven:game-stages-268655:2951844"
compileOnly "net.darkhax.tesla:Tesla-1.12.2:1.0.63"
compileOnly "curse.maven:CoFHCore-69162:2920433"
compileOnly "CraftTweaker2:CraftTweaker2-API:4.1.20.684"
compileOnly "curse.maven:inventory-tweaks-223094:2482482"
compileOnly "curse.maven:inventory-bogo-sorter-632327:4399738"
compileOnly rfg.deobf("curse.maven:ctm-267602:2915363") // CTM 1.0.2.31
compileOnly rfg.deobf("curse.maven:actually-additions-228404:3117927") // ActuallyAdditions r152
}
minecraft {
injectedTags.put('AEVERSION', aeversion)
injectedTags.put('AECHANNEL', aechannel)
injectedTags.put('AEBUILD', aebuild)
}
+73 -109
View File
@@ -1,184 +1,148 @@
modName = AE2 Unofficial Extended Life
# This is a case-sensitive string to identify your mod. Convention is to use lower case.
modId = appliedenergistics2
modGroup = appeng
# Version of your mod.
# This field can be left empty if you want your mod's version to be determined by the latest git tag instead.
modVersion =
# AE2 Specific Version Settings
aeversion=rv6
aechannel=stable
aebuild=7
aegroup=appeng
aebasename=appliedenergistics2
#########################################################
# Versions #
#########################################################
minecraft_version=1.12.2
mcp_mappings=snapshot_20171003
forge_version=14.23.5.2847
#########################################################
# Installable #
#########################################################
hwyla_version=1.8.26-B41_1.12.2
#########################################################
# Provided APIs #
#########################################################
jei_version=4.16.1.302
tesla_version=1.0.63
ic2_version=2.8.73-ex112
top_version=1.12-1.4.23-16
crafttweaker_version=4.1.20.684
ctm_version=MC1.12.2-0.3.1.16
forestry_version=5.8.2.387
#########################################################
# Deployment #
#########################################################
website_version=1.12.2
curse_versions=1.12.2
mapping_channel=snapshot
mapping_version=20171003
# Run Configurations
minecraft_username=Developer
extra_jvm_args=
modName=AE2 Unofficial Extended Life
# This is a case-sensitive string to identify your mod. Convention is to use lower case.
modId=appliedenergistics2
modGroup=appeng
# Version of your mod.
# This field can be left empty if you want your mod's version to be determined by the latest git tag instead.
modVersion=rv6-stable-7-extended_life-v0.55.29
# Whether to use the old jar naming structure (modid-mcversion-version) instead of the new version (modid-version)
includeMCVersionJar = false
includeMCVersionJar=false
# The name of your jar when you produce builds, not including any versioning info
modArchivesBaseName = ae2-uel
modArchivesBaseName=appliedenergistics2
# Will update your build.gradle automatically whenever an update is available
autoUpdateBuildScript = false
minecraftVersion = 1.12.2
autoUpdateBuildScript=false
minecraftVersion=1.12.2
# Select a username for testing your mod with breakpoints. You may leave this empty for a random username 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
# Alternatively this can be set with the 'DEV_USERNAME' environment variable.
developmentEnvironmentUserName = Developer
developmentEnvironmentUserName=Developer
# Enables using modern java syntax (up to version 17) via Jabel, while still targeting JVM 8.
# See https://github.com/bsideup/jabel for details on how this works.
# Using this requires that you use a Java 17 JDK for development.
enableModernJavaSyntax = true
enableModernJavaSyntax=true
# Generate a class with String fields for the mod id, name and version named with the fields below
generateGradleTokenClass = appeng.Tags
gradleTokenModId = MODID
gradleTokenModName = MODNAME
gradleTokenVersion = VERSION
generateGradleTokenClass=appeng.Tags
gradleTokenModId=
gradleTokenModName=
gradleTokenVersion=VERSION
# 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 = api
# If you want to keep your API code in src/api instead of src/main
useSrcApiPath = true
apiPackage=api
# Specify the configuration file for Forge's access transformers here. It must be placed into /src/main/resources/
# There can be multiple files in a comma-separated list.
# Example value: mymodid_at.cfg,jei_at.cfg
accessTransformersFile = appliedenergistics2_at.cfg
accessTransformersFile=appliedenergistics2_at.cfg
# Provides setup for Mixins if enabled. If you don't know what mixins are: Keep it disabled!
usesMixins = false
usesMixins=false
# Specify the package that contains all of your Mixins. You may only place Mixins in this package or the build will fail!
mixinsPackage =
# Automatically generates a mixin config json if enabled, with the name mixins.modid.json
generateMixinConfig = false
mixinsPackage=
# Specify the core mod entry class if you use a core mod. This class must implement IFMLLoadingPlugin!
# Example value: coreModClass = asm.FMLPlugin + modGroup = com.myname.mymodid -> com.myname.mymodid.asm.FMLPlugin
coreModClass = core.AE2ELCore
coreModClass=core.AE2ELCore
# If your project is only a consolidation of mixins or a core mod and does NOT contain a 'normal' mod (meaning that
# there is no class annotated with @Mod) you want this to be true. When in doubt: leave it on false!
containsMixinsAndOrCoreModOnly = false
containsMixinsAndOrCoreModOnly=false
# Enables Mixins even if this mod doesn't use them, useful if one of the dependencies uses mixins.
forceEnableMixins = false
# Outputs pre-transformed and post-transformed loaded classes to run/CLASSLOADER_TEMP. Can be used in combination with
# diff to see exactly what your ASM or Mixins are changing in the target file.
# Optionally can be specified with the 'CORE_MOD_DEBUG' env var. Will output a lot of files!
enableCoreModDebug = false
forceEnableMixins=false
# Adds CurseMaven, Modrinth Maven, BlameJared maven, and some more well-known 1.12.2 repositories
includeWellKnownRepositories = true
includeWellKnownRepositories=true
# Adds JEI and TheOneProbe to your development environment. Adds them as 'implementation', meaning they will
# be available at compiletime and runtime for your mod (in-game and in-code).
# Overrides the above setting to be always true, as these repositories are needed to fetch the mods
includeCommonDevEnvMods = true
includeCommonDevEnvMods=true
# 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
usesShadowedDependencies=false
# If disabled, won't remove unused classes from shaded dependencies. Some libraries use reflection to access
# their own classes, making the minimization unreliable.
minimizeShadowedDependencies = true
minimizeShadowedDependencies=true
# If disabled, won't rename the shadowed classes.
relocateShadowedDependencies = true
# Separate run directories into "run/client" for runClient task, and "run/server" for runServer task.
# Useful for debugging a server and client simultaneously. If not enabled, it will be in the standard location "run/"
separateRunDirectories = false
# The display name format of versions published to Curse and Modrinth. $MOD_NAME and $VERSION are available variables.
# Default: $MOD_NAME \u2212 $VERSION. \u2212 is the minus character which looks much better than the hyphen minus on Curse.
versionDisplayFormat = $MOD_NAME \u2212 $VERSION
relocateShadowedDependencies=true
# Publishing to modrinth requires you to set the MODRINTH_API_KEY environment variable to your current modrinth API token.
# The project's ID on Modrinth. Can be either the slug or the ID.
# Leave this empty if you don't want to publish on Modrinth.
# Alternatively this can be set with the 'MODRINTH_PROJECT_ID' environment variable.
modrinthProjectId =
modrinthProjectId=
# The project's relations on Modrinth. You can use this to refer to other projects on Modrinth.
# Syntax: scope1-type1:name1;scope2-type2:name2;...
# Where scope can be one of [required, optional, incompatible, embedded],
# type can be one of [project, version],
# and the name is the Modrinth project or version slug/id of the other mod.
# Example: required-project:jei;optional-project:top;incompatible-project:gregtech
modrinthRelations =
modrinthRelations=
# Publishing to CurseForge requires you to set the CURSEFORGE_API_KEY environment variable to one of your CurseForge API tokens.
# The project's numeric ID on CurseForge. You can find this in the About Project box.
# Leave this empty if you don't want to publish on CurseForge.
# Alternatively this can be set with the 'CURSEFORGE_PROJECT_ID' environment variable.
curseForgeProjectId =
curseForgeProjectId=
# The project's relations on CurseForge. You can use this to refer to other projects on CurseForge.
# Syntax: type1:name1;type2:name2;...
# Where type can be one of [requiredDependency, embeddedLibrary, optionalDependency, tool, incompatible],
# and the name is the CurseForge project slug of the other mod.
# Example: requiredDependency:railcraft;embeddedLibrary:cofhlib;incompatible:buildcraft
curseForgeRelations =
curseForgeRelations=
# This project's release type on CurseForge and/or Modrinth
# Alternatively this can be set with the 'RELEASE_TYPE' environment variable.
# Allowed types: release, beta, alpha
releaseType = release
releaseType=beta
# Generate a default changelog for releases. Requires git to be installed, as it uses it to generate a changelog of
# commits since the last tagged release.
generateDefaultChangelog = false
generateDefaultChangelog=false
# Prevent the source code from being published
noPublishedSources = false
# Publish to a custom maven location. Follows a few rules:
# Group ID can be set with the 'ARTIFACT_GROUP_ID' environment variable, default to 'project.group'
# Artifact ID can be set with the 'ARTIFACT_ID' environment variable, default to 'project.name'
# Version can be set with the 'RELEASE_VERSION' environment variable, default to 'modVersion'
# For maven credentials:
# Username is set with the 'MAVEN_USER' environment variable, default to "NONE"
# Password is set with the 'MAVEN_PASSWORD' environment variable, default to "NONE"
customMavenPublishUrl = https://maven.gtceu.com
# The group for maven artifacts. Defaults to the 'project.modGroup' until the last '.' (if any).
# So 'mymod' becomes 'mymod' and 'com.myname.mymodid' 'becomes com.myname'
mavenArtifactGroup =
noPublishedSources=false
# Enable spotless checks
# Enforces code formatting on your source code
# By default this will use the files found here: https://github.com/GregTechCEu/Buildscripts/tree/master/spotless
# to format your code. However, you can create your own version of these files and place them in your project's
# root directory to apply your own formatting options instead.
enableSpotless = false
enableSpotless=false
# Enable JUnit testing platform used for testing your code.
# Uses JUnit 5. See guide and documentation here: https://junit.org/junit5/docs/current/user-guide/
enableJUnit = true
enableJUnit=true
# Deployment debug setting
# Uncomment this to test deployments to CurseForge and Modrinth
# Alternatively, you can set the 'DEPLOYMENT_DEBUG' environment variable.
deploymentDebug = false
deploymentDebug=false
# Gradle Settings
# Effectively applies the '--stacktrace' flag by default
org.gradle.logging.stacktrace = all
org.gradle.logging.stacktrace=all
# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
# This is required to provide enough memory for the Minecraft decompilation process.
org.gradle.jvmargs = -Xmx3G
org.gradle.jvmargs=-Xmx3G
+116
View File
@@ -0,0 +1,116 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
repositories {
mavenLocal()
maven {
url "https://cursemaven.com"
}
maven {
name = "CurseForge"
url = "https://minecraft.curseforge.com/api/maven/"
}
maven {
name "Mobius"
url "http://mobiusstrip.eu/maven"
}
maven {
name = "JEI repo"
url "http://dvs1.progwml6.com/files/maven"
}
maven {
name "Ellpeck"
url "https://maven.ellpeck.de"
}
maven {
name = "CoFH Maven"
url = "http://maven.covers1624.net"
}
maven { // TheOneProbe
name 'tterrag maven'
url "http://maven.tterrag.com/"
}
maven { // McJtyLib
name 'mcjty'
url "http://maven.k-4u.nl/"
}
maven { // CraftTweaker
name 'jared maven'
url "http://maven.blamejared.com/"
}
//maven { // modmaven, maven proxy
// name 'modmaven'
// url "https://modmaven.k-4u.nl/"
//}
}
configurations {
mods
}
dependencies {
// deobfCompile "gregtechce:gregtech:1.12.2:1.15.1.735"
// installable runtime dependencies
implementation rfg.deobf("curse.maven:gregtechceu-557242:4429261")
compileOnly "curse.maven:chisel-235279:2915375"
implementation rfg.deobf("curse.maven:baubles-227083:2518667")
//mods "mcp.mobius.waila:Hwyla:${hwyla_version}"
mods "curse.maven:hwyla-253449:2568751"
mods "net.industrial-craft:industrialcraft-2:${ic2_version}:dev"
mods "mcjty.theoneprobe:TheOneProbe-${minecraft_version}:${top_version}"
// compile against provided APIs
compileOnly "mezz.jei:jei_${minecraft_version}:${jei_version}:api"
//compileOnly "mcp.mobius.waila:Hwyla:${hwyla_version}"
compileOnly "curse.maven:hwyla-253449:2568751"
//Code chicken lib, GTCE dependency
implementation rfg.deobf("curse.maven:CCL-242818:2779848")
compileOnly "curse.maven:recipe-stages-280554:3405072"
compileOnly "curse.maven:item-stages-280316:2696769"
compileOnly "curse.maven:game-stages-268655:2951844"
compileOnly "net.darkhax.tesla:Tesla-1.12.2:${tesla_version}"
//compileOnly "net.industrial-craft:industrialcraft-2:${ic2_version}:api"
implementation rfg.deobf("curse.maven:industrial-craft-242638:2547175")
compileOnly "mcjty.theoneprobe:TheOneProbe-1.12:${top_version}:api"
compileOnly "curse.maven:CoFHCore-69162:2920433"
compileOnly "CraftTweaker2:CraftTweaker2-API:${crafttweaker_version}"
compileOnly "curse.maven:inventory-tweaks-223094:2482482"
compileOnly "curse.maven:inventory-bogo-sorter-632327:4399738"
compileOnly "team.chisel.ctm:CTM:${ctm_version}"
compileOnly "de.ellpeck.actuallyadditions:ActuallyAdditions:1.12.2-r152.16:api"
implementation rfg.deobf("curse.maven:forestry-59751:2684780")
// at runtime, use the full JEI jar
runtimeOnly "mezz.jei:jei_${minecraft_version}:${jei_version}"
// unit test dependencies
testImplementation "junit:junit:4.12"
}
+54
View File
@@ -0,0 +1,54 @@
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
// HWYLA
tasks.register('installHwyla', Copy) {
dependsOn "deinstallHwyla"
from { configurations.mods }
include "**/*Hwyla*.jar"
into file("/run/mods")
}
tasks.register('deinstallHwyla', Delete) {
delete fileTree(dir: "/run/mods", include: "*Hwyla*.jar")
}
// IC2
tasks.register('installIC2', Copy) {
dependsOn "deinstallIC2"
from { configurations.mods }
include "**/*industrialcraft-2*.jar"
into file("/run/mods")
}
tasks.register('deinstallIC2', Delete) {
delete fileTree(dir: "/run/mods", include: "*industrialcraft-2*.jar")
}
// TOP
tasks.register('installTop', Copy) {
dependsOn["deinstallTop"]
from { configurations.mods }
include "**/*TheOneProbe*.jar"
into file("/run/mods")
}
tasks.register('deinstallTop', Delete) {
delete fileTree(dir: "/run/mods", include: "*TheOneProbe*.jar")
}
+1 -2
View File
@@ -1,7 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-all.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+4 -8
View File
@@ -85,6 +85,9 @@ done
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -130,13 +133,10 @@ location of your Java installation."
fi
else
JAVACMD=java
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
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
fi
# Increase the maximum file descriptors if we can.
@@ -197,10 +197,6 @@ if "$cygwin" || "$msys" ; then
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
Vendored
+24 -32
View File
@@ -1,20 +1,4 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%"=="" @echo off
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@@ -25,23 +9,19 @@
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -55,7 +35,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -65,26 +45,38 @@ echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
+5 -9
View File
@@ -3,7 +3,9 @@ pluginManagement {
maven {
// RetroFuturaGradle
name 'GTNH Maven'
url 'https://nexus.gtnewhorizons.com/repository/public/'
//noinspection HttpUrlsUsage
url 'http://jenkins.usrv.eu:8081/nexus/content/groups/public/'
allowInsecureProtocol = true
//noinspection GroovyAssignabilityCheck
mavenContent {
includeGroup 'com.gtnewhorizons'
@@ -17,14 +19,8 @@ pluginManagement {
}
plugins {
id 'com.diffplug.blowdryerSetup' version '1.7.0'
// Automatic toolchain provisioning
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.7.0'
id 'org.gradle.toolchains.foojay-resolver-convention' version '0.4.0'
}
blowdryerSetup {
repoSubfolder 'spotless'
github 'GregTechCEu/Buildscripts', 'tag', 'v1.0.7'
}
rootProject.name = rootProject.projectDir.getName()
rootProject.name = rootProject.projectDir.getName()
@@ -38,12 +38,8 @@ public enum ActionItems
DIVIDE_BY_THREE,
DECREASE_BY_ONE,
MAX_COUNT,
MOLECULAR_ASSEMBLERS_ON,
MOLECULAR_ASSEMBLERS_OFF,
FREE_MOLECULAR_SLOT_SHORTCUT,
TOGGLE_SHOW_FULL_INTERFACES_ON,
TOGGLE_SHOW_FULL_INTERFACES_OFF,
TOGGLE_SHOW_ONLY_INVALID_PATTERNS_ON,
TOGGLE_SHOW_ONLY_INVALID_PATTERNS_OFF,
HIGHLIGHT_INTERFACE,
CONFIGURE_INTERFACE
}
HIGHLIGHT_INTERFACE
}
@@ -1,26 +0,0 @@
package appeng.api.config;
public enum LockCraftingMode {
/**
* Crafting is never locked.
*/
NONE,
/**
* After pushing a pattern to an adjacent machine, the interface will not accept further crafts until a
* redstone pulse is received.
*/
LOCK_UNTIL_PULSE,
/**
* Crafting is locked while the interface is receiving a redstone signal.
*/
LOCK_WHILE_HIGH,
/**
* Crafting is locked while the interface is not receiving a redstone signal.
*/
LOCK_WHILE_LOW,
/**
* After pushing a pattern to an adjacent machine, the interface will not accept further crafts until the
* primary pattern result is returned to the network through the interface.
*/
LOCK_UNTIL_RESULT
}
+1 -7
View File
@@ -57,8 +57,6 @@ public enum Settings
IO_DIRECTION( EnumSet.of( RelativeDirection.LEFT, RelativeDirection.RIGHT ) ),
UNLOCK(EnumSet.allOf(LockCraftingMode.class)),
BLOCK( EnumSet.of( YesNo.YES, YesNo.NO ) ),
OPERATION_MODE( EnumSet.allOf( OperationMode.class ) ),
@@ -83,11 +81,7 @@ public enum Settings
PLACE_BLOCK( EnumSet.of( YesNo.YES, YesNo.NO ) ),
SCHEDULING_MODE( EnumSet.allOf( SchedulingMode.class ) ),
STICKY_MODE( EnumSet.of( YesNo.YES, YesNo.NO ) ),
;
SCHEDULING_MODE( EnumSet.allOf( SchedulingMode.class ) );
private final EnumSet<? extends Enum<?>> values;
+12 -61
View File
@@ -24,65 +24,16 @@
package appeng.api.config;
import appeng.api.AEApi;
import appeng.api.definitions.IItemDefinition;
import appeng.api.definitions.IParts;
import appeng.api.parts.IPartItem;
import com.google.common.base.Preconditions;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.util.EnumHelper;
import javax.annotation.Nonnull;
import java.util.function.Function;
import java.util.function.Supplier;
public enum TunnelType {
ME(tryPartStack(IParts::p2PTunnelME)),
IC2_POWER(tryPartStack(IParts::p2PTunnelEU)),
FE_POWER(tryPartStack(IParts::p2PTunnelFE)),
GTEU_POWER(tryPartStack(IParts::p2PTunnelGTEU)),
REDSTONE(tryPartStack(IParts::p2PTunnelRedstone)),
FLUID(tryPartStack(IParts::p2PTunnelFE)),
ITEM(tryPartStack(IParts::p2PTunnelItems)),
LIGHT(tryPartStack(IParts::p2PTunnelLight));
private ItemStack partItemStack;
private Supplier<ItemStack> partItemStackSupplier;
@Deprecated
TunnelType() {
this.partItemStack = ItemStack.EMPTY;
this.partItemStackSupplier = null;
}
// Public facing.
TunnelType(ItemStack partItemStack) {
this.partItemStack = partItemStack;
this.partItemStackSupplier = null;
}
// Work around things instantiating this class too early.
TunnelType(Supplier<ItemStack> supplier) {
this.partItemStack = null;
this.partItemStackSupplier = supplier;
}
private static Supplier<ItemStack> tryPartStack(Function<IParts, IItemDefinition> supplier) {
return () -> supplier.apply(AEApi.instance().definitions().parts()).maybeStack(1).orElse(ItemStack.EMPTY);
}
public static TunnelType registerTunnelType(@Nonnull String name, @Nonnull ItemStack partItemStack) {
Preconditions.checkArgument(partItemStack.isEmpty() || partItemStack.getItem() instanceof IPartItem<?>,
"Part item must be an instance of IPartItem");
return EnumHelper.addEnum(TunnelType.class, name, new Class[]{ItemStack.class}, partItemStack);
}
public ItemStack getPartItemStack() {
if (this.partItemStackSupplier != null) {
this.partItemStack = this.partItemStackSupplier.get();
this.partItemStackSupplier = null;
}
return partItemStack;
}
public enum TunnelType
{
ME, // Network Tunnel
IC2_POWER, // EU Tunnel
FE_POWER, // Forge Energy tunnel
GTEU_POWER, // Forge Energy tunnel
REDSTONE, // Redstone Tunnel
FLUID, // Fluid Tunnel
ITEM, // Item Tunnel
LIGHT, // Light Tunnel
BUNDLED_REDSTONE, // Bundled Redstone Tunnel
COMPUTER_MESSAGE // Computer Message Tunnel
}
@@ -40,7 +40,6 @@ public enum Upgrades {
REDSTONE(0),
CRAFTING(0),
MAGNET(0),
STICKY(0),
/**
* Diamond Tier Upgrades.
@@ -67,8 +67,6 @@ public interface IItems {
IItemDefinition wirelessPatternTerminal();
IItemDefinition wirelessInterfaceTerminal();
IItemDefinition wirelessFluidTerminal();
IItemDefinition biometricCard();
@@ -100,8 +100,6 @@ public interface IMaterials {
IItemDefinition cardCrafting();
IItemDefinition cardSticky();
IItemDefinition enderDust();
IItemDefinition flour();
@@ -19,12 +19,13 @@
package appeng.api.features;
import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import java.util.List;
import java.util.Optional;
import javax.annotation.Nonnull;
import net.minecraft.item.ItemStack;
/**
* Registration Records for {@link IInscriberRegistry}
@@ -56,35 +57,21 @@ public interface IInscriberRecipe
@Nonnull
ItemStack getOutput();
@Nonnull
List<ItemStack> getTopInputs();
/**
* gets the top optional
*
* @return item which is used top
*/
@Deprecated
@Nonnull
default Optional<ItemStack> getTopOptional(){
return getTopInputs().isEmpty() ? Optional.empty() : Optional.of(getTopInputs().get(0));
}
@Nonnull
List<ItemStack> getBottomInputs();
Optional<ItemStack> getTopOptional();
/**
* gets the bottom optional
*
* @return item which is used bottom
*/
@Deprecated
@Nonnull
default Optional<ItemStack> getBottomOptional() {
return getBottomInputs().isEmpty() ? Optional.empty() : Optional.of(getBottomInputs().get(0));
}
Optional<ItemStack> getBottomOptional();
/**
* type of inscriber process
@@ -19,11 +19,11 @@
package appeng.api.features;
import net.minecraft.item.ItemStack;
import java.util.Collection;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.Collections;
import net.minecraft.item.ItemStack;
/**
@@ -66,7 +66,7 @@ public interface IInscriberRecipeBuilder
* @return currently used builder
*/
@Nonnull
IInscriberRecipeBuilder withTopOptional(@Nonnull Collection<ItemStack> topOptional );
IInscriberRecipeBuilder withTopOptional( @Nonnull ItemStack topOptional );
/**
* Creates an inscriber recipe with bot.
@@ -77,7 +77,7 @@ public interface IInscriberRecipeBuilder
* @return currently used builder
*/
@Nonnull
IInscriberRecipeBuilder withBottomOptional( @Nonnull Collection<ItemStack> bottomOptional );
IInscriberRecipeBuilder withBottomOptional( @Nonnull ItemStack bottomOptional );
/**
* Creates an inscriber recipe with type.
@@ -104,14 +104,4 @@ public interface IInscriberRecipeBuilder
*/
@Nonnull
IInscriberRecipe build();
@Deprecated
default IInscriberRecipeBuilder withTopOptional(@Nonnull ItemStack topOptional){
return withTopOptional(Collections.singleton(topOptional));
}
@Deprecated
default IInscriberRecipeBuilder withBottomOptional(@Nonnull ItemStack bottomOptional){
return withBottomOptional(Collections.singleton(bottomOptional));
}
}
@@ -24,12 +24,13 @@
package appeng.api.features;
import appeng.api.config.TunnelType;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.item.ItemStack;
import net.minecraftforge.common.capabilities.Capability;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import appeng.api.config.TunnelType;
/**
@@ -58,8 +59,6 @@ public interface IP2PTunnelRegistry
*
* @return null if no attunement can be found or attunement
*/
@Nullable
@Nonnull
TunnelType getTunnelTypeByItem( ItemStack trigger );
TunnelType registerTunnelType( @Nonnull String enumName, @Nonnull ItemStack partStack );
}
@@ -77,14 +77,6 @@ public interface ICraftingPatternDetails
*/
IAEItemStack[] getCondensedOutputs();
/**
* The primary output of this pattern. The pattern will only be used to craft the primary output; the others are
* just byproducts.
*/
default IAEItemStack getPrimaryOutput() {
return getOutputs()[0];
}
/**
* @return a list of the outputs, will include nulls.
*/
@@ -41,13 +41,6 @@ import appeng.api.util.AEPartLocation;
public interface IFacadeContainer
{
/**
* Checks if the {@link IFacadePart} can be added to the given side.
*
* @return true if the facade can be successfully added
*/
boolean canAddFacade( IFacadePart a );
/**
* Attempts to add the {@link IFacadePart} to the given side.
*
+26 -50
View File
@@ -24,7 +24,6 @@
package appeng.api.parts;
import appeng.api.util.AEPartLocation;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumActionResult;
@@ -33,11 +32,35 @@ import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import javax.annotation.Nullable;
public interface IPartHelper
{
/**
* Register a new layer with the part layer system, this allows you to write an in between between tile entities and
* parts.
*
* AE By Default includes,
*
* 1. ISidedInventory ( and by extension IInventory. )
*
* 2. IFluidHandler Forge Fluids
*
* 3. IPowerEmitter BC Power output.
*
* 4. IPowerReceptor BC Power input.
*
* 5. IEnergySink IC2 Power input.
*
* 6. IEnergySource IC2 Power output.
*
* 7. IPipeConnection BC Pipe Connections
*
* As long as a valid layer is registered for a interface you can simply implement that interface on a part get
* implement it.
*
* @return true on success, false on failure, usually a error will be logged as well.
*/
boolean registerNewLayer( String string, String layerInterface );
/**
* use in use item, to try and place a IBusItem
@@ -56,51 +79,4 @@ public interface IPartHelper
* @return the render mode
*/
CableRenderMode getCableRenderMode();
/**
* Try to get a part at a specific place in the world.
*
* @param w world the part is in
* @param pos pos of the part host
* @param side side to test for a part on.
*
* @return the part if it exists, null otherwise
*/
@Nullable
IPart getPart( World w, BlockPos pos, AEPartLocation side );
/**
* Try to get a part host at a specific place in the world.
*
* @param w world the part host is in
* @param pos pos of the part host
*
* @return the part host if it exists, null otherwise
*/
@Nullable
IPartHost getPartHost( World w, BlockPos pos );
/**
* Get a part host if it exists, or place one if it doesn't.
*
* @param w world the part host is in
* @param pos pos to get or place the part host
* @param force whether to skip permission and existing block checks and forcibly place the part host here.
* @param p the placing player, or null if none
*
* @return the existing or created part host, or null if it didn't already exist and part host is unable to be placed.
*/
@Nullable
IPartHost getOrPlacePartHost( World w, BlockPos pos, boolean force, @Nullable EntityPlayer p );
/**
* Test if a part host can be successfully placed at a given position by the provided player.
*
* @param w world the part host is in
* @param pos pos to test for part host placement
* @param p the placing player, or null if none
*
* @return if the part can be placed at the provided world and position
*/
boolean canPlacePartHost( World w, BlockPos pos, @Nullable EntityPlayer p );
}
+7 -13
View File
@@ -145,24 +145,13 @@ public interface IPartHost extends ICustomCableConnection
*/
SelectedPart selectPart( Vec3d pos );
/**
* Same as {@link #selectPart(Vec3d)}, but with global instead of local coordinates.
*/
default SelectedPart selectPartGlobal( Vec3d pos ) {
DimensionalCoord globalPos = getLocation();
return selectPart(pos.subtract(
globalPos.getPos().getX(),
globalPos.getPos().getY(),
globalPos.getPos().getZ()));
}
/**
* can be used by parts to trigger the tile or part to save.
*/
void markForSave();
/**
* called when parts are added or removed
* part of the {@link LayerBase}
*/
void partChanged();
@@ -180,6 +169,11 @@ public interface IPartHost extends ICustomCableConnection
*/
boolean isEmpty();
/**
* @return a mutable list of flags you can adjust to track state.
*/
Set<LayerFlags> getLayerFlags();
/**
* remove host from world...
*/
@@ -197,4 +191,4 @@ public interface IPartHost extends ICustomCableConnection
*/
boolean isInWorld();
}
}
@@ -0,0 +1,98 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 AlgorithmX2
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package appeng.api.parts;
import java.util.Set;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import appeng.api.util.AEPartLocation;
/**
* All Layers must extends this, this get part implementation is provided to interface with the parts, however a real
* implementation will be used at runtime.
*
* TODO: Consider removing and replacing with capabilities.
*/
public abstract class LayerBase extends TileEntity // implements IPartHost
{
/**
* Grants access for the layer to the parts of the host.
*
* This Method looks silly, that is because its not used at runtime, a real implementation will be used instead.
*
* @param side side of part
*
* @return the part for the requested side.
*/
public IPart getPart( final AEPartLocation side )
{
return null; // place holder.
}
/**
* Grants access for the layer to the parts of the host.
*
* This Method looks silly, that is because its not used at runtime, a real implementation will be used instead.
*
* @param side side of part
*
* @return the part for the requested side.
*/
public IPart getPart( final EnumFacing side )
{
return null; // place holder.
}
/**
* called when the parts change in the container, YOU MUST CALL super.PartChanged();
*/
public void notifyNeighbors()
{
}
/**
* called when the parts change in the container, YOU MUST CALL super.PartChanged();
*/
public void partChanged()
{
}
/**
* @return a mutable list of flags you can adjust to track state.
*/
public Set<LayerFlags> getLayerFlags()
{
return null; // place holder.
}
public void markForSave()
{
// something!
}
}
@@ -0,0 +1,35 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 AlgorithmX2
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package appeng.api.parts;
/**
* TODO: Consider removing and replacing with capabilities.
*/
public enum LayerFlags
{
IC2_ENET
}
@@ -89,12 +89,4 @@ public interface IMEInventoryHandler<T extends IAEStack<T>> extends IMEInventory
* @return true, if this inventory is valid for this pass.
*/
boolean validForPass( int i );
/**
* Gets whether an inventory is "Sticky" i.e. only it and other sticky storages that have partitions with certain
* items are allowed to be put into sticky storages.
*/
default boolean isSticky() {
return false;
}
}
@@ -1,87 +0,0 @@
package yalter.mousetweaks.api;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.Slot;
/**
* This is the interface you want to implement in your GuiScreen to make it compatible with Mouse Tweaks.
* If this interface is not enough (for example, you need a custom slot click function, or if you use a custom Container
* which happens to be incompatible), check IMTModGuiContainer2Ex instead.
* If you just need to disable Mouse Tweaks or the wheel tweak, see the MouseTweaksIgnore
* or the MouseTweaksDisableWheelTweak annotations.
*/
public interface IMTModGuiContainer2 {
/**
* If you want to disable Mouse Tweaks in your GuiScreen, return true from this method.
*
* @return True if Mouse Tweaks should be disabled, false otherwise.
*/
boolean MT_isMouseTweaksDisabled();
/**
* If you want to disable the Wheel Tweak in your GuiScreen, return true from this method.
*
* @return True if the Wheel Tweak should be disabled, false otherwise.
*/
boolean MT_isWheelTweakDisabled();
/**
* Returns the Container.
*
* @return Container that is currently in use.
*/
Container MT_getContainer();
/**
* Returns the Slot that is currently selected by the player, or null if no Slot is selected.
*
* @return Slot that is located under the mouse, or null if no Slot it currently under the mouse.
*/
Slot MT_getSlotUnderMouse();
/**
* Return true if the given Slot behaves like the vanilla crafting output slots (inside the crafting table,
* or the furnace output slot, or the anvil output slot, etc.). These slots are handled differently by Mouse Tweaks.
*
* @param slot the slot to check
* @return True if slot is a crafting output slot.
*/
boolean MT_isCraftingOutput(Slot slot);
/**
* Return true if the given Slot should be ignored by Mouse Tweaks. Examples of ignored slots are the item select
* slots and the Destroy Item slot in the vanilla creative inventory.
*
* @param slot the slot to check
* @return Tru if slot should be ignored by Mouse Tweaks.
*/
boolean MT_isIgnored(Slot slot);
/**
* If your container has an RMB dragging functionality (like vanilla containers), disable it inside this method.
* This method is called every frame (render tick), which is after all mouseClicked / mouseClickMove / mouseReleased
* events are handled (although note these events are handled every game tick, which is far less frequent than every
* render tick).<br><br>
* <p>
* If true is returned from this method, Mouse Tweaks (after checking other conditions like isIgnored) will click
* the slot on which the right mouse button was initially pressed (in most cases this is the slot currently under
* mouse). This is needed because the vanilla RMB dragging functionality prevents the initial slot click.<br><br>
* <p>
* For vanilla containers this method looks like this:
* <pre>
* this.ignoreMouseUp = true;
*
* if (this.dragSplitting) {
* if (this.dragSplittingButton == 1) {
* this.dragSplitting = false;
* return true;
* }
* }
*
* return false;
* </pre>
*
* @return True if Mouse Tweaks should click the slot on which the RMB was pressed.
*/
boolean MT_disableRMBDraggingFunctionality();
}
@@ -0,0 +1,14 @@
package yalter.mousetweaks.api;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Put this on your GuiScreen to disable Mouse Tweaks.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MouseTweaksIgnore {
}
@@ -21,10 +21,11 @@ package appeng.block;
import appeng.api.config.AccessRestriction;
import appeng.api.config.Actionable;
import appeng.api.config.PowerUnits;
import appeng.api.definitions.IBlockDefinition;
import appeng.api.implementations.items.IAEItemPowerStorage;
import appeng.core.Api;
import appeng.core.localization.Tooltips;
import appeng.core.localization.GuiText;
import appeng.util.Platform;
import net.minecraft.block.Block;
import net.minecraft.client.util.ITooltipFlag;
@@ -34,6 +35,7 @@ import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import java.text.MessageFormat;
import java.util.List;
@@ -55,7 +57,10 @@ public class AEBaseItemBlockChargeable extends AEBaseItemBlock implements IAEIte
internalCurrentPower = tag.getDouble("internalCurrentPower");
}
lines.add(Tooltips.energyStorageComponent(internalCurrentPower, internalMaxPower).getFormattedText());
final double percent = internalCurrentPower / internalMaxPower;
lines.add(GuiText.StoredEnergy.getLocal() + ':' + MessageFormat.format(" {0,number,#} ", internalCurrentPower) + Platform
.gui_localize(PowerUnits.AE.unlocalizedName) + " - " + MessageFormat.format(" {0,number,#.##%} ", percent));
}
}
@@ -25,14 +25,12 @@ import appeng.block.AEBaseTileBlock;
import appeng.core.sync.GuiBridge;
import appeng.tile.misc.TileInterface;
import appeng.util.Platform;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
@@ -95,12 +93,4 @@ public class BlockInterface extends AEBaseTileBlock {
((TileInterface) rotatable).setSide(axis);
}
}
@Override
public void neighborChanged(IBlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos) {
TileEntity tileEntity = this.getTileEntity(worldIn, pos);
if (tileEntity != null) {
((TileInterface) tileEntity).updateRedstoneState();
}
}
}
@@ -29,10 +29,9 @@ import appeng.block.AEBaseTileBlock;
import appeng.client.UnlistedProperty;
import appeng.client.render.cablebus.CableBusBakedModel;
import appeng.client.render.cablebus.CableBusRenderState;
import appeng.client.render.cablebus.FacadeRenderState;
import appeng.core.Api;
import appeng.core.AppEng;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketCableBusLandingParticle;
import appeng.core.sync.packets.PacketClick;
import appeng.helpers.AEGlassMaterial;
import appeng.integration.abstraction.IAEFacade;
@@ -72,12 +71,10 @@ import net.minecraft.util.math.RayTraceResult.Type;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.property.ExtendedBlockState;
import net.minecraftforge.common.property.IExtendedBlockState;
import net.minecraftforge.common.property.IUnlistedProperty;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
@@ -94,6 +91,10 @@ public class BlockCableBus extends AEBaseTileBlock implements IAEFacade {
private static final ICableBusContainer NULL_CABLE_BUS = new NullCableBusContainer();
private static Class<? extends AEBaseTile> noTesrTile;
private static Class<? extends AEBaseTile> tesrTile;
public BlockCableBus() {
super(AEGlassMaterial.INSTANCE);
this.setLightOpacity(0);
@@ -302,90 +303,6 @@ public class BlockCableBus extends AEBaseTileBlock implements IAEFacade {
return true;
}
@Override
public boolean addRunningEffects(IBlockState state, World world, BlockPos pos, Entity entity) {
if (world.isRemote) {
addRunningParticle(world, pos, entity);
}
return true;
}
@SideOnly(Side.CLIENT)
private void addRunningParticle(World world, BlockPos pos, Entity entity) {
final ICableBusContainer cb = this.cb(world, pos);
final IBakedModel model = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(this.getDefaultState());
if (!(model instanceof CableBusBakedModel cableBusModel)) {
return;
}
final CableBusRenderState renderState = cb.getRenderState();
final TextureAtlasSprite texture = getSpriteForParticle(renderState, cableBusModel);
if (texture != null) {
final double d0 = entity.posX + (world.rand.nextFloat() - 0.5f) * entity.width;
final double d1 = entity.getEntityBoundingBox().minY + 0.1f;
final double d2 = entity.posZ + (world.rand.nextFloat() - 0.5f) * entity.width;
final ParticleDigging particle = new DestroyFX(world, d0, d1, d2, -entity.motionX * 4.0f, 1.5f, -entity.motionZ * 4.0f, this.getDefaultState()).setBlockPos(pos);
particle.setParticleTexture(texture);
Minecraft.getMinecraft().effectRenderer.addEffect(particle);
}
}
@Override
public boolean addLandingEffects(IBlockState state, WorldServer world, BlockPos pos, IBlockState iblockstate, EntityLivingBase entity, int numberOfParticles) {
// for reasons only notch can explain, this method is only called on the server, so we have to sync
// a packet to all tracking players for landing particle effects
if (!world.isRemote) {
final PacketCableBusLandingParticle packet = new PacketCableBusLandingParticle(pos, entity, numberOfParticles);
final NetworkRegistry.TargetPoint point = new NetworkRegistry.TargetPoint(world.provider.getDimension(), pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, 32);
NetworkHandler.instance().sendToAllTracking(packet, point);
}
return true;
}
@SideOnly(Side.CLIENT)
public void addLandingParticle(BlockPos pos, double entityX, double entityY, double entityZ, int numberOfParticles) {
final World world = Minecraft.getMinecraft().world;
final ICableBusContainer cb = this.cb(world, pos);
final IBakedModel model = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(this.getDefaultState());
if (!(model instanceof CableBusBakedModel cableBusModel)) {
return;
}
final TextureAtlasSprite texture = getSpriteForParticle(cb.getRenderState(), cableBusModel);
if (texture != null) {
final Vec3d startVec = new Vec3d(entityX, entityY, entityZ);
final Vec3d endVec = startVec.add(0.0f, -4.0f, 0.0f);
RayTraceResult result = world.rayTraceBlocks(startVec, endVec, true, false, true);
final double speed = 0.15f;
if (result != null && result.typeOfHit == Type.BLOCK && numberOfParticles != 0) {
for (int i = 0; i < numberOfParticles; i++) {
final double d0 = world.rand.nextGaussian() * speed;
final double d1 = world.rand.nextGaussian() * speed;
final double d2 = world.rand.nextGaussian() * speed;
final ParticleDigging particle = new DestroyFX(world, entityX, entityY, entityZ, d0, d1, d2, this.getDefaultState()).setBlockPos(pos);
particle.setParticleTexture(texture);
Minecraft.getMinecraft().effectRenderer.addEffect(particle);
}
}
}
}
@SideOnly(Side.CLIENT)
private TextureAtlasSprite getSpriteForParticle(CableBusRenderState renderState, CableBusBakedModel cableBusModel) {
final FacadeRenderState frs = renderState.getFacades().get(EnumFacing.UP);
if (frs != null) {
final IBlockState state = frs.getSourceBlock();
final IBakedModel model = Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState(state);
return model.getParticleTexture();
}
return Platform.pickRandom(cableBusModel.getParticleTextures(renderState));
}
@Override
public void neighborChanged(IBlockState state, World world, BlockPos pos, Block blockIn, BlockPos fromPos) {
if (Platform.isServer()) {
@@ -461,9 +378,10 @@ public class BlockCableBus extends AEBaseTileBlock implements IAEFacade {
}
public void setupTile() {
this.setTileEntity(TileCableBus.class);
noTesrTile = Api.INSTANCE.partHelper().getCombinedInstance(TileCableBus.class);
this.setTileEntity(noTesrTile);
GameRegistry.registerTileEntity(TileCableBus.class, AppEng.MOD_ID.toLowerCase() + ":" + "BlockCableBus");
GameRegistry.registerTileEntity(noTesrTile, AppEng.MOD_ID.toLowerCase() + ":" + "BlockCableBus");
if (Platform.isClient()) {
setupTesr();
@@ -472,8 +390,9 @@ public class BlockCableBus extends AEBaseTileBlock implements IAEFacade {
@SideOnly(Side.CLIENT)
private static void setupTesr() {
GameRegistry.registerTileEntity(TileCableBusTESR.class, AppEng.MOD_ID.toLowerCase() + ":" + "ClientOnly_TESR_CableBus");
ClientRegistry.bindTileEntitySpecialRenderer(TileCableBusTESR.class, new CableBusTESR());
tesrTile = Api.INSTANCE.partHelper().getCombinedInstance(TileCableBusTESR.class);
GameRegistry.registerTileEntity(tesrTile, AppEng.MOD_ID.toLowerCase() + ":" + "ClientOnly_TESR_CableBus");
ClientRegistry.bindTileEntitySpecialRenderer(BlockCableBus.getTesrTile(), new CableBusTESR());
}
@Override
@@ -519,6 +438,14 @@ public class BlockCableBus extends AEBaseTileBlock implements IAEFacade {
super.onEntityWalk(world, pos, entityIn);
}
public static Class<? extends AEBaseTile> getNoTesrTile() {
return noTesrTile;
}
public static Class<? extends AEBaseTile> getTesrTile() {
return tesrTile;
}
// Helper to get access to the protected constructor
@SideOnly(Side.CLIENT)
private static class DestroyFX extends ParticleDigging {
+15 -17
View File
@@ -46,6 +46,7 @@ import appeng.helpers.IMouseWheelItem;
import appeng.hooks.TickHandler;
import appeng.hooks.TickHandler.PlayerColor;
import appeng.items.tools.powered.Terminal;
import appeng.items.tools.powered.ToolWirelessTerminal;
import appeng.server.ServerHelper;
import appeng.util.Platform;
import net.minecraft.client.Minecraft;
@@ -61,6 +62,8 @@ import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.client.event.*;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.client.settings.KeyConflictContext;
import net.minecraftforge.client.settings.KeyModifier;
import net.minecraftforge.common.ForgeModContainer;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.client.FMLClientHandler;
@@ -69,12 +72,21 @@ import net.minecraftforge.fml.client.registry.RenderingRegistry;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.InputEvent;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import java.io.IOException;
import java.util.*;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Random;
import static appeng.client.KeyBindings.*;
import static appeng.client.KeyBindings.WCT;
import static appeng.client.KeyBindings.WFT;
import static appeng.client.KeyBindings.WPT;
import static appeng.client.KeyBindings.WT;
public class ClientHelper extends ServerHelper {
@@ -340,8 +352,6 @@ public class ClientHelper extends ServerHelper {
NetworkHandler.instance().sendToServer(new PacketTerminalUse(Terminal.WIRELESS_PATTERN_TERMINAL));
} else if (k == WFT.getKeyBinding()) {
NetworkHandler.instance().sendToServer(new PacketTerminalUse(Terminal.WIRELESS_FLUID_TERMINAL));
} else if (k == WIT.getKeyBinding()) {
NetworkHandler.instance().sendToServer(new PacketTerminalUse(Terminal.WIRELESS_INTERFACE_TERMINAL));
}
}
}
@@ -362,16 +372,4 @@ public class ClientHelper extends ServerHelper {
public boolean isActionKey(ActionKey key, int pressedKeyCode) {
return this.bindings.get(key).isActiveAndMatches(pressedKeyCode);
}
@Override
public EntityPlayer getPlayerByUUID(UUID uuid) {
if (Platform.isClient()) {
if (Minecraft.getMinecraft().player.getUniqueID().equals(uuid)) {
return Minecraft.getMinecraft().player;
}
return null;
} else {
return super.getPlayerByUUID(uuid);
}
}
}
}
+1 -2
View File
@@ -12,8 +12,7 @@ public enum KeyBindings {
WT(new KeyBinding("key.open_wireless_terminal.desc", KeyConflictContext.UNIVERSAL, KeyModifier.SHIFT, Keyboard.KEY_T, KEY_CATEGORY)),
WCT(new KeyBinding("key.open_wireless_crafting_terminal.desc", KeyConflictContext.UNIVERSAL, KeyModifier.SHIFT, Keyboard.KEY_E, KEY_CATEGORY)),
WPT(new KeyBinding("key.open_wireless_pattern_terminal.desc", KeyConflictContext.UNIVERSAL, KeyModifier.SHIFT, Keyboard.KEY_R, KEY_CATEGORY)),
WFT(new KeyBinding("key.open_wireless_fluid_terminal.desc", KeyConflictContext.UNIVERSAL, KeyModifier.SHIFT, Keyboard.KEY_F, KEY_CATEGORY)),
WIT(new KeyBinding("key.open_wireless_interface_terminal.desc",KeyConflictContext.UNIVERSAL,KeyModifier.SHIFT,Keyboard.KEY_I,KEY_CATEGORY));
WFT(new KeyBinding("key.open_wireless_fluid_terminal.desc", KeyConflictContext.UNIVERSAL, KeyModifier.SHIFT, Keyboard.KEY_F, KEY_CATEGORY));
private KeyBinding keyBinding;
+6 -127
View File
@@ -72,7 +72,7 @@ import net.minecraftforge.fml.common.Optional;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
import org.lwjgl.opengl.GL11;
import yalter.mousetweaks.api.IMTModGuiContainer2;
import yalter.mousetweaks.api.MouseTweaksIgnore;
import java.awt.*;
import java.io.IOException;
@@ -85,8 +85,9 @@ import java.util.concurrent.TimeUnit;
import static appeng.integration.modules.jei.JEIPlugin.aeGuiHandler;
import static appeng.integration.modules.jei.JEIPlugin.runtime;
@Optional.Interface(iface = "yalter.mousetweaks.api.IMTModGuiContainer2", modid = "mousetweaks")
public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContainer2 {
@MouseTweaksIgnore
public abstract class AEBaseGui extends GuiContainer {
private final List<InternalSlotME> meSlots = new ArrayList<>();
// drag y
private final Set<Slot> drag_click = new HashSet<>();
@@ -183,12 +184,6 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
this.drawTooltip((ITooltip) c, mouseX, mouseY);
}
}
for (final Object o : this.labelList) {
if (o instanceof ITooltip) {
this.drawTooltip((ITooltip) o, mouseX, mouseY);
}
}
GlStateManager.enableDepth();
if (Platform.isModLoaded("jei")) {
bookmarkedJEIghostItem(mouseX, mouseY);
@@ -263,7 +258,7 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
}
}
protected void drawTooltip(ITooltip tooltip, int mouseX, int mouseY) {
private void drawTooltip(ITooltip tooltip, int mouseX, int mouseY) {
final int x = tooltip.xPos(); // ((GuiImgButton) c).x;
int y = tooltip.yPos(); // ((GuiImgButton) c).y;
@@ -955,42 +950,10 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
this.zLevel = 0.0F;
this.itemRender.zLevel = 0.0F;
boolean wasDragSplitting = this.dragSplitting;
this.dragSplitting = false; // to prevent the vanilla slot renderer from rendering the stack count during drag splitting, we're re-enabling it later
// Annoying but easier than trying to splice into render item
super.drawSlot(s);
ItemStack stackInSlot = ((AppEngSlot)s).getDisplayStack();
ItemStack stackUnderCursor = this.mc.player.inventory.getItemStack();
if (wasDragSplitting
&& this.dragSplittingSlots.contains(s)
&& this.dragSplittingSlots.size() > 1
&& !stackUnderCursor.isEmpty()) {
if (Container.canAddItemToSlot(s, stackUnderCursor, true) && this.inventorySlots.canDragIntoSlot(s))
{
drawRect(s.xPos, s.yPos, s.xPos + 16, s.yPos + 16, -2130706433);
stackInSlot = stackUnderCursor.copy();
Container.computeStackSize(this.dragSplittingSlots, this.dragSplittingLimit, stackInSlot, s.getStack().isEmpty() ? 0 : s.getStack().getCount());
int k = Math.min(stackInSlot.getMaxStackSize(), s.getItemStackLimit(stackInSlot));
if (stackInSlot.getCount() > k)
{
stackInSlot.setCount(k);
}
}
else
{
this.dragSplittingSlots.remove(s);
this.updateDragSplitting();
}
}
this.dragSplitting = wasDragSplitting;
this.stackSizeRenderer.renderStackSize(this.fontRenderer, AEItemStack.fromItemStack(stackInSlot), s.xPos, s.yPos);
this.stackSizeRenderer.renderStackSize(this.fontRenderer, AEItemStack.fromItemStack(appEngSlot.getDisplayStack()), s.xPos, s.yPos);
return;
} else {
super.drawSlot(s);
@@ -1025,88 +988,4 @@ public abstract class AEBaseGui extends GuiContainer implements IMTModGuiContain
protected List<InternalSlotME> getMeSlots() {
return this.meSlots;
}
// TODO: remove this when refactoring slot rendering
private void updateDragSplitting()
{
ItemStack itemstack = this.mc.player.inventory.getItemStack();
if (!itemstack.isEmpty() && this.dragSplitting)
{
if (this.dragSplittingLimit == 2)
{
this.dragSplittingRemnant = itemstack.getMaxStackSize();
}
else
{
this.dragSplittingRemnant = itemstack.getCount();
for (Slot slot : this.dragSplittingSlots)
{
ItemStack itemstack1 = itemstack.copy();
ItemStack itemstack2 = slot.getStack();
int i = itemstack2.isEmpty() ? 0 : itemstack2.getCount();
Container.computeStackSize(this.dragSplittingSlots, this.dragSplittingLimit, itemstack1, i);
int j = Math.min(itemstack1.getMaxStackSize(), slot.getItemStackLimit(itemstack1));
if (itemstack1.getCount() > j)
{
itemstack1.setCount(j);
}
this.dragSplittingRemnant -= itemstack1.getCount() - i;
}
}
}
}
@Override
@Optional.Method(modid = "mousetweaks")
public boolean MT_isMouseTweaksDisabled() {
return false;
}
@Override
@Optional.Method(modid = "mousetweaks")
public boolean MT_isWheelTweakDisabled() {
return true;
}
@Override
@Optional.Method(modid = "mousetweaks")
public Container MT_getContainer() {
return this.inventorySlots;
}
@Override
@Optional.Method(modid = "mousetweaks")
public Slot MT_getSlotUnderMouse() {
return getSlotUnderMouse();
}
@Override
@Optional.Method(modid = "mousetweaks")
public boolean MT_isCraftingOutput(Slot slot) {
return slot instanceof SlotOutput || slot instanceof AppEngCraftingSlot;
}
@Override
@Optional.Method(modid = "mousetweaks")
public boolean MT_isIgnored(Slot slot) {
return false;
}
@Override
@Optional.Method(modid = "mousetweaks")
public boolean MT_disableRMBDraggingFunctionality() {
if (this.dragSplitting && this.dragSplittingButton == 1) {
this.dragSplitting = false;
// Don't ignoreMouseUp on slots that can't accept the item. (crafting output, ME slot, etc.)
if (this.getSlotUnderMouse() != null && this.getSlotUnderMouse().isItemValid(this.mc.player.inventory.getItemStack())) {
this.ignoreMouseUp = true;
}
return true;
}
return false;
}
}
@@ -1,21 +1,13 @@
package appeng.client.gui;
import appeng.api.storage.data.IAEItemStack;
import appeng.client.gui.implementations.GuiCraftAmount;
import appeng.client.gui.implementations.GuiCraftConfirm;
import appeng.client.gui.implementations.GuiCraftingCPU;
import appeng.client.gui.implementations.GuiExpandedProcessingPatternTerm;
import appeng.client.gui.implementations.GuiPatternTerm;
import appeng.client.gui.implementations.GuiUpgradeable;
import appeng.client.gui.widgets.GuiCustomSlot;
import appeng.client.gui.implementations.*;
import appeng.container.interfaces.IJEIGhostIngredients;
import appeng.container.interfaces.ISpecialSlotIngredient;
import appeng.container.slot.IJEITargetSlot;
import appeng.container.slot.SlotFake;
import appeng.fluids.client.gui.widgets.GuiFluidSlot;
import mezz.jei.api.gui.IAdvancedGuiHandler;
import mezz.jei.api.gui.IGhostIngredientHandler;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.inventory.Slot;
import org.lwjgl.input.Mouse;
import javax.annotation.Nonnull;
@@ -67,39 +59,11 @@ public class AEGuiHandler implements IAdvancedGuiHandler<AEBaseGui>, IGhostIngre
if (guiContainer instanceof GuiCraftAmount) {
if (guiContainer.getSlotUnderMouse() != null) {
result = guiContainer.getSlotUnderMouse().getStack();
} else {
return null;
}
}
if (result != null) {
return result;
}
Slot slot = guiContainer.getSlotUnderMouse();
if (slot instanceof ISpecialSlotIngredient ss) {
return ss.getIngredient();
}
for (GuiCustomSlot customSlot : guiContainer.guiSlots) {
if (this.checkSlotArea(guiContainer, customSlot, mouseX, mouseY)) {
return customSlot.getIngredient();
}
}
return result;
}
private boolean checkSlotArea(GuiContainer gui, GuiCustomSlot slot, int mouseX, int mouseY) {
int i = gui.guiLeft;
int j = gui.guiTop;
mouseX = mouseX - i;
mouseY = mouseY - j;
return mouseX >= slot.xPos() - 1 &&
mouseX < slot.xPos() + slot.getWidth() + 1 &&
mouseY >= slot.yPos() - 1 &&
mouseY < slot.yPos() + slot.getHeight() + 1;
}
private int getSlotidx(AEBaseGui guiContainer, int mouseX, int mouseY, int rows) {
int guileft = guiContainer.getGuiLeft();
int guitop = guiContainer.getGuiTop();
@@ -114,12 +78,12 @@ public class AEGuiHandler implements IAdvancedGuiHandler<AEBaseGui>, IGhostIngre
return (guiSloty * 3) + guiSlotx + (currentScroll * 3);
}
@SuppressWarnings("unchecked")
@Override
@Nonnull
public <I> List<Target<I>> getTargets(@Nonnull AEBaseGui gui, @Nonnull I ingredient, boolean doStart) {
ArrayList<Target<I>> targets = new ArrayList<>();
if (gui instanceof IJEIGhostIngredients g) {
if (gui instanceof IJEIGhostIngredients) {
IJEIGhostIngredients g = (IJEIGhostIngredients) gui;
List<Target<?>> phantomTargets = g.getPhantomTargets(ingredient);
targets.addAll((List<Target<I>>) (Object) phantomTargets);
}
@@ -127,8 +91,13 @@ public class AEGuiHandler implements IAdvancedGuiHandler<AEBaseGui>, IGhostIngre
if (gui instanceof GuiUpgradeable || gui instanceof GuiPatternTerm || gui instanceof GuiExpandedProcessingPatternTerm) {
IJEIGhostIngredients ghostGui = ((IJEIGhostIngredients) gui);
for (Target<I> target : targets) {
if (ghostGui.getFakeSlotTargetMap().get(target) instanceof IJEITargetSlot jeiSlot) {
if (jeiSlot.needAccept()) {
if (ghostGui.getFakeSlotTargetMap().get(target) instanceof SlotFake) {
if (((SlotFake) ghostGui.getFakeSlotTargetMap().get(target)).getStack().isEmpty()) {
target.accept(ingredient);
break;
}
} else if (ghostGui.getFakeSlotTargetMap().get(target) instanceof GuiFluidSlot) {
if (((GuiFluidSlot) ghostGui.getFakeSlotTargetMap().get(target)).getFluidStack() == null) {
target.accept(ingredient);
break;
}
@@ -1,208 +0,0 @@
package appeng.client.gui;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collections;
import java.util.Stack;
public class MathExpressionParser {
private final Stack<String> postfixStack = new Stack<>();
private final Stack<Character> opStack = new Stack<>();
private static final int[] OPERATOR_PRIORITY = new int[] { 0, 3, 2, 1, -1, 1, 0, 2 };
public static double parse(String expression) {
double result;
if (expression == null) return Double.NaN;
expression = expression.replace(" ", "");
if (expression.length() == 1 && Character.isDigit(expression.charAt(0))) {
return expression.charAt(0) - '0';
}
try {
expression = transform(expression);
result = new MathExpressionParser().calculate(expression);
} catch (Exception e) {
return Double.NaN;
}
return result;
}
/**
* replace '-' with '~'
* e.g.-2+-1*(-3E-2)-(-1) -> ~2+~1*(~3E~2)-(~1)
*/
private static String transform(String expression) {
char[] arr = expression.toCharArray();
for (int i = 0; i < arr.length; i++) {
if (arr[i] == '-') {
if (i == 0) {
arr[i] = '~';
} else {
char c = arr[i - 1];
if (c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == 'E' || c == 'e') {
arr[i] = '~';
}
}
}
}
if (arr[0] == '~' || arr[1] == '(') {
arr[0] = '-';
return "0" + new String(arr);
} else {
return new String(arr);
}
}
public double calculate(String expression) {
Stack<String> resultStack = new Stack<>();
prepare(expression);
Collections.reverse(postfixStack);
String firstValue, secondValue, currentValue;
while (!postfixStack.isEmpty()) {
currentValue = postfixStack.pop();
if (!isOperator(currentValue.charAt(0))) {
currentValue = currentValue.replace("~", "-");
resultStack.push(currentValue);
} else {
secondValue = resultStack.pop();
firstValue = resultStack.pop();
firstValue = firstValue.replace("~", "-");
secondValue = secondValue.replace("~", "-");
String tempResult = calculate(firstValue, secondValue, currentValue.charAt(0));
resultStack.push(String.valueOf(tempResult));
}
}
return Double.parseDouble(resultStack.pop());
}
private void prepare(String expression) {
opStack.push(',');
char[] arr = expression.toCharArray();
int currentIndex = 0;
int count = 0;
char currentOp, peekOp;
for (int i = 0; i < arr.length; i++) {
currentOp = arr[i];
if (isOperator(currentOp)) {
if (count > 0) {
postfixStack.push(new String(arr, currentIndex, count));
}
peekOp = opStack.peek();
if (currentOp == ')') {
while (opStack.peek() != '(') {
postfixStack.push(String.valueOf(opStack.pop()));
}
opStack.pop();
} else {
while (currentOp != '(' && peekOp != ',' && compare(currentOp, peekOp)) {
postfixStack.push(String.valueOf(opStack.pop()));
peekOp = opStack.peek();
}
opStack.push(currentOp);
}
count = 0;
currentIndex = i + 1;
} else {
count++;
}
}
if (count > 1 || (count == 1 && !isOperator(arr[currentIndex]))) {
postfixStack.push(new String(arr, currentIndex, count));
}
while (opStack.peek() != ',') {
postfixStack.push(String.valueOf(opStack.pop()));
}
}
private static boolean isOperator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')';
}
private static boolean compare(char cur, char peek) {
return OPERATOR_PRIORITY[(peek) - 40] >= OPERATOR_PRIORITY[(cur) - 40];
}
private String calculate(String firstValue, String secondValue, char currentOp) {
return switch (currentOp) {
case '+' -> add(firstValue, secondValue);
case '-' -> sub(firstValue, secondValue);
case '*' -> mul(firstValue, secondValue);
case '/' -> div(firstValue, secondValue);
default -> "";
};
}
public static String add(String v1, String v2) {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return String.valueOf(b1.add(b2));
}
/**
* subtraction
*
* @param v1 p1
* @param v2 p2
* @return sub
*/
public static String sub(String v1, String v2) {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return String.valueOf(b1.subtract(b2));
}
/**
* multiplication
*
* @param v1 p1
* @param v2 p2
* @return mul
*/
public static String mul(String v1, String v2) {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return String.valueOf(b1.multiply(b2));
}
/**
* division. e = 10^-10
*
* @param v1 p1
* @param v2 p2
* @return div
*/
public static String div(String v1, String v2) {
BigDecimal b1 = new BigDecimal(v1);
BigDecimal b2 = new BigDecimal(v2);
return String.valueOf(b1.divide(b2, 16, RoundingMode.HALF_UP));
}
/**
* rounding
*
* @param v p
* @param scale scale
* @return result
*/
public static double round(double v, int scale) {
if (scale < 0) {
throw new IllegalArgumentException("The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(Double.toString(v));
return b.divide(BigDecimal.ONE, scale, RoundingMode.HALF_UP).doubleValue();
}
public static String round(String v, int scale) {
if (scale < 0) {
throw new IllegalArgumentException("The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(v);
return String.valueOf(b.divide(BigDecimal.ONE, scale, RoundingMode.HALF_UP));
}
}
@@ -22,9 +22,10 @@ package appeng.client.gui.implementations;
import appeng.api.AEApi;
import appeng.api.definitions.IDefinitions;
import appeng.api.definitions.IParts;
import appeng.api.features.IWirelessTermHandler;
import appeng.api.storage.ITerminalHost;
import appeng.client.gui.AEBaseGui;
import appeng.client.gui.MathExpressionParser;
import appeng.client.gui.widgets.GuiNumberBox;
import appeng.client.gui.widgets.GuiTabButton;
import appeng.container.AEBaseContainer;
import appeng.container.implementations.ContainerCraftAmount;
@@ -41,7 +42,6 @@ import appeng.parts.reporting.PartExpandedProcessingPatternTerminal;
import appeng.parts.reporting.PartPatternTerminal;
import appeng.parts.reporting.PartTerminal;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.item.ItemStack;
import org.lwjgl.input.Keyboard;
@@ -50,7 +50,7 @@ import java.io.IOException;
public class GuiCraftAmount extends AEBaseGui {
private GuiTextField amountToCraft;
private GuiNumberBox amountToCraft;
private GuiTabButton originalGuiBtn;
private GuiButton next;
@@ -126,7 +126,7 @@ public class GuiCraftAmount extends AEBaseGui {
this.buttonList.add(this.originalGuiBtn = new GuiTabButton(this.guiLeft + 154, this.guiTop, myIcon, myIcon.getDisplayName(), this.itemRender));
}
this.amountToCraft = new GuiTextField(0, this.fontRenderer, this.guiLeft + 62, this.guiTop + 57, 59, this.fontRenderer.FONT_HEIGHT);
this.amountToCraft = new GuiNumberBox(this.fontRenderer, this.guiLeft + 62, this.guiTop + 57, 59, this.fontRenderer.FONT_HEIGHT, Integer.class);
this.amountToCraft.setEnableBackgroundDrawing(false);
this.amountToCraft.setMaxStringLength(16);
this.amountToCraft.setTextColor(0xFFFFFF);
@@ -149,17 +149,8 @@ public class GuiCraftAmount extends AEBaseGui {
this.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize);
try {
String out = this.amountToCraft.getText();
double resultD = MathExpressionParser.parse(out);
long amt;
if (resultD <= 0 || Double.isNaN(resultD)) {
amt = 0;
} else {
amt = (long) MathExpressionParser.round(resultD, 0);
}
this.next.enabled = amt > 0;
long amt = Long.parseLong(this.amountToCraft.getText());
this.next.enabled = (!this.amountToCraft.getText().isEmpty() && amt > 0);
} catch (final NumberFormatException e) {
this.next.enabled = false;
}
@@ -173,7 +164,33 @@ public class GuiCraftAmount extends AEBaseGui {
if (key == Keyboard.KEY_RETURN || key == Keyboard.KEY_NUMPADENTER) {
this.actionPerformed(this.next);
}
if (!this.amountToCraft.textboxKeyTyped(character, key)) {
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);
}
}
@@ -190,15 +207,7 @@ public class GuiCraftAmount extends AEBaseGui {
}
if (btn == this.next) {
double resultD = MathExpressionParser.parse(this.amountToCraft.getText());
int result;
if (resultD <= 0 || Double.isNaN(resultD)) {
result = 1;
} else {
result = (int) MathExpressionParser.round(resultD, 0);
}
NetworkHandler.instance().sendToServer(new PacketCraftRequest(result, isShiftKeyDown()));
NetworkHandler.instance().sendToServer(new PacketCraftRequest(Integer.parseInt(this.amountToCraft.getText()), isShiftKeyDown()));
}
} catch (final NumberFormatException e) {
// nope..
@@ -217,15 +226,22 @@ public class GuiCraftAmount extends AEBaseGui {
try {
String out = this.amountToCraft.getText();
double resultD = MathExpressionParser.parse(out);
int result;
if (resultD <= 0 || Double.isNaN(resultD)) {
result = 0;
} else {
result = (int) MathExpressionParser.round(resultD, 0);
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;
}
@@ -235,7 +251,8 @@ public class GuiCraftAmount extends AEBaseGui {
result = 1;
}
out = Integer.toString(result);
out = Long.toString(result);
Integer.parseInt(out);
this.amountToCraft.setText(out);
} catch (final NumberFormatException e) {
// :P
@@ -19,11 +19,9 @@
package appeng.client.gui.implementations;
import appeng.api.config.LockCraftingMode;
import appeng.api.config.Settings;
import appeng.api.config.YesNo;
import appeng.client.gui.widgets.GuiImgButton;
import appeng.client.gui.widgets.GuiImgLabel;
import appeng.client.gui.widgets.GuiTabButton;
import appeng.client.gui.widgets.GuiToggleButton;
import appeng.container.implementations.ContainerInterface;
@@ -43,22 +41,14 @@ import java.io.IOException;
public class GuiInterface extends GuiUpgradeable {
private GuiTabButton priority;
private GuiImgButton UnlockMode;
private GuiImgButton BlockMode;
private GuiToggleButton interfaceMode;
private GuiImgLabel lockReason;
public GuiInterface(final InventoryPlayer inventoryPlayer, final IInterfaceHost te) {
super(new ContainerInterface(inventoryPlayer, te));
this.ySize = 256;
}
@Override
public void initGui() {
super.initGui();
this.addLabel();
}
@Override
protected void addButtons() {
this.priority = new GuiTabButton(this.guiLeft + 154, this.guiTop, 2 + 4 * 16, GuiText.Priority.getLocal(), this.itemRender);
@@ -67,41 +57,16 @@ public class GuiInterface extends GuiUpgradeable {
this.BlockMode = new GuiImgButton(this.guiLeft - 18, this.guiTop + 8, Settings.BLOCK, YesNo.NO);
this.buttonList.add(this.BlockMode);
this.UnlockMode = new GuiImgButton(this.guiLeft - 18, this.guiTop + 26, Settings.UNLOCK, LockCraftingMode.NONE);
this.buttonList.add(this.UnlockMode);
this.interfaceMode = new GuiToggleButton(this.guiLeft - 18, this.guiTop + 44, 84, 85, GuiText.InterfaceTerminal.getLocal(), GuiText.InterfaceTerminalHint.getLocal());
this.interfaceMode = new GuiToggleButton(this.guiLeft - 18, this.guiTop + 26, 84, 85, GuiText.InterfaceTerminal.getLocal(), GuiText.InterfaceTerminalHint.getLocal());
this.buttonList.add(this.interfaceMode);
}
protected void addLabel() {
if (lockReason != null) {
labelList.remove(this.lockReason);
}
this.lockReason = new GuiImgLabel(this.fontRenderer, guiLeft + 40, guiTop + 12, Settings.UNLOCK, LockCraftingMode.NONE);
this.lockReason.setVisibility(false);
labelList.add(lockReason);
}
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
if (this.BlockMode != null) {
this.BlockMode.set(((ContainerInterface) this.cvb).getBlockingMode());
}
if (this.UnlockMode != null) {
this.UnlockMode.set(((ContainerInterface) this.cvb).getUnlockMode());
if (this.lockReason != null) {
if (this.UnlockMode.getCurrentValue() == LockCraftingMode.NONE) {
this.lockReason.setVisibility(false);
} else {
this.lockReason.setVisibility(true);
this.lockReason.set(((ContainerInterface) this.cvb).getCraftingLockedReason());
}
}
}
if (this.interfaceMode != null) {
this.interfaceMode.setState(((ContainerInterface) this.cvb).getInterfaceTerminalMode() == YesNo.YES);
}
@@ -141,10 +106,6 @@ public class GuiInterface extends GuiUpgradeable {
if (btn == this.BlockMode) {
NetworkHandler.instance().sendToServer(new PacketConfigButton(this.BlockMode.getSetting(), backwards));
}
if (btn == this.UnlockMode) {
NetworkHandler.instance.sendToServer(new PacketConfigButton(this.UnlockMode.getSetting(), backwards));
}
}
}
@@ -27,22 +27,14 @@ import appeng.api.storage.channels.IItemStorageChannel;
import appeng.client.gui.AEBaseGui;
import appeng.client.gui.widgets.GuiImgButton;
import appeng.client.gui.widgets.GuiScrollbar;
import appeng.client.gui.widgets.MEGuiTooltipTextField;
import appeng.client.gui.widgets.MEGuiTextField;
import appeng.client.me.ClientDCInternalInv;
import appeng.client.me.SlotDisconnected;
import appeng.container.implementations.ContainerInterfaceTerminal;
import appeng.container.implementations.ContainerWirelessInterfaceTerminal;
import appeng.container.slot.AppEngSlot;
import appeng.core.AEConfig;
import appeng.core.AppEng;
import appeng.core.localization.ButtonToolTips;
import appeng.core.localization.GuiText;
import appeng.core.localization.PlayerMessages;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketConfigureInterface;
import appeng.helpers.DualityInterface;
import appeng.helpers.PatternHelper;
import appeng.helpers.WirelessTerminalGuiObject;
import appeng.parts.reporting.PartInterfaceTerminal;
import appeng.util.BlockPosUtils;
import appeng.util.Platform;
@@ -50,20 +42,27 @@ import com.google.common.collect.HashMultimap;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.util.text.TextComponentString;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.fml.common.Loader;
import org.lwjgl.input.Mouse;
import java.awt.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.*;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import static appeng.client.render.BlockPosHighlighter.hilightBlock;
import static appeng.helpers.ItemStackHelper.stackFromNBT;
@@ -71,13 +70,15 @@ import static appeng.helpers.ItemStackHelper.stackFromNBT;
public class GuiInterfaceTerminal extends AEBaseGui {
protected static final int OFFSET_X = 21;
protected final GuiText guiTitle;
private static final int MAGIC_HEIGHT_NUMBER = 52 + 99;
private static final String MOLECULAR_ASSEMBLER = "tile.appliedenergistics2.molecular_assembler";
private int rows = 6;
private final boolean jeiEnabled;
private final int jeiButtonPadding;
// TODO: copied from GuiMEMonitorable. It looks not changed, maybe unneeded?
private final int offsetX = 21;
private int maxRows = Integer.MAX_VALUE;
protected int jeiOffset = Loader.isModLoaded("jei") ? 24 : 0;
private int reservedSpace = 0;
private final HashMap<Long, ClientDCInternalInv> byId = new HashMap<>();
private final HashMultimap<String, ClientDCInternalInv> byName = HashMultimap.create();
@@ -87,139 +88,99 @@ public class GuiInterfaceTerminal extends AEBaseGui {
private final ArrayList<String> names = new ArrayList<>();
private final ArrayList<Object> lines = new ArrayList<>();
private final Set<Object> matchedStacks = new HashSet<>();
private final Set<ClientDCInternalInv> matchedInterfaces = new HashSet<>();
private final Map<String, Set<Object>> cachedSearches = new WeakHashMap<>();
private final Map<ClientDCInternalInv, Integer> dimHashMap = new HashMap<>();
private final MEGuiTooltipTextField searchFieldOutputs;
private final MEGuiTooltipTextField searchFieldInputs;
private final MEGuiTooltipTextField searchFieldNames;
private final GuiImgButton guiButtonHideFull;
private final GuiImgButton guiButtonAssemblersOnly;
private final GuiImgButton guiButtonBrokenRecipes;
private final GuiImgButton terminalStyleBox;
private boolean refreshList = false;
private MEGuiTextField searchFieldOutputs;
private MEGuiTextField searchFieldInputs;
private final PartInterfaceTerminal partInterfaceTerminal;
private GuiButton guiButtonHide;
private GuiButton guiButtonNextAssembler;
private GuiImgButton terminalStyleBox;
/* These are worded so that the intended default is false */
private boolean onlyShowWithSpace = false;
private boolean onlyMolecularAssemblers = false;
private boolean onlyBrokenRecipes = false;
private int rows = 6;
private final HashMap<ClientDCInternalInv, Integer> dimHashMap = new HashMap<>();
private int drawnRows = 0;
public GuiInterfaceTerminal(final InventoryPlayer inventoryPlayer, final PartInterfaceTerminal te) {
super(new ContainerInterfaceTerminal(inventoryPlayer, te));
this.partInterfaceTerminal = te;
final GuiScrollbar scrollbar = new GuiScrollbar();
this.setScrollBar(scrollbar);
this.xSize = 208;
this.ySize = 255;
this.jeiEnabled = Platform.isModLoaded("jei");
this.jeiButtonPadding = jeiEnabled ? 22 : 0;
searchFieldInputs = createTextField(86, 12, ButtonToolTips.SearchFieldInputs.getLocal());
searchFieldOutputs = createTextField(86, 12, ButtonToolTips.SearchFieldOutputs.getLocal());
searchFieldNames = createTextField(71, 12, ButtonToolTips.SearchFieldNames.getLocal());
searchFieldNames.setFocused(true);
guiButtonAssemblersOnly = new GuiImgButton(0, 0, Settings.ACTIONS, null);
guiButtonHideFull = new GuiImgButton(0, 0, Settings.ACTIONS, null);
guiButtonBrokenRecipes = new GuiImgButton(0, 0, Settings.ACTIONS, null);
terminalStyleBox = new GuiImgButton(0, 0, Settings.TERMINAL_STYLE, null);
guiTitle = GuiText.InterfaceTerminal;
}
public GuiInterfaceTerminal(final InventoryPlayer inventoryPlayer, final WirelessTerminalGuiObject guiObject) {
super(new ContainerWirelessInterfaceTerminal(inventoryPlayer, guiObject));
final GuiScrollbar scrollbar = new GuiScrollbar();
this.setScrollBar(scrollbar);
this.xSize = 208;
this.ySize = 255;
this.jeiEnabled = Platform.isModLoaded("jei");
this.jeiButtonPadding = jeiEnabled ? 22 : 0;
searchFieldInputs = createTextField(86, 12, ButtonToolTips.SearchFieldInputs.getLocal());
searchFieldOutputs = createTextField(86, 12, ButtonToolTips.SearchFieldOutputs.getLocal());
searchFieldNames = createTextField(71, 12, ButtonToolTips.SearchFieldNames.getLocal());
searchFieldNames.setFocused(true);
guiButtonAssemblersOnly = new GuiImgButton(0, 0, Settings.ACTIONS, null);
guiButtonHideFull = new GuiImgButton(0, 0, Settings.ACTIONS, null);
guiButtonBrokenRecipes = new GuiImgButton(0, 0, Settings.ACTIONS, null);
terminalStyleBox = new GuiImgButton(0, 0, Settings.TERMINAL_STYLE, null);
guiTitle = GuiText.WirelessTerminal;
}
private MEGuiTooltipTextField createTextField(final int width, final int height, final String tooltip) {
MEGuiTooltipTextField textField = new MEGuiTooltipTextField(width, height, tooltip) {
@Override
public void onTextChange(String oldText) {
refreshList();
}
};
textField.setEnableBackgroundDrawing(false);
textField.setMaxStringLength(25);
textField.setTextColor(0xFFFFFF);
textField.setCursorPositionZero();
return textField;
}
private void setScrollBar() {
this.getScrollBar().setTop(52).setLeft(189).setHeight(this.rows * 18 - 2);
this.getScrollBar().setRange(0, this.lines.size() - 1, 1);
}
private int calculateRowsCount() {
final int maxRows = getMaxRows();
final int jeiPadding = jeiEnabled ? 22 + 18 : 0;
final int extraSpace = this.height - MAGIC_HEIGHT_NUMBER - jeiPadding;
return Math.max(6, Math.min(maxRows, extraSpace / 18));
this.setReservedSpace(82);
}
@Override
public void initGui() {
this.rows = calculateRowsCount();
this.maxRows = AEConfig.instance()
.getConfigManager()
.getSetting(
Settings.TERMINAL_STYLE) != TerminalStyle.TALL ? 6 : Integer.MAX_VALUE;
super.initGui();
final int magicNumber = 82 + 14;
final int extraSpace = this.height - magicNumber - this.reservedSpace;
this.ySize = MAGIC_HEIGHT_NUMBER + this.rows * 18;
this.rows = (int) Math.floor(extraSpace / 18);
if (this.rows > this.maxRows) {
this.rows = this.maxRows;
}
if (this.rows < 6) {
this.rows = 6;
}
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));
searchFieldInputs.x = guiLeft + 32;
searchFieldInputs.y = guiTop + 25;
searchFieldOutputs.x = guiLeft + 32;
searchFieldOutputs.y = guiTop + 38;
searchFieldNames.x = guiLeft + 32 + 99;
searchFieldNames.y = guiTop + 38;
super.initGui();
terminalStyleBox.x = guiLeft - 18;
terminalStyleBox.y = guiTop + 8 + jeiButtonPadding;
guiButtonBrokenRecipes.x = guiLeft - 18;
guiButtonBrokenRecipes.y = terminalStyleBox.y + 20;
guiButtonHideFull.x = guiLeft - 18;
guiButtonHideFull.y = guiButtonBrokenRecipes.y + 20;
guiButtonAssemblersOnly.x = guiLeft - 18;
guiButtonAssemblersOnly.y = guiButtonHideFull.y + 20;
this.getScrollBar().setLeft(189);
this.getScrollBar().setHeight(106);
this.getScrollBar().setTop(51);
this.searchFieldInputs = new MEGuiTextField(this.fontRenderer, this.guiLeft + Math.max(32, this.offsetX), this.guiTop + 25, 65, 12);
this.searchFieldInputs.setEnableBackgroundDrawing(false);
this.searchFieldInputs.setMaxStringLength(25);
this.searchFieldInputs.setTextColor(0xFFFFFF);
this.searchFieldInputs.setVisible(true);
this.searchFieldInputs.setFocused(false);
this.searchFieldOutputs = new MEGuiTextField(this.fontRenderer, this.guiLeft + Math.max(32, this.offsetX), this.guiTop + 38, 65, 12);
this.searchFieldOutputs.setEnableBackgroundDrawing(false);
this.searchFieldOutputs.setMaxStringLength(25);
this.searchFieldOutputs.setTextColor(0xFFFFFF);
this.searchFieldOutputs.setVisible(true);
this.searchFieldOutputs.setFocused(true);
this.searchFieldInputs.setText(partInterfaceTerminal.in);
this.searchFieldOutputs.setText(partInterfaceTerminal.out);
this.fontRenderer.drawString(this.getGuiDisplayName(GuiText.InterfaceTerminal.getLocal()), 8, 6, 4210752);
this.fontRenderer.drawString(GuiText.inventory.getLocal(), this.offsetX + 2, this.ySize - 96 + 3, 4210752);
this.setScrollBar();
this.repositionSlots();
}
protected void repositionSlots() {
for (final Object obj : this.inventorySlots.inventorySlots) {
if (obj instanceof AppEngSlot slot) {
slot.yPos = this.ySize + slot.getY() - 78 - 7;
slot.xPos = slot.getX() + 14;
}
}
protected void repositionSlot(final AppEngSlot s) {
this.ySize = 82 + 14 + this.drawnRows * 18 + this.reservedSpace;
s.yPos = s.getY() + this.ySize - 112;
s.xPos = s.getX() + 14;
}
@Override
public void onGuiClosed() {
partInterfaceTerminal.saveSearchStrings(this.searchFieldInputs.getText().toLowerCase(), this.searchFieldOutputs.getText().toLowerCase());
super.onGuiClosed();
}
@Override
public List<Rectangle> getJEIExclusionArea() {
Rectangle tallButton = new Rectangle(this.guiLeft - 18, this.guiTop + 24 + 24, 18, 18);
Rectangle tallButton = new Rectangle(this.guiLeft - 18, this.guiTop + 24 + jeiOffset, 18, 18);
List<Rectangle> area = new ArrayList<>();
area.add(tallButton);
return area;
@@ -227,151 +188,154 @@ public class GuiInterfaceTerminal extends AEBaseGui {
@Override
public void drawFG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.fontRenderer.drawString(this.getGuiDisplayName(guiTitle.getLocal()), OFFSET_X + 2, 6, 4210752);
this.fontRenderer.drawString(GuiText.inventory.getLocal(), OFFSET_X + 2, this.ySize - 96, 4210752);
this.buttonList.clear();
final int currentScroll = this.getScrollBar().getCurrentScroll();
int offset = 51;
this.guiButtonNextAssembler = new GuiImgButton(guiLeft + 123, guiTop + 25, Settings.ACTIONS, ActionItems.FREE_MOLECULAR_SLOT_SHORTCUT);
this.buttonList.add(guiButtonNextAssembler);
guiButtonHide = new GuiImgButton(guiLeft + 141, guiTop + 25, Settings.ACTIONS, this.partInterfaceTerminal.onlyInterfacesWithFreeSlots ? ActionItems.TOGGLE_SHOW_FULL_INTERFACES_OFF : ActionItems.TOGGLE_SHOW_FULL_INTERFACES_ON);
this.buttonList.add(guiButtonHide);
this.buttonList.add(this.terminalStyleBox = new GuiImgButton(this.guiLeft - 18, guiTop + 24 + jeiOffset, Settings.TERMINAL_STYLE, AEConfig.instance()
.getConfigManager()
.getSetting(Settings.TERMINAL_STYLE)));
this.inventorySlots.inventorySlots.removeIf(slot -> slot instanceof SlotDisconnected);
for (final Slot s : this.inventorySlots.inventorySlots) {
if (s instanceof AppEngSlot) {
if (s.xPos < 197) {
this.repositionSlot((AppEngSlot) s);
}
}
}
int offset = 52;
int linesDraw = 0;
for (int x = 0; x < rows && linesDraw < rows && currentScroll + x < this.lines.size(); x++) {
final Object lineObj = this.lines.get(currentScroll + x);
if (lineObj instanceof ClientDCInternalInv inv) {
if (lineObj instanceof ClientDCInternalInv) {
final ClientDCInternalInv inv = (ClientDCInternalInv) lineObj;
GuiButton guiButton = new GuiImgButton(guiLeft + 4, guiTop + offset, Settings.ACTIONS, ActionItems.HIGHLIGHT_INTERFACE);
guiButtonHashMap.put(guiButton, inv);
this.buttonList.add(guiButton);
int extraLines = numUpgradesMap.get(inv);
final int extraLines = numUpgradesMap.get(inv);
for (int row = 0; row < 1 + extraLines && linesDraw < rows; ++row) {
for (int z = 0; z < 9; z++) {
this.inventorySlots.inventorySlots.add(new SlotDisconnected(inv, z + (row * 9), (z * 18 + 22), offset));
if (this.matchedStacks.contains(inv.getInventory().getStackInSlot(z + (row * 9)))) {
drawRect(z * 18 + 22, 1 + offset, z * 18 + 22 + 16, 1 + offset + 16, 0x2A00FF00);
drawRect(z * 18 + 22, offset, z * 18 + 22 + 16, offset + 16, 0x8A00FF00);
} else if (!matchedInterfaces.contains(inv)) {
drawRect(z * 18 + 22, offset, z * 18 + 22 + 16, offset + 16, 0x6A000000);
}
}
linesDraw++;
offset += 18;
}
} else if (lineObj instanceof String name) {
} else if (lineObj instanceof String) {
String name = (String) lineObj;
final int rows = this.byName.get(name).size();
if (rows > 1) {
name = name + " (" + rows + ')';
}
while (name.length() > 2 && this.fontRenderer.getStringWidth(name) > 158) {
while (name.length() > 2 && this.fontRenderer.getStringWidth(name) > 155) {
name = name.substring(0, name.length() - 1);
}
this.fontRenderer.drawString(name, OFFSET_X + 3, 6 + offset, 4210752);
linesDraw++;
offset += 18;
}
}
}
@Override
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
buttonList.clear();
guiButtonHashMap.clear();
inventorySlots.inventorySlots.removeIf(slot -> slot instanceof SlotDisconnected);
guiButtonAssemblersOnly.set(onlyMolecularAssemblers ? ActionItems.MOLECULAR_ASSEMBLERS_ON : ActionItems.MOLECULAR_ASSEMBLERS_OFF);
guiButtonHideFull.set(onlyShowWithSpace ? ActionItems.TOGGLE_SHOW_FULL_INTERFACES_OFF : ActionItems.TOGGLE_SHOW_FULL_INTERFACES_ON);
guiButtonBrokenRecipes.set(onlyBrokenRecipes ? ActionItems.TOGGLE_SHOW_ONLY_INVALID_PATTERNS_ON : ActionItems.TOGGLE_SHOW_ONLY_INVALID_PATTERNS_OFF);
terminalStyleBox.set(AEConfig.instance().getConfigManager().getSetting(Settings.TERMINAL_STYLE));
buttonList.add(guiButtonAssemblersOnly);
buttonList.add(guiButtonHideFull);
buttonList.add(guiButtonBrokenRecipes);
buttonList.add(terminalStyleBox);
int offset = 51;
final int currentScroll = this.getScrollBar().getCurrentScroll();
int linesDraw = 0;
for (int x = 0; x < rows && linesDraw < rows && currentScroll + x < this.lines.size(); x++) {
final Object lineObj = this.lines.get(currentScroll + x);
if (lineObj instanceof ClientDCInternalInv inv) {
GuiButton highlightBtn = new GuiImgButton(guiLeft + 4, guiTop + offset + 1, Settings.ACTIONS, ActionItems.HIGHLIGHT_INTERFACE);
guiButtonHashMap.put(highlightBtn, inv);
this.buttonList.add(highlightBtn);
GuiButton configBtn = new GuiImgButton(guiLeft + 4, guiTop + offset + 1 - 16, Settings.ACTIONS, ActionItems.CONFIGURE_INTERFACE);
guiButtonHashMap.put(configBtn, inv);
this.buttonList.add(configBtn);
final int extraLines = numUpgradesMap.get(inv);
for (int row = 0; row < 1 + extraLines && linesDraw < rows; ++row) {
for (int z = 0; z < 9; z++) {
this.inventorySlots.inventorySlots.add(new SlotDisconnected(inv, z + (row * 9), z * 18 + 22, 1+ offset));
}
linesDraw++;
offset += 18;
}
} else if (lineObj instanceof String) {
this.fontRenderer.drawString(name, this.offsetX + 2, 5 + offset, 4210752);
linesDraw++;
offset += 18;
}
}
super.drawScreen(mouseX, mouseY, partialTicks);
if (searchFieldInputs.isMouseIn(mouseX, mouseY)) {
drawTooltip(Mouse.getEventX() * this.width / this.mc.displayWidth - offsetX, mouseY - guiTop, "Inputs OR names");
} else if (searchFieldOutputs.isMouseIn(mouseX, mouseY)) {
drawTooltip(Mouse.getEventX() * this.width / this.mc.displayWidth - offsetX, mouseY - guiTop, "Outputs OR names");
}
drawTooltip(searchFieldInputs, mouseX, mouseY);
drawTooltip(searchFieldOutputs, mouseX, mouseY);
drawTooltip(searchFieldNames, mouseX, mouseY);
}
@Override
protected void mouseClicked(final int xCoord, final int yCoord, final int btn) throws IOException {
this.searchFieldInputs.mouseClicked(xCoord, yCoord, btn);
if (btn == 1 && this.searchFieldInputs.isMouseIn(xCoord, yCoord)) {
this.searchFieldInputs.setText("");
this.refreshList();
}
this.searchFieldOutputs.mouseClicked(xCoord, yCoord, btn);
this.searchFieldNames.mouseClicked(xCoord, yCoord, btn);
if (btn == 1 && this.searchFieldOutputs.isMouseIn(xCoord, yCoord)) {
this.searchFieldOutputs.setText("");
this.refreshList();
}
super.mouseClicked(xCoord, yCoord, btn);
}
@Override
protected void actionPerformed(final GuiButton btn) throws IOException {
if (guiButtonHashMap.containsKey(btn) && btn instanceof GuiImgButton guiImgButton) {
ClientDCInternalInv inv = guiButtonHashMap.get(this.selectedButton);
BlockPos blockPos = blockPosHashMap.get(inv);
if (guiButtonHashMap.containsKey(btn)) {
BlockPos blockPos = blockPosHashMap.get(guiButtonHashMap.get(this.selectedButton));
BlockPos blockPos2 = mc.player.getPosition();
int playerDim = mc.world.provider.getDimension();
int interfaceDim = dimHashMap.get(inv);
int interfaceDim = dimHashMap.get(guiButtonHashMap.get(this.selectedButton));
if (playerDim != interfaceDim) {
try {
mc.player.sendStatusMessage(PlayerMessages.InterfaceInOtherDimParam.get(interfaceDim, DimensionManager.getWorld(interfaceDim).provider.getDimensionType().getName()), false);
mc.player.sendStatusMessage(new TextComponentString("Interface located at dimension: " + interfaceDim + " [" + DimensionManager.getWorld(interfaceDim).provider.getDimensionType().getName() + "] and cant be highlighted"), false);
} catch (Exception e) {
mc.player.sendStatusMessage(PlayerMessages.InterfaceInOtherDim.get(), false);
mc.player.sendStatusMessage(new TextComponentString("Interface is located in another dimension and cannot be highlighted"), false);
}
} else {
if (guiImgButton.getCurrentValue() == ActionItems.HIGHLIGHT_INTERFACE) {
hilightBlock(blockPos, System.currentTimeMillis() + 500 * BlockPosUtils.getDistance(blockPos, blockPos2), playerDim);
mc.player.sendStatusMessage(PlayerMessages.InterfaceHighlighted.get(blockPos.getX(), blockPos.getY(), blockPos.getZ()), false);
mc.player.closeScreen();
} else if (guiImgButton.getCurrentValue() == ActionItems.CONFIGURE_INTERFACE) {
NetworkHandler.instance.sendToServer(new PacketConfigureInterface(inv.getId()));
}
hilightBlock(blockPos, System.currentTimeMillis() + 500 * BlockPosUtils.getDistance(blockPos, blockPos2), playerDim);
mc.player.sendStatusMessage(new TextComponentString("The interface is now highlighted at " + "X: " + blockPos.getX() + " Y: " + blockPos.getY() + " Z: " + blockPos.getZ()), false);
}
} else if (btn == guiButtonHideFull) {
onlyShowWithSpace = !onlyShowWithSpace;
this.refreshList();
} else if (btn == guiButtonAssemblersOnly) {
onlyMolecularAssemblers = !onlyMolecularAssemblers;
this.refreshList();
} else if (btn == guiButtonBrokenRecipes) {
onlyBrokenRecipes = !onlyBrokenRecipes;
this.refreshList();
} else if (btn instanceof GuiImgButton iBtn) {
mc.player.closeScreen();
}
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 boolean backwards = Mouse.isButtonDown(1);
final Enum<?> next = Platform.rotateEnum(cv, backwards, iBtn.getSetting().getPossibleValues());
final Enum cv = iBtn.getCurrentValue();
final Enum next = Platform.rotateEnum(cv, backwards, iBtn.getSetting().getPossibleValues());
if (btn == this.terminalStyleBox) {
AEConfig.instance().getConfigManager().putSetting(iBtn.getSetting(), next);
}
iBtn.set(next);
if (next.getClass() == TerminalStyle.class) {
this.reinitalize();
}
iBtn.set(next);
}
}
if (btn == guiButtonHide) {
partInterfaceTerminal.onlyInterfacesWithFreeSlots = !partInterfaceTerminal.onlyInterfacesWithFreeSlots;
this.refreshList();
}
if (btn == guiButtonNextAssembler) {
// Set Search to "Molecular Assembler" and set "Only Free Interface"
boolean currentOnlyInterfacesWithFreeSlots = this.partInterfaceTerminal.onlyInterfacesWithFreeSlots;
String currentSearchText = this.searchFieldOutputs.getText();
this.partInterfaceTerminal.onlyInterfacesWithFreeSlots = true;
this.searchFieldOutputs.setText("Molecular Assembler");
this.refreshList();
this.partInterfaceTerminal.onlyInterfacesWithFreeSlots = currentOnlyInterfacesWithFreeSlots;
this.searchFieldOutputs.setText(currentSearchText);
}
}
private void reinitalize() {
@@ -382,66 +346,74 @@ public class GuiInterfaceTerminal extends AEBaseGui {
@Override
public void drawBG(final int offsetX, final int offsetY, final int mouseX, final int mouseY) {
this.bindTexture("guis/newinterfaceterminal.png");
// draw the top portion of the background, above the interface list
this.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, 53);
for (int x = 0; x < this.rows; x++) {
// draw the background of the rows in the interface list
this.drawTexturedModalRect(offsetX, offsetY + 53 + x * 18, 0, 52, this.xSize, 18);
}
//split the texture for the top
this.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, 166);
int offset = 51;
final int ex = this.getScrollBar().getCurrentScroll();
int linesDraw = 0;
for (int x = 0; x < this.rows && linesDraw < rows && ex + x < this.lines.size(); x++) {
for (int x = 0; x < rows && linesDraw < rows && ex + x < this.lines.size(); x++) {
final Object lineObj = this.lines.get(ex + x);
if (lineObj instanceof ClientDCInternalInv) {
GlStateManager.color(1, 1, 1, 1);
final int width = 9 * 18;
final int extraLines = numUpgradesMap.get(lineObj);
// draw the slot backgrounds
int extraLines = numUpgradesMap.get(lineObj);
for (int row = 0; row < 1 + extraLines && linesDraw < rows; ++row) {
if (linesDraw == 6) {
this.drawTexturedModalRect(offsetX, offsetY + offset + 7, 0, 166, 190, 7);
this.drawTexturedModalRect(offsetX, offsetY + offset + 14, 0, 166, 190, 4);
} else if (linesDraw >= 7) {
this.drawTexturedModalRect(offsetX, offsetY + offset, 0, 173, 190, 18);
}
this.drawTexturedModalRect(offsetX + 20, offsetY + offset, 20, 173, width, 18);
offset += 18;
linesDraw++;
}
} else {
if (linesDraw == 6) {
this.drawTexturedModalRect(offsetX, offsetY + offset + 7, 0, 166, 190, 7);
this.drawTexturedModalRect(offsetX, offsetY + offset + 14, 0, 166, 190, 4);
this.drawTexturedModalRect(offsetX, offsetY + offset, 0, 53, 183, 18);
} else if (linesDraw >= 7) {
this.drawTexturedModalRect(offsetX, offsetY + offset, 0, 53, 183, 18);
this.drawTexturedModalRect(offsetX + 183, offsetY + offset, 183, 166, 7, 18);
}
offset += 18;
linesDraw++;
}
}
offset = 51 + Math.max(6 * 18, linesDraw * 18);
if (linesDraw > 6) {
this.drawTexturedModalRect(offsetX, offsetY + offset, 0, 166, 190, 7);
}
this.drawTexturedModalRect(offsetX, offsetY + offset + 7, 0, 166, this.xSize, 90);
// draw the background below the interface list
this.drawTexturedModalRect(offsetX, offsetY + 50 + this.rows * 18, 0, 158, this.xSize, 99);
this.drawnRows = Math.max(6, linesDraw);
// draw the text boxes
this.searchFieldInputs.drawTextBox();
this.searchFieldOutputs.drawTextBox();
this.searchFieldNames.drawTextBox();
if (this.searchFieldInputs != null) {
this.searchFieldInputs.drawTextBox();
}
if (this.searchFieldOutputs != null) {
this.searchFieldOutputs.drawTextBox();
}
}
@Override
protected void keyTyped(final char character, final int key) throws IOException {
if (!this.checkHotbarKeys(key)) {
if (character == ' ') {
if ((this.searchFieldInputs.getText().isEmpty() && this.searchFieldInputs.isFocused())
|| (this.searchFieldOutputs.getText().isEmpty() && this.searchFieldOutputs.isFocused())
|| (this.searchFieldNames.getText().isEmpty() && this.searchFieldNames.isFocused())) {
return;
}
} else if (character == '\t') {
if (handleTab()) {
return;
}
if (character == ' ' && this.searchFieldInputs.getText().isEmpty() && this.searchFieldInputs.isFocused()) {
return;
}
if (this.searchFieldInputs.textboxKeyTyped(character, key)
|| this.searchFieldOutputs.textboxKeyTyped(character, key)
|| this.searchFieldNames.textboxKeyTyped(character, key)) {
if (character == ' ' && this.searchFieldOutputs.getText().isEmpty() && this.searchFieldOutputs.isFocused()) {
return;
}
if (this.searchFieldInputs.textboxKeyTyped(character, key) || this.searchFieldOutputs.textboxKeyTyped(character, key)) {
this.refreshList();
} else {
super.keyTyped(character, key);
@@ -449,34 +421,14 @@ public class GuiInterfaceTerminal extends AEBaseGui {
}
}
/** Cycle to the next search bar if tab is pressed, going in reverse if shift is held. */
private boolean handleTab() {
if (searchFieldInputs.isFocused()) {
searchFieldInputs.setFocused(false);
if (isShiftKeyDown()) searchFieldNames.setFocused(true);
else searchFieldOutputs.setFocused(true);
return true;
} else if (searchFieldOutputs.isFocused()) {
searchFieldOutputs.setFocused(false);
if (isShiftKeyDown()) searchFieldInputs.setFocused(true);
else searchFieldNames.setFocused(true);
return true;
} else if (searchFieldNames.isFocused()) {
searchFieldNames.setFocused(false);
if (isShiftKeyDown()) searchFieldOutputs.setFocused(true);
else searchFieldInputs.setFocused(true);
return true;
}
return false;
}
public void postUpdate(final NBTTagCompound in) {
if (in.getBoolean("clear")) {
this.byId.clear();
this.refreshList = true;
}
for (final String key : in.getKeySet()) {
for (final Object oKey : in.getKeySet()) {
final String key = (String) oKey;
if (key.startsWith("=")) {
try {
final long id = Long.parseLong(key.substring(1), Character.MAX_RADIX);
@@ -514,13 +466,12 @@ public class GuiInterfaceTerminal extends AEBaseGui {
this.byName.clear();
this.buttonList.clear();
this.matchedStacks.clear();
this.matchedInterfaces.clear();
final String searchFieldInputs = this.searchFieldInputs.getText().toLowerCase();
final String searchFieldOutputs = this.searchFieldOutputs.getText().toLowerCase();
final String searchFieldNames = this.searchFieldNames.getText().toLowerCase();
final Set<Object> cachedSearch = this.getCacheForSearchTerm("IN:" + searchFieldInputs + " OUT:" + searchFieldOutputs
+ "NAME:" + searchFieldNames + onlyShowWithSpace + onlyMolecularAssemblers + onlyBrokenRecipes);
final Set<Object> cachedSearch = this.getCacheForSearchTerm("IN:" + searchFieldInputs + " OUT:" + searchFieldOutputs + partInterfaceTerminal.onlyInterfacesWithFreeSlots);
final boolean rebuild = cachedSearch.isEmpty();
for (final ClientDCInternalInv entry : this.byId.values()) {
@@ -531,101 +482,78 @@ public class GuiInterfaceTerminal extends AEBaseGui {
// Shortcut to skip any filter if search term is ""/empty
boolean found = searchFieldInputs.isEmpty() && searchFieldOutputs.isEmpty();
boolean found = (searchFieldInputs.isEmpty() && searchFieldOutputs.isEmpty() && !partInterfaceTerminal.onlyInterfacesWithFreeSlots);
boolean interfaceHasFreeSlots = false;
boolean interfaceHasBrokenRecipes = false;
// Search if the current inventory holds a pattern containing the search term.
if (!found || onlyShowWithSpace || onlyBrokenRecipes) {
if (!found) {
int slot = 0;
for (final ItemStack itemStack : entry.getInventory()) {
if (slot > 8 + numUpgradesMap.get(entry) * 9) {
break;
}
if (!searchFieldInputs.isEmpty() && !searchFieldOutputs.isEmpty()) {
if (this.itemStackMatchesSearchTerm(itemStack, searchFieldInputs, 0) || this.itemStackMatchesSearchTerm(itemStack, searchFieldOutputs, 1)) {
found = true;
matchedStacks.add(itemStack);
}
} else if (!searchFieldInputs.isEmpty()) {
if (this.itemStackMatchesSearchTerm(itemStack, searchFieldInputs, 0)) {
found = true;
matchedStacks.add(itemStack);
}
} else if (!searchFieldOutputs.isEmpty()) {
if (this.itemStackMatchesSearchTerm(itemStack, searchFieldOutputs, 1)) {
found = true;
matchedStacks.add(itemStack);
}
}
// If only Interfaces with empty slots should be shown, check that here
if (itemStack.isEmpty()) {
interfaceHasFreeSlots = true;
}
if (onlyBrokenRecipes && recipeIsBroken(itemStack)) {
interfaceHasBrokenRecipes = true;
}
if ((!searchFieldInputs.isEmpty() && itemStackMatchesSearchTerm(itemStack, searchFieldInputs, 0))
|| (!searchFieldOutputs.isEmpty() && itemStackMatchesSearchTerm(itemStack, searchFieldOutputs, 1))) {
found = true;
matchedStacks.add(itemStack);
}
slot++;
}
}
// Exit if not found
if (!found) {
cachedSearch.remove(entry);
continue;
// if found, filter skipped or machine name matching the search term, add it
if ((searchFieldInputs.isEmpty() && searchFieldOutputs.isEmpty()) ||
!searchFieldInputs.isEmpty() && entry.getName().toLowerCase().contains(searchFieldInputs) ||
(!searchFieldOutputs.isEmpty() && entry.getName().toLowerCase().contains(searchFieldOutputs))) {
this.matchedInterfaces.add(entry);
found = true;
}
// Exit if the interface does not match the name search
if (!entry.getName().toLowerCase().contains(searchFieldNames)) {
if (found) {
if (!partInterfaceTerminal.onlyInterfacesWithFreeSlots) {
this.byName.put(entry.getName(), entry);
cachedSearch.add(entry);
} else if (interfaceHasFreeSlots) {
this.byName.put(entry.getName(), entry);
cachedSearch.add(entry);
}
} else {
cachedSearch.remove(entry);
continue;
}
// Exit if molecular assembler filter is on and this is not a molecular assembler
// Forge documantation said unlocalized name shouldn't be use for logic, so we might need a better way......
if (onlyMolecularAssemblers && !entry.getUnlocalizedName().equals(MOLECULAR_ASSEMBLER)) {
cachedSearch.remove(entry);
continue;
}
// Exit if we are only showing interfaces with free slots and there are none free in this interface
if (onlyShowWithSpace && !interfaceHasFreeSlots) {
cachedSearch.remove(entry);
continue;
}
// Exit if we are only showing interfaces with broken patterns and there are no broken patterns in this interface
if (onlyBrokenRecipes && !interfaceHasBrokenRecipes) {
cachedSearch.remove(entry);
continue;
}
// Successful search
this.byName.put(entry.getName(), entry);
cachedSearch.add(entry);
}
this.names.clear();
this.names.addAll(this.byName.keySet());
Collections.sort(this.names);
this.lines.clear();
this.lines.ensureCapacity(this.names.size() + this.byId.size());
this.lines.ensureCapacity(this.getMaxRows());
for (final String n : this.names) {
this.lines.add(n);
final ArrayList<ClientDCInternalInv> clientInventories = new ArrayList<>(this.byName.get(n));
final ArrayList<ClientDCInternalInv> clientInventories = new ArrayList<>();
clientInventories.addAll(this.byName.get(n));
Collections.sort(clientInventories);
this.lines.addAll(clientInventories);
}
this.setScrollBar();
}
private boolean recipeIsBroken(final ItemStack stack) {
if (stack == null) return false;
if (stack.isEmpty()) return false;
final NBTTagCompound encodedValue = stack.getTagCompound();
if (encodedValue == null) return true;
final World w = AppEng.proxy.getWorld();
if (w == null) return false;
try {
new PatternHelper(stack, w);
return false;
} catch (Throwable ignored) {
return true;
}
this.getScrollBar().setRange(0, this.lines.size() - 1, 1);
}
private boolean itemStackMatchesSearchTerm(final ItemStack itemStack, final String searchTerm, int pass) {
@@ -639,15 +567,15 @@ public class GuiInterfaceTerminal extends AEBaseGui {
return searchTerm.matches(GuiText.InvalidPattern.getLocal());
}
final NBTTagList tag;
NBTTagList tag = new NBTTagList();
if (pass == 0) {
tag = encodedValue.getTagList("in", Constants.NBT.TAG_COMPOUND);
tag = encodedValue.getTagList("in", 10);
} else {
tag = encodedValue.getTagList("out", Constants.NBT.TAG_COMPOUND);
tag = encodedValue.getTagList("out", 10);
}
boolean foundMatchingItemStack = false;
final String[] splitTerm = searchTerm.split(" ");
for (int i = 0; i < tag.tagCount(); i++) {
final ItemStack parsedItemStack = new ItemStack(tag.getCompoundTagAt(i));
@@ -656,7 +584,7 @@ public class GuiInterfaceTerminal extends AEBaseGui {
.getItemDisplayName(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class).createStack(parsedItemStack))
.toLowerCase();
for (String term : splitTerm) {
for (String term : searchTerm.split(" ")) {
if (term.length() > 1 && (term.startsWith("-") || term.startsWith("!"))) {
term = term.substring(1);
if (displayName.contains(term)) {
@@ -664,6 +592,8 @@ public class GuiInterfaceTerminal extends AEBaseGui {
}
} else if (displayName.contains(term)) {
foundMatchingItemStack = true;
} else {
return false;
}
}
}
@@ -695,8 +625,13 @@ public class GuiInterfaceTerminal extends AEBaseGui {
return cache;
}
/**
* The max amount of unique names and each inv row. Not affected by the filtering.
*
* @return max amount of unique names and each inv row
*/
private int getMaxRows() {
return AEConfig.instance().getConfigManager().getSetting(Settings.TERMINAL_STYLE) != TerminalStyle.TALL ? 6 : Integer.MAX_VALUE;
return this.names.size() + this.byId.size();
}
private ClientDCInternalInv getById(final long id, final long sortBy, final String string) {
@@ -709,4 +644,12 @@ public class GuiInterfaceTerminal extends AEBaseGui {
return o;
}
int getReservedSpace() {
return this.reservedSpace;
}
void setReservedSpace(final int reservedSpace) {
this.reservedSpace = reservedSpace;
}
}
@@ -31,7 +31,11 @@ import appeng.api.util.IConfigManager;
import appeng.api.util.IConfigurableObject;
import appeng.client.ActionKey;
import appeng.client.gui.AEBaseMEGui;
import appeng.client.gui.widgets.*;
import appeng.client.gui.widgets.GuiImgButton;
import appeng.client.gui.widgets.GuiScrollbar;
import appeng.client.gui.widgets.GuiTabButton;
import appeng.client.gui.widgets.ISortSource;
import appeng.client.gui.widgets.MEGuiTextField;
import appeng.client.me.InternalSlotME;
import appeng.client.me.ItemRepo;
import appeng.client.me.SlotME;
@@ -57,6 +61,7 @@ import net.minecraft.client.gui.GuiButton;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.common.Loader;
import org.lwjgl.input.Keyboard;
import org.lwjgl.input.Mouse;
@@ -98,7 +103,7 @@ public class GuiMEMonitorable extends AEBaseMEGui implements ISortSource, IConfi
private int currentMouseY = 0;
private boolean delayedUpdate;
protected int jeiOffset = Platform.isModLoaded("jei") ? 24 : 0;
protected int jeiOffset = Loader.isModLoaded("jei") ? 24 : 0;
public GuiMEMonitorable(final InventoryPlayer inventoryPlayer, final ITerminalHost te) {
this(inventoryPlayer, te, new ContainerMEMonitorable(inventoryPlayer, te));
@@ -172,9 +177,10 @@ public class GuiMEMonitorable extends AEBaseMEGui implements ISortSource, IConfi
NetworkHandler.instance().sendToServer(new PacketSwitchGuis(GuiBridge.GUI_CRAFTING_STATUS));
}
if (btn instanceof GuiImgButton iBtn) {
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());
@@ -461,7 +467,6 @@ public class GuiMEMonitorable extends AEBaseMEGui implements ISortSource, IConfi
}
final boolean mouseInGui = this.isPointInRegion(0, 0, this.xSize, this.ySize, this.currentMouseX, this.currentMouseY);
final boolean wasSearchFieldFocused = this.searchField.isFocused();
if (this.isAutoFocus && !this.searchField.isFocused() && mouseInGui) {
this.searchField.setFocused(true);
@@ -473,10 +478,6 @@ public class GuiMEMonitorable extends AEBaseMEGui implements ISortSource, IConfi
// tell forge the key event is handled and should not be sent out
this.keyHandled = mouseInGui;
} else {
if (!wasSearchFieldFocused) {
// prevent unhandled keys (like shift) from focusing the search field
searchField.setFocused(false);
}
super.keyTyped(character, key);
}
}
@@ -20,14 +20,13 @@ package appeng.client.gui.implementations;
import appeng.api.implementations.guiobjects.IPortableCell;
import appeng.container.implementations.ContainerMEPortableCell;
import net.minecraft.entity.player.InventoryPlayer;
public class GuiMEPortableCell extends GuiMEMonitorable {
public GuiMEPortableCell(final InventoryPlayer inventoryPlayer, final IPortableCell te) {
super(inventoryPlayer, te, new ContainerMEPortableCell(inventoryPlayer, te));
super(inventoryPlayer, te);
}
@Override
@@ -4,6 +4,7 @@ import appeng.api.config.AccessRestriction;
import appeng.api.config.ActionItems;
import appeng.api.config.Settings;
import appeng.api.config.StorageFilter;
import appeng.client.gui.AEBaseGui;
import appeng.client.gui.widgets.GuiImgButton;
import appeng.client.gui.widgets.GuiTabButton;
import appeng.client.gui.widgets.MEGuiTextField;
@@ -26,7 +27,7 @@ import java.io.IOException;
import java.util.regex.Pattern;
public class GuiOreDictStorageBus extends GuiUpgradeable {
public class GuiOreDictStorageBus extends AEBaseGui {
private final ContainerOreDictStorageBus container;
PartOreDicStorageBus part;
private GuiTabButton priority;
@@ -40,11 +41,13 @@ public class GuiOreDictStorageBus extends GuiUpgradeable {
super(new ContainerOreDictStorageBus(inventoryPlayer, te));
this.container = (ContainerOreDictStorageBus) super.inventorySlots;
part = te;
this.ySize = 170;
this.ySize = 84;
}
@Override
protected void addButtons() {
public void initGui() {
super.initGui();
this.searchFieldInputs = new MEGuiTextField(this.fontRenderer, this.guiLeft + 3, this.guiTop + 22, 170, 12);
this.searchFieldInputs.setEnableBackgroundDrawing(false);
this.searchFieldInputs.setMaxStringLength(512);
@@ -63,6 +66,7 @@ public class GuiOreDictStorageBus extends GuiUpgradeable {
} catch (IOException e) {
e.printStackTrace();
}
}
public void fillRegex(String regex) {
@@ -138,14 +142,11 @@ public class GuiOreDictStorageBus extends GuiUpgradeable {
}
}
@Override
protected String getBackground() {
return "guis/oredictstoragebus.png";
}
@Override
public void drawBG(int offsetX, int offsetY, int mouseX, int mouseY) {
super.drawBG(offsetX, offsetY, mouseX, mouseY);
this.bindTexture("guis/oredictstoragebus.png");
this.drawTexturedModalRect(offsetX, offsetY, 0, 0, 175, 85);
if (this.searchFieldInputs != null) {
this.searchFieldInputs.drawTextBox();
}
@@ -47,7 +47,6 @@ import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidUtil;
import org.lwjgl.input.Mouse;
import javax.annotation.Nonnull;
import java.awt.*;
import java.io.IOException;
import java.util.List;
@@ -55,7 +54,7 @@ import java.util.*;
public class GuiUpgradeable extends AEBaseGui implements IJEIGhostIngredients {
protected final Map<Target<?>, Object> mapTargetSlot = new HashMap<>();
private final Map<Target<?>, Object> mapTargetSlot = new HashMap<>();
protected final ContainerUpgradeable cvb;
protected final IUpgradeableHost bc;
@@ -219,25 +218,24 @@ public class GuiUpgradeable extends AEBaseGui implements IJEIGhostIngredients {
List<Target<?>> targets = new ArrayList<>();
List<IJEITargetSlot> slots = new ArrayList<>();
if (!this.inventorySlots.inventorySlots.isEmpty()) {
if (this.inventorySlots.inventorySlots.size() > 0) {
for (Slot slot : this.inventorySlots.inventorySlots) {
if (slot instanceof SlotFake && (!itemStack.isEmpty() || this instanceof GuiCellWorkbench && fluidStack != null)) {
slots.add((IJEITargetSlot) slot);
}
}
}
if (!this.getGuiSlots().isEmpty()) {
if (this.getGuiSlots().size() > 0) {
for (GuiCustomSlot slot : this.getGuiSlots()) {
if (slot instanceof GuiFluidSlot && fluidStack != null) {
slots.add((IJEITargetSlot) slot);
}
}
}
for (IJEITargetSlot slot : slots) {
for (Object slot : slots) {
ItemStack finalItemStack = itemStack;
FluidStack finalFluidStack = fluidStack;
Target<Object> targetItem = new Target<>() {
@Nonnull
Target<Object> targetItem = new Target<Object>() {
@Override
public Rectangle getArea() {
if (slot instanceof SlotFake && ((SlotFake) slot).isSlotEnabled()) {
@@ -249,20 +247,20 @@ public class GuiUpgradeable extends AEBaseGui implements IJEIGhostIngredients {
}
@Override
public void accept(@Nonnull Object ingredient) {
public void accept(Object ingredient) {
PacketInventoryAction p = null;
try {
if (slot instanceof SlotFake && ((SlotFake) slot).isSlotEnabled()) {
if (finalItemStack.isEmpty() && finalFluidStack != null) {
p = new PacketInventoryAction(InventoryAction.PLACE_JEI_GHOST_ITEM, slot, AEItemStack.fromItemStack(FluidUtil.getFilledBucket(finalFluidStack)));
p = new PacketInventoryAction(InventoryAction.PLACE_JEI_GHOST_ITEM, (IJEITargetSlot) slot, AEItemStack.fromItemStack(FluidUtil.getFilledBucket(finalFluidStack)));
} else if (!finalItemStack.isEmpty()) {
p = new PacketInventoryAction(InventoryAction.PLACE_JEI_GHOST_ITEM, slot, AEItemStack.fromItemStack(finalItemStack));
p = new PacketInventoryAction(InventoryAction.PLACE_JEI_GHOST_ITEM, (IJEITargetSlot) slot, AEItemStack.fromItemStack(finalItemStack));
}
} else {
if (finalFluidStack == null) {
return;
}
p = new PacketInventoryAction(InventoryAction.PLACE_JEI_GHOST_ITEM, slot, AEItemStack.fromItemStack(AEFluidStack.fromFluidStack(finalFluidStack).asItemStackRepresentation()));
p = new PacketInventoryAction(InventoryAction.PLACE_JEI_GHOST_ITEM, (IJEITargetSlot) slot, AEItemStack.fromItemStack(AEFluidStack.fromFluidStack(finalFluidStack).asItemStackRepresentation()));
}
NetworkHandler.instance().sendToServer(p);
@@ -1,18 +0,0 @@
package appeng.client.gui.implementations;
import appeng.helpers.WirelessTerminalGuiObject;
import net.minecraft.client.gui.Gui;
import net.minecraft.entity.player.InventoryPlayer;
public class GuiWirelessInterfaceTerminal extends GuiInterfaceTerminal {
public GuiWirelessInterfaceTerminal(InventoryPlayer inventoryPlayer, final WirelessTerminalGuiObject te) {
super(inventoryPlayer, te);
}
@Override
public void drawBG(int offsetX, int offsetY, int mouseX, int mouseY) {
this.bindTexture("guis/wirelessupgrades.png");
Gui.drawModalRectWithCustomSizedTexture(offsetX + 189, offsetY + 165, 0, 0, 32, 32, 32, 32);
super.drawBG(offsetX, offsetY, mouseX, mouseY);
}
}
@@ -1,14 +1,13 @@
package appeng.client.gui.widgets;
import appeng.container.interfaces.ISpecialSlotIngredient;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
public abstract class GuiCustomSlot extends Gui implements ITooltip, ISpecialSlotIngredient {
public abstract class GuiCustomSlot extends Gui implements ITooltip {
protected final int x;
protected final int y;
protected final int id;
@@ -69,9 +68,4 @@ public abstract class GuiCustomSlot extends Gui implements ITooltip, ISpecialSlo
return true;
}
@Override
public Object getIngredient() {
return null;
}
}
@@ -116,14 +116,10 @@ public class GuiImgButton extends GuiButton implements ITooltip {
this.registerApp(11 + 4 * 16, Settings.ACTIONS, ActionItems.DECREASE_BY_ONE, ButtonToolTips.DecreaseByOne, ButtonToolTips.DecreaseByOneDesc);
this.registerApp(12 + 4 * 16, Settings.ACTIONS, ActionItems.MAX_COUNT, ButtonToolTips.MaxCount, ButtonToolTips.MaxCountDesc);
this.registerApp(6 + 5 * 16, Settings.ACTIONS, ActionItems.MOLECULAR_ASSEMBLERS_ON, ButtonToolTips.ToggleMolecularAssemblers, ButtonToolTips.ToggleMolecularAssemblersOnDesc);
this.registerApp(6 + 5 * 16, Settings.ACTIONS, ActionItems.FREE_MOLECULAR_SLOT_SHORTCUT, ButtonToolTips.FreeMolecularSlotShortcut, ButtonToolTips.FreeMolecularSlotShortcutDesc);
this.registerApp(7 + 5 * 16, Settings.ACTIONS, ActionItems.TOGGLE_SHOW_FULL_INTERFACES_ON, ButtonToolTips.ToggleShowFullInterfaces, ButtonToolTips.ToggleShowFullInterfacesOnDesc);
this.registerApp(8 + 5 * 16, Settings.ACTIONS, ActionItems.TOGGLE_SHOW_FULL_INTERFACES_OFF, ButtonToolTips.ToggleShowFullInterfaces, ButtonToolTips.ToggleShowFullInterfacesOffDesc);
this.registerApp(9 + 5 * 16, Settings.ACTIONS, ActionItems.MOLECULAR_ASSEMBLERS_OFF, ButtonToolTips.ToggleMolecularAssemblers, ButtonToolTips.ToggleMolecularAssemblersOffDesc);
this.registerApp(6 + 6 * 16, Settings.ACTIONS, ActionItems.HIGHLIGHT_INTERFACE, ButtonToolTips.HighlightInterface, "");
this.registerApp(66, Settings.ACTIONS, ActionItems.CONFIGURE_INTERFACE, ButtonToolTips.ConfigureInterface, "");
this.registerApp(4 + 5 * 16, Settings.ACTIONS, ActionItems.TOGGLE_SHOW_ONLY_INVALID_PATTERNS_OFF, ButtonToolTips.ToggleShowOnlyInvalidInterface, ButtonToolTips.ToggleShowOnlyInvalidInterfaceOffDesc);
this.registerApp(5 + 5 * 16, Settings.ACTIONS, ActionItems.TOGGLE_SHOW_ONLY_INVALID_PATTERNS_ON, ButtonToolTips.ToggleShowOnlyInvalidInterface, ButtonToolTips.ToggleShowOnlyInvalidInterfaceOnDesc);
this.registerApp(8, Settings.ACTIONS, ActionItems.ENCODE, ButtonToolTips.Encode, ButtonToolTips.EncodeDescription);
this.registerApp(4 + 3 * 16, Settings.ACTIONS, ItemSubstitution.ENABLED, ButtonToolTips.Substitutions, ButtonToolTips.SubstitutionsDescEnabled);
@@ -161,12 +157,6 @@ public class GuiImgButton extends GuiButton implements ITooltip {
this.registerApp(16 * 15, Settings.SCHEDULING_MODE, SchedulingMode.DEFAULT, ButtonToolTips.SchedulingMode, ButtonToolTips.SchedulingModeDefault);
this.registerApp(16 * 15 + 1, Settings.SCHEDULING_MODE, SchedulingMode.ROUNDROBIN, ButtonToolTips.SchedulingMode, ButtonToolTips.SchedulingModeRoundRobin);
this.registerApp(16 * 15 + 2, Settings.SCHEDULING_MODE, SchedulingMode.RANDOM, ButtonToolTips.SchedulingMode, ButtonToolTips.SchedulingModeRandom);
this.registerApp(10, Settings.UNLOCK,LockCraftingMode.NONE,ButtonToolTips.LockCraftingMode, ButtonToolTips.LockCraftingModeNone);
this.registerApp(7, Settings.UNLOCK,LockCraftingMode.LOCK_UNTIL_RESULT,ButtonToolTips.LockCraftingMode, ButtonToolTips.LockCraftingUntilResultReturned);
this.registerApp(0, Settings.UNLOCK, LockCraftingMode.LOCK_WHILE_LOW, ButtonToolTips.LockCraftingMode, ButtonToolTips.LockCraftingWhileRedstoneLow);
this.registerApp(1, Settings.UNLOCK, LockCraftingMode.LOCK_WHILE_HIGH, ButtonToolTips.LockCraftingMode, ButtonToolTips.LockCraftingWhileRedstoneHigh);
this.registerApp(2, Settings.UNLOCK, LockCraftingMode.LOCK_UNTIL_PULSE, ButtonToolTips.LockCraftingMode, ButtonToolTips.LockCraftingUntilRedstonePulse);
}
}
@@ -346,7 +336,7 @@ public class GuiImgButton extends GuiButton implements ITooltip {
this.fillVar = fillVar;
}
public static final class EnumPair {
private static final class EnumPair {
final Enum setting;
final Enum value;
@@ -1,142 +0,0 @@
package appeng.client.gui.widgets;
import appeng.api.config.LockCraftingMode;
import appeng.api.config.Settings;
import appeng.core.localization.GuiText;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiLabel;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.translation.I18n;
import java.util.HashMap;
import java.util.Map;
public class GuiImgLabel extends GuiLabel implements ITooltip {
public GuiImgLabel(FontRenderer fontRendererObj, final int x, final int y, final Enum idx, final Enum val) {
super(fontRendererObj, 0, x, y, 16, 16, 0);
this.currentValue = val;
this.labelSetting = idx;
this.fontRenderer = fontRendererObj;
if (appearances == null) {
appearances = new HashMap<>();
registerApp(10, Settings.UNLOCK, LockCraftingMode.NONE, GuiText.NoneLock, null, 0x00FF00);
registerApp(9, Settings.UNLOCK, LockCraftingMode.LOCK_WHILE_LOW, GuiText.CraftingLock, GuiText.LowRedstoneLock, 0xFF0000);
registerApp(9, Settings.UNLOCK, LockCraftingMode.LOCK_WHILE_HIGH, GuiText.CraftingLock, GuiText.HighRedstoneLock, 0xFF0000);
registerApp(9, Settings.UNLOCK, LockCraftingMode.LOCK_UNTIL_PULSE, GuiText.CraftingLock, GuiText.UntilPulseUnlock, 0xFF0000);
registerApp(9, Settings.UNLOCK, LockCraftingMode.LOCK_UNTIL_RESULT, GuiText.CraftingLock, GuiText.ResultLock, 0xFF0000);
}
}
private final Enum labelSetting;
private Enum currentValue;
private static Map<GuiImgButton.EnumPair, LabelAppearance> appearances;
private final FontRenderer fontRenderer;
public void setVisibility(final boolean vis) {
this.visible = vis;
}
@Override
public void drawLabel(Minecraft mc, int mouseX, int mouseY) {
if (this.visible) {
final int iconIndex = this.getIconIndex();
if (iconIndex == -1) {
return;
}
mc.renderEngine.bindTexture(new ResourceLocation("appliedenergistics2", "textures/guis/states.png"));
GlStateManager.color(1.0f, 1.0f, 1.0f, 1.0f);
final int uv_y = (int) Math.floor(iconIndex / 16);
final int uv_x = iconIndex - uv_y * 16;
this.drawTexturedModalRect(this.x, this.y, uv_x * 16, uv_y * 16, 16, 16);
if (labelSetting != null && currentValue != null) {
LabelAppearance labelAppearance = appearances.get(new GuiImgButton.EnumPair(this.labelSetting, this.currentValue));
String translated = I18n.translateToLocal(labelAppearance.displayLabel);
fontRenderer.drawString(translated, x + 16, y + 5, labelAppearance.color);
width = 16 + fontRenderer.getStringWidth(translated);
}
}
}
private int getIconIndex() {
if (this.labelSetting != null && this.currentValue != null) {
final LabelAppearance app = appearances.get(new GuiImgButton.EnumPair(this.labelSetting, this.currentValue));
if (app == null) {
return -1;
}
return app.index;
}
return -1;
}
private void registerApp(final int iconIndex, final Settings setting, final Enum val, final GuiText label, final Object hint, int color) {
final LabelAppearance a = new LabelAppearance();
if (hint != null) {
a.hiddenValue = (String) (hint instanceof String ? hint : ((GuiText) hint).getUnlocalized());
} else {
a.hiddenValue = null;
}
a.index = iconIndex;
a.displayLabel = label.getUnlocalized();
a.color = color;
appearances.put(new GuiImgButton.EnumPair(setting, val), a);
}
@Override
public String getMessage() {
if (labelSetting != null && this.currentValue != null) {
LabelAppearance labelAppearance = appearances.get(new GuiImgButton.EnumPair(this.labelSetting, this.currentValue));
if (labelAppearance == null) {
return "No Such Message";
}
if (labelAppearance.hiddenValue != null) {
return I18n.translateToLocal(labelAppearance.hiddenValue);
}
}
return null;
}
public void set(final Enum e) {
if (this.currentValue != e) {
this.currentValue = e;
}
}
@Override
public int xPos() {
return x;
}
@Override
public int yPos() {
return y;
}
@Override
public int getWidth() {
return width;
}
@Override
public int getHeight() {
return height;
}
@Override
public boolean isVisible() {
return visible;
}
private static class LabelAppearance {
public int index;
public String displayLabel;
public String hiddenValue;
public int color;
}
}
@@ -1,236 +0,0 @@
package appeng.client.gui.widgets;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.GuiTextField;
import org.lwjgl.input.Keyboard;
/**
* Different implementation of a text field that wraps instead of extends
* MC's {@link GuiTextField}. This is necessary because of deobfuscated name
* collision between {@link ITooltip} and GuiTextField, which would cause
* crashes in an obfuscated environment. Additionally, since we are not extending that
* class, we can construct this object differently and allow its position to be
* mutable like most other widgets.
*/
public class MEGuiTooltipTextField implements ITooltip {
protected GuiTextField field;
private static final int PADDING = 2;
private static boolean previousKeyboardRepeatEnabled;
private static MEGuiTooltipTextField previousKeyboardRepeatEnabledField;
private String tooltip;
private int fontPad;
public int x;
public int y;
public int w;
public int h;
/**
* Uses the values to instantiate a padded version of a text field. Pays attention to the '_' caret.
*
* @param width absolute width
* @param height absolute height
* @param tooltip tooltip message
*/
public MEGuiTooltipTextField(final int width, final int height, final String tooltip) {
final FontRenderer fontRenderer = Minecraft.getMinecraft().fontRenderer;
field = new GuiTextField(0, fontRenderer, 0, 0, 0, 0);
w = width;
h = height;
setMessage(tooltip);
this.fontPad = fontRenderer.getCharWidth('_');
setDimensionsAndColor();
}
public MEGuiTooltipTextField(final int width, final int height) {
this(width, height, "");
}
public MEGuiTooltipTextField() {
this(0, 0);
}
protected void setDimensionsAndColor() {
field.x = this.x + PADDING;
field.y = this.y + PADDING;
field.width = this.w - PADDING * 2 - this.fontPad;
field.height = this.h - PADDING * 2;
}
public void onTextChange(final String oldText) {}
public void mouseClicked(final int xPos, final int yPos, final int button) {
if (!this.isMouseIn(xPos, yPos)) {
setFocused(false);
return;
}
field.setCanLoseFocus(false);
setFocused(true);
if (button == 1) {
setText("");
} else {
field.mouseClicked(xPos, yPos, button);
}
field.setCanLoseFocus(true);
}
/**
* Checks if the mouse is within the element
*
* @param xCoord current x coord of the mouse
* @param yCoord current y coord of the mouse
* @return true if mouse position is within the getText field area
*/
public boolean isMouseIn(final int xCoord, final int yCoord) {
final boolean withinXRange = this.x <= xCoord && xCoord < this.x + this.w;
final boolean withinYRange = this.y <= yCoord && yCoord < this.y + this.h;
return withinXRange && withinYRange;
}
public boolean textboxKeyTyped(final char keyChar, final int keyID) {
if (!isFocused()) {
return false;
}
final String oldText = getText();
boolean handled = field.textboxKeyTyped(keyChar, keyID);
if (!handled && (keyID == Keyboard.KEY_RETURN || keyID == Keyboard.KEY_NUMPADENTER
|| keyID == Keyboard.KEY_ESCAPE)) {
setFocused(false);
}
if (handled) {
onTextChange(oldText);
}
return handled;
}
public void drawTextBox() {
if (field.getVisible()) {
setDimensionsAndColor();
GuiTextField.drawRect(
this.x + 1,
this.y + 1,
this.x + this.w - 1,
this.y + this.h - 1,
isFocused() ? 0xFF606060 : 0xFFA8A8A8);
field.drawTextBox();
}
}
public void setText(String text, boolean ignoreTrigger) {
final String oldText = getText();
int currentCursorPos = field.getCursorPosition();
field.setText(text);
field.setCursorPosition(currentCursorPos);
if (!ignoreTrigger) {
onTextChange(oldText);
}
}
public void setText(String text) {
setText(text, false);
}
public void setCursorPositionEnd() {
field.setCursorPositionEnd();
}
public void setFocused(boolean focus) {
if (field.isFocused() == focus) {
return;
}
field.setFocused(focus);
if (focus) {
if (previousKeyboardRepeatEnabledField == null) {
previousKeyboardRepeatEnabled = Keyboard.areRepeatEventsEnabled();
}
previousKeyboardRepeatEnabledField = this;
Keyboard.enableRepeatEvents(true);
} else {
if (previousKeyboardRepeatEnabledField == this) {
previousKeyboardRepeatEnabledField = null;
Keyboard.enableRepeatEvents(previousKeyboardRepeatEnabled);
}
}
}
public void setMaxStringLength(final int size) {
field.setMaxStringLength(size);
}
public void setEnableBackgroundDrawing(final boolean b) {
field.setEnableBackgroundDrawing(b);
}
public void setTextColor(final int color) {
field.setTextColor(color);
}
public void setCursorPositionZero() {
field.setCursorPositionZero();
}
public boolean isFocused() {
return field.isFocused();
}
public String getText() {
return field.getText();
}
public void setMessage(String t) {
tooltip = t;
}
@Override
public String getMessage() {
return tooltip;
}
@Override
public boolean isVisible() {
return field.getVisible();
}
@Override
public int xPos() {
return x;
}
@Override
public int yPos() {
return y;
}
@Override
public int getWidth() {
return w;
}
@Override
public int getHeight() {
return h;
}
}
@@ -55,10 +55,6 @@ public class ClientDCInternalInv implements Comparable<ClientDCInternalInv> {
return s;
}
public String getUnlocalizedName() {
return this.unlocalizedName;
}
@Override
public int compareTo(@Nonnull final ClientDCInternalInv o) {
return Long.compare(this.sortBy, o.sortBy);
@@ -20,13 +20,11 @@ package appeng.client.me;
import appeng.api.storage.data.IAEFluidStack;
import appeng.container.interfaces.ISpecialSlotIngredient;
import appeng.fluids.container.slots.IMEFluidSlot;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.SlotItemHandler;
import org.jetbrains.annotations.Nullable;
import javax.annotation.Nonnull;
@@ -36,7 +34,7 @@ import javax.annotation.Nonnull;
* @version rv6 - 22/05/2018
* @since rv6 22/05/2018
*/
public class SlotFluidME extends SlotItemHandler implements IMEFluidSlot, ISpecialSlotIngredient {
public class SlotFluidME extends SlotItemHandler implements IMEFluidSlot {
private final InternalFluidSlotME slot;
@@ -97,11 +95,4 @@ public class SlotFluidME extends SlotItemHandler implements IMEFluidSlot, ISpeci
public boolean canTakeStack(final EntityPlayer par1EntityPlayer) {
return false;
}
@Nullable
@Override
public Object getIngredient() {
return this.getAEFluidStack() == null ? null : this.getAEFluidStack().getFluidStack();
}
}
@@ -24,10 +24,6 @@ import appeng.api.parts.IPartModel;
import appeng.api.util.AECableType;
import appeng.api.util.AEColor;
import appeng.block.networking.BlockCableBus;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.cache.Weigher;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.BakedQuad;
@@ -42,7 +38,6 @@ import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.MinecraftForgeClient;
import net.minecraftforge.common.property.IExtendedBlockState;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;
import java.util.Map.Entry;
@@ -50,6 +45,8 @@ import java.util.Map.Entry;
public class CableBusBakedModel implements IBakedModel {
static final Map<CableBusRenderState, List<BakedQuad>> CABLE_MODEL_CACHE = new HashMap<>();
private final CableBuilder cableBuilder;
private final FacadeBuilder facadeBuilder;
@@ -60,24 +57,11 @@ public class CableBusBakedModel implements IBakedModel {
private final TextureMap textureMap = Minecraft.getMinecraft().getTextureMapBlocks();
private final LoadingCache<CableBusRenderState, List<BakedQuad>> cableModelCache;
CableBusBakedModel(CableBuilder cableBuilder, FacadeBuilder facadeBuilder, Map<ResourceLocation, IBakedModel> partModels, TextureAtlasSprite particleTexture) {
this.cableBuilder = cableBuilder;
this.facadeBuilder = facadeBuilder;
this.partModels = partModels;
this.particleTexture = particleTexture;
this.cableModelCache = CacheBuilder.newBuilder()
.maximumWeight(5000)
.weigher((Weigher<CableBusRenderState, List<BakedQuad>>) (k, v) -> v.size())
.build(new CacheLoader<>() {
@Override
public List<BakedQuad> load(@Nonnull CableBusRenderState rs) {
final List<BakedQuad> model = new ArrayList<>();
addCableQuads(rs, model);
return model;
}
});
}
@Override
@@ -98,7 +82,12 @@ public class CableBusBakedModel implements IBakedModel {
if (layer == BlockRenderLayer.CUTOUT) {
// First, handle the cable at the center of the cable bus
final List<BakedQuad> cableModel = cableModelCache.getUnchecked(renderState);
final List<BakedQuad> cableModel = CABLE_MODEL_CACHE.computeIfAbsent(renderState, k ->
{
final List<BakedQuad> model = new ArrayList<>();
this.addCableQuads(renderState, model);
return model;
});
quads.addAll(cableModel);
// Then handle attachments
@@ -27,21 +27,26 @@ import com.google.common.collect.ImmutableMap;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.model.IModel;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.client.resource.IResourceType;
import net.minecraftforge.client.resource.ISelectiveResourceReloadListener;
import net.minecraftforge.client.resource.VanillaResourceType;
import net.minecraftforge.common.model.IModelState;
import net.minecraftforge.common.model.TRSRTransformation;
import java.util.Collection;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Predicate;
/**
* The built-in model for the cable bus block.
*/
public class CableBusModel implements IModel {
public class CableBusModel implements IModel, ISelectiveResourceReloadListener {
private final PartModels partModels;
@@ -101,4 +106,12 @@ public class CableBusModel implements IModel {
public IModelState getDefaultState() {
return TRSRTransformation.identity();
}
@Override
public void onResourceManagerReload(IResourceManager resourceManager, Predicate<IResourceType> resourcePredicate) {
if (resourcePredicate.test(VanillaResourceType.MODELS)) {
CableBusBakedModel.CABLE_MODEL_CACHE.clear();
}
}
}
@@ -1,6 +1,7 @@
package appeng.client.render.model;
import com.google.common.collect.ImmutableMap;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel;
@@ -8,8 +9,9 @@ import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
import net.minecraft.client.renderer.block.model.ItemOverrideList;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.client.model.PerspectiveMapWrapper;
import net.minecraftforge.common.model.TRSRTransformation;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import javax.vecmath.Matrix4f;
@@ -22,12 +24,15 @@ class ColorApplicatorBakedModel implements IBakedModel {
private final IBakedModel baseModel;
private final ImmutableMap<ItemCameraTransforms.TransformType, TRSRTransformation> transforms;
private final EnumMap<EnumFacing, List<BakedQuad>> quadsBySide;
private final List<BakedQuad> generalQuads;
ColorApplicatorBakedModel(IBakedModel baseModel, TextureAtlasSprite texDark, TextureAtlasSprite texMedium, TextureAtlasSprite texBright) {
ColorApplicatorBakedModel(IBakedModel baseModel, ImmutableMap<ItemCameraTransforms.TransformType, TRSRTransformation> map, TextureAtlasSprite texDark, TextureAtlasSprite texMedium, TextureAtlasSprite texBright) {
this.baseModel = baseModel;
this.transforms = map;
// Put the tint indices in... Since this is an item model, we are ignoring rand
this.generalQuads = this.fixQuadTint(null, texDark, texMedium, texBright);
@@ -63,7 +68,7 @@ class ColorApplicatorBakedModel implements IBakedModel {
}
@Override
public @NotNull List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand) {
public List<BakedQuad> getQuads(@Nullable IBlockState state, @Nullable EnumFacing side, long rand) {
if (side == null) {
return this.generalQuads;
}
@@ -86,22 +91,22 @@ class ColorApplicatorBakedModel implements IBakedModel {
}
@Override
public @NotNull TextureAtlasSprite getParticleTexture() {
public TextureAtlasSprite getParticleTexture() {
return this.baseModel.getParticleTexture();
}
@Override
public @NotNull ItemCameraTransforms getItemCameraTransforms() {
public ItemCameraTransforms getItemCameraTransforms() {
return this.baseModel.getItemCameraTransforms();
}
@Override
public @NotNull ItemOverrideList getOverrides() {
public ItemOverrideList getOverrides() {
return this.baseModel.getOverrides();
}
@Override
public @NotNull Pair<? extends IBakedModel, Matrix4f> handlePerspective(@NotNull ItemCameraTransforms.TransformType type) {
return this.baseModel.handlePerspective(type);
public Pair<? extends IBakedModel, Matrix4f> handlePerspective(ItemCameraTransforms.TransformType type) {
return PerspectiveMapWrapper.handlePerspective(this, this.transforms, type);
}
}
@@ -55,7 +55,7 @@ public class ColorApplicatorModel implements IModel {
ImmutableMap<ItemCameraTransforms.TransformType, TRSRTransformation> map = PerspectiveMapWrapper.getTransforms(state);
return new ColorApplicatorBakedModel(baseModel, texDark, texMedium, texBright);
return new ColorApplicatorBakedModel(baseModel, map, texDark, texMedium, texBright);
}
private IBakedModel getBaseModel(IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter) {
@@ -60,9 +60,6 @@ public class DriveBakedModel implements IBakedModel {
}
DriveSlotsState slotsState = extState.getValue(BlockDrive.SLOTS_STATE);
if (slotsState == null) {
return result;
}
for (int row = 0; row < 5; row++) {
for (int col = 0; col < 2; col++) {
@@ -93,7 +90,6 @@ public class DriveBakedModel implements IBakedModel {
}
}
return result;
}
@@ -399,17 +399,9 @@ public abstract class AEBaseContainer extends Container {
return ItemStack.EMPTY; // don't insert duplicate encoded patterns to interfaces
}
final int maxSize;
if (d instanceof SlotOversized slotOversized) {
maxSize = slotOversized.getSlotStackLimit();
} else {
maxSize = Math.min(tis.getMaxStackSize(), d.getSlotStackLimit());
}
int maxSize = Math.max(tis.getMaxStackSize(), d.getSlotStackLimit());
int placeAble = maxSize - t.getCount();
if (placeAble <= 0) {
continue;
}
if (tis.getCount() < placeAble) {
placeAble = tis.getCount();
@@ -443,7 +435,7 @@ public abstract class AEBaseContainer extends Container {
if (d.isItemValid(tis)) {
if (!d.getHasStack()) {
int maxSize = Math.min(tis.getMaxStackSize(), d.getSlotStackLimit());
int maxSize = Math.max(tis.getMaxStackSize(), d.getSlotStackLimit());
final ItemStack tmp = tis.copy();
if (tmp.getCount() > maxSize) {
@@ -961,13 +953,9 @@ public abstract class AEBaseContainer extends Container {
@Override
public ItemStack slotClick(int slotId, int dragType, ClickType clickTypeIn, @NotNull EntityPlayer player) {
if (slotId >= 0) {
if (slotId >= 0 && clickTypeIn == ClickType.PICKUP) {
final var slot = this.getSlot(slotId);
if (slot instanceof SlotDisabled) {
return ItemStack.EMPTY;
}
if (slot instanceof AppEngSlot appEngSlot && clickTypeIn == ClickType.PICKUP) {
if (slot instanceof AppEngSlot appEngSlot) {
var slotStack = slot.getStack();
var draggedStack = this.invPlayer.getItemStack();
@@ -976,34 +964,26 @@ public abstract class AEBaseContainer extends Container {
if (!draggedStack.isEmpty()) {
if (appEngSlot.isItemValid(draggedStack)) {
if (slotStack.getItem() == draggedStack.getItem() && slotStack.getMetadata() == draggedStack.getMetadata() && ItemStack.areItemStackTagsEqual(slotStack, draggedStack)) {
// Slot size or stack size, whichever is smaller.
var maxSize = Math.min(appEngSlot.getSlotStackLimit(), draggedStack.getMaxStackSize());
var maxSize = Math.max(appEngSlot.getSlotStackLimit(), draggedStack.getMaxStackSize());
var maxInsertable = Math.min(draggedStack.getCount(), maxSize - appEngSlot.getStack().getCount());
var toInsert = Math.min(maxInsertable, dragType == 0 ? maxInsertable : 1);
// The maximum number of items that can be inserted into the slot, non-negative.
var maxInsertable = Math.min(draggedStack.getCount(),
Math.max(0, maxSize - appEngSlot.getStack().getCount()));
draggedStack.shrink(toInsert);
slotStack.grow(toInsert);
if (maxInsertable != 0) {
var toInsert = Math.min(maxInsertable, dragType == 0 ? maxInsertable : 1);
draggedStack.shrink(toInsert);
slotStack.grow(toInsert);
slot.putStack(slot.getStack());
return ItemStack.EMPTY;
}
slot.onSlotChanged();
return ItemStack.EMPTY;
}
}
}
// Fixes taking and halving issues from oversized slots.
else if (dragType == 0 || dragType == 1) {
if (slot.canTakeStack(player) && !slotStack.isEmpty()) {
var result = slotStack.copy();
var toTake = Math.min(slotStack.getCount(), slotStack.getMaxStackSize());
this.invPlayer.setItemStack(slot.decrStackSize(dragType == 0 ? toTake : (toTake + 1) / 2));
slot.putStack(slot.getStack());
return result;
slot.onTake(player, invPlayer.getItemStack());
return ItemStack.EMPTY;
}
}
@@ -31,7 +31,7 @@ import appeng.api.networking.crafting.ICraftingLink;
import appeng.api.networking.security.IActionHost;
import appeng.api.networking.security.IActionSource;
import appeng.api.networking.storage.IStorageGrid;
import appeng.api.storage.IMEMonitor;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.ITerminalHost;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
@@ -213,7 +213,7 @@ public class ContainerCraftConfirm extends AEBaseContainer {
p.setStackSize(out.getCountRequestable());
final IStorageGrid sg = grid.getCache(IStorageGrid.class);
final IMEMonitor<IAEItemStack> items = sg.getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class));
final IMEInventory<IAEItemStack> items = sg.getInventory(AEApi.instance().storage().getStorageChannel(IItemStorageChannel.class));
IAEItemStack m = null;
if (c != null && this.result.isSimulation()) {
@@ -330,7 +330,8 @@ public class ContainerCraftConfirm extends AEBaseContainer {
if (te != null) {
Platform.openGUI(this.getInventoryPlayer().player, te, this.getOpenContext().getSide(), originalGui);
} else {
if (ah instanceof IInventorySlotAware i) {
if (ah instanceof IInventorySlotAware) {
IInventorySlotAware i = ((IInventorySlotAware) ah);
Platform.openGUI(this.getInventoryPlayer().player, i.getInventorySlot(), originalGui, i.isBaubleSlot());
}
}
@@ -116,19 +116,15 @@ public class ContainerInscriber extends ContainerUpgradeable implements IProgres
boolean matches = false;
for (final IInscriberRecipe recipe : AEApi.instance().registries().inscriber().getRecipes()) {
// Check if plateA matches any item in the list of top components of the recipe
final boolean matchA = top.isEmpty() && recipe.getTopInputs().isEmpty() ||
recipe.getTopInputs().stream().anyMatch(topItem -> Platform.itemComparisons().isSameItem(top, topItem)) &&
(bot.isEmpty() && recipe.getBottomInputs().isEmpty() ||
recipe.getBottomInputs().stream().anyMatch(bottomItem -> Platform.itemComparisons().isSameItem(bot, bottomItem)));
final boolean matchA = !top
.isEmpty() && (Platform.itemComparisons().isSameItem(top, recipe.getTopOptional().orElse(ItemStack.EMPTY)) || Platform
.itemComparisons()
.isSameItem(top, recipe.getBottomOptional().orElse(ItemStack.EMPTY)));
final boolean matchB = !bot
.isEmpty() && (Platform.itemComparisons().isSameItem(bot, recipe.getTopOptional().orElse(ItemStack.EMPTY)) || Platform
.itemComparisons()
.isSameItem(bot, recipe.getBottomOptional().orElse(ItemStack.EMPTY)));
// Check if plateB matches any item in the list of top components of the recipe
final boolean matchB = bot.isEmpty() && recipe.getTopInputs().isEmpty() ||
recipe.getTopInputs().stream().anyMatch(topItem -> Platform.itemComparisons().isSameItem(bot, topItem)) &&
(top.isEmpty() && recipe.getBottomInputs().isEmpty() ||
recipe.getBottomInputs().stream().anyMatch(bottomItem -> Platform.itemComparisons().isSameItem(top, bottomItem)));
// If either matchA or matchB is true, iterate through the recipe's inputs
if (matchA || matchB) {
matches = true;
for (final ItemStack option : recipe.getInputs()) {
@@ -156,22 +152,10 @@ public class ContainerInscriber extends ContainerUpgradeable implements IProgres
// everything else
for (final IInscriberRecipe recipe : AEApi.instance().registries().inscriber().getRecipes()) {
boolean isValid = false;
// Check if otherSlot matches any item in the top component list
boolean matchTop = recipe.getTopInputs().stream()
.anyMatch(topItem -> Platform.itemComparisons().isSameItem(otherSlot, topItem));
// Check if otherSlot matches any item in the bottom component list
boolean matchBottom = recipe.getBottomInputs().stream()
.anyMatch(bottomItem -> Platform.itemComparisons().isSameItem(otherSlot, bottomItem));
if (matchTop) {
// If otherSlot matches a top component, check if 'is' matches any item in the bottom component list
isValid = recipe.getBottomInputs().stream()
.anyMatch(bottomItem -> Platform.itemComparisons().isSameItem(is, bottomItem));
} else if (matchBottom) {
// If otherSlot matches a bottom component, check if 'is' matches any item in the top component list
isValid = recipe.getTopInputs().stream()
.anyMatch(topItem -> Platform.itemComparisons().isSameItem(is, topItem));
if (Platform.itemComparisons().isSameItem(otherSlot, recipe.getTopOptional().orElse(ItemStack.EMPTY))) {
isValid = Platform.itemComparisons().isSameItem(is, recipe.getBottomOptional().orElse(ItemStack.EMPTY));
} else if (Platform.itemComparisons().isSameItem(otherSlot, recipe.getBottomOptional().orElse(ItemStack.EMPTY))) {
isValid = Platform.itemComparisons().isSameItem(is, recipe.getTopOptional().orElse(ItemStack.EMPTY));
}
if (isValid) {
@@ -19,7 +19,10 @@
package appeng.container.implementations;
import appeng.api.config.*;
import appeng.api.config.SecurityPermissions;
import appeng.api.config.Settings;
import appeng.api.config.Upgrades;
import appeng.api.config.YesNo;
import appeng.api.util.IConfigManager;
import appeng.container.guisync.GuiSync;
import appeng.container.slot.*;
@@ -37,17 +40,11 @@ public class ContainerInterface extends ContainerUpgradeable implements IOptiona
public YesNo bMode = YesNo.NO;
@GuiSync(4)
public LockCraftingMode lMode = LockCraftingMode.NONE;
public YesNo iTermMode = YesNo.YES;
@GuiSync(7)
public int patternExpansions = 0;
@GuiSync(8)
public YesNo iTermMode = YesNo.YES;
@GuiSync(9)
public LockCraftingMode lockReason = LockCraftingMode.NONE;
public ContainerInterface(final InventoryPlayer ip, final IInterfaceHost te) {
super(ip, te.getInterfaceDuality().getHost());
@@ -97,10 +94,6 @@ public class ContainerInterface extends ContainerUpgradeable implements IOptiona
patternExpansions = getPatternUpgrades();
this.myDuality.dropExcessPatterns();
}
if (Platform.isServer()){
lockReason = myDuality.getCraftingLockedReason();
}
super.detectAndSendChanges();
}
@@ -114,14 +107,9 @@ public class ContainerInterface extends ContainerUpgradeable implements IOptiona
@Override
protected void loadSettingsFromHost(final IConfigManager cm) {
this.setBlockingMode((YesNo) cm.getSetting(Settings.BLOCK));
this.setUnlockMode((LockCraftingMode) cm.getSetting(Settings.UNLOCK));
this.setInterfaceTerminalMode((YesNo) cm.getSetting(Settings.INTERFACE_TERMINAL));
}
public LockCraftingMode getUnlockMode() {return this.lMode;}
public void setUnlockMode(final LockCraftingMode mode) {this.lMode = mode;}
public YesNo getBlockingMode() {
return this.bMode;
}
@@ -141,8 +129,4 @@ public class ContainerInterface extends ContainerUpgradeable implements IOptiona
public int getPatternUpgrades() {
return this.myDuality.getInstalledUpgrades(Upgrades.PATTERN_EXPANSION);
}
public LockCraftingMode getCraftingLockedReason() {
return lockReason;
}
}
@@ -34,7 +34,6 @@ import appeng.core.sync.packets.PacketInventoryAction;
import appeng.helpers.DualityInterface;
import appeng.helpers.IInterfaceHost;
import appeng.helpers.InventoryAction;
import appeng.helpers.WirelessTerminalGuiObject;
import appeng.items.misc.ItemEncodedPattern;
import appeng.parts.misc.PartInterface;
import appeng.parts.reporting.PartInterfaceTerminal;
@@ -66,7 +65,7 @@ import java.util.Map.Entry;
import static appeng.helpers.ItemStackHelper.stackWriteToNBT;
public class ContainerInterfaceTerminal extends AEBaseContainer {
public final class ContainerInterfaceTerminal extends AEBaseContainer {
/**
* this stuff is all server side..
@@ -88,21 +87,6 @@ public class ContainerInterfaceTerminal extends AEBaseContainer {
this.bindPlayerInventory(ip, 0, 0);
}
public ContainerInterfaceTerminal(final InventoryPlayer ip, final WirelessTerminalGuiObject guiObject, boolean bindInventory) {
super(ip, guiObject);
if (Platform.isServer()) {
IGridNode node = guiObject.getActionableNode();
if (node != null && node.isActive()) {
this.grid = node.getGrid();
}
}
if (bindInventory) {
this.bindPlayerInventory(ip, 0, 0);
}
}
@Override
public void detectAndSendChanges() {
if (Platform.isClient()) {
@@ -192,15 +176,6 @@ public class ContainerInterfaceTerminal extends AEBaseContainer {
}
}
public DualityInterface getById(long id) {
var tracker = this.byId.get(id);
if (tracker == null) {
return null;
}
return tracker.getDualityInterface();
}
@Override
public void doAction(final EntityPlayerMP player, final InventoryAction action, final int slot, final long id) {
final InvTracker inv = this.byId.get(id);
@@ -210,16 +185,14 @@ public class ContainerInterfaceTerminal extends AEBaseContainer {
final AppEngSlot playerSlot;
try {
playerSlot = (AppEngSlot) this.inventorySlots.get(slot);
} catch (IndexOutOfBoundsException ignored) {
return;
}
} catch (IndexOutOfBoundsException ignored) { return; }
if (!playerSlot.isPlayerSide() || !playerSlot.getHasStack()) return;
var itemStack = playerSlot.getStack();
if (!itemStack.isEmpty()) {
var handler = new WrapperFilteredItemHandler(
new WrapperRangeItemHandler(inv.server, 0, 9 * (inv.numUpgrades + 1)), new PatternSlotFilter());
new WrapperRangeItemHandler(inv.server, 0, 9 * (inv.numUpgrades + 1)), new PatternSlotFilter());
playerSlot.putStack(ItemHandlerHelper.insertItem(handler, itemStack, false));
detectAndSendChanges();
}
@@ -415,7 +388,7 @@ public class ContainerInterfaceTerminal extends AEBaseContainer {
if (slot instanceof SlotDisconnected slotDisconnected && !slot.getHasStack()) {
// Signal the server to move the pattern.
var packet = new PacketInventoryAction(InventoryAction.PLACE_SINGLE,
playerAppEngSlot.slotNumber, slotDisconnected.getSlot().getId());
playerAppEngSlot.slotNumber, slotDisconnected.getSlot().getId());
NetworkHandler.instance().sendToServer(packet);
@@ -437,10 +410,8 @@ public class ContainerInterfaceTerminal extends AEBaseContainer {
private final BlockPos pos;
private final int dim;
private final int numUpgrades;
private final DualityInterface dualityInterface;
public InvTracker(final DualityInterface dual, final IItemHandler patterns, final String unlocalizedName) {
this.dualityInterface = dual;
this.server = patterns;
this.client = new AppEngInternalInventory(null, this.server.getSlots());
this.unlocalizedName = unlocalizedName;
@@ -449,10 +420,6 @@ public class ContainerInterfaceTerminal extends AEBaseContainer {
this.dim = dual.getLocation().getWorld().provider.getDimension();
this.numUpgrades = dual.getInstalledUpgrades(Upgrades.PATTERN_EXPANSION);
}
public DualityInterface getDualityInterface() {
return dualityInterface;
}
}
private static class PatternSlotFilter implements IAEItemFilter {
@@ -46,8 +46,6 @@ import appeng.api.util.IConfigurableObject;
import appeng.client.gui.implementations.GuiMEMonitorable;
import appeng.container.AEBaseContainer;
import appeng.container.guisync.GuiSync;
import appeng.container.slot.SlotPlayerHotBar;
import appeng.container.slot.SlotPlayerInv;
import appeng.container.slot.SlotRestrictedInput;
import appeng.core.AELog;
import appeng.core.sync.network.NetworkHandler;
@@ -62,10 +60,9 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.IContainerListener;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.fml.common.Loader;
import javax.annotation.Nonnull;
import java.io.IOException;
@@ -87,7 +84,7 @@ public class ContainerMEMonitorable extends AEBaseContainer implements IConfigMa
private IConfigManagerHost gui;
private IConfigManager serverCM;
private IGridNode networkNode;
protected int jeiOffset = Platform.isModLoaded("jei") ? 24 : 0;
protected int jeiOffset = Loader.isModLoaded("jei") ? 24 : 0;
public ContainerMEMonitorable(final InventoryPlayer ip, final ITerminalHost monitorable) {
@@ -164,51 +161,6 @@ public class ContainerMEMonitorable extends AEBaseContainer implements IConfigMa
}
}
@Override
public ItemStack transferStackInSlot(final EntityPlayer p, final int idx) {
if (Platform.isClient()) {
return ItemStack.EMPTY;
}
// Below logic is all about handling shift click for view cells
if (!(this.host instanceof IViewCellStorage)) {
return super.transferStackInSlot(p, idx);
}
// Is it a view cell?
final Slot clickSlot = this.inventorySlots.get(idx);
ItemStack itemStack = clickSlot.getStack();
if (!AEApi.instance().definitions().items().viewCell().isSameAs(itemStack)) {
return super.transferStackInSlot(p, idx);
}
// Are we clicking from the player's inventory?
final boolean isPlayerInventorySlot = this.inventorySlots.get(idx) instanceof SlotPlayerInv || this.inventorySlots.get(idx) instanceof SlotPlayerHotBar;
if (!isPlayerInventorySlot) {
return super.transferStackInSlot(p, idx);
}
// Attempt to move the item into the view cell storage
final IItemHandler viewCellInv = ((IViewCellStorage) this.host).getViewCellStorage();
for (int slot = 0; slot < viewCellInv.getSlots(); slot++) {
if (viewCellInv.isItemValid(slot, itemStack) && viewCellInv.getStackInSlot(slot).isEmpty()) {
ItemStack remainder = viewCellInv.insertItem(slot, itemStack, true);
if (!remainder.isEmpty()) { // That slot can't take the item
continue;
}
remainder = viewCellInv.insertItem(slot, itemStack, false);
clickSlot.putStack(remainder);
this.detectAndSendChanges();
if (!remainder.isEmpty()) {
// How??
return super.transferStackInSlot(p, idx);
}
return ItemStack.EMPTY;
}
}
return super.transferStackInSlot(p, idx);
}
public IGridNode getNetworkNode() {
return this.networkNode;
}
@@ -1,12 +1,15 @@
package appeng.container.implementations;
import appeng.api.AEApi;
import appeng.api.config.*;
import appeng.api.config.AccessRestriction;
import appeng.api.config.SecurityPermissions;
import appeng.api.config.Settings;
import appeng.api.config.StorageFilter;
import appeng.api.storage.IMEInventory;
import appeng.api.storage.channels.IItemStorageChannel;
import appeng.api.storage.data.IAEItemStack;
import appeng.container.AEBaseContainer;
import appeng.container.guisync.GuiSync;
import appeng.container.slot.SlotRestrictedInput;
import appeng.core.sync.network.NetworkHandler;
import appeng.core.sync.packets.PacketValueConfig;
import appeng.parts.misc.PartOreDicStorageBus;
@@ -15,7 +18,6 @@ import appeng.util.item.AEItemStack;
import appeng.util.item.OreReference;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.oredict.OreDictionary;
import java.io.IOException;
@@ -24,7 +26,7 @@ import java.util.Iterator;
import java.util.Set;
public class ContainerOreDictStorageBus extends ContainerUpgradeable {
public class ContainerOreDictStorageBus extends AEBaseContainer {
private final PartOreDicStorageBus part;
@GuiSync(3)
@@ -33,9 +35,6 @@ public class ContainerOreDictStorageBus extends ContainerUpgradeable {
@GuiSync(4)
public StorageFilter storageFilter = StorageFilter.EXTRACTABLE_ONLY;
@GuiSync(7)
public YesNo stickyMode = YesNo.NO;
public ContainerOreDictStorageBus(final InventoryPlayer ip, final PartOreDicStorageBus anchor) {
super(ip, anchor);
this.part = anchor;
@@ -48,15 +47,9 @@ public class ContainerOreDictStorageBus extends ContainerUpgradeable {
if (Platform.isServer()) {
this.setReadWriteMode((AccessRestriction) part.getConfigManager().getSetting(Settings.ACCESS));
this.setStorageFilter((StorageFilter) part.getConfigManager().getSetting(Settings.STORAGE_FILTER));
this.setStickyMode((YesNo) this.getUpgradeable().getConfigManager().getSetting(Settings.STICKY_MODE));
}
super.standardDetectAndSendChanges();
}
@Override
protected int getHeight() {
return 170;
super.detectAndSendChanges();
}
public void partition() {
@@ -123,29 +116,4 @@ public class ContainerOreDictStorageBus extends ContainerUpgradeable {
private void setStorageFilter(final StorageFilter storageFilter) {
this.storageFilter = storageFilter;
}
@Override
protected void setupConfig() {
final IItemHandler upgrades = this.getUpgradeable().getInventoryByName("upgrades");
this.addSlotToContainer((new SlotRestrictedInput(SlotRestrictedInput.PlacableItemType.UPGRADES, upgrades, 0, 187, 8, this.getInventoryPlayer()))
.setNotDraggable());
}
@Override
public int availableUpgrades() {
return 1;
}
@Override
protected boolean supportCapacity() {
return false;
}
public YesNo getStickyMode() {
return this.stickyMode;
}
private void setStickyMode(final YesNo stickyMode) {
this.stickyMode = stickyMode;
}
}
@@ -30,13 +30,13 @@ import appeng.container.slot.SlotOutput;
import appeng.container.slot.SlotRestrictedInput;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.tile.misc.TileSecurityStation;
import appeng.util.Platform;
import appeng.util.inv.IAEAppEngInventory;
import appeng.util.inv.InvOperation;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.IContainerListener;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.items.IItemHandler;
@@ -53,7 +53,7 @@ public class ContainerSecurityStation extends ContainerMEMonitorable implements
@GuiSync(0)
public int permissionMode = 0;
protected int jeiOffset = Platform.isModLoaded("jei") ? 24 : 0;
protected int jeiOffset = Loader.isModLoaded("jei") ? 24 : 0;
public ContainerSecurityStation(final InventoryPlayer ip, final ITerminalHost monitorable) {
super(ip, monitorable, false);
@@ -75,7 +75,8 @@ public class ContainerSecurityStation extends ContainerMEMonitorable implements
final SecurityPermissions permission = SecurityPermissions.valueOf(value);
final ItemStack a = this.configSlot.getStack();
if (!a.isEmpty() && a.getItem() instanceof IBiometricCard bc) {
if (!a.isEmpty() && a.getItem() instanceof IBiometricCard) {
final IBiometricCard bc = (IBiometricCard) a.getItem();
if (bc.hasPermission(a, permission)) {
bc.removePermission(a, permission);
} else {
@@ -94,7 +95,8 @@ public class ContainerSecurityStation extends ContainerMEMonitorable implements
this.setPermissionMode(0);
final ItemStack a = this.configSlot.getStack();
if (!a.isEmpty() && a.getItem() instanceof IBiometricCard bc) {
if (!a.isEmpty() && a.getItem() instanceof IBiometricCard) {
final IBiometricCard bc = (IBiometricCard) a.getItem();
for (final SecurityPermissions sp : bc.getPermissions(a)) {
this.setPermissionMode(this.getPermissionMode() | (1 << sp.ordinal()));
@@ -50,9 +50,6 @@ public class ContainerStorageBus extends ContainerUpgradeable {
@GuiSync(4)
public StorageFilter storageFilter = StorageFilter.EXTRACTABLE_ONLY;
@GuiSync(7)
public YesNo stickyMode = YesNo.NO;
public ContainerStorageBus(final InventoryPlayer ip, final PartStorageBus te) {
super(ip, te);
this.storageBus = te;
@@ -114,7 +111,6 @@ public class ContainerStorageBus extends ContainerUpgradeable {
this.setFuzzyMode((FuzzyMode) this.getUpgradeable().getConfigManager().getSetting(Settings.FUZZY_MODE));
this.setReadWriteMode((AccessRestriction) this.getUpgradeable().getConfigManager().getSetting(Settings.ACCESS));
this.setStorageFilter((StorageFilter) this.getUpgradeable().getConfigManager().getSetting(Settings.STORAGE_FILTER));
this.setStickyMode((YesNo) this.getUpgradeable().getConfigManager().getSetting(Settings.STICKY_MODE));
}
this.standardDetectAndSendChanges();
@@ -172,12 +168,4 @@ public class ContainerStorageBus extends ContainerUpgradeable {
private void setStorageFilter(final StorageFilter storageFilter) {
this.storageFilter = storageFilter;
}
public YesNo getStickyMode() {
return this.stickyMode;
}
private void setStickyMode(final YesNo stickyMode) {
this.stickyMode = stickyMode;
}
}
@@ -1,198 +0,0 @@
package appeng.container.implementations;
import appeng.api.config.Actionable;
import appeng.api.config.PowerMultiplier;
import appeng.api.implementations.IUpgradeableCellContainer;
import appeng.api.networking.security.IActionHost;
import appeng.container.interfaces.IInventorySlotAware;
import appeng.container.slot.SlotRestrictedInput;
import appeng.core.AEConfig;
import appeng.core.localization.PlayerMessages;
import appeng.helpers.WirelessTerminalGuiObject;
import appeng.parts.automation.StackUpgradeInventory;
import appeng.tile.inventory.AppEngInternalInventory;
import appeng.util.Platform;
import appeng.util.inv.IAEAppEngInventory;
import appeng.util.inv.InvOperation;
import baubles.api.BaublesApi;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.ClickType;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.items.IItemHandler;
import org.jetbrains.annotations.NotNull;
public class ContainerWirelessInterfaceTerminal extends ContainerInterfaceTerminal implements IInventorySlotAware, IUpgradeableCellContainer, IAEAppEngInventory {
private final WirelessTerminalGuiObject wirelessTerminalGUIObject;
private final int slot;
private double powerMultiplier = 0.5;
private int ticks = 0;
protected AppEngInternalInventory upgrades;
protected SlotRestrictedInput magnetSlot;
public ContainerWirelessInterfaceTerminal(InventoryPlayer ip, WirelessTerminalGuiObject guiObject) {
super(ip, guiObject,false);
if (guiObject != null) {
final int slotIndex = guiObject.getInventorySlot();
if (!guiObject.isBaubleSlot()) {
this.lockPlayerInventorySlot(slotIndex);
}
this.slot = slotIndex;
} else {
this.lockPlayerInventorySlot(ip.currentItem);
this.slot = -1;
}
this.bindPlayerInventory(ip,0,0);
this.wirelessTerminalGUIObject = guiObject;
upgrades = new StackUpgradeInventory(wirelessTerminalGUIObject.getItemStack(), this, 2);
this.loadFromNBT();
setupUpgrades();
}
@Override
public void detectAndSendChanges() {
if (Platform.isServer()) {
final ItemStack currentItem;
if (wirelessTerminalGUIObject.isBaubleSlot()) {
currentItem = BaublesApi.getBaublesHandler(this.getPlayerInv().player).getStackInSlot(this.slot);
} else {
currentItem = this.slot < 0 ? this.getPlayerInv().getCurrentItem() : this.getPlayerInv().getStackInSlot(this.slot);
}
if (currentItem.isEmpty()) {
this.setValidContainer(false);
} else if (!this.wirelessTerminalGUIObject.getItemStack().isEmpty() && currentItem != this.wirelessTerminalGUIObject.getItemStack()) {
if (ItemStack.areItemsEqual(this.wirelessTerminalGUIObject.getItemStack(), currentItem)) {
if (wirelessTerminalGUIObject.isBaubleSlot()) {
BaublesApi.getBaublesHandler(this.getPlayerInv().player).setStackInSlot(this.slot, this.wirelessTerminalGUIObject.getItemStack());
} else {
this.getPlayerInv().setInventorySlotContents(this.slot, this.wirelessTerminalGUIObject.getItemStack());
}
} else {
this.setValidContainer(false);
}
}
// drain 1 ae t
this.ticks++;
if (this.ticks > 10) {
double ext = this.wirelessTerminalGUIObject.extractAEPower(this.getPowerMultiplier() * this.ticks, Actionable.MODULATE, PowerMultiplier.CONFIG);
if (ext < this.getPowerMultiplier() * this.ticks) {
if (Platform.isServer() && this.isValidContainer()) {
this.getPlayerInv().player.sendMessage(PlayerMessages.DeviceNotPowered.get());
}
this.setValidContainer(false);
}
this.ticks = 0;
}
if (!this.wirelessTerminalGUIObject.rangeCheck()) {
if (Platform.isServer() && this.isValidContainer()) {
this.getPlayerInv().player.sendMessage(PlayerMessages.OutOfRange.get());
}
this.setValidContainer(false);
} else {
this.setPowerMultiplier(AEConfig.instance().wireless_getDrainRate(this.wirelessTerminalGUIObject.getRange()));
}
super.detectAndSendChanges();
}
}
@Override
public ItemStack slotClick(int slotId, int dragType, ClickType clickTypeIn, @NotNull EntityPlayer player) {
if (slotId >= 0 && slotId < this.inventorySlots.size()) {
if (clickTypeIn == ClickType.PICKUP && dragType == 1) {
if (this.inventorySlots.get(slotId) == magnetSlot) {
ItemStack itemStack = magnetSlot.getStack();
if (!magnetSlot.getStack().isEmpty()) {
NBTTagCompound tag = itemStack.getTagCompound();
if (tag == null) {
tag = new NBTTagCompound();
}
if (tag.hasKey("enabled")) {
boolean e = tag.getBoolean("enabled");
tag.setBoolean("enabled", !e);
} else {
tag.setBoolean("enabled", false);
}
magnetSlot.getStack().setTagCompound(tag);
magnetSlot.onSlotChanged();
return ItemStack.EMPTY;
}
}
}
}
return super.slotClick(slotId, dragType, clickTypeIn, player);
}
private double getPowerMultiplier() {
return this.powerMultiplier;
}
void setPowerMultiplier(final double powerMultiplier) {
this.powerMultiplier = powerMultiplier;
}
@Override
protected IActionHost getActionHost() {
return wirelessTerminalGUIObject;
}
@Override
public int getInventorySlot() {
return wirelessTerminalGUIObject.getInventorySlot();
}
@Override
public boolean isBaubleSlot() {
return wirelessTerminalGUIObject.isBaubleSlot();
}
@Override
public int availableUpgrades() {
return 1;
}
@Override
public void setupUpgrades() {
if (wirelessTerminalGUIObject != null) {
for (int upgradeSlot = 0; upgradeSlot < availableUpgrades(); upgradeSlot++) {
this.magnetSlot = new SlotRestrictedInput(SlotRestrictedInput.PlacableItemType.UPGRADES, upgrades, upgradeSlot, 183, -1 + upgradeSlot * 18, this.getInventoryPlayer());
this.magnetSlot.setNotDraggable();
this.addSlotToContainer(magnetSlot);
}
}
}
private void loadFromNBT() {
NBTTagCompound data = wirelessTerminalGUIObject.getItemStack().getTagCompound();
if (data != null) {
upgrades.readFromNBT(wirelessTerminalGUIObject.getItemStack().getTagCompound().getCompoundTag("upgrades"));
}
}
@Override
public void saveChanges() {
if (Platform.isServer()) {
NBTTagCompound tag = new NBTTagCompound();
this.upgrades.writeToNBT(tag, "upgrades");
this.wirelessTerminalGUIObject.saveChanges(tag);
}
}
@Override
public void onChangeInventory(IItemHandler inv, int slot, InvOperation mc, ItemStack removedStack, ItemStack newStack) {
}
}
@@ -1,10 +0,0 @@
package appeng.container.interfaces;
import javax.annotation.Nullable;
public interface ISpecialSlotIngredient {
@Nullable
Object getIngredient();
}
@@ -1,9 +1,4 @@
package appeng.container.slot;
public interface IJEITargetSlot {
default boolean needAccept() {
return false;
}
}
@@ -41,6 +41,9 @@ import appeng.util.inv.WrapperCursorItemHandler;
import appeng.util.inv.WrapperInvItemHandler;
import appeng.util.item.AEItemStack;
import com.blamejared.recipestages.recipes.RecipeStage;
import net.darkhax.gamestages.GameStageHelper;
import net.darkhax.itemstages.ItemStages;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.InventoryCrafting;
import net.minecraft.item.Item;
@@ -50,6 +53,9 @@ import net.minecraft.item.crafting.IRecipe;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.items.IItemHandler;
import java.util.ArrayList;
@@ -151,7 +157,8 @@ public class SlotCraftingTerm extends AppEngCraftingSlot {
// TODO: This is really hacky and NEEDS to be solved with a full container/gui refactoring.
protected IRecipe findRecipe(InventoryCrafting ic, World world, EntityPlayer player) {
if (this.container instanceof ContainerCraftingTerm containerTerminal) {
if (this.container instanceof ContainerCraftingTerm) {
final ContainerCraftingTerm containerTerminal = (ContainerCraftingTerm) this.container;
final IRecipe recipe = containerTerminal.getCurrentRecipe();
if (recipe != null && recipe.matches(ic, world)) {
@@ -164,8 +171,9 @@ public class SlotCraftingTerm extends AppEngCraftingSlot {
// Returns null in case this recipe is not yet unlocked
private IRecipe handleRecipe(InventoryCrafting ic, IRecipe recipe, EntityPlayer player) {
if (Platform.isModLoaded("recipestages")) {
if (recipe instanceof RecipeStage staged) {
if (Loader.isModLoaded("recipestages")) {
if (recipe instanceof RecipeStage) {
final RecipeStage staged = (RecipeStage) recipe;
if (!staged.isGoodForCrafting(ic))
return null;
}
@@ -177,7 +185,8 @@ public class SlotCraftingTerm extends AppEngCraftingSlot {
// TODO: This is really hacky and NEEDS to be solved with a full container/gui refactoring.
@Override
protected NonNullList<ItemStack> getRemainingItems(InventoryCrafting ic, World world) {
if (this.container instanceof ContainerCraftingTerm containerTerminal) {
if (this.container instanceof ContainerCraftingTerm) {
final ContainerCraftingTerm containerTerminal = (ContainerCraftingTerm) this.container;
final IRecipe recipe = containerTerminal.getCurrentRecipe();
if (recipe != null && recipe.matches(ic, world)) {
@@ -50,6 +50,7 @@ public class SlotFake extends AppEngSlot implements IJEITargetSlot {
if (!is.isEmpty()) {
is = is.copy();
}
super.putStack(is);
}
@@ -57,10 +58,4 @@ public class SlotFake extends AppEngSlot implements IJEITargetSlot {
public boolean canTakeStack(final EntityPlayer par1EntityPlayer) {
return false;
}
@Override
public boolean needAccept() {
return this.getStack().isEmpty();
}
}
-12
View File
@@ -83,8 +83,6 @@ public final class AEConfig extends Configuration implements IConfigurableObject
private int craftingCalculationTimePerTick = 5;
private PowerUnits selectedPowerUnit = PowerUnits.AE;
private boolean showCraftableTooltip = true;
private boolean showPlacementPreview = true;
private boolean showCellContentsPreview = true;
// Spatial IO/Dimension
private int storageProviderID = -1;
@@ -259,8 +257,6 @@ public final class AEConfig extends Configuration implements IConfigurableObject
this.useLargeFonts = this.get("Client", "useTerminalUseLargeFont", false).getBoolean(false);
this.useColoredCraftingStatus = this.get("Client", "useColoredCraftingStatus", true).getBoolean(true);
this.showCraftableTooltip = this.get("Client", "showCraftableTooltip", true, "Whether to add \"Craftable\" to item tooltips when they can be crafted automatically.").getBoolean(true);
this.showPlacementPreview = this.get("Client", "showPlacementPreview", true, "Whether to show a preview of part and facade placement.").getBoolean(true);
this.showCellContentsPreview = this.get("Client", "showCellContentsPreview", true, "Whether to show a preview of cell contents in tooltips.").getBoolean(true);
// load buttons..
for (int btnNum = 0; btnNum < 4; btnNum++) {
@@ -518,14 +514,6 @@ public final class AEConfig extends Configuration implements IConfigurableObject
return this.showCraftableTooltip;
}
public boolean showPlacementPreview() {
return this.showPlacementPreview;
}
public boolean showCellContentsPreview() {
return showCellContentsPreview;
}
public boolean isDisableColoredCableRecipesInJEI() {
return this.disableColoredCableRecipesInJEI;
}
@@ -25,7 +25,6 @@ import appeng.client.ActionKey;
import appeng.client.EffectType;
import appeng.core.sync.AppEngPacket;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
@@ -33,7 +32,6 @@ import net.minecraft.world.World;
import javax.annotation.Nonnull;
import java.util.List;
import java.util.Random;
import java.util.UUID;
public abstract class CommonHelper {
@@ -68,5 +66,4 @@ public abstract class CommonHelper {
public abstract boolean isActionKey(@Nonnull final ActionKey key, int pressedKeyCode);
public abstract EntityPlayer getPlayerByUUID(UUID uuid);
}
+3 -25
View File
@@ -55,12 +55,12 @@ import appeng.core.stats.Stats;
import appeng.core.worlddata.SpatialDimensionManager;
import appeng.fluids.registries.BasicFluidCellGuiHandler;
import appeng.hooks.TickHandler;
import appeng.hooks.WrenchClickHook;
import appeng.items.materials.ItemMaterial;
import appeng.items.parts.ItemFacade;
import appeng.items.parts.ItemPart;
import appeng.loot.ChestLoot;
import appeng.me.cache.*;
import appeng.parts.PartPlacement;
import appeng.recipes.AEItemResolver;
import appeng.recipes.AERecipeLoader;
import appeng.recipes.game.DisassembleRecipe;
@@ -109,6 +109,7 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -192,7 +193,7 @@ final class Registration {
MinecraftForge.EVENT_BUS.register(TickHandler.INSTANCE);
MinecraftForge.EVENT_BUS.register(new WrenchClickHook());
MinecraftForge.EVENT_BUS.register(new PartPlacement());
if (AEConfig.instance().isFeatureEnabled(AEFeature.CHEST_LOOT)) {
MinecraftForge.EVENT_BUS.register(new ChestLoot());
@@ -364,19 +365,15 @@ final class Registration {
// Storage Cells
Upgrades.FUZZY.registerItem(items.cell1k(), 1);
Upgrades.INVERTER.registerItem(items.cell1k(), 1);
Upgrades.STICKY.registerItem(items.cell1k(), 1);
Upgrades.FUZZY.registerItem(items.cell4k(), 1);
Upgrades.INVERTER.registerItem(items.cell4k(), 1);
Upgrades.STICKY.registerItem(items.cell4k(), 1);
Upgrades.FUZZY.registerItem(items.cell16k(), 1);
Upgrades.INVERTER.registerItem(items.cell16k(), 1);
Upgrades.STICKY.registerItem(items.cell16k(), 1);
Upgrades.FUZZY.registerItem(items.cell64k(), 1);
Upgrades.INVERTER.registerItem(items.cell64k(), 1);
Upgrades.STICKY.registerItem(items.cell64k(), 1);
Upgrades.FUZZY.registerItem(items.portableCell(), 1);
Upgrades.INVERTER.registerItem(items.portableCell(), 1);
@@ -387,32 +384,14 @@ final class Registration {
Upgrades.FUZZY.registerItem(AEApi.instance().definitions().materials().cardMagnet(), 1);
Upgrades.INVERTER.registerItem(AEApi.instance().definitions().materials().cardMagnet(), 1);
// Fluid Cells
Upgrades.INVERTER.registerItem(items.fluidCell1k(), 1);
Upgrades.STICKY.registerItem(items.fluidCell1k(), 1);
Upgrades.INVERTER.registerItem(items.fluidCell4k(), 1);
Upgrades.STICKY.registerItem(items.fluidCell4k(), 1);
Upgrades.INVERTER.registerItem(items.fluidCell16k(), 1);
Upgrades.STICKY.registerItem(items.fluidCell16k(), 1);
Upgrades.INVERTER.registerItem(items.fluidCell64k(), 1);
Upgrades.STICKY.registerItem(items.fluidCell64k(), 1);
// Storage Bus
Upgrades.FUZZY.registerItem(parts.storageBus(), 1);
Upgrades.INVERTER.registerItem(parts.storageBus(), 1);
Upgrades.CAPACITY.registerItem(parts.storageBus(), 5);
Upgrades.STICKY.registerItem(parts.storageBus(), 1);
// OreDict Storage Bus
Upgrades.STICKY.registerItem(parts.oreDictStorageBus(), 1);
// Storage Bus Fluids
Upgrades.INVERTER.registerItem(parts.fluidStorageBus(), 1);
Upgrades.CAPACITY.registerItem(parts.fluidStorageBus(), 5);
Upgrades.STICKY.registerItem(parts.fluidStorageBus(), 1);
// Formation Plane
Upgrades.FUZZY.registerItem(parts.formationPlane(), 1);
@@ -445,7 +424,6 @@ final class Registration {
});
}
items.wirelessFluidTerminal().maybeItem().ifPresent(terminal -> registries.wireless().registerWirelessHandler((IWirelessTermHandler) terminal));
items.wirelessInterfaceTerminal().maybeItem().ifPresent(terminal -> registries.wireless().registerWirelessHandler((IWirelessTermHandler) terminal));
// Charge Rates
items.chargedStaff().maybeItem().ifPresent(chargedStaff -> registries.charger().addChargeRate(chargedStaff, 320d));
@@ -11,9 +11,7 @@ import appeng.api.storage.data.IAEItemStack;
import appeng.api.storage.data.IAEStack;
import appeng.api.storage.data.IItemList;
import appeng.api.util.IClientHelper;
import appeng.core.AEConfig;
import appeng.core.localization.GuiText;
import appeng.core.localization.Tooltips;
import appeng.fluids.items.FluidDummyItem;
import appeng.fluids.util.AEFluidStack;
import appeng.util.ReadableNumberConverter;
@@ -45,9 +43,10 @@ public class ApiClientHelper implements IClientHelper {
final ICellInventory<?> cellInventory = handler.getCellInv();
if (cellInventory != null) {
lines.add(Tooltips.bytesUsed(cellInventory.getUsedBytes(),cellInventory.getTotalBytes()).getFormattedText());
lines.add(cellInventory.getUsedBytes() + " " + GuiText.Of.getLocal() + ' ' + cellInventory.getTotalBytes() + ' ' + GuiText.BytesUsed.getLocal());
lines.add(Tooltips.typesUsed(cellInventory.getStoredItemTypes(),cellInventory.getTotalItemTypes()).getFormattedText());
lines.add(cellInventory.getStoredItemTypes() + " " + GuiText.Of.getLocal() + ' ' + cellInventory.getTotalItemTypes() + ' ' + GuiText.Types
.getLocal());
}
IItemList<?> itemList = cellInventory.getChannel().createList();
@@ -61,10 +60,6 @@ public class ApiClientHelper implements IClientHelper {
lines.add("[" + GuiText.Partitioned.getLocal() + "]" + " - " + list + ' ' + GuiText.Precise.getLocal());
}
if (handler.isSticky()) {
lines.add(GuiText.Sticky.getLocal());
}
if (Minecraft.getMinecraft().gameSettings.advancedItemTooltips || Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) {
IItemHandler inv = cellInventory.getConfigInventory();
cellInventory.getAvailableItems((IItemList) itemList);
@@ -110,10 +105,7 @@ public class ApiClientHelper implements IClientHelper {
}
}
} else {
if (!AEConfig.instance().showCellContentsPreview()) return;
if (Minecraft.getMinecraft().gameSettings.advancedItemTooltips
|| Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)
) {
if (Minecraft.getMinecraft().gameSettings.advancedItemTooltips || Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) {
cellInventory.getAvailableItems((IItemList) itemList);
for (IAEStack<?> s : itemList) {
if (s instanceof IAEItemStack) {
+281 -51
View File
@@ -19,18 +19,18 @@
package appeng.core.api;
import appeng.api.AEApi;
import appeng.api.definitions.ITileDefinition;
import appeng.api.parts.CableRenderMode;
import appeng.api.parts.IPart;
import appeng.api.parts.IPartHelper;
import appeng.api.parts.LayerBase;
import appeng.core.AELog;
import appeng.core.AppEng;
import appeng.parts.PartPlacement;
import appeng.api.parts.IPartHost;
import appeng.api.util.AEPartLocation;
import appeng.util.Platform;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import appeng.tile.AEBaseTile;
import appeng.tile.networking.TileCableBus;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
@@ -39,15 +39,243 @@ import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.commons.ClassRemapper;
import org.objectweb.asm.commons.Remapper;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.*;
public class ApiPart implements IPartHelper {
private final LoadingCache<CacheKey, Class<? extends AEBaseTile>> cache = CacheBuilder.newBuilder()
.build(new CacheLoader<CacheKey, Class<? extends AEBaseTile>>() {
@Override
public Class<? extends AEBaseTile> load(CacheKey key) throws Exception {
return ApiPart.this.generateCombinedClass(key);
}
});
private final Map<Class<?>, String> interfaces2Layer = new HashMap<>();
private final List<String> desc = new ArrayList<>();
/**
* Conceptually this method will build a new class hierarchy that is rooted at the given base class, and includes a
* chain of all registered layers.
* <p/>
* To accomplish this, it takes the first registered layer, replaces it's inheritance from LayerBase with an
* inheritance from the given baseClass,
* and uses the resulting class as the parent class for the next registered layer, for which it repeats this
* process. This process is then repeated
* until a class hierarchy of all layers is formed. While janking out the inheritance from LayerBase, it'll make
* also sure that calls to that
* classes method will instead be forwarded to the superclass that was inserted as part of the described process.
* <p/>
* Example: If layers A and B are registered, and TileCableBus is passed in as the baseClass, a synthetic class
* A_B_TileCableBus should be returned,
* which has A_B_TileCableBus -extends-> B_TileCableBus -extends-> TileCableBus as it's class hierarchy, where
* A_B_TileCableBus has been generated
* from A, and B_TileCableBus has been generated from B.
*/
public Class<? extends AEBaseTile> getCombinedInstance(final Class<? extends AEBaseTile> baseClass) {
if (this.desc.isEmpty()) {
// No layers registered...
return baseClass;
}
return this.cache.getUnchecked(new CacheKey(baseClass, this.desc));
}
private Class<? extends AEBaseTile> generateCombinedClass(CacheKey cacheKey) {
final Class<? extends AEBaseTile> parentClass;
// Get the list of interfaces that still need to be implemented beyond the current one
List<String> remainingInterfaces = cacheKey.getInterfaces().subList(1, cacheKey.getInterfaces().size());
// We are not at the root of the class hierarchy yet
if (!remainingInterfaces.isEmpty()) {
CacheKey parentKey = new CacheKey(cacheKey.getBaseClass(), remainingInterfaces);
parentClass = this.cache.getUnchecked(parentKey);
} else {
parentClass = cacheKey.getBaseClass();
}
// Which interface should be implemented in this layer?
String interfaceName = cacheKey.getInterfaces().get(0);
try {
// This is the particular interface that this layer was registered for. Loading the class may fail if i.e.
// an API is broken or not present
// and in this case, the layer will be skipped!
Class<?> interfaceClass = Class.forName(interfaceName);
String layerImpl = this.interfaces2Layer.get(interfaceClass);
return this.getClassByDesc(parentClass, layerImpl);
} catch (final Throwable t) {
AELog.warn("Error loading " + interfaceName);
AELog.debug(t);
return parentClass;
}
}
@SuppressWarnings("unchecked")
private Class<? extends AEBaseTile> getClassByDesc(Class<? extends AEBaseTile> baseClass, final String next) {
final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
final ClassNode n = this.getReader(next);
final String originalName = n.name;
try {
n.name = n.name + '_' + baseClass.getSimpleName();
n.superName = baseClass.getName().replace('.', '/');
} catch (final Throwable t) {
AELog.debug(t);
}
for (final MethodNode mn : n.methods) {
final Iterator<AbstractInsnNode> i = mn.instructions.iterator();
while (i.hasNext()) {
this.processNode(i.next(), n.superName);
}
}
final DefaultPackageClassNameRemapper remapper = new DefaultPackageClassNameRemapper();
remapper.inputOutput.put("appeng/api/parts/LayerBase", n.superName);
remapper.inputOutput.put(originalName, n.name);
n.accept(new ClassRemapper(cw, remapper));
// n.accept( cw );
// n.accept( new TraceClassVisitor( new PrintWriter( System.out ) ) );
final byte[] byteArray = cw.toByteArray();
final int size = byteArray.length;
final Class clazz = this.loadClass(n.name.replace("/", "."), byteArray);
try {
final Object fish = clazz.newInstance();
boolean hasError = false;
if (!baseClass.isInstance(fish)) {
hasError = true;
AELog.error("Error, Expected layer to implement " + baseClass + " did not.");
}
if (fish instanceof LayerBase) {
hasError = true;
AELog.error("Error, Expected layer to NOT implement LayerBase but it DID.");
}
if (!(fish instanceof TileCableBus)) {
hasError = true;
AELog.error("Error, Expected layer to implement TileCableBus did not.");
}
if (!(fish instanceof TileEntity)) {
hasError = true;
AELog.error("Error, Expected layer to implement TileEntity did not.");
}
if (!hasError) {
AELog.info("Layer: " + n.name + " loaded successfully - " + size + " bytes");
}
} catch (final Throwable t) {
AELog.error("Layer: " + n.name + " Failed.");
AELog.debug(t);
}
return clazz;
}
private ClassNode getReader(final String name) {
final String path = '/' + name.replace(".", "/") + ".class";
final InputStream is = this.getClass().getResourceAsStream(path);
try {
final ClassReader cr = new ClassReader(is);
final ClassNode cn = new ClassNode();
cr.accept(cn, ClassReader.EXPAND_FRAMES);
return cn;
} catch (final IOException e) {
throw new IllegalStateException("Error loading " + name, e);
}
}
private void processNode(final AbstractInsnNode next, final String nePar) {
if (next instanceof MethodInsnNode) {
final MethodInsnNode min = (MethodInsnNode) next;
if (min.owner.equals("appeng/api/parts/LayerBase")) {
min.owner = nePar;
}
}
}
private Class loadClass(final String name, byte[] b) {
// override classDefine (as it is protected) and define the class.
Class clazz = null;
try {
final ClassLoader loader = this.getClass().getClassLoader();// ClassLoader.getSystemClassLoader();
final Class<ClassLoader> root = ClassLoader.class;
final Class<? extends ClassLoader> cls = loader.getClass();
final Method defineClassMethod = root.getDeclaredMethod("defineClass", String.class, byte[].class, int.class, int.class);
final Method runTransformersMethod = cls.getDeclaredMethod("runTransformers", String.class, String.class, byte[].class);
runTransformersMethod.setAccessible(true);
defineClassMethod.setAccessible(true);
try {
final Object[] argsA = {
name,
name,
b
};
b = (byte[]) runTransformersMethod.invoke(loader, argsA);
final Object[] args = {
name,
b,
0,
b.length
};
clazz = (Class) defineClassMethod.invoke(loader, args);
} finally {
runTransformersMethod.setAccessible(false);
defineClassMethod.setAccessible(false);
}
} catch (final Exception e) {
AELog.debug(e);
throw new IllegalStateException("Unable to manage part API.", e);
}
return clazz;
}
@Override
public boolean registerNewLayer(final String layer, final String layerInterface) {
try {
final Class<?> layerInterfaceClass = Class.forName(layerInterface);
if (this.interfaces2Layer.get(layerInterfaceClass) == null) {
this.interfaces2Layer.put(layerInterfaceClass, layer);
this.desc.add(layerInterface);
return true;
} else {
AELog.info("Layer " + layer + " not registered, " + layerInterface + " already has a layer.");
}
} catch (final Throwable ignored) {
}
return false;
}
@Override
public EnumActionResult placeBus(final ItemStack is, final BlockPos pos, final EnumFacing side, final EntityPlayer player, final EnumHand hand, final World w) {
return PartPlacement.place(is, pos, side, player, hand, w);
return PartPlacement.place(is, pos, side, player, hand, w, PartPlacement.PlaceType.PLACE_ITEM, 0);
}
@Override
@@ -55,55 +283,57 @@ public class ApiPart implements IPartHelper {
return AppEng.proxy.getRenderMode();
}
@Nullable
@Override
public IPart getPart(World w, BlockPos pos, AEPartLocation side) {
final TileEntity tile = w.getTileEntity(pos);
if (tile instanceof IPartHost partHost) {
return partHost.getPart(side);
private static class DefaultPackageClassNameRemapper extends Remapper {
private final HashMap<String, String> inputOutput = new HashMap<>();
@Override
public String map(final String typeName) {
final String o = this.inputOutput.get(typeName);
if (o == null) {
return typeName;
}
return o;
}
return null;
}
@Nullable
@Override
public IPartHost getPartHost(World w, BlockPos pos) {
final TileEntity tile = w.getTileEntity(pos);
if (tile instanceof IPartHost partHost) {
return partHost;
}
return null;
}
private static class CacheKey {
private final Class<? extends AEBaseTile> baseClass;
@Nullable
@Override
public IPartHost getOrPlacePartHost(World w, BlockPos pos, boolean force, @Nullable EntityPlayer p) {
final TileEntity tile = w.getTileEntity(pos);
if (tile instanceof IPartHost partHost) {
return partHost;
} else {
if (!force && !canPlacePartHost(w, pos, p)) {
return null;
private final List<String> interfaces;
private CacheKey(Class<? extends AEBaseTile> baseClass, List<String> interfaces) {
this.baseClass = baseClass;
this.interfaces = ImmutableList.copyOf(interfaces);
}
private Class<? extends AEBaseTile> getBaseClass() {
return this.baseClass;
}
private List<String> getInterfaces() {
return this.interfaces;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || this.getClass() != o.getClass()) {
return false;
}
final ITileDefinition multiPart = AEApi.instance().definitions().blocks().multiPart();
if (!multiPart.isEnabled()) return null;
Block blk = multiPart.maybeBlock().orElse(null);
if (blk == null) return null;
CacheKey cacheKey = (CacheKey) o;
final IBlockState state = blk.getDefaultState();
w.setBlockState(pos, state, 3);
return w.getTileEntity(pos) instanceof IPartHost host ? host : null;
}
}
@Override
public boolean canPlacePartHost(World w, BlockPos pos, @Nullable EntityPlayer p) {
if (p != null && !Platform.hasPermissions(w, pos, p)) {
return false;
return this.baseClass.equals(cacheKey.baseClass) && this.interfaces.equals(cacheKey.interfaces);
}
final Block blk = w.getBlockState(pos).getBlock();
return blk == null || blk.isReplaceable(w, pos);
@Override
public int hashCode() {
int result = this.baseClass.hashCode();
result = 31 * result + this.interfaces.hashCode();
return result;
}
}
}
@@ -80,7 +80,6 @@ public final class ApiItems implements IItems {
private final IItemDefinition wirelessTerminal;
private final IItemDefinition wirelessCraftingTerminal;
private final IItemDefinition wirelessPatternTerminal;
private final IItemDefinition wirelessInterfaceTerminal;
private final IItemDefinition wirelessFluidTerminal;
private final IItemDefinition biometricCard;
private final IItemDefinition chargedStaff;
@@ -185,7 +184,6 @@ public final class ApiItems implements IItems {
this.wirelessCraftingTerminal = powerTools.item("wireless_crafting_terminal", ToolWirelessCraftingTerminal::new).addFeatures(AEFeature.WIRELESS_CRAFTING_TERMINAL).build();
this.wirelessPatternTerminal = powerTools.item("wireless_pattern_terminal", ToolWirelessPatternTerminal::new).addFeatures(AEFeature.WIRELESS_PATTERN_TERMINAL).build();
this.wirelessFluidTerminal = powerTools.item("wireless_fluid_terminal", ToolWirelessFluidTerminal::new).addFeatures(AEFeature.WIRELESS_FLUID_TERMINAL).build();
this.wirelessInterfaceTerminal = powerTools.item("wireless_interface_terminal",ToolWirelessInterfaceTerminal::new).addFeatures(AEFeature.WIRELESS_INTERFACE_TERMINAL).build();
this.chargedStaff = powerTools.item("charged_staff", ToolChargedStaff::new).addFeatures(AEFeature.CHARGED_STAFF).build();
this.massCannon = powerTools.item("matter_cannon", ToolMatterCannon::new)
@@ -367,11 +365,6 @@ public final class ApiItems implements IItems {
return wirelessPatternTerminal;
}
@Override
public IItemDefinition wirelessInterfaceTerminal() {
return wirelessInterfaceTerminal;
}
@Override
public IItemDefinition biometricCard() {
return this.biometricCard;
@@ -90,7 +90,6 @@ public final class ApiMaterials implements IMaterials {
private final IItemDefinition cardFuzzy;
private final IItemDefinition cardInverter;
private final IItemDefinition cardCrafting;
private final IItemDefinition cardSticky;
private final IItemDefinition enderDust;
private final IItemDefinition flour;
@@ -209,7 +208,6 @@ public final class ApiMaterials implements IMaterials {
this.cardFuzzy = new DamagedItemDefinition("material.card.fuzzy", materials.createMaterial(MaterialType.CARD_FUZZY));
this.cardInverter = new DamagedItemDefinition("material.card.inverter", materials.createMaterial(MaterialType.CARD_INVERTER));
this.cardCrafting = new DamagedItemDefinition("material.card.crafting", materials.createMaterial(MaterialType.CARD_CRAFTING));
this.cardSticky = new DamagedItemDefinition("material.card.sticky", materials.createMaterial(MaterialType.CARD_STICKY));
this.enderDust = new DamagedItemDefinition("material.dust.ender", materials.createMaterial(MaterialType.ENDER_DUST));
this.flour = new DamagedItemDefinition("material.flour", materials.createMaterial(MaterialType.FLOUR));
@@ -427,11 +425,6 @@ public final class ApiMaterials implements IMaterials {
return this.cardCrafting;
}
@Override
public IItemDefinition cardSticky() {
return this.cardSticky;
}
@Override
public IItemDefinition enderDust() {
return this.enderDust;
@@ -67,7 +67,6 @@ public enum AEFeature {
WIRELESS_CRAFTING_TERMINAL("WirelessCraftingTerminal", Constants.CATEGORY_TOOLS),
WIRELESS_PATTERN_TERMINAL("WirelessPatternTerminal", Constants.CATEGORY_TOOLS),
WIRELESS_FLUID_TERMINAL("WirelessFluidTerminal", Constants.CATEGORY_TOOLS),
WIRELESS_INTERFACE_TERMINAL("WirelessInterfaceTerminal", Constants.CATEGORY_TOOLS),
COLOR_APPLICATOR("ColorApplicator", Constants.CATEGORY_TOOLS),
METEORITE_COMPASS("MeteoriteCompass", Constants.CATEGORY_TOOLS),
@@ -37,7 +37,6 @@ import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
import net.minecraftforge.oredict.OreDictionary;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@@ -278,9 +277,4 @@ public final class P2PTunnelRegistry implements IP2PTunnelRegistry {
private void addNewAttunement(final IItemDefinition definition, final TunnelType type) {
definition.maybeStack(1).ifPresent(definitionStack -> this.addNewAttunement(definitionStack, type));
}
@Override
public TunnelType registerTunnelType(@NotNull String enumName, @NotNull ItemStack partStack) {
return TunnelType.registerTunnelType(enumName, partStack);
}
}
@@ -25,7 +25,6 @@ import net.minecraft.item.ItemStack;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
/**
@@ -36,7 +35,7 @@ import java.util.List;
* @since rv2
*/
public class InscriberInscribeRecipe extends InscriberRecipe {
InscriberInscribeRecipe(@Nonnull final Collection<ItemStack> inputs, @Nonnull final ItemStack output, @Nullable final List<ItemStack> top, @Nullable final List<ItemStack> bot) {
InscriberInscribeRecipe(@Nonnull final Collection<ItemStack> inputs, @Nonnull final ItemStack output, @Nullable final ItemStack top, @Nullable final ItemStack bot) {
super(inputs, output, top, bot, InscriberProcessType.INSCRIBE);
}
}
@@ -27,8 +27,8 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
/**
@@ -46,21 +46,21 @@ public class InscriberRecipe implements IInscriberRecipe {
private final ItemStack output;
@Nonnull
private final List<ItemStack> maybeTop;
private final Optional<ItemStack> maybeTop;
@Nonnull
private final List<ItemStack> maybeBot;
private final Optional<ItemStack> maybeBot;
@Nonnull
private final InscriberProcessType type;
InscriberRecipe(@Nonnull final Collection<ItemStack> inputs, @Nonnull final ItemStack output, @Nullable final List<ItemStack> top, @Nullable final List<ItemStack> bot, @Nonnull final InscriberProcessType type) {
InscriberRecipe(@Nonnull final Collection<ItemStack> inputs, @Nonnull final ItemStack output, @Nullable final ItemStack top, @Nullable final ItemStack bot, @Nonnull final InscriberProcessType type) {
this.inputs = new ArrayList<>(inputs.size());
this.inputs.addAll(inputs);
this.output = output;
this.maybeTop = top == null || top.isEmpty() ? Collections.emptyList() : top;
this.maybeBot = bot == null || bot.isEmpty() ? Collections.emptyList() : bot;
this.maybeTop = Optional.ofNullable(top);
this.maybeBot = Optional.ofNullable(bot);
this.type = type;
}
@@ -79,13 +79,13 @@ public class InscriberRecipe implements IInscriberRecipe {
@Nonnull
@Override
public final List<ItemStack> getTopInputs() {
public final Optional<ItemStack> getTopOptional() {
return this.maybeTop;
}
@Nonnull
@Override
public final List<ItemStack> getBottomInputs() {
public final Optional<ItemStack> getBottomOptional() {
return this.maybeBot;
}
@@ -112,10 +112,10 @@ public class InscriberRecipe implements IInscriberRecipe {
if (!this.output.equals(that.getOutput())) {
return false;
}
if (!this.maybeTop.equals(that.getTopInputs())) {
if (!this.maybeTop.equals(that.getTopOptional())) {
return false;
}
if (!this.maybeBot.equals(that.getBottomInputs())) {
if (!this.maybeBot.equals(that.getBottomOptional())) {
return false;
}
return this.type == that.getProcessType();
@@ -75,8 +75,9 @@ public final class InscriberRegistry implements IInscriberRegistry {
Preconditions.checkNotNull(recipe, "Tried to add (null) as inscriber recipe to the registry.");
if (this.recipes.add(recipe)) {
this.optionals.addAll(recipe.getTopInputs());
this.optionals.addAll(recipe.getBottomInputs());
recipe.getTopOptional().ifPresent(this.optionals::add);
recipe.getBottomOptional().ifPresent(this.optionals::add);
this.inputs.addAll(recipe.getInputs());
return true;
@@ -109,8 +110,8 @@ public final class InscriberRegistry implements IInscriberRegistry {
private static final class Builder implements IInscriberRecipeBuilder {
private List<ItemStack> inputs;
private ItemStack output;
private List<ItemStack> topOptional;
private List<ItemStack> bottomOptional;
private ItemStack topOptional;
private ItemStack bottomOptional;
private InscriberProcessType type;
@Nonnull
@@ -138,22 +139,22 @@ public final class InscriberRegistry implements IInscriberRegistry {
@Nonnull
@Override
public Builder withTopOptional(@Nonnull final Collection<ItemStack> topOptional) {
public Builder withTopOptional(@Nonnull final ItemStack topOptional) {
Preconditions.checkNotNull(topOptional);
Preconditions.checkArgument(!topOptional.isEmpty());
this.topOptional = new ArrayList<>(topOptional.size());
this.topOptional.addAll(topOptional);
this.topOptional = topOptional;
return this;
}
@Nonnull
@Override
public Builder withBottomOptional(@Nonnull final Collection<ItemStack> bottomOptional) {
public Builder withBottomOptional(@Nonnull final ItemStack bottomOptional) {
Preconditions.checkNotNull(bottomOptional);
Preconditions.checkArgument(!bottomOptional.isEmpty());
this.bottomOptional = new ArrayList<>(bottomOptional.size());
this.bottomOptional.addAll(bottomOptional);
this.bottomOptional = bottomOptional;
return this;
}
@@ -98,13 +98,6 @@ public enum ButtonToolTips {
Blocking,
NonBlocking,
LockCraftingMode,
LockCraftingModeNone,
LockCraftingUntilRedstonePulse,
LockCraftingWhileRedstoneHigh,
LockCraftingWhileRedstoneLow,
LockCraftingUntilResultReturned,
LevelType,
LevelType_Energy,
LevelType_Item,
@@ -157,22 +150,13 @@ public enum ButtonToolTips {
DecreaseByOneDesc,
MaxCount,
MaxCountDesc,
ToggleMolecularAssemblers,
ToggleMolecularAssemblersOnDesc,
ToggleMolecularAssemblersOffDesc,
FreeMolecularSlotShortcut,
FreeMolecularSlotShortcutDesc,
ToggleShowFullInterfaces,
ToggleShowFullInterfacesOnDesc,
ToggleShowFullInterfacesOffDesc,
ToggleShowOnlyInvalidInterface,
ToggleShowOnlyInvalidInterfaceOnDesc,
ToggleShowOnlyInvalidInterfaceOffDesc,
HighlightInterface,
HighlightInterfaceDesc,
ConfigureInterface,
ConfigureInterfaceDesc,
SearchFieldInputs,
SearchFieldOutputs,
SearchFieldNames,
// Used in the tooltips of the items in the terminal, when moused over
ItemsStored,
@@ -19,8 +19,6 @@
package appeng.core.localization;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.util.text.translation.I18n;
@@ -99,7 +97,6 @@ public enum GuiText {
RedstoneTunnel,
EUTunnel,
FluidTunnel,
FluidTerminal,
OCTunnel,
LightTunnel,
FETunnel,
@@ -198,7 +195,6 @@ public enum GuiText {
Partitioned,
Precise,
Fuzzy,
Sticky,
// Used in a terminal to indicate that an item is craftable
SmallFontCraft,
@@ -209,20 +205,7 @@ public enum GuiText {
// Used in Crafting Toasts
CraftingToastDone,
CraftingToastCancelled,
//Used in Lock Crafting,
CraftingLock,
NoneLock,
LowRedstoneLock,
HighRedstoneLock,
ResultLock,
UntilPulseUnlock,
// Used in Annihilation Planes
CanBeEnchanted,
IncreasedEnergyUseFromEnchants,
Deprecated;
CraftingToastCancelled;
private final String root;
@@ -238,10 +221,6 @@ public enum GuiText {
return I18n.translateToLocal(this.getUnlocalized());
}
public ITextComponent getLocalizedWithArgs(Object... args) {
return new TextComponentTranslation(this.getUnlocalized(), args);
}
public String getUnlocalized() {
return this.root + '.' + this;
}
@@ -41,15 +41,7 @@ public enum PlayerMessages {
DeviceNotLinked,
StationCanNotBeLocated,
SettingCleared,
MissingPatternsToEncode,
InterfaceInOtherDimParam,
InterfaceInOtherDim,
InterfaceHighlighted,
;
public ITextComponent get(Object... params) {
return new TextComponentTranslation(this.getName(), params);
}
MissingPatternsToEncode;
public ITextComponent get() {
return new TextComponentTranslation(this.getName());
@@ -1,203 +0,0 @@
package appeng.core.localization;
import appeng.api.config.PowerUnits;
import com.github.bsideup.jabel.Desugar;
import net.minecraft.util.text.*;
import java.text.DecimalFormat;
import java.text.MessageFormat;
import java.util.Arrays;
/**
* Static utilities for constructing tooltips in various places.
*/
public final class Tooltips {
private static final char SEP;
static {
var format = (DecimalFormat) DecimalFormat.getInstance();
var symbols = format.getDecimalFormatSymbols();
SEP = symbols.getDecimalSeparator();
}
public static final Style UNIT_TEXT = new Style().setColor(TextFormatting.YELLOW).setItalic(false);
public static final Style NORMAL_TOOLTIP_TEXT = new Style().setColor(TextFormatting.GRAY).setItalic(false);
public static final Style NUMBER_TEXT = new Style().setColor(TextFormatting.LIGHT_PURPLE).setItalic(false);
public static final String[] units = new String[] { "k", "M", "G", "T", "P", "E" };
public static final long[] DECIMAL_NUMS = new long[] { 1000L, 1000_000L, 1000_000_000L, 1000_000_000_000L,
1000_000_000_000_000L,
1000_000_000_000_000_000L };
public static ITextComponent of(ITextComponent... components) {
ITextComponent s = new TextComponentString("");
for (var c : components) {
s = s.appendSibling(c);
}
return s;
}
public static ITextComponent of(String s) {
return new TextComponentString(s);
}
public static ITextComponent ofPercent(double percent) {
return ofPercent(percent,true);
}
public static ITextComponent ofPercent(double percent, boolean oneIsGreen) {
return new TextComponentString(MessageFormat.format("{0,number,#.##%}", percent))
.setStyle(colorFromRatio(percent, oneIsGreen));
}
public static ITextComponent of(PowerUnits pU) {
return new TextComponentTranslation(pU.unlocalizedName).setStyle(UNIT_TEXT);
}
public static ITextComponent ofNumber(double number, double max) {
MaxedAmount amount = getMaxedAmount(number, max);
return ofNumber(amount);
}
public static ITextComponent of(GuiText guiText, Object... args) {
return of(guiText, NORMAL_TOOLTIP_TEXT, args);
}
public static ITextComponent of(GuiText guiText, Style style, Object... args) {
if (args.length > 0 && args[0] instanceof Integer) {
return guiText.getLocalizedWithArgs(Arrays.stream(args).map((o) -> ofUnformattedNumber((Integer) o)).toArray()).createCopy()
.setStyle(style);
} else if (args.length > 0 && args[0] instanceof Long) {
return guiText.getLocalizedWithArgs(Arrays.stream(args).map((o) -> ofUnformattedNumber((Long) o)).toArray()).createCopy()
.setStyle(style);
}
return guiText.getLocalizedWithArgs(args).createCopy().setStyle(style);
}
public static ITextComponent ofUnformattedNumber(long number) {
return new TextComponentString(String.valueOf(number)).setStyle(NUMBER_TEXT);
}
public static ITextComponent ofUnformattedNumberWithRatioColor(long number, double ratio, boolean oneIsGreen) {
return new TextComponentString(String.valueOf(number)).setStyle(colorFromRatio(ratio, oneIsGreen));
}
private static ITextComponent ofNumber(MaxedAmount number) {
boolean numberUnit = !number.digit().equals("0");
return new TextComponentString(number.digit() + (numberUnit ? number.unit() : "")).setStyle(NUMBER_TEXT)
.appendSibling(new TextComponentString("/")
.setStyle(NORMAL_TOOLTIP_TEXT))
.appendText(number.maxDigit() + number.unit()).setStyle(NUMBER_TEXT);
}
@Desugar
public record MaxedAmount(String digit, String maxDigit, String unit) {
}
@Desugar
public record Amount(String digit, String unit) {
}
public static Style colorFromRatio(double ratio, boolean oneIsGreen) {
double p = ratio;
if (!oneIsGreen) {
p = 1 - p;
}
TextFormatting colorCode = getColorCode(p);
return new Style().setItalic(false).setColor(colorCode);
}
public static String getAmount(double amount, long num) {
double fract = amount / num;
String returned;
if (fract < 10) {
returned = String.format("%.3f", fract);
} else if (fract < 100) {
returned = String.format("%.2f", fract);
} else {
returned = String.format("%.1f", fract);
}
while (returned.endsWith("0")) {
returned = returned.substring(0, returned.length() - 1);
}
if (returned.endsWith(String.valueOf(SEP))) {
returned = returned.substring(0, returned.length() - 1);
}
return returned;
}
public static Amount getAmount(double amount) {
if (amount < 10000) {
return new Amount(getAmount(amount, 1), "");
} else {
int i = 0;
while (amount / DECIMAL_NUMS[i] >= 1000) {
i++;
}
return new Amount(getAmount(amount, DECIMAL_NUMS[i]), units[i]);
}
}
public static MaxedAmount getMaxedAmount(double amount, double max) {
if (max < 10000) {
return new MaxedAmount(getAmount(amount, 1), getAmount(max, 1), "");
} else {
int i = 0;
while (max / DECIMAL_NUMS[i] >= 1000) {
i++;
}
return new MaxedAmount(getAmount(amount, DECIMAL_NUMS[i]), getAmount(max, DECIMAL_NUMS[i]), units[i]);
}
}
private static TextFormatting getColorCode(double p) {
if (p < 0.33) {
return TextFormatting.RED;
} else if (p < 0.66) {
return TextFormatting.YELLOW;
} else {
return TextFormatting.GREEN;
}
}
public static ITextComponent energyStorageComponent(double energy, double max) {
return Tooltips.of(
Tooltips.of(GuiText.StoredEnergy.getLocal()),
Tooltips.of(": "),
Tooltips.ofNumber(energy, max),
Tooltips.of(" "),
Tooltips.of(PowerUnits.AE),
Tooltips.of(" ("),
Tooltips.ofPercent(energy / max),
Tooltips.of(")"));
}
public static ITextComponent bytesUsed(long bytes, long max) {
return of(
Tooltips.of(
ofUnformattedNumberWithRatioColor(bytes, (double) bytes / max, false),
of(" "),
of(GuiText.Of),
of(" "),
ofUnformattedNumber(max),
of(" "),
of(GuiText.BytesUsed)));
}
public static ITextComponent typesUsed(long types, long max) {
return Tooltips.of(
ofUnformattedNumberWithRatioColor(types, (double) types / max, false),
of(" "),
of(GuiText.Of),
of(" "),
ofUnformattedNumber(max),
of(" "),
of(GuiText.Types));
}
}
@@ -41,9 +41,7 @@ public enum WailaText {
Showing,
Contains,
Channels,
EnchantedWith,
IdentityDeprecated;
Channels;
private final String root;
@@ -44,6 +44,8 @@ public class AppEngPacketHandlerBase {
PACKET_CONFIG_BUTTON(PacketConfigButton.class),
PACKET_PART_PLACEMENT(PacketPartPlacement.class),
PACKET_LIGHTNING(PacketLightning.class),
PACKET_MATTER_CANNON(PacketMatterCannon.class),
@@ -86,15 +88,7 @@ public class AppEngPacketHandlerBase {
PACKET_TERMINAL_KEYBIND(PacketTerminalUse.class),
PACKET_CRAFTING_TOAST(PacketCraftingToast.class),
PACKET_COLOR_APPLICATOR_SELECT_COLOR(PacketColorApplicatorSelectColor.class),
PACKET_CABLE_BUS_LANDING_PARTICLE(PacketCableBusLandingParticle.class),
PACKET_CONFIGURE_INTERFACE(PacketConfigureInterface.class),
;
PACKET_CRAFTING_TOAST(PacketCraftingToast.class);
private final Class<? extends AppEngPacket> packetClass;
+2 -12
View File
@@ -43,6 +43,7 @@ import appeng.container.AEBaseContainer;
import appeng.container.ContainerNull;
import appeng.container.ContainerOpenContext;
import appeng.container.implementations.*;
import appeng.container.interfaces.IInventorySlotAware;
import appeng.fluids.container.*;
import appeng.fluids.helper.IFluidInterfaceHost;
import appeng.fluids.parts.PartFluidFormationPlane;
@@ -105,7 +106,7 @@ public enum GuiBridge implements IGuiHandler {
GUI_WIRELESS_CRAFTING_TERMINAL(ContainerWirelessCraftingTerminal.class, WirelessTerminalGuiObject.class, GuiHostType.ITEM, null),
GUI_WIRELESS_PATTERN_TERMINAL(ContainerWirelessPatternTerminal.class, WirelessTerminalGuiObject.class, GuiHostType.ITEM, null),
GUI_WIRELESS_FLUID_TERMINAL(ContainerWirelessFluidTerminal.class, WirelessTerminalGuiObject.class, GuiHostType.ITEM, null),
GUI_WIRELESS_INTERFACE_TERMINAL(ContainerWirelessInterfaceTerminal.class, WirelessTerminalGuiObject.class, GuiHostType.ITEM, null),
GUI_NETWORK_STATUS(ContainerNetworkStatus.class, INetworkTool.class, GuiHostType.ITEM, null),
@@ -184,7 +185,6 @@ public enum GuiBridge implements IGuiHandler {
private Class guiClass;
private GuiHostType type;
private SecurityPermissions requiredPermission;
private GuiWrapper.IExternalGui externalGui = null;
GuiBridge() {
this.tileClass = null;
@@ -192,16 +192,6 @@ public enum GuiBridge implements IGuiHandler {
this.containerClass = null;
}
GuiBridge(GuiWrapper.IExternalGui obj) {
this.tileClass = null;
this.containerClass = null;
this.externalGui = obj;
}
public GuiWrapper.IExternalGui getExternalGui() {
return this.externalGui;
}
GuiBridge(final Class containerClass, final SecurityPermissions requiredPermission) {
this.requiredPermission = requiredPermission;
this.containerClass = containerClass;
@@ -1,90 +0,0 @@
package appeng.core.sync;
import it.unimi.dsi.fastutil.Hash;
import it.unimi.dsi.fastutil.objects.Object2ObjectMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.util.EnumHelper;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Allow to register custom GuiBridge from third-party
*/
public class GuiWrapper {
public static final GuiWrapper INSTANCE = new GuiWrapper();
private GuiWrapper() {
// NO-OP
}
private final Object2ObjectMap<ResourceLocation, Opener> openers = new Object2ObjectOpenHashMap<>();
private final Object2ObjectMap<IExternalGui, GuiBridge> externalGuis = new Object2ObjectOpenCustomHashMap<>(new Hash.Strategy<IExternalGui>() {
@Override
public int hashCode(IExternalGui o) {
return o.getID().hashCode();
}
@Override
public boolean equals(@Nullable IExternalGui a, @Nullable IExternalGui b) {
return a == b || (a != null && b != null && a.getID().equals(b.getID()));
}
});
public synchronized void registerExternalGuiHandler(@Nonnull ResourceLocation id, @Nonnull Opener opener) {
openers.put(id, opener);
}
@Nullable
public Opener getOpener(ResourceLocation id) {
return openers.get(id);
}
public GuiBridge wrap(IExternalGui obj) {
return externalGuis.computeIfAbsent(obj, this::create);
}
private GuiBridge create(IExternalGui obj) {
return EnumHelper.addEnum(GuiBridge.class, obj.getID().toString(), new Class<?>[] {IExternalGui.class}, obj);
}
@FunctionalInterface
public interface Opener {
<T extends IExternalGui> void open(T obj, GuiContext context);
}
public interface IExternalGui {
ResourceLocation getID();
}
public static class GuiContext {
public final World world;
public final EntityPlayer player;
public final BlockPos pos;
public final EnumFacing facing;
public final NBTTagCompound extra;
public GuiContext(World world, EntityPlayer player, BlockPos pos, EnumFacing face, NBTTagCompound extra) {
this.world = world;
this.player = player;
this.pos = pos;
this.facing = face;
this.extra = extra;
}
}
}
@@ -112,10 +112,6 @@ public class NetworkHandler {
this.ec.sendToAllAround(message.getProxy(), point);
}
public void sendToAllTracking(final AppEngPacket message, final NetworkRegistry.TargetPoint point) {
this.ec.sendToAllTracking(message.getProxy(), point);
}
public void sendToDimension(final AppEngPacket message, final int dimensionId) {
this.ec.sendToDimension(message.getProxy(), dimensionId);
}
@@ -1,55 +0,0 @@
package appeng.core.sync.packets;
import appeng.block.networking.BlockCableBus;
import appeng.core.sync.AppEngPacket;
import appeng.core.sync.network.INetworkInfo;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class PacketCableBusLandingParticle extends AppEngPacket {
private BlockPos pos;
private double entityX;
private double entityY;
private double entityZ;
private int numberOfParticles;
public PacketCableBusLandingParticle(final ByteBuf stream) {
this.pos = BlockPos.fromLong(stream.readLong());
this.entityX = stream.readDouble();
this.entityY = stream.readDouble();
this.entityZ = stream.readDouble();
this.numberOfParticles = stream.readInt();
}
public PacketCableBusLandingParticle(final BlockPos pos, final Entity entity, final int numberOfParticles) {
final ByteBuf data = Unpooled.buffer();
data.writeInt(this.getPacketID());
data.writeLong(pos.toLong());
data.writeDouble(entity.posX);
data.writeDouble(entity.posY);
data.writeDouble(entity.posZ);
data.writeInt(numberOfParticles);
this.configureWrite(data);
}
@Override
@SideOnly(Side.CLIENT)
public void clientPacketData(INetworkInfo network, AppEngPacket packet, EntityPlayer player) {
final World world = Minecraft.getMinecraft().world;
final IBlockState state = world.getBlockState(pos);
if (state.getBlock() instanceof BlockCableBus cb) {
cb.addLandingParticle(pos, entityX, entityY, entityZ, numberOfParticles);
}
}
}
@@ -19,10 +19,16 @@
package appeng.core.sync.packets;
import appeng.api.AEApi;
import appeng.api.definitions.IComparableDefinition;
import appeng.api.definitions.IItems;
import appeng.api.implementations.items.IMemoryCard;
import appeng.api.implementations.items.MemoryCardMessages;
import appeng.block.networking.BlockCableBus;
import appeng.core.sync.AppEngPacket;
import appeng.core.sync.network.INetworkInfo;
import appeng.items.tools.ToolNetworkTool;
import appeng.items.tools.powered.ToolColorApplicator;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.minecraft.block.Block;
@@ -93,6 +99,10 @@ public class PacketClick extends AppEngPacket {
@Override
public void serverPacketData(final INetworkInfo manager, final AppEngPacket packet, final EntityPlayer player) {
final ItemStack is = player.inventory.getCurrentItem();
final IItems items = AEApi.instance().definitions().items();
final IComparableDefinition maybeMemoryCard = items.memoryCard();
final IComparableDefinition maybeColorApplicator = items.colorApplicator();
final BlockPos pos = new BlockPos(this.x, this.y, this.z);
if (this.leftClick) {
final Block block = player.world.getBlockState(pos).getBlock();
@@ -100,9 +110,19 @@ public class PacketClick extends AppEngPacket {
((BlockCableBus) block).onBlockClickPacket(player.world, pos, player, this.hand, new Vec3d(this.hitX, this.hitY, this.hitZ));
}
} else {
final ItemStack is = player.inventory.getCurrentItem();
if (!is.isEmpty() && is.getItem() instanceof ToolNetworkTool tnt) {
tnt.serverSideToolLogic(is, player, hand, player.world, pos, side, hitX, hitY, hitZ);
if (!is.isEmpty()) {
if (is.getItem() instanceof ToolNetworkTool) {
final ToolNetworkTool tnt = (ToolNetworkTool) is.getItem();
tnt.serverSideToolLogic(is, player, this.hand, player.world, pos, this.side, this.hitX, this.hitY,
this.hitZ);
} else if (maybeMemoryCard.isSameAs(is)) {
final IMemoryCard mem = (IMemoryCard) is.getItem();
mem.notifyUser(player, MemoryCardMessages.SETTINGS_CLEARED);
is.setTagCompound(null);
} else if (maybeColorApplicator.isSameAs(is)) {
final ToolColorApplicator mem = (ToolColorApplicator) is.getItem();
mem.cycleColors(is, mem.getColor(is), 1);
}
}
}
}
@@ -1,53 +0,0 @@
package appeng.core.sync.packets;
import appeng.api.util.AEColor;
import appeng.core.sync.AppEngPacket;
import appeng.core.sync.network.INetworkInfo;
import appeng.items.tools.powered.ToolColorApplicator;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import javax.annotation.Nullable;
public class PacketColorApplicatorSelectColor extends AppEngPacket {
@Nullable
private AEColor color = null;
@SuppressWarnings("unused")
public PacketColorApplicatorSelectColor(final ByteBuf stream) {
if (stream.readBoolean()) {
byte colorIdx = stream.readByte();
AEColor[] values = AEColor.values();
if (colorIdx >= 0 && colorIdx < values.length) {
this.color = values[colorIdx];
}
}
}
public PacketColorApplicatorSelectColor(@Nullable final AEColor color) {
final ByteBuf data = Unpooled.buffer();
data.writeInt(this.getPacketID());
if (color != null) {
data.writeBoolean(true);
data.writeByte(color.ordinal());
} else {
data.writeBoolean(false);
}
this.configureWrite(data);
}
@Override
public void serverPacketData(INetworkInfo manager, AppEngPacket packet, EntityPlayer player) {
switchColor(player.getHeldItemMainhand(), color);
switchColor(player.getHeldItemOffhand(), color);
}
private static void switchColor(ItemStack stack, AEColor color) {
if (!stack.isEmpty() && stack.getItem() instanceof ToolColorApplicator colorApp) {
colorApp.setActiveColor(stack, color);
}
}
}
@@ -1,52 +0,0 @@
package appeng.core.sync.packets;
import appeng.api.util.AEPartLocation;
import appeng.container.implementations.ContainerInterfaceTerminal;
import appeng.core.sync.AppEngPacket;
import appeng.core.sync.network.INetworkInfo;
import appeng.helpers.IPriorityHost;
import appeng.parts.AEBasePart;
import appeng.util.Platform;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.minecraft.entity.player.EntityPlayer;
public class PacketConfigureInterface extends AppEngPacket {
private final long id;
// automatic.
public PacketConfigureInterface(final ByteBuf stream) {
this.id = stream.readLong();
}
// api
public PacketConfigureInterface(final long id) {
this.id = id;
final ByteBuf data = Unpooled.buffer();
data.writeInt(this.getPacketID());
data.writeLong(id);
this.configureWrite(data);
}
@Override
public void serverPacketData(INetworkInfo manager, AppEngPacket packet, EntityPlayer player) {
var container = player.openContainer;
if (container instanceof ContainerInterfaceTerminal terminal) {
var byId = terminal.getById(this.id);
if (byId != null) {
var host = byId.getHost();
// I don't know why this is in IPriorityHost.
if (host instanceof IPriorityHost guiHandler) {
var bridge = guiHandler.getGuiBridge();
var side = host instanceof AEBasePart part ? part.getSide() : AEPartLocation.INTERNAL;
Platform.openGUI(player, host.getTile(), side, bridge);
}
}
}
}
}
@@ -11,8 +11,6 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import java.io.IOException;
@@ -41,15 +39,11 @@ public class PacketCraftingToast extends AppEngPacket {
@Override
public void clientPacketData(INetworkInfo network, AppEngPacket packet, EntityPlayer player) {
if (AEConfig.instance().isFeatureEnabled(AEFeature.CRAFTING_TOASTS)) {
doCraftingToast();
Minecraft.getMinecraft()
.getToastGui().add(new CraftingStatusToast(stack.asItemStackRepresentation(), cancelled));
}
}
@SideOnly(Side.CLIENT)
private void doCraftingToast() {
Minecraft.getMinecraft().getToastGui().add(new CraftingStatusToast(stack.asItemStackRepresentation(), cancelled));
}
@Override
public void serverPacketData(INetworkInfo manager, AppEngPacket packet, EntityPlayer player) {}
}

Some files were not shown because too many files have changed in this diff Show More