Compare commits
84 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| aa88fb70f1 | |||
| e76ca86602 | |||
| b8f48407cd | |||
| 489b0f635e | |||
| e6fb553a53 | |||
| cacd824db3 | |||
| 876bb52087 | |||
| 971a9d22e8 | |||
| 76efe6026d | |||
| 4e03cbd356 | |||
| 9005db6f1c | |||
| 58afe755b8 | |||
| f368f9dac2 | |||
| e5b45d51cc | |||
| 5a1d5356d1 | |||
| 1759f92164 | |||
| e50c13e570 | |||
| 749dd35f88 | |||
| ca79a377bd | |||
| 475c8ff5a1 | |||
| 5b3ccf26d0 | |||
| e73dbe4891 | |||
| 38244000c9 | |||
| d87ff9d1e7 | |||
| 4ba97ec899 | |||
| 0147e1ddfb | |||
| 621d2ee715 | |||
| d07937fa93 | |||
| 65f58913a4 | |||
| b8e53adf40 | |||
| 44544c598f | |||
| bcee2ec427 | |||
| 9e41d543f5 | |||
| 81cc0b804d | |||
| e1fc9908b3 | |||
| 9ed1535477 | |||
| 1ef345d4a4 | |||
| ff7d1b9719 | |||
| 88c9370e4f | |||
| f2aae3ef0f | |||
| 12739f1e66 | |||
| 81d2170ada | |||
| 0f469e9df6 | |||
| 0f34f09b32 | |||
| 8e54a8fed9 | |||
| d9bb81a00f | |||
| 39e038d916 | |||
| 12ca8d109a | |||
| f0d0595c8f | |||
| b756d68be1 | |||
| 60b07e5ca5 | |||
| 7c99fca789 | |||
| ab393b0ed1 | |||
| 957bc4c5cc | |||
| 133ed1f09d | |||
| e90dd2f9c6 | |||
| 9719c7ffc3 | |||
| 319d92a371 | |||
| db9ec2b070 | |||
| 3a0552c56e | |||
| 8a0dd192e5 | |||
| a97b35f3d0 | |||
| 00d4c20d9f | |||
| 1394ab0863 | |||
| 5efc085693 | |||
| 159f4c7f14 | |||
| aff94cec8c | |||
| ee7fe9f40d | |||
| 2184d03d0b | |||
| 9c9a49f9e7 | |||
| 44c0931c02 | |||
| b7949e4134 | |||
| ea95913ec8 | |||
| 423ab81813 | |||
| 33d7f02323 | |||
| 4e42b17e81 | |||
| b8d4f0cffa | |||
| fc0f8eab56 | |||
| 7e1bfdb5ac | |||
| 41b7900706 | |||
| 1f9707e256 | |||
| 7656157b0d | |||
| 954ce1442e | |||
| ee67c5ea50 |
@@ -2,7 +2,8 @@ name: 'Build PRs'
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
branches:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
@@ -55,7 +55,15 @@ jobs:
|
||||
KEY_STORE_ALIAS: ${{ secrets.KEY_STORE_ALIAS }}
|
||||
KEY_STORE_KEY_PASS: ${{ secrets.KEY_STORE_KEY_PASS }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: ./gradlew publish --no-daemon --max-workers 1
|
||||
run: ./gradlew publishMavenPublicationToGitHubPackagesRepository --no-daemon --max-workers 1
|
||||
- name: Publish to modmaven
|
||||
env:
|
||||
KEY_STORE_PASS: ${{ secrets.KEY_STORE_PASS }}
|
||||
KEY_STORE_ALIAS: ${{ secrets.KEY_STORE_ALIAS }}
|
||||
KEY_STORE_KEY_PASS: ${{ secrets.KEY_STORE_KEY_PASS }}
|
||||
MODMAVEN_USER: ${{ secrets.MODMAVEN_USER }}
|
||||
MODMAVEN_PASSWORD: ${{ secrets.MODMAVEN_PASSWORD }}
|
||||
run: ./gradlew publishMavenPublicationToModmavenRepository --no-daemon --max-workers 1
|
||||
- name: Prepare artifact metadata
|
||||
id: prepare_artifact_metadata
|
||||
run: |
|
||||
|
||||
@@ -72,12 +72,20 @@ The API for Applied Energistics 2. It is open source to discuss changes, improve
|
||||
|
||||
### Maven
|
||||
|
||||
We use Github Packages as maven repository now. You can use the following snippet as example on how to add a repository to your gradle build file.
|
||||
Our authoritative Maven repository is Github Packages, which you can also use in your builds. Use of Github Packages
|
||||
[requires special setup](https://docs.github.com/en/packages/using-github-packages-with-your-projects-ecosystem/configuring-gradle-for-use-with-github-packages#authenticating-to-github-packages)
|
||||
to authenticate with your personal access token.
|
||||
|
||||
AE2 is also available without authentication from Modmaven. You can use the following snippet as example on how to add a repository to your gradle build file.
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name "AE2"
|
||||
url "https://maven.pkg.github.com/AppliedEnergistics/Applied-Energistics-2"
|
||||
name "Modmaven"
|
||||
url "https://modmaven.k-4u.nl/"
|
||||
// For Gradle 5.1 and above, limit it to just AE2
|
||||
content {
|
||||
includeGroup 'appeng'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+191
-25
@@ -20,7 +20,6 @@ buildscript {
|
||||
repositories {
|
||||
maven { url = 'https://files.minecraftforge.net/maven' }
|
||||
maven { url = 'https://repo.spongepowered.org/maven' }
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
@@ -30,23 +29,62 @@ buildscript {
|
||||
}
|
||||
|
||||
plugins {
|
||||
id "maven-publish"
|
||||
id "com.diffplug.gradle.spotless" version "4.3.0"
|
||||
id "com.matthewprenger.cursegradle" version "1.4.0"
|
||||
id "org.sonarqube" version "2.8"
|
||||
id "jacoco"
|
||||
id "maven-publish"
|
||||
id "com.diffplug.gradle.spotless" version "4.3.0"
|
||||
id "com.matthewprenger.cursegradle" version "1.4.0"
|
||||
id "idea"
|
||||
}
|
||||
|
||||
apply plugin: 'net.minecraftforge.gradle'
|
||||
apply plugin: 'org.spongepowered.mixin'
|
||||
apply plugin: "eclipse"
|
||||
|
||||
// All jar files from this folder will be added automatically as runtime mod dependencies
|
||||
def extraModsDir = "extra-mods-${minecraft_version}"
|
||||
|
||||
repositories {
|
||||
flatDir {
|
||||
name "extra-mods"
|
||||
dir file(extraModsDir)
|
||||
}
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
maven { // modmaven, maven proxy
|
||||
name 'modmaven'
|
||||
url "https://modmaven.k-4u.nl/"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
|
||||
|
||||
// compile against provided APIs
|
||||
compileOnly "mezz.jei:jei-${jei_minecraft_version}:${jei_version}:api"
|
||||
compileOnly "mcjty.theoneprobe:TheOneProbe-${minecraft_release}:${minecraft_release}-${top_version}:api"
|
||||
|
||||
// Runtime, Mods
|
||||
runtimeOnly fg.deobf("mezz.jei:jei-${jei_minecraft_version}:${jei_version}")
|
||||
runtimeOnly fg.deobf("mcjty.theoneprobe:TheOneProbe-${minecraft_release}:${minecraft_release}-${top_version}")
|
||||
|
||||
// Locally sourced extra mods for runtime (i.e. testing)
|
||||
for (extraModJar in fileTree(dir: extraModsDir, include: '*.jar')) {
|
||||
def basename = extraModJar.name.substring(0, extraModJar.name.length() - ".jar".length())
|
||||
def versionSep = basename.lastIndexOf('-')
|
||||
assert versionSep != -1
|
||||
def artifactId = basename.substring(0, versionSep)
|
||||
def version = basename.substring(versionSep + 1)
|
||||
runtimeOnly fg.deobf("extra-mods:$artifactId:$version")
|
||||
}
|
||||
|
||||
// unit test dependencies
|
||||
testCompile "junit:junit:4.13"
|
||||
|
||||
// Annotation Processors
|
||||
annotationProcessor 'org.spongepowered:mixin:0.8:processor'
|
||||
}
|
||||
group = artifact_group
|
||||
archivesBaseName = artifact_basename
|
||||
|
||||
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_1_8
|
||||
compileJava {
|
||||
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_1_8
|
||||
@@ -58,7 +96,8 @@ tasks.withType(JavaCompile) {
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
|
||||
// Create version number
|
||||
///////////////////
|
||||
// Version Number
|
||||
version = version_major + "." + version_minor + "." + version_patch
|
||||
|
||||
ext.pr = System.getenv('PR_NUMBER') ?: ""
|
||||
@@ -76,10 +115,8 @@ if (ext.release) {
|
||||
version = ext.release
|
||||
}
|
||||
|
||||
|
||||
// Maven group and artifact name
|
||||
group = artifact_group
|
||||
archivesBaseName = artifact_basename
|
||||
ext.isAlpha = project.version.contains("alpha")
|
||||
ext.isBeta = project.version.contains("beta")
|
||||
|
||||
sourceSets {
|
||||
api
|
||||
@@ -103,9 +140,8 @@ configurations {
|
||||
apiCompile.extendsFrom(compile)
|
||||
}
|
||||
|
||||
apply from: 'gradle/scripts/dependencies.gradle'
|
||||
apply from: 'gradle/scripts/spotless.gradle'
|
||||
|
||||
////////////////////
|
||||
// Forge/Minecraft
|
||||
minecraft {
|
||||
mappings channel: "snapshot", version: project.mcp_mappings
|
||||
|
||||
@@ -136,6 +172,9 @@ minecraft {
|
||||
data {
|
||||
property 'forge.logging.console.level', 'debug'
|
||||
workingDirectory project.file('run')
|
||||
// ForgeGradle will just force-exit the Gradle Daemon which fails our builds in case
|
||||
// a daemon is used for any reason.
|
||||
forceExit false
|
||||
args '--mod', 'appliedenergistics2', '--all', '--output', file('src/generated/resources/')
|
||||
mods {
|
||||
appliedenergistics2 {
|
||||
@@ -147,18 +186,14 @@ minecraft {
|
||||
}
|
||||
}
|
||||
|
||||
///////////
|
||||
// Mixins
|
||||
mixin {
|
||||
add sourceSets.main, "appliedenergistics2.mixins.refmap.json"
|
||||
}
|
||||
|
||||
jar {
|
||||
manifest {
|
||||
attributes([
|
||||
"MixinConfigs": "appliedenergistics2.mixins.json"
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
////////////////
|
||||
// Jar Signing
|
||||
def signProps = [:]
|
||||
if (System.getenv("KEY_STORE_FILE")) {
|
||||
signProps['keyStore'] = System.getenv("KEY_STORE_FILE")
|
||||
@@ -181,15 +216,88 @@ task signJar(type: net.minecraftforge.gradle.common.task.SignJar, dependsOn: 're
|
||||
}
|
||||
}
|
||||
|
||||
apply from: 'gradle/scripts/artifacts.gradle'
|
||||
apply from: 'gradle/scripts/curseforge.gradle'
|
||||
//////////////
|
||||
// Aritfacts
|
||||
processResources {
|
||||
exclude '.cache'
|
||||
}
|
||||
|
||||
jar {
|
||||
finalizedBy 'reobfJar'
|
||||
finalizedBy 'signJar'
|
||||
|
||||
from sourceSets.main.output.classesDirs
|
||||
from sourceSets.api.output.classesDirs
|
||||
from sourceSets.main.output.resourcesDir
|
||||
from sourceSets.api.output.resourcesDir
|
||||
|
||||
manifest {
|
||||
attributes([
|
||||
"Specification-Title": "Applied Energistics 2",
|
||||
"Specification-Vendor": "TeamAppliedEnergistics",
|
||||
"Specification-Version": "${project.version}",
|
||||
"Implementation-Title": "${project.name}",
|
||||
"Implementation-Version": "${project.version}",
|
||||
"Implementation-Vendor" :"TeamAppliedEnergistics",
|
||||
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
|
||||
"MixinConfigs": "appliedenergistics2.mixins.json"
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
task javadocs(type: Javadoc) {
|
||||
classpath = sourceSets.main.compileClasspath
|
||||
source = sourceSets.api.java
|
||||
include "appeng/api/**"
|
||||
|
||||
options.addStringOption('Xdoclint:none', '-quiet')
|
||||
options.encoding = 'UTF-8'
|
||||
options.charSet = 'UTF-8'
|
||||
}
|
||||
|
||||
task javadocJar(type: Jar, dependsOn: javadocs) {
|
||||
classifier = "javadoc"
|
||||
from javadoc.destinationDir
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar) {
|
||||
classifier = "sources"
|
||||
from sourceSets.main.allJava
|
||||
from sourceSets.api.allJava
|
||||
}
|
||||
|
||||
task apiJar(type: Jar) {
|
||||
classifier = "api"
|
||||
from sourceSets.api.output
|
||||
include "appeng/api/**"
|
||||
|
||||
// TODO: when FG bug is fixed, remove allJava from the api jar.
|
||||
// https://github.com/MinecraftForge/ForgeGradle/issues/369
|
||||
// Gradle should be able to pull them from the -sources jar.
|
||||
from sourceSets.api.allJava
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives javadocJar
|
||||
archives sourcesJar
|
||||
archives apiJar
|
||||
}
|
||||
|
||||
//////////////////
|
||||
// Maven publish
|
||||
publishing {
|
||||
publications {
|
||||
maven(MavenPublication) {
|
||||
groupId = project.group
|
||||
artifactId = project.archivesBaseName
|
||||
version = project.version
|
||||
|
||||
// ForgeGradle will generate wild dependency definitions, see https://github.com/MinecraftForge/ForgeGradle/issues/584
|
||||
// Since we don't actually depend on anything, just remove the entire node.
|
||||
pom.withXml {
|
||||
asNode().remove(asNode().dependencies)
|
||||
}
|
||||
|
||||
from components.java
|
||||
artifact sourcesJar
|
||||
artifact javadocJar
|
||||
@@ -205,5 +313,63 @@ publishing {
|
||||
name = "GitHubPackages"
|
||||
url = "https://maven.pkg.github.com/AppliedEnergistics/Applied-Energistics-2"
|
||||
}
|
||||
maven {
|
||||
credentials {
|
||||
username System.getenv("MODMAVEN_USER")
|
||||
password System.getenv("MODMAVEN_PASSWORD")
|
||||
}
|
||||
name = "modmaven"
|
||||
url = "https://modmaven.k-4u.nl/artifactory/local-releases/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////
|
||||
// Spotless
|
||||
spotless {
|
||||
java {
|
||||
target 'src/*/java/appeng/**/*.java'
|
||||
|
||||
indentWithSpaces()
|
||||
eclipse().configFile 'codeformat/codeformat.xml'
|
||||
importOrderFile 'codeformat/ae2.importorder'
|
||||
}
|
||||
format 'json', {
|
||||
target 'src/*/resources/**/*.json'
|
||||
targetExclude 'src/generated/resources/**'
|
||||
prettier().config(['parser': 'json'])
|
||||
}
|
||||
}
|
||||
|
||||
////////////////
|
||||
// Curse Forge
|
||||
if (System.getenv("CURSEFORGE")) {
|
||||
def cfReleaseType = "release"
|
||||
if (ext.isAlpha) {
|
||||
cfReleaseType = "alpha"
|
||||
} else if (ext.isBeta) {
|
||||
cfReleaseType = "beta"
|
||||
}
|
||||
|
||||
curseforge {
|
||||
apiKey = System.getenv("CURSEFORGE")
|
||||
project {
|
||||
id = project.curseforge_project
|
||||
changelogType = "markdown"
|
||||
changelog = System.getenv("CHANGELOG") ?: "Please visit our [releases](https://github.com/AppliedEnergistics/Applied-Energistics-2/releases) for a changelog"
|
||||
releaseType = cfReleaseType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////
|
||||
// IntelliJ Project Import
|
||||
// The Mixin annotation process does not have an obfuscation source when running through the IntelliJ compiler,
|
||||
// thus we have to prevent it from being activated as part of importing this Gradle project into IntelliJ.
|
||||
if (System.getProperty("idea.sync.active") == "true") {
|
||||
afterEvaluate {
|
||||
tasks.withType(JavaCompile).all {
|
||||
it.options.annotationProcessorPath = files()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -9,16 +9,16 @@ artifact_basename=appliedenergistics2
|
||||
# Minecraft Versions #
|
||||
#########################################################
|
||||
minecraft_release=1.16
|
||||
minecraft_version=1.16.2
|
||||
mcp_mappings=20200723-1.16.1
|
||||
forge_version=33.0.5
|
||||
minecraft_version=1.16.3
|
||||
mcp_mappings=20200916-1.16.2
|
||||
forge_version=34.1.15
|
||||
|
||||
#########################################################
|
||||
# Provided APIs #
|
||||
#########################################################
|
||||
jei_minecraft_version=1.16.1
|
||||
jei_version=7.0.0.6
|
||||
top_version=3.0.1-beta-4
|
||||
jei_minecraft_version=1.16.2
|
||||
jei_version=7.3.2.25
|
||||
top_version=3.0.3-beta-6
|
||||
hwyla_version=1.10.8-B72_1.15.2
|
||||
ctm_version=MC1.15.2-1.1.0.9
|
||||
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
/*
|
||||
* 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>.
|
||||
*/
|
||||
|
||||
processResources {
|
||||
exclude '.cache'
|
||||
}
|
||||
|
||||
jar {
|
||||
finalizedBy 'reobfJar'
|
||||
finalizedBy 'signJar'
|
||||
|
||||
from sourceSets.main.output.classesDirs
|
||||
from sourceSets.api.output.classesDirs
|
||||
from sourceSets.main.output.resourcesDir
|
||||
from sourceSets.api.output.resourcesDir
|
||||
|
||||
manifest {
|
||||
attributes([
|
||||
"Specification-Title": "Applied Energistics 2",
|
||||
"Specification-Vendor": "TeamAppliedEnergistics",
|
||||
"Specification-Version": "${project.version}",
|
||||
"Implementation-Title": "${project.name}",
|
||||
"Implementation-Version": "${project.version}",
|
||||
"Implementation-Vendor" :"TeamAppliedEnergistics",
|
||||
"Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ"),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
task javadocs(type: Javadoc) {
|
||||
classpath = sourceSets.main.compileClasspath
|
||||
source = sourceSets.api.java
|
||||
include "appeng/api/**"
|
||||
|
||||
options.addStringOption('Xdoclint:none', '-quiet')
|
||||
options.encoding = 'UTF-8'
|
||||
options.charSet = 'UTF-8'
|
||||
}
|
||||
|
||||
task javadocJar(type: Jar, dependsOn: javadocs) {
|
||||
classifier = "javadoc"
|
||||
from javadoc.destinationDir
|
||||
}
|
||||
|
||||
task sourcesJar(type: Jar) {
|
||||
classifier = "sources"
|
||||
from sourceSets.main.allJava
|
||||
from sourceSets.api.allJava
|
||||
}
|
||||
|
||||
task apiJar(type: Jar) {
|
||||
classifier = "api"
|
||||
from sourceSets.api.output
|
||||
include "appeng/api/**"
|
||||
|
||||
// TODO: when FG bug is fixed, remove allJava from the api jar.
|
||||
// https://github.com/MinecraftForge/ForgeGradle/issues/369
|
||||
// Gradle should be able to pull them from the -sources jar.
|
||||
from sourceSets.api.allJava
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives javadocJar
|
||||
archives sourcesJar
|
||||
archives apiJar
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2020, TeamAppliedEnergistics, 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
|
||||
*g 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>.
|
||||
*/
|
||||
|
||||
def isAlpha = project.version.contains("alpha")
|
||||
def isBeta = project.version.contains("beta")
|
||||
|
||||
def cfReleaseType = "release"
|
||||
if (isAlpha) {
|
||||
cfReleaseType = "alpha"
|
||||
} else if (isBeta) {
|
||||
cfReleaseType = "beta"
|
||||
}
|
||||
|
||||
if (System.getenv("CURSEFORGE")) {
|
||||
curseforge {
|
||||
apiKey = System.getenv("CURSEFORGE")
|
||||
project {
|
||||
id = project.curseforge_project
|
||||
changelogType = "markdown"
|
||||
changelog = System.getenv("CHANGELOG") ?: "Please visit our [releases](https://github.com/AppliedEnergistics/Applied-Energistics-2/releases) for a changelog"
|
||||
releaseType = cfReleaseType
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* 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 { // modmaven, maven proxy
|
||||
name 'modmaven'
|
||||
url "https://modmaven.k-4u.nl/"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}"
|
||||
|
||||
// compile against provided APIs
|
||||
compileOnly "mezz.jei:jei-${jei_minecraft_version}:${jei_version}:api"
|
||||
compileOnly "mcjty.theoneprobe:TheOneProbe-${minecraft_release}:${minecraft_release}-${top_version}:api"
|
||||
|
||||
// Runtime, Mods
|
||||
// FIXME 1.16.2 runtimeOnly fg.deobf("mezz.jei:jei-${jei_minecraft_version}:${jei_version}")
|
||||
// FIXME 1.16.2 runtimeOnly fg.deobf("mcjty.theoneprobe:TheOneProbe-${minecraft_release}:${minecraft_release}-${top_version}")
|
||||
//runtimeOnly fg.deobf("team.chisel.ctm:CTM:${ctm_version}")
|
||||
|
||||
// unit test dependencies
|
||||
testCompile "junit:junit:4.13"
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2020, 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
|
||||
*g 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>.
|
||||
*/
|
||||
|
||||
spotless {
|
||||
java {
|
||||
target 'src/*/java/appeng/**/*.java'
|
||||
|
||||
indentWithSpaces()
|
||||
eclipse().configFile 'codeformat/codeformat.xml'
|
||||
importOrderFile 'codeformat/ae2.importorder'
|
||||
}
|
||||
format 'json', {
|
||||
target 'src/*/resources/**/*.json'
|
||||
targetExclude 'src/generated/resources/**'
|
||||
prettier().config(['parser': 'json'])
|
||||
}
|
||||
}
|
||||
Vendored
BIN
Binary file not shown.
+1
-1
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.3-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -53,6 +53,8 @@ public interface ICraftingHelper {
|
||||
* @param stack If null, a new item will be created to hold the encoded pattern.
|
||||
* Otherwise the given item must already contains an encoded
|
||||
* pattern that will be overwritten.
|
||||
* @throws IllegalArgumentException If either in or out contain only empty
|
||||
* ItemStacks.
|
||||
* @return A new encoded pattern, or the given stack with the pattern encoded in
|
||||
* it.
|
||||
*/
|
||||
@@ -73,6 +75,8 @@ public interface ICraftingHelper {
|
||||
* operation by the ME system.
|
||||
* @param allowSubstitutes Controls whether the ME system will allow the use of
|
||||
* equivalent items to craft this recipe.
|
||||
* @throws IllegalArgumentException If either in or out contain only empty
|
||||
* ItemStacks.
|
||||
*/
|
||||
ItemStack encodeCraftingPattern(@Nullable ItemStack stack, ICraftingRecipe recipe, ItemStack[] in, ItemStack out,
|
||||
boolean allowSubstitutes);
|
||||
|
||||
@@ -23,13 +23,23 @@
|
||||
|
||||
package appeng.api.implementations.items;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.material.Material;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public interface IGrowableCrystal {
|
||||
|
||||
ItemStack triggerGrowth(ItemStack is);
|
||||
|
||||
float getMultiplier(Block blk, Material mat);
|
||||
/**
|
||||
* Gets the crystal growth multiplier based on the material it is submerged in.
|
||||
*
|
||||
* @param state The blockstate of the block the crystal is currently in.
|
||||
* @return The multiplier for the growth tick progress. Zero if the crystal
|
||||
* cannot grow in the current material.
|
||||
*/
|
||||
float getMultiplier(BlockState state, @Nullable World world, @Nullable BlockPos pos);
|
||||
}
|
||||
|
||||
@@ -28,4 +28,9 @@ public enum GridNotification {
|
||||
* the visible connections for this node have changed, useful for cable.
|
||||
*/
|
||||
CONNECTIONS_CHANGED,
|
||||
|
||||
/**
|
||||
* the owner of the grid node has changed, and the node needs to be re-saved
|
||||
*/
|
||||
OWNER_CHANGED
|
||||
}
|
||||
|
||||
@@ -87,7 +87,8 @@ public interface IGridBlock {
|
||||
AEColor getGridColor();
|
||||
|
||||
/**
|
||||
* Notifies your IGridBlock that changes were made to your connections
|
||||
* Called by the {@link IGridNode} to notify its {@link IGridBlock} about
|
||||
* events.
|
||||
*/
|
||||
void onGridNotification(@Nonnull GridNotification notification);
|
||||
|
||||
|
||||
@@ -46,19 +46,19 @@ public class DimensionalCoord extends WorldCoord {
|
||||
public DimensionalCoord(final TileEntity tileEntity) {
|
||||
super(tileEntity);
|
||||
this.world = tileEntity.getWorld();
|
||||
this.dimension = this.world.func_230315_m_();
|
||||
this.dimension = this.world.getDimensionType();
|
||||
}
|
||||
|
||||
public DimensionalCoord(final World world, final int x, final int y, final int z) {
|
||||
super(x, y, z);
|
||||
this.world = world;
|
||||
this.dimension = world.func_230315_m_();
|
||||
this.dimension = world.getDimensionType();
|
||||
}
|
||||
|
||||
public DimensionalCoord(final World world, final BlockPos pos) {
|
||||
super(pos);
|
||||
this.world = world;
|
||||
this.dimension = world.func_230315_m_();
|
||||
this.dimension = world.getDimensionType();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -39,6 +39,8 @@ import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.DyeColor;
|
||||
import net.minecraft.item.ItemGroup;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.state.IntegerProperty;
|
||||
import net.minecraft.state.StateContainer;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction;
|
||||
@@ -82,8 +84,12 @@ public class CableBusBlock extends AEBaseTileBlock<CableBusTileEntity> implement
|
||||
|
||||
private static final ICableBusContainer NULL_CABLE_BUS = new NullCableBusContainer();
|
||||
|
||||
private static final IntegerProperty LIGHT_LEVEL = IntegerProperty.create("light_level", 0, 15);
|
||||
|
||||
public CableBusBlock() {
|
||||
super(defaultProps(AEMaterials.GLASS).notSolid().noDrops().variableOpacity());
|
||||
super(defaultProps(AEMaterials.GLASS).notSolid().noDrops().variableOpacity()
|
||||
.setLightLevel(state -> state.get(LIGHT_LEVEL)));
|
||||
setDefaultState(getDefaultState().with(LIGHT_LEVEL, 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -126,11 +132,9 @@ public class CableBusBlock extends AEBaseTileBlock<CableBusTileEntity> implement
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLightValue(final BlockState state, final IBlockReader world, final BlockPos pos) {
|
||||
if (state.getBlock() != this) {
|
||||
return state.getBlock().getLightValue(state, world, pos);
|
||||
}
|
||||
return this.cb(world, pos).getLightValue();
|
||||
protected void fillStateContainer(StateContainer.Builder<Block, BlockState> builder) {
|
||||
super.fillStateContainer(builder);
|
||||
builder.add(LIGHT_LEVEL);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -386,4 +390,13 @@ public class CableBusBlock extends AEBaseTileBlock<CableBusTileEntity> implement
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockState updateBlockStateFromTileEntity(BlockState currentState, CableBusTileEntity te) {
|
||||
if (currentState.getBlock() != this) {
|
||||
return currentState;
|
||||
}
|
||||
int lightLevel = te.getCableBus().getLightValue();
|
||||
return super.updateBlockStateFromTileEntity(currentState, te).with(LIGHT_LEVEL, lightLevel);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -79,10 +79,10 @@ class PaintSplotchesBakedModel implements IDynamicBakedModel {
|
||||
|
||||
if (s.isLumen()) {
|
||||
builder.setColorRGB(s.getColor().whiteVariant);
|
||||
builder.setRenderFullBright(true);
|
||||
builder.setEmissiveMaterial(true);
|
||||
} else {
|
||||
builder.setColorRGB(s.getColor().mediumVariant);
|
||||
builder.setRenderFullBright(false);
|
||||
builder.setEmissiveMaterial(false);
|
||||
}
|
||||
|
||||
float offset = offsetConstant;
|
||||
@@ -167,7 +167,7 @@ class PaintSplotchesBakedModel implements IDynamicBakedModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean func_230044_c_() {
|
||||
public boolean isSideLit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ class QnbFormedBakedModel implements IDynamicBakedModel {
|
||||
|
||||
if (formedState.isPowered()) {
|
||||
builder.setTexture(this.lightCornerTexture);
|
||||
builder.setRenderFullBright(true);
|
||||
builder.setEmissiveMaterial(true);
|
||||
for (Direction facing : Direction.values()) {
|
||||
// Offset the face by a slight amount so that it is drawn over the already drawn
|
||||
// ring texture
|
||||
@@ -131,6 +131,7 @@ class QnbFormedBakedModel implements IDynamicBakedModel {
|
||||
DEFAULT_RENDER_MIN - zOffset, DEFAULT_RENDER_MAX + xOffset,
|
||||
DEFAULT_RENDER_MAX + yOffset, DEFAULT_RENDER_MAX + zOffset);
|
||||
}
|
||||
builder.setEmissiveMaterial(false);
|
||||
}
|
||||
} else {
|
||||
builder.setTexture(this.ringTexture);
|
||||
@@ -143,7 +144,7 @@ class QnbFormedBakedModel implements IDynamicBakedModel {
|
||||
|
||||
if (formedState.isPowered()) {
|
||||
builder.setTexture(this.lightTexture);
|
||||
builder.setRenderFullBright(true);
|
||||
builder.setEmissiveMaterial(true);
|
||||
for (Direction facing : Direction.values()) {
|
||||
// Offset the face by a slight amount so that it is drawn over the already drawn
|
||||
// ring texture
|
||||
@@ -202,7 +203,7 @@ class QnbFormedBakedModel implements IDynamicBakedModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean func_230044_c_() {
|
||||
public boolean isSideLit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ class BlockDefinitionBuilder implements IBlockBuilder {
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void setup() {
|
||||
ItemModelsProperties.func_239418_a_(item, new ResourceLocation("appliedenergistics2:fill_level"),
|
||||
ItemModelsProperties.registerProperty(item, new ResourceLocation("appliedenergistics2:fill_level"),
|
||||
(is, world, entity) -> {
|
||||
double curPower = chargeable.getAECurrentPower(is);
|
||||
double maxPower = chargeable.getAEMaxPower(is);
|
||||
|
||||
@@ -106,6 +106,7 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
|
||||
private Stopwatch dbl_clickTimer = Stopwatch.createStarted();
|
||||
private ItemStack dbl_whichItem = ItemStack.EMPTY;
|
||||
private Slot bl_clicked;
|
||||
private boolean handlingRightClick;
|
||||
protected final List<CustomSlotWidget> guiSlots = new ArrayList<>();
|
||||
|
||||
public AEBaseScreen(T container, PlayerInventory playerInventory, ITextComponent title) {
|
||||
@@ -146,7 +147,7 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
|
||||
RenderSystem.popMatrix();
|
||||
RenderSystem.enableDepthTest();
|
||||
|
||||
this.func_230459_a_(matrixStack, mouseX, mouseY);
|
||||
this.renderHoveredTooltip(matrixStack, mouseX, mouseY);
|
||||
|
||||
for (final Object c : this.buttons) {
|
||||
if (c instanceof ITooltip) {
|
||||
@@ -229,7 +230,7 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
|
||||
RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||
|
||||
if (this.getScrollBar() != null) {
|
||||
this.getScrollBar().draw(this);
|
||||
this.getScrollBar().draw(matrixStack, this);
|
||||
}
|
||||
|
||||
this.drawFG(matrixStack, ox, oy, x, y);
|
||||
@@ -275,12 +276,18 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
|
||||
public boolean mouseClicked(final double xCoord, final double yCoord, final int btn) {
|
||||
this.drag_click.clear();
|
||||
|
||||
// Forward right-clicks as-if they were left-clicks
|
||||
if (btn == 1) {
|
||||
for (final Object o : this.buttons) {
|
||||
final Widget widget = (Widget) o;
|
||||
if (widget.isMouseOver(xCoord, yCoord)) {
|
||||
return super.mouseClicked(xCoord, yCoord, 0);
|
||||
handlingRightClick = true;
|
||||
try {
|
||||
for (final Object o : this.buttons) {
|
||||
final Widget widget = (Widget) o;
|
||||
if (widget.isMouseOver(xCoord, yCoord)) {
|
||||
return super.mouseClicked(xCoord, yCoord, 0);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
handlingRightClick = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,22 +298,36 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
|
||||
}
|
||||
}
|
||||
|
||||
if (this.getScrollBar() != null) {
|
||||
this.getScrollBar().click(xCoord - this.guiLeft, yCoord - this.guiTop);
|
||||
// Forward left mouse button down events to the scrollbar
|
||||
if (btn == 0 && this.getScrollBar() != null) {
|
||||
if (this.getScrollBar().mouseDown(xCoord - this.guiLeft, yCoord - this.guiTop)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return super.mouseClicked(xCoord, yCoord, btn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseDragged(double mouseX, double mouseY, int mouseButton, double dragX, double dragY) {
|
||||
public boolean mouseReleased(double mouseX, double mouseY, int button) {
|
||||
// Forward left mouse button up events to the scrollbar
|
||||
if (button == 0 && this.getScrollBar() != null) {
|
||||
if (this.getScrollBar().mouseUp(mouseX - this.guiLeft, mouseY - this.guiTop)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return super.mouseReleased(mouseX, mouseY, button);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mouseDragged(double mouseX, double mouseY, int mouseButton, double dragX, double dragY) {
|
||||
final Slot slot = this.getSlot((int) mouseX, (int) mouseY);
|
||||
final ItemStack itemstack = getPlayer().inventory.getItemStack();
|
||||
|
||||
if (this.getScrollBar() != null) {
|
||||
// FIXME: Coordinate system of mouseX/mouseY is unclear
|
||||
this.getScrollBar().click((int) mouseX - this.guiLeft, (int) mouseY - this.guiTop);
|
||||
this.getScrollBar().mouseDragged((int) mouseX - this.guiLeft, (int) mouseY - this.guiTop);
|
||||
}
|
||||
|
||||
if (slot instanceof FakeSlot && !itemstack.isEmpty()) {
|
||||
@@ -581,7 +602,7 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
|
||||
if (slot instanceof SlotME) {
|
||||
final IAEItemStack item = ((SlotME) slot).getAEStack();
|
||||
if (item != null) {
|
||||
((AEBaseContainer) this.container).setTargetStack(item);
|
||||
this.container.setTargetStack(item);
|
||||
final InventoryAction direction = wheel > 0 ? InventoryAction.ROLL_DOWN : InventoryAction.ROLL_UP;
|
||||
final int times = (int) Math.abs(wheel);
|
||||
final int inventorySize = this.getInventorySlots().size();
|
||||
@@ -614,15 +635,7 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
|
||||
}
|
||||
|
||||
protected ITextComponent getGuiDisplayName(final ITextComponent in) {
|
||||
return this.hasCustomInventoryName() ? new StringTextComponent(this.getInventoryName()) : in;
|
||||
}
|
||||
|
||||
private boolean hasCustomInventoryName() {
|
||||
return this.container.getCustomName() != null;
|
||||
}
|
||||
|
||||
private String getInventoryName() {
|
||||
return this.container.getCustomName();
|
||||
return title.getString().isEmpty() ? in : title;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -796,6 +809,11 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
|
||||
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
if (this.getScrollBar() != null) {
|
||||
this.getScrollBar().tick();
|
||||
}
|
||||
|
||||
for (IGuiEventListener child : children) {
|
||||
if (child instanceof ITickingWidget) {
|
||||
((ITickingWidget) child).tick();
|
||||
@@ -803,4 +821,12 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends ContainerS
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true while the current event being handled is a click of the right
|
||||
* mouse button.
|
||||
*/
|
||||
public boolean isHandlingRightClick() {
|
||||
return handlingRightClick;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,19 +8,18 @@ import net.minecraft.inventory.container.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.items.SlotItemHandler;
|
||||
|
||||
/**
|
||||
* A proxy for a slot that will always return an itemstack with size 1, if there
|
||||
* is an item in the slot. Used to prevent the default item count from
|
||||
* rendering.
|
||||
*/
|
||||
class Size1Slot extends SlotItemHandler {
|
||||
class Size1Slot extends Slot {
|
||||
|
||||
private final SlotItemHandler delegate;
|
||||
private final Slot delegate;
|
||||
|
||||
public Size1Slot(SlotItemHandler delegate) {
|
||||
super(delegate.getItemHandler(), delegate.getSlotIndex(), delegate.xPos, delegate.yPos);
|
||||
public Size1Slot(Slot delegate) {
|
||||
super(delegate.inventory, delegate.getSlotIndex(), delegate.xPos, delegate.yPos);
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,35 +55,23 @@ final class AESubScreen {
|
||||
IPriorityHost priorityHost = (IPriorityHost) containerTarget;
|
||||
this.previousContainerIcon = priorityHost.getItemStackRepresentation();
|
||||
this.previousContainerType = ChestContainer.TYPE;
|
||||
}
|
||||
|
||||
else if (containerTarget instanceof IPriorityHost) {
|
||||
} else if (containerTarget instanceof IPriorityHost) {
|
||||
IPriorityHost priorityHost = (IPriorityHost) containerTarget;
|
||||
this.previousContainerIcon = priorityHost.getItemStackRepresentation();
|
||||
this.previousContainerType = priorityHost.getContainerType();
|
||||
}
|
||||
|
||||
else if (containerTarget instanceof WirelessTerminalGuiObject) {
|
||||
} else if (containerTarget instanceof WirelessTerminalGuiObject) {
|
||||
this.previousContainerIcon = definitions.items().wirelessTerminal().maybeStack(1).orElse(ItemStack.EMPTY);
|
||||
this.previousContainerType = WirelessTermContainer.TYPE;
|
||||
}
|
||||
|
||||
else if (containerTarget instanceof TerminalPart) {
|
||||
} else if (containerTarget instanceof TerminalPart) {
|
||||
this.previousContainerIcon = parts.terminal().maybeStack(1).orElse(ItemStack.EMPTY);
|
||||
this.previousContainerType = MEMonitorableContainer.TYPE;
|
||||
}
|
||||
|
||||
else if (containerTarget instanceof CraftingTerminalPart) {
|
||||
} else if (containerTarget instanceof CraftingTerminalPart) {
|
||||
this.previousContainerIcon = parts.craftingTerminal().maybeStack(1).orElse(ItemStack.EMPTY);
|
||||
this.previousContainerType = CraftingTermContainer.TYPE;
|
||||
}
|
||||
|
||||
else if (containerTarget instanceof PatternTerminalPart) {
|
||||
} else if (containerTarget instanceof PatternTerminalPart) {
|
||||
this.previousContainerIcon = parts.patternTerminal().maybeStack(1).orElse(ItemStack.EMPTY);
|
||||
this.previousContainerType = PatternTermContainer.TYPE;
|
||||
}
|
||||
|
||||
else {
|
||||
} else {
|
||||
this.previousContainerIcon = null;
|
||||
this.previousContainerType = null;
|
||||
}
|
||||
|
||||
@@ -48,22 +48,28 @@ public class CraftAmountScreen extends AEBaseScreen<CraftAmountContainer> {
|
||||
public void init() {
|
||||
super.init();
|
||||
|
||||
this.amountToCraft = new NumberEntryWidget(this, 20, 30, 138, 62, NumberEntryType.CRAFT_ITEM_COUNT, value -> {
|
||||
});
|
||||
this.amountToCraft = new NumberEntryWidget(this, 20, 30, 138, 62, NumberEntryType.CRAFT_ITEM_COUNT);
|
||||
this.amountToCraft.setValue(1);
|
||||
this.amountToCraft.setTextFieldBounds(62, 57, 50);
|
||||
this.amountToCraft.setMinValue(1);
|
||||
this.amountToCraft.setHideValidationIcon(true);
|
||||
this.amountToCraft.addButtons(children::add, this::addButton);
|
||||
|
||||
this.next = this.addButton(
|
||||
new Button(this.guiLeft + 128, this.guiTop + 51, 38, 20, GuiText.Next.text(), this::confirm));
|
||||
this.amountToCraft.setOnConfirm(() -> this.confirm(this.next));
|
||||
|
||||
subGui.addBackButton(this::addButton, 154, 0);
|
||||
|
||||
changeFocus(true);
|
||||
}
|
||||
|
||||
private void confirm(Button button) {
|
||||
NetworkHandler.instance()
|
||||
.sendToServer(new CraftRequestPacket((int) this.amountToCraft.getValue(), hasShiftDown()));
|
||||
int amount = this.amountToCraft.getIntValue().orElse(0);
|
||||
if (amount <= 0) {
|
||||
return;
|
||||
}
|
||||
NetworkHandler.instance().sendToServer(new CraftRequestPacket(amount, hasShiftDown()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -80,23 +86,9 @@ public class CraftAmountScreen extends AEBaseScreen<CraftAmountContainer> {
|
||||
this.bindTexture("guis/craft_amt.png");
|
||||
GuiUtils.drawTexturedModalRect(offsetX, offsetY, 0, 0, this.xSize, this.ySize, getBlitOffset());
|
||||
|
||||
this.next.active = this.amountToCraft.getValue() > 0;
|
||||
this.next.active = this.amountToCraft.getIntValue().orElse(0) > 0;
|
||||
|
||||
this.amountToCraft.render(matrixStack, offsetX, offsetY, partialTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
|
||||
if (keyCode == 28) {
|
||||
this.next.onPress();
|
||||
return true;
|
||||
} else {
|
||||
return super.keyPressed(keyCode, scanCode, p_keyPressed_3_);
|
||||
}
|
||||
}
|
||||
|
||||
protected String getBackground() {
|
||||
return "guis/craftAmt.png";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ import com.google.common.base.Joiner;
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import net.minecraft.client.gui.widget.button.Button;
|
||||
import net.minecraft.client.util.InputMappings;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
@@ -76,10 +78,6 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
|
||||
this.setScrollBar(scrollbar);
|
||||
}
|
||||
|
||||
boolean isAutoStart() {
|
||||
return this.container.isAutoStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
@@ -90,13 +88,14 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
|
||||
this.addButton(this.start);
|
||||
|
||||
this.selectCPU = new Button(this.guiLeft + (219 - 180) / 2, this.guiTop + this.ySize - 68, 180, 20,
|
||||
new StringTextComponent(GuiText.CraftingCPU.getLocal() + ": " + GuiText.Automatic),
|
||||
btn -> selectNextCpu());
|
||||
getNextCpuButtonLabel(), btn -> selectNextCpu());
|
||||
this.selectCPU.active = false;
|
||||
this.addButton(this.selectCPU);
|
||||
|
||||
addButton(new Button(this.guiLeft + 6, this.guiTop + this.ySize - 25, 50, 20, GuiText.Cancel.text(),
|
||||
btn -> subGui.goBack()));
|
||||
|
||||
this.setScrollBar();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -137,22 +136,22 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
|
||||
}
|
||||
|
||||
private void updateCPUButtonText() {
|
||||
String btnTextText = GuiText.CraftingCPU.getLocal() + ": " + GuiText.Automatic.getLocal();
|
||||
if (this.container.getSelectedCpu() >= 0)// && status.selectedCpu < status.cpus.size() )
|
||||
{
|
||||
if (this.container.getName() != null) {
|
||||
final String name = this.container.getName().getStringTruncated(20);
|
||||
btnTextText = GuiText.CraftingCPU.getLocal() + ": " + name;
|
||||
} else {
|
||||
btnTextText = GuiText.CraftingCPU.getLocal() + ": #" + this.container.getSelectedCpu();
|
||||
}
|
||||
}
|
||||
this.selectCPU.setMessage(getNextCpuButtonLabel());
|
||||
}
|
||||
|
||||
private ITextComponent getNextCpuButtonLabel() {
|
||||
if (this.container.hasNoCPU()) {
|
||||
btnTextText = GuiText.NoCraftingCPUs.getLocal();
|
||||
return GuiText.NoCraftingCPUs.text();
|
||||
}
|
||||
|
||||
this.selectCPU.setMessage(new StringTextComponent(btnTextText));
|
||||
ITextComponent cpuName;
|
||||
if (this.container.cpuName == null) {
|
||||
cpuName = GuiText.Automatic.text();
|
||||
} else {
|
||||
cpuName = this.container.cpuName;
|
||||
}
|
||||
|
||||
return GuiText.CraftingCPU.withSuffix(": ").append(cpuName);
|
||||
}
|
||||
|
||||
private boolean isSimulation() {
|
||||
@@ -445,7 +444,7 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
|
||||
@Override
|
||||
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
|
||||
if (!this.checkHotbarKeys(InputMappings.getInputByCode(keyCode, scanCode))) {
|
||||
if (keyCode == 28) {
|
||||
if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER) {
|
||||
this.start();
|
||||
return true;
|
||||
}
|
||||
@@ -454,7 +453,7 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
|
||||
}
|
||||
|
||||
private void selectNextCpu() {
|
||||
final boolean backwards = minecraft.mouseHelper.isRightDown();
|
||||
final boolean backwards = isHandlingRightClick();
|
||||
NetworkHandler.instance().sendToServer(new ConfigValuePacket("Terminal.Cpu", backwards ? "Prev" : "Next"));
|
||||
}
|
||||
|
||||
|
||||
@@ -16,10 +16,6 @@
|
||||
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
package appeng.client.gui.implementations;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
@@ -27,7 +23,6 @@ import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import net.minecraft.client.gui.widget.button.Button;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
|
||||
import appeng.container.implementations.CraftingStatusContainer;
|
||||
import appeng.core.localization.GuiText;
|
||||
@@ -50,14 +45,13 @@ public class CraftingStatusScreen extends CraftingCPUScreen<CraftingStatusContai
|
||||
public void init() {
|
||||
super.init();
|
||||
|
||||
this.selectCPU = new Button(this.guiLeft + 8, this.guiTop + this.ySize - 25, 150, 20,
|
||||
new StringTextComponent(GuiText.CraftingCPU.getLocal() + ": " + GuiText.NoCraftingCPUs),
|
||||
this.selectCPU = new Button(this.guiLeft + 8, this.guiTop + this.ySize - 25, 150, 20, getNextCpuButtonLabel(),
|
||||
btn -> selectNextCpu());
|
||||
this.addButton(this.selectCPU);
|
||||
|
||||
subGui.addBackButton(btn -> {
|
||||
addButton(btn);
|
||||
btn.setHideEdge(13);
|
||||
btn.setHideEdge(true);
|
||||
}, 213, -4);
|
||||
}
|
||||
|
||||
@@ -68,23 +62,14 @@ public class CraftingStatusScreen extends CraftingCPUScreen<CraftingStatusContai
|
||||
}
|
||||
|
||||
private void updateCPUButtonText() {
|
||||
String btnTextText = GuiText.NoCraftingJobs.getLocal();
|
||||
|
||||
if (this.container.selectedCpu >= 0)// && status.selectedCpu < status.cpus.size() )
|
||||
{
|
||||
if (this.container.myName != null) {
|
||||
final String name = this.container.myName.getStringTruncated(20);
|
||||
btnTextText = GuiText.CPUs.getLocal() + ": " + name;
|
||||
} else {
|
||||
btnTextText = GuiText.CPUs.getLocal() + ": #" + this.container.selectedCpu;
|
||||
}
|
||||
}
|
||||
this.selectCPU.setMessage(getNextCpuButtonLabel());
|
||||
}
|
||||
|
||||
private ITextComponent getNextCpuButtonLabel() {
|
||||
if (this.container.noCPU) {
|
||||
btnTextText = GuiText.NoCraftingJobs.getLocal();
|
||||
return GuiText.NoCraftingJobs.text();
|
||||
}
|
||||
|
||||
this.selectCPU.setMessage(new StringTextComponent(btnTextText));
|
||||
return GuiText.CraftingCPU.withSuffix(": ").append(container.cpuName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -92,9 +77,8 @@ public class CraftingStatusScreen extends CraftingCPUScreen<CraftingStatusContai
|
||||
return in; // the cup name is on the button
|
||||
}
|
||||
|
||||
// FIXME: Extract to separate class? Shared with GuiCraftConfirm
|
||||
private void selectNextCpu() {
|
||||
final boolean backwards = minecraft.mouseHelper.isRightDown();
|
||||
final boolean backwards = isHandlingRightClick();
|
||||
NetworkHandler.instance().sendToServer(new ConfigValuePacket("Terminal.Cpu", backwards ? "Prev" : "Next"));
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ public class InterfaceScreen extends UpgradeableScreen<InterfaceContainer> {
|
||||
}
|
||||
|
||||
private void selectNextInterfaceMode() {
|
||||
final boolean backwards = getMinecraft().mouseHelper.isRightDown();
|
||||
final boolean backwards = isHandlingRightClick();
|
||||
NetworkHandler.instance().sendToServer(new ConfigButtonPacket(Settings.INTERFACE_TERMINAL, backwards));
|
||||
}
|
||||
|
||||
|
||||
@@ -71,8 +71,7 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
|
||||
public InterfaceTerminalScreen(InterfaceTerminalContainer container, PlayerInventory playerInventory,
|
||||
ITextComponent title) {
|
||||
super(container, playerInventory, title);
|
||||
final Scrollbar scrollbar = new Scrollbar();
|
||||
this.setScrollBar(scrollbar);
|
||||
this.setScrollBar(new Scrollbar().setLeft(175).setTop(18).setHeight(106));
|
||||
this.xSize = 195;
|
||||
this.ySize = 222;
|
||||
}
|
||||
@@ -81,16 +80,14 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
|
||||
public void init() {
|
||||
super.init();
|
||||
|
||||
this.getScrollBar().setLeft(175);
|
||||
this.getScrollBar().setHeight(106);
|
||||
this.getScrollBar().setTop(18);
|
||||
|
||||
this.searchField = new AETextField(this.font, this.guiLeft + 104, this.guiTop + 4, 65, 12);
|
||||
this.searchField.setEnableBackgroundDrawing(false);
|
||||
this.searchField.setMaxStringLength(25);
|
||||
this.searchField.setTextColor(0xFFFFFF);
|
||||
this.searchField.setVisible(true);
|
||||
this.searchField.setFocused2(true);
|
||||
this.searchField.setResponder(str -> this.refreshList());
|
||||
this.addListener(this.searchField);
|
||||
this.changeFocus(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -131,11 +128,8 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
|
||||
|
||||
@Override
|
||||
public boolean mouseClicked(final double xCoord, final double yCoord, final int btn) {
|
||||
if (this.searchField.mouseClicked(xCoord, yCoord, btn)) {
|
||||
if (btn == 1 && this.searchField.isMouseOver(xCoord, yCoord)) {
|
||||
this.searchField.setText("");
|
||||
this.refreshList();
|
||||
}
|
||||
if (btn == 1 && this.searchField.isMouseOver(xCoord, yCoord)) {
|
||||
this.searchField.setText("");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -173,11 +167,7 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
|
||||
if (character == ' ' && this.searchField.getText().isEmpty()) {
|
||||
return true;
|
||||
}
|
||||
if (this.searchField.charTyped(character, key)) {
|
||||
this.refreshList();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return super.charTyped(character, key);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -221,7 +211,7 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
|
||||
try {
|
||||
final long id = Long.parseLong(key.substring(1), Character.MAX_RADIX);
|
||||
final CompoundNBT invData = in.getCompound(key);
|
||||
ITextComponent un = ITextComponent.Serializer.func_240643_a_(invData.getString("un"));
|
||||
ITextComponent un = ITextComponent.Serializer.getComponentFromJson(invData.getString("un"));
|
||||
final ClientDCInternalInv current = this.getById(id, invData.getLong("sortBy"), un);
|
||||
|
||||
for (int x = 0; x < current.getInventory().getSlots(); x++) {
|
||||
@@ -245,7 +235,7 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
|
||||
|
||||
/**
|
||||
* Rebuilds the list of interfaces.
|
||||
*
|
||||
* <p>
|
||||
* Respects a search term if present (ignores case) and adding only matching
|
||||
* patterns.
|
||||
*/
|
||||
@@ -338,12 +328,11 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
|
||||
|
||||
/**
|
||||
* Tries to retrieve a cache for a with search term as keyword.
|
||||
*
|
||||
* <p>
|
||||
* If this cache should be empty, it will populate it with an earlier cache if
|
||||
* available or at least the cache for the empty string.
|
||||
*
|
||||
* @param searchTerm the corresponding search
|
||||
*
|
||||
* @return a Set matching a superset of the search term
|
||||
*/
|
||||
private Set<Object> getCacheForSearchTerm(final String searchTerm) {
|
||||
|
||||
@@ -35,8 +35,6 @@ import appeng.client.gui.widgets.ServerSettingToggleButton;
|
||||
import appeng.client.gui.widgets.SettingToggleButton;
|
||||
import appeng.container.implementations.LevelEmitterContainer;
|
||||
import appeng.core.localization.GuiText;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.ConfigValuePacket;
|
||||
|
||||
public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer> {
|
||||
|
||||
@@ -52,15 +50,18 @@ public class LevelEmitterScreen extends UpgradeableScreen<LevelEmitterContainer>
|
||||
public void init() {
|
||||
super.init();
|
||||
|
||||
this.level = new NumberEntryWidget(this, 20, 17, 138, 62, NumberEntryType.LEVEL_ITEM_COUNT,
|
||||
this::onLevelChange);
|
||||
this.level = new NumberEntryWidget(this, 20, 17, 138, 62, NumberEntryType.LEVEL_ITEM_COUNT);
|
||||
this.level.setTextFieldBounds(25, 44, 75);
|
||||
this.level.addButtons(children::add, this::addButton);
|
||||
container.setTextField(this.level);
|
||||
this.level.setValue(container.getReportingValue());
|
||||
this.level.setOnChange(this::saveReportingValue);
|
||||
this.level.setOnConfirm(this::closeScreen);
|
||||
|
||||
this.changeFocus(true);
|
||||
}
|
||||
|
||||
private void onLevelChange(long level) {
|
||||
NetworkHandler.instance().sendToServer(new ConfigValuePacket("LevelEmitter.Value", String.valueOf(level)));
|
||||
private void saveReportingValue() {
|
||||
this.level.getLongValue().ifPresent(container::setReportingValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -51,6 +51,7 @@ import appeng.client.gui.widgets.SettingToggleButton;
|
||||
import appeng.client.gui.widgets.TabButton;
|
||||
import appeng.client.me.InternalSlotME;
|
||||
import appeng.client.me.ItemRepo;
|
||||
import appeng.client.render.StackSizeRenderer;
|
||||
import appeng.container.implementations.CraftingStatusContainer;
|
||||
import appeng.container.implementations.MEMonitorableContainer;
|
||||
import appeng.container.slot.AppEngSlot;
|
||||
@@ -237,7 +238,7 @@ public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBas
|
||||
if (this.viewCell || this instanceof WirelessTermScreen) {
|
||||
this.craftingStatusBtn = this.addButton(new TabButton(this.guiLeft + 170, this.guiTop - 4, 2 + 11 * 16,
|
||||
GuiText.CraftingStatus.text(), this.itemRenderer, btn -> showCraftingStatus()));
|
||||
this.craftingStatusBtn.setHideEdge(13);
|
||||
this.craftingStatusBtn.setHideEdge(true);
|
||||
}
|
||||
|
||||
this.isAutoFocus = SearchBoxMode.AUTOSEARCH == searchMode || SearchBoxMode.JEI_AUTOSEARCH == searchMode
|
||||
@@ -283,6 +284,8 @@ public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBas
|
||||
craftingGridOffsetX -= 25;
|
||||
craftingGridOffsetY -= 6;
|
||||
|
||||
this.setScrollBar();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -293,6 +296,16 @@ public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBas
|
||||
|
||||
this.currentMouseX = mouseX;
|
||||
this.currentMouseY = mouseY;
|
||||
|
||||
// Show the number of active crafting jobs
|
||||
if (this.craftingStatusBtn != null && container.activeCraftingJobs != -1) {
|
||||
// The stack size renderer expects a 16x16 slot, while the button is normally
|
||||
// bigger
|
||||
int x = this.craftingStatusBtn.x + (this.craftingStatusBtn.getWidth() - 16) / 2;
|
||||
int y = this.craftingStatusBtn.y + (this.craftingStatusBtn.getHeightRealms() - 16) / 2;
|
||||
StackSizeRenderer.renderSizeLabel(font, x - this.guiLeft, y - this.guiTop,
|
||||
String.valueOf(container.activeCraftingJobs));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -357,6 +370,7 @@ public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBas
|
||||
if (this.searchField != null) {
|
||||
this.searchField.render(matrixStack, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected String getBackground() {
|
||||
|
||||
@@ -2,43 +2,60 @@ package appeng.client.gui.implementations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.OptionalLong;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.LongConsumer;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
|
||||
import net.minecraft.client.gui.AbstractGui;
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.IGuiEventListener;
|
||||
import net.minecraft.client.gui.widget.button.Button;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraft.util.text.TranslationTextComponent;
|
||||
|
||||
import appeng.client.gui.AEBaseScreen;
|
||||
import appeng.client.gui.NumberEntryType;
|
||||
import appeng.client.gui.widgets.ITickingWidget;
|
||||
import appeng.client.gui.widgets.NumberBox;
|
||||
import appeng.client.gui.widgets.ConfirmableTextField;
|
||||
import appeng.client.gui.widgets.ValidationIcon;
|
||||
import appeng.core.AEConfig;
|
||||
|
||||
/**
|
||||
* A utility widget that consists of a text-field to enter a number with
|
||||
* attached buttons to increment/decrement the number in fixed intervals.
|
||||
*/
|
||||
public class NumberEntryWidget implements ITickingWidget {
|
||||
public class NumberEntryWidget extends AbstractGui {
|
||||
|
||||
private static final ITextComponent INVALID_NUMBER = new TranslationTextComponent(
|
||||
"gui.appliedenergistics2.validation.InvalidNumber");
|
||||
private static final String NUMBER_LESS_THAN_MIN_VALUE = "gui.appliedenergistics2.validation.NumberLessThanMinValue";
|
||||
private static final ITextComponent PLUS = new StringTextComponent("+");
|
||||
private static final ITextComponent MINUS = new StringTextComponent("-");
|
||||
private static final int TEXT_COLOR_ERROR = 0xFF1900;
|
||||
private static final int TEXT_COLOR_NORMAL = 0xFFFFFF;
|
||||
|
||||
private final AEBaseScreen<?> parent;
|
||||
|
||||
private final int x;
|
||||
private final int y;
|
||||
|
||||
private final NumberBox level;
|
||||
private final ConfirmableTextField textField;
|
||||
private final NumberEntryType type;
|
||||
private List<Button> buttons;
|
||||
private long minValue;
|
||||
private ValidationIcon validationIcon;
|
||||
|
||||
public NumberEntryWidget(AEBaseScreen<?> parent, int x, int y, int width, int height, NumberEntryType type,
|
||||
LongConsumer changeListener) {
|
||||
// Called when the value changes
|
||||
private Runnable onChange;
|
||||
|
||||
// Called when the user presses enter while there's a valid number in the field
|
||||
private Runnable onConfirm;
|
||||
|
||||
private boolean hideValidationIcon;
|
||||
|
||||
public NumberEntryWidget(AEBaseScreen<?> parent, int x, int y, int width, int height, NumberEntryType type) {
|
||||
this.parent = parent;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
@@ -47,28 +64,51 @@ public class NumberEntryWidget implements ITickingWidget {
|
||||
FontRenderer font = parent.getMinecraft().fontRenderer;
|
||||
int inputX = parent.getGuiLeft() + x;
|
||||
int inputY = parent.getGuiTop() + y;
|
||||
this.level = new NumberBox(font, inputX, inputY, width, font.FONT_HEIGHT, type.getInputType(), changeListener);
|
||||
this.level.setEnableBackgroundDrawing(false);
|
||||
this.level.setMaxStringLength(16);
|
||||
this.level.setTextColor(0xFFFFFF);
|
||||
this.level.setVisible(true);
|
||||
this.level.setFocused2(true);
|
||||
parent.setFocusedDefault(this.level);
|
||||
this.textField = new ConfirmableTextField(font, inputX, inputY, width, font.FONT_HEIGHT,
|
||||
StringTextComponent.EMPTY);
|
||||
this.textField.setEnableBackgroundDrawing(false);
|
||||
this.textField.setMaxStringLength(16);
|
||||
this.textField.setTextColor(TEXT_COLOR_NORMAL);
|
||||
this.textField.setVisible(true);
|
||||
this.textField.setFocused2(true);
|
||||
parent.setFocusedDefault(this.textField);
|
||||
this.textField.setResponder(text -> {
|
||||
validate();
|
||||
if (onChange != null) {
|
||||
this.onChange.run();
|
||||
}
|
||||
});
|
||||
this.textField.setOnConfirm(() -> {
|
||||
// Only confirm if it's actually valid
|
||||
if (this.onConfirm != null && getLongValue().isPresent()) {
|
||||
this.onConfirm.run();
|
||||
}
|
||||
});
|
||||
validate();
|
||||
}
|
||||
|
||||
public void setOnConfirm(Runnable callback) {
|
||||
this.onConfirm = callback;
|
||||
}
|
||||
|
||||
public void setOnChange(Runnable callback) {
|
||||
this.onChange = callback;
|
||||
}
|
||||
|
||||
public void setActive(boolean active) {
|
||||
this.level.setEnabled(active);
|
||||
this.textField.setEnabled(active);
|
||||
this.buttons.forEach(b -> b.active = active);
|
||||
}
|
||||
|
||||
public void setTextFieldBounds(int x, int y, int width) {
|
||||
this.level.x = parent.getGuiLeft() + x;
|
||||
this.level.y = parent.getGuiTop() + y;
|
||||
this.level.setWidth(width);
|
||||
this.textField.x = parent.getGuiLeft() + x;
|
||||
this.textField.y = parent.getGuiTop() + y;
|
||||
this.textField.setWidth(width);
|
||||
}
|
||||
|
||||
public void setMinValue(long minValue) {
|
||||
this.level.setMinValue(minValue);
|
||||
this.minValue = minValue;
|
||||
validate();
|
||||
}
|
||||
|
||||
public void addButtons(Consumer<IGuiEventListener> addChildren, Consumer<Button> addButton) {
|
||||
@@ -81,54 +121,116 @@ public class NumberEntryWidget implements ITickingWidget {
|
||||
int left = parent.getGuiLeft() + x;
|
||||
int top = parent.getGuiTop() + y;
|
||||
|
||||
List<Button> buttons = new ArrayList<>(8);
|
||||
List<Button> buttons = new ArrayList<>(9);
|
||||
|
||||
buttons.add(new Button(left, top, 22, 20, makeLabel(PLUS, a), btn -> addQty(a)));
|
||||
buttons.add(new Button(left + 28, top, 28, 20, makeLabel(PLUS, b), btn -> addQty(b)));
|
||||
buttons.add(new Button(left + 62, top, 32, 20, makeLabel(PLUS, c), btn -> addQty(c)));
|
||||
buttons.add(new Button(left + 100, top, 38, 20, makeLabel(PLUS, d), btn -> addQty(d)));
|
||||
|
||||
// Need to add these now for sensible tab-order
|
||||
buttons.forEach(addButton);
|
||||
|
||||
// Placing this here will give a sensible tab order
|
||||
addChildren.accept(this.level);
|
||||
addChildren.accept(this.textField);
|
||||
|
||||
buttons.add(new Button(left, top + 42, 22, 20, makeLabel(MINUS, a), btn -> addQty(-a)));
|
||||
buttons.add(new Button(left + 28, top + 42, 28, 20, makeLabel(MINUS, b), btn -> addQty(-b)));
|
||||
buttons.add(new Button(left + 62, top + 42, 32, 20, makeLabel(MINUS, c), btn -> addQty(-c)));
|
||||
buttons.add(new Button(left + 100, top + 42, 38, 20, makeLabel(MINUS, d), btn -> addQty(-d)));
|
||||
|
||||
// This element is not focusable
|
||||
if (!hideValidationIcon) {
|
||||
this.validationIcon = new ValidationIcon(left + 104, top + 27);
|
||||
buttons.add(this.validationIcon);
|
||||
}
|
||||
|
||||
// Add the rest to the tab order
|
||||
buttons.subList(4, buttons.size()).forEach(addButton);
|
||||
|
||||
this.buttons = buttons;
|
||||
this.buttons.forEach(addButton);
|
||||
|
||||
// we need to re-validate because the icon may now be present and needs it's
|
||||
// initial state
|
||||
this.validate();
|
||||
}
|
||||
|
||||
private void addQty(final long i) {
|
||||
long currentValue = this.level.getValue();
|
||||
long minValue = this.level.getMinValue();
|
||||
this.level.setText(String.valueOf(Math.max(minValue, currentValue + i)));
|
||||
/**
|
||||
* Returns the integer value currently in the text-field, if it is a valid
|
||||
* number and is within the allowed min/max value.
|
||||
*/
|
||||
public OptionalInt getIntValue() {
|
||||
String text = textField.getText().trim();
|
||||
try {
|
||||
int value = Integer.parseInt(text, 10);
|
||||
if (value < minValue) {
|
||||
return OptionalInt.empty();
|
||||
}
|
||||
return OptionalInt.of(value);
|
||||
} catch (NumberFormatException ignored) {
|
||||
return OptionalInt.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
|
||||
this.level.render(matrixStack, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
public void setValue(long value, boolean skipNotify) {
|
||||
this.level.setValue(value, skipNotify);
|
||||
/**
|
||||
* Returns the long value currently in the text-field, if it is a valid number
|
||||
* and is within the allowed min/max value.
|
||||
*/
|
||||
public OptionalLong getLongValue() {
|
||||
String text = textField.getText().trim();
|
||||
try {
|
||||
long value = Long.parseLong(text, 10);
|
||||
if (value < minValue) {
|
||||
return OptionalLong.empty();
|
||||
}
|
||||
return OptionalLong.of(value);
|
||||
} catch (NumberFormatException ignored) {
|
||||
return OptionalLong.empty();
|
||||
}
|
||||
}
|
||||
|
||||
public void setValue(long value) {
|
||||
setValue(value, false);
|
||||
this.textField.setText(String.valueOf(Math.max(minValue, value)));
|
||||
this.textField.setCursorPositionEnd();
|
||||
this.textField.setSelectionPos(0);
|
||||
validate();
|
||||
}
|
||||
|
||||
public long getValue() {
|
||||
return level.getValue();
|
||||
private void addQty(final long i) {
|
||||
getLongValue().ifPresent(currentValue -> setValue(currentValue + i));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
this.level.tick();
|
||||
public void render(MatrixStack matrices, int mouseX, int mouseY, float partialTicks) {
|
||||
this.textField.render(matrices, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
private void validate() {
|
||||
List<ITextComponent> validationErrors = new ArrayList<>();
|
||||
|
||||
String text = textField.getText().trim();
|
||||
try {
|
||||
long value = Long.parseLong(text, 10);
|
||||
if (value < minValue) {
|
||||
validationErrors.add(new TranslationTextComponent(NUMBER_LESS_THAN_MIN_VALUE, minValue));
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
validationErrors.add(INVALID_NUMBER);
|
||||
}
|
||||
|
||||
boolean valid = validationErrors.isEmpty();
|
||||
this.textField.setTextColor(valid ? TEXT_COLOR_NORMAL : TEXT_COLOR_ERROR);
|
||||
if (this.validationIcon != null) {
|
||||
this.validationIcon.setValid(valid);
|
||||
this.validationIcon.setTooltip(validationErrors);
|
||||
}
|
||||
}
|
||||
|
||||
private ITextComponent makeLabel(ITextComponent prefix, int amount) {
|
||||
return prefix.copyRaw().appendString(String.valueOf(amount));
|
||||
}
|
||||
|
||||
public void setHideValidationIcon(boolean hideValidationIcon) {
|
||||
this.hideValidationIcon = hideValidationIcon;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
|
||||
package appeng.client.gui.implementations;
|
||||
|
||||
import java.util.OptionalInt;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
@@ -27,8 +29,6 @@ import appeng.client.gui.AEBaseScreen;
|
||||
import appeng.client.gui.NumberEntryType;
|
||||
import appeng.container.implementations.PriorityContainer;
|
||||
import appeng.core.localization.GuiText;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.ConfigValuePacket;
|
||||
|
||||
public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
|
||||
|
||||
@@ -39,24 +39,38 @@ public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
|
||||
public PriorityScreen(PriorityContainer container, PlayerInventory playerInventory, ITextComponent title) {
|
||||
super(container, playerInventory, title);
|
||||
this.subGui = new AESubScreen(this, container.getPriorityHost());
|
||||
|
||||
// This is the effective size of the background image
|
||||
xSize = 175;
|
||||
ySize = 128;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
|
||||
this.priority = new NumberEntryWidget(this, 20, 30, 138, 62, NumberEntryType.PRIORITY, this::onPriorityChange);
|
||||
this.priority = new NumberEntryWidget(this, 20, 30, 138, 62, NumberEntryType.PRIORITY);
|
||||
this.priority.setTextFieldBounds(62, 57, 50);
|
||||
this.priority.setMinValue(Integer.MIN_VALUE);
|
||||
container.setTextField(this.priority);
|
||||
this.priority.setValue(this.container.getPriorityValue());
|
||||
this.priority.addButtons(children::add, this::addButton);
|
||||
|
||||
this.subGui.addBackButton(this::addButton, 154, 0);
|
||||
|
||||
this.priority.setOnChange(this::savePriority);
|
||||
this.priority.setOnConfirm(() -> {
|
||||
savePriority();
|
||||
this.subGui.goBack();
|
||||
});
|
||||
|
||||
changeFocus(true);
|
||||
}
|
||||
|
||||
private void onPriorityChange(long priority) {
|
||||
NetworkHandler.instance()
|
||||
.sendToServer(new ConfigValuePacket("PriorityHost.Priority", String.valueOf(priority)));
|
||||
private void savePriority() {
|
||||
OptionalInt priority = this.priority.getIntValue();
|
||||
if (priority.isPresent()) {
|
||||
container.setPriority(priority.getAsInt());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -68,13 +82,10 @@ public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
|
||||
@Override
|
||||
public void drawBG(MatrixStack matrixStack, final int offsetX, final int offsetY, final int mouseX,
|
||||
final int mouseY, float partialTicks) {
|
||||
this.bindTexture(getBackground());
|
||||
this.bindTexture("guis/priority.png");
|
||||
blit(matrixStack, offsetX, offsetY, 0, 0, this.xSize, this.ySize);
|
||||
|
||||
this.priority.render(matrixStack, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
protected String getBackground() {
|
||||
return "guis/priority.png";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2015, 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>.
|
||||
*/
|
||||
|
||||
package appeng.client.gui.widgets;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
public class ConfirmableTextField extends TextFieldWidget {
|
||||
|
||||
private Runnable onConfirm;
|
||||
|
||||
public ConfirmableTextField(FontRenderer fontRenderer, int x, int y, int width, int height, ITextComponent text) {
|
||||
super(fontRenderer, x, y, width, height, text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
if (canWrite() && (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER)) {
|
||||
if (this.onConfirm != null) {
|
||||
this.onConfirm.run();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.keyPressed(keyCode, scanCode, modifiers);
|
||||
}
|
||||
|
||||
public void setOnConfirm(Runnable onConfirm) {
|
||||
this.onConfirm = onConfirm;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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>.
|
||||
*/
|
||||
|
||||
package appeng.client.gui.widgets;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* This class can be used to implement repeating events such as holding down a
|
||||
* button to fire an event repeatedly while the button is still being held, or
|
||||
* repeatedly scrolling down a page, while the mouse is held down on the
|
||||
* scrollbar.
|
||||
*/
|
||||
public class EventRepeater {
|
||||
|
||||
/**
|
||||
* -1 if no repeat event is scheduled. Otherwise contains the
|
||||
* {@link System#nanoTime()} at which the next event should occur.
|
||||
*/
|
||||
private long nextEventTime = -1;
|
||||
|
||||
private EventCallback eventCallback = null;
|
||||
|
||||
private final long eventDelay; // In nanoseconds
|
||||
|
||||
private final long eventInterval; // In nanoseconds
|
||||
|
||||
public EventRepeater(Duration delay, Duration interval) {
|
||||
this.eventDelay = delay.toNanos();
|
||||
this.eventInterval = interval.toNanos();
|
||||
}
|
||||
|
||||
public void tick() {
|
||||
if (this.eventCallback == null) {
|
||||
return; // No event scheduled
|
||||
}
|
||||
|
||||
// Use nanoTime here because it is monotonically increasing, while
|
||||
// System.currentTimeMillis is not
|
||||
long nanoTime = System.nanoTime();
|
||||
if (nanoTime < this.nextEventTime) {
|
||||
return; // Event time not reached
|
||||
}
|
||||
|
||||
// Before triggering, recompute the next event, since
|
||||
// the event callback itself may reschedule/cancel, and
|
||||
// we should not overwrite that
|
||||
this.nextEventTime = nanoTime + this.eventInterval;
|
||||
this.eventCallback.trigger();
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule the given callback to be called after a given initial delay, and
|
||||
* then after the given interval repeatedly.
|
||||
*
|
||||
* <p>
|
||||
* Replaces any previously queued callback.
|
||||
*/
|
||||
public void repeat(EventCallback callback) {
|
||||
long time = System.nanoTime();
|
||||
this.eventCallback = callback;
|
||||
this.nextEventTime = time + eventDelay;
|
||||
}
|
||||
|
||||
public boolean isRepeating() {
|
||||
return this.eventCallback != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop repeating the event.
|
||||
*/
|
||||
public void stop() {
|
||||
this.eventCallback = null;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface EventCallback {
|
||||
void trigger();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.audio.SoundHandler;
|
||||
import net.minecraft.client.gui.widget.button.Button;
|
||||
import net.minecraft.client.renderer.texture.TextureManager;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
@@ -35,6 +36,10 @@ public abstract class IconButton extends Button implements ITooltip {
|
||||
|
||||
private boolean halfSize = false;
|
||||
|
||||
private boolean disableClickSound = false;
|
||||
|
||||
private boolean disableBackground = false;
|
||||
|
||||
public IconButton(final int x, final int y, IPressable onPress) {
|
||||
super(x, y, 16, 16, StringTextComponent.EMPTY, onPress);
|
||||
}
|
||||
@@ -44,6 +49,13 @@ public abstract class IconButton extends Button implements ITooltip {
|
||||
this.active = vis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playDownSound(SoundHandler soundHandler) {
|
||||
if (!disableClickSound) {
|
||||
super.playDownSound(soundHandler);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderButton(MatrixStack matrixStack, final int mouseX, final int mouseY, float partial) {
|
||||
|
||||
@@ -74,7 +86,9 @@ public abstract class IconButton extends Button implements ITooltip {
|
||||
final int uv_y = iconIndex / 16;
|
||||
final int uv_x = iconIndex - uv_y * 16;
|
||||
|
||||
GuiUtils.drawTexturedModalRect(0, 0, 256 - 16, 256 - 16, 16, 16, 0);
|
||||
if (!disableBackground) {
|
||||
GuiUtils.drawTexturedModalRect(0, 0, 256 - 16, 256 - 16, 16, 16, 0);
|
||||
}
|
||||
GuiUtils.drawTexturedModalRect(0, 0, uv_x * 16, uv_y * 16, 16, 16, 0);
|
||||
RenderSystem.popMatrix();
|
||||
} else {
|
||||
@@ -87,12 +101,18 @@ public abstract class IconButton extends Button implements ITooltip {
|
||||
final int uv_y = iconIndex / 16;
|
||||
final int uv_x = iconIndex - uv_y * 16;
|
||||
|
||||
GuiUtils.drawTexturedModalRect(this.x, this.y, 256 - 16, 256 - 16, 16, 16, 0);
|
||||
if (!disableBackground) {
|
||||
GuiUtils.drawTexturedModalRect(this.x, this.y, 256 - 16, 256 - 16, 16, 16, 0);
|
||||
}
|
||||
GuiUtils.drawTexturedModalRect(this.x, this.y, uv_x * 16, uv_y * 16, 16, 16, 0);
|
||||
}
|
||||
RenderSystem.enableDepthTest();
|
||||
RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
if (isHovered()) {
|
||||
renderToolTip(matrixStack, mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
protected abstract int getIconIndex();
|
||||
@@ -135,4 +155,20 @@ public abstract class IconButton extends Button implements ITooltip {
|
||||
this.halfSize = halfSize;
|
||||
}
|
||||
|
||||
public boolean isDisableClickSound() {
|
||||
return disableClickSound;
|
||||
}
|
||||
|
||||
public void setDisableClickSound(boolean disableClickSound) {
|
||||
this.disableClickSound = disableClickSound;
|
||||
}
|
||||
|
||||
public boolean isDisableBackground() {
|
||||
return disableBackground;
|
||||
}
|
||||
|
||||
public void setDisableBackground(boolean disableBackground) {
|
||||
this.disableBackground = disableBackground;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2015, 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>.
|
||||
*/
|
||||
|
||||
package appeng.client.gui.widgets;
|
||||
|
||||
import java.util.function.LongConsumer;
|
||||
|
||||
import net.minecraft.client.gui.FontRenderer;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
|
||||
public class NumberBox extends TextFieldWidget {
|
||||
|
||||
private final LongConsumer changeListener;
|
||||
|
||||
private long lastValue;
|
||||
|
||||
private long minValue = 0;
|
||||
|
||||
private long maxValue;
|
||||
|
||||
public NumberBox(final FontRenderer fontRenderer, final int x, final int y, final int width, final int height,
|
||||
final Class<?> type, LongConsumer changeListener) {
|
||||
super(fontRenderer, x, y, width, height, new StringTextComponent("0"));
|
||||
this.setText("0");
|
||||
setResponder(this::handleTextChanged);
|
||||
this.lastValue = 0;
|
||||
this.changeListener = changeListener;
|
||||
if (type == int.class || type == Integer.class) {
|
||||
maxValue = Integer.MAX_VALUE;
|
||||
} else {
|
||||
maxValue = Long.MAX_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: This method MUST NOT BE NAMED like a method in the superclass because
|
||||
// of a ForgeGradle remapping bug
|
||||
// since it'll not remap this method's name, but it will remap the name of the
|
||||
// method reference above.
|
||||
private void handleTextChanged(String text) {
|
||||
if (text.isEmpty()) {
|
||||
setText("0"); // Will call onTextChanged recursively
|
||||
return;
|
||||
}
|
||||
|
||||
boolean canBeNegative = canBeNegative();
|
||||
if (canBeNegative && text.equals("-")) {
|
||||
// Allow this as a special case to make typing in a negative number easier
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder sanitized = new StringBuilder(text);
|
||||
boolean encounteredNonZero = false;
|
||||
for (int i = 0; i < sanitized.length(); i++) {
|
||||
char ch = sanitized.charAt(i);
|
||||
if (canBeNegative && i == 0 && ch == '-') {
|
||||
continue; // Allow leading minus sign
|
||||
}
|
||||
if (ch >= '1' && ch <= '9') {
|
||||
encounteredNonZero = true;
|
||||
continue;
|
||||
}
|
||||
if (ch != '0' || !encounteredNonZero) {
|
||||
sanitized.deleteCharAt(i--);
|
||||
}
|
||||
}
|
||||
if (sanitized.length() == 0) {
|
||||
sanitized.append('0');
|
||||
}
|
||||
String sanitizedStr = sanitized.toString();
|
||||
if (!sanitizedStr.equals(text)) {
|
||||
setText(sanitizedStr); // Will call onTextChanged recursively
|
||||
return;
|
||||
}
|
||||
if (getValue() < minValue) {
|
||||
setText(String.valueOf(minValue)); // Will call onTextChanged recursively
|
||||
return;
|
||||
}
|
||||
if (getValue() > maxValue) {
|
||||
setText(String.valueOf(maxValue)); // Will call onTextChanged recursively
|
||||
return;
|
||||
}
|
||||
|
||||
reportChange();
|
||||
}
|
||||
|
||||
private void reportChange() {
|
||||
long value = getValue();
|
||||
if (value != lastValue) {
|
||||
lastValue = value;
|
||||
changeListener.accept(value);
|
||||
}
|
||||
}
|
||||
|
||||
public void setValue(long value, boolean skipNotify) {
|
||||
// This check avoid changing the cursor position needlessly
|
||||
if (value == this.getValue()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (skipNotify) {
|
||||
lastValue = value;
|
||||
}
|
||||
setText(String.valueOf(value));
|
||||
}
|
||||
|
||||
public long getValue() {
|
||||
if (getText().equals("-") && canBeNegative()) {
|
||||
return lastValue; // Allow this as a special case to type in a negative number more easily
|
||||
}
|
||||
|
||||
return Long.parseLong(getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int p_keyPressed_1_, int p_keyPressed_2_, int p_keyPressed_3_) {
|
||||
if (super.keyPressed(p_keyPressed_1_, p_keyPressed_2_, p_keyPressed_3_)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Swallow key presses for numbers because they would otherwise trigger the
|
||||
// hotbar swapping unintentionally
|
||||
return isFocused() && p_keyPressed_1_ >= '0' && p_keyPressed_1_ <= '9';
|
||||
}
|
||||
|
||||
public void setMinValue(long minValue) {
|
||||
this.minValue = minValue;
|
||||
}
|
||||
|
||||
public long getMinValue() {
|
||||
return minValue;
|
||||
}
|
||||
|
||||
private boolean canBeNegative() {
|
||||
return minValue < 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,17 +18,75 @@
|
||||
|
||||
package appeng.client.gui.widgets;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import java.time.Duration;
|
||||
|
||||
import net.minecraftforge.fml.client.gui.GuiUtils;
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
|
||||
import net.minecraft.client.gui.AbstractGui;
|
||||
import net.minecraft.client.renderer.Rectangle2d;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
import appeng.client.gui.AEBaseScreen;
|
||||
|
||||
public class Scrollbar implements IScrollSource {
|
||||
/**
|
||||
* Implements a vertical scrollbar using Vanilla's scrollbar handle texture from
|
||||
* the creative tab.
|
||||
* <p>
|
||||
* It is expected that the background of the UI contains a pre-baked scrollbar
|
||||
* track border, and that the exact rectangle of that track is set on this
|
||||
* object via {@link #setLeft(int)}, {@link #setTop(int)} and
|
||||
* {@link #setHeight(int)}. While the width of the track can also be set, the
|
||||
* drawn handle will use vanilla's sprite width (see {@link #HANDLE_WIDTH}.
|
||||
*/
|
||||
public class Scrollbar extends AbstractGui implements IScrollSource {
|
||||
|
||||
/**
|
||||
* Width of the scrollbar handle sprite in the source texture.
|
||||
*/
|
||||
private static final int HANDLE_WIDTH = 12;
|
||||
|
||||
/**
|
||||
* Height of the scrollbar handle sprite in the source texture.
|
||||
*/
|
||||
private static final int HANDLE_HEIGHT = 15;
|
||||
|
||||
/**
|
||||
* Texture containing the scrollbar handle sprites.
|
||||
*/
|
||||
private static final ResourceLocation TEXTURE = new ResourceLocation("minecraft",
|
||||
"textures/gui/container/creative_inventory/tabs.png");
|
||||
|
||||
/**
|
||||
* Rectangle in the source texture that contains the sprite for an enabled
|
||||
* handle.
|
||||
*/
|
||||
private static final Rectangle2d ENABLED = new Rectangle2d(232, 0, HANDLE_WIDTH, HANDLE_HEIGHT);
|
||||
|
||||
/**
|
||||
* Rectangle in the source texture that contains the sprite for a disabled
|
||||
* handle.
|
||||
*/
|
||||
private static final Rectangle2d DISABLED = new Rectangle2d(232 + HANDLE_WIDTH, 0, HANDLE_WIDTH, HANDLE_HEIGHT);
|
||||
|
||||
/**
|
||||
* The screen x-coordinate of the scrollbar's inner track.
|
||||
*/
|
||||
private int displayX = 0;
|
||||
|
||||
/**
|
||||
* The screen y-coordinate of the scrollbar's inner track.
|
||||
*/
|
||||
private int displayY = 0;
|
||||
private int width = 12;
|
||||
|
||||
/**
|
||||
* The inner width of the scrollbar track.
|
||||
*/
|
||||
private int width = HANDLE_WIDTH;
|
||||
|
||||
/**
|
||||
* The inner height of the scrollbar track.
|
||||
*/
|
||||
private int height = 16;
|
||||
private int pageSize = 1;
|
||||
|
||||
@@ -36,18 +94,58 @@ public class Scrollbar implements IScrollSource {
|
||||
private int minScroll = 0;
|
||||
private int currentScroll = 0;
|
||||
|
||||
public void draw(final AEBaseScreen<?> g) {
|
||||
g.bindTexture("minecraft", "gui/container/creative_inventory/tabs.png");
|
||||
RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
/**
|
||||
* True if the scrollbar's handle is currently being dragged.
|
||||
*/
|
||||
private boolean dragging;
|
||||
/**
|
||||
* The y-coordinate relative to the upper edge of the scrollbar handle, where
|
||||
* the user pressed the mouse button to drag. While dragging, this is applied as
|
||||
* an offset to the effective scrollbar position.
|
||||
*/
|
||||
private int dragYOffset;
|
||||
|
||||
private final EventRepeater eventRepeater = new EventRepeater(Duration.ofMillis(250), Duration.ofMillis(150));
|
||||
|
||||
/**
|
||||
* Draws the handle of the scrollbar.
|
||||
* <p>
|
||||
* The GUI is assumed to already contain a prebaked scrollbar track in its
|
||||
* background.
|
||||
*/
|
||||
public void draw(MatrixStack matrices, final AEBaseScreen<?> g) {
|
||||
setBlitOffset(g.getBlitOffset());
|
||||
|
||||
// Draw the track (nice for debugging)
|
||||
// fill(matrices, displayX, displayY, this.displayX + width, this.displayY +
|
||||
// height, 0xffff0000);
|
||||
|
||||
g.bindTexture(TEXTURE);
|
||||
|
||||
int yOffset;
|
||||
Rectangle2d sourceRect;
|
||||
if (this.getRange() == 0) {
|
||||
GuiUtils.drawTexturedModalRect(this.displayX, this.displayY, 232 + this.width, 0, this.width, 15,
|
||||
g.getBlitOffset());
|
||||
yOffset = 0;
|
||||
sourceRect = DISABLED;
|
||||
} else {
|
||||
final int offset = (this.currentScroll - this.minScroll) * (this.height - 15) / this.getRange();
|
||||
GuiUtils.drawTexturedModalRect(this.displayX, offset + this.displayY, 232, 0, this.width, 15,
|
||||
g.getBlitOffset());
|
||||
yOffset = getHandleYOffset();
|
||||
sourceRect = ENABLED;
|
||||
}
|
||||
|
||||
blit(matrices, this.displayX, this.displayY + yOffset, sourceRect.getX(), sourceRect.getY(),
|
||||
sourceRect.getWidth(), sourceRect.getHeight());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the y-position of the scrollbar handle in relation to the upper edge
|
||||
* of the scrollbar's track.
|
||||
*/
|
||||
private int getHandleYOffset() {
|
||||
if (getRange() == 0) {
|
||||
return 0;
|
||||
}
|
||||
int availableHeight = this.height - HANDLE_HEIGHT;
|
||||
return (this.currentScroll - this.minScroll) * availableHeight / this.getRange();
|
||||
}
|
||||
|
||||
private int getRange() {
|
||||
@@ -111,24 +209,96 @@ public class Scrollbar implements IScrollSource {
|
||||
return this.currentScroll;
|
||||
}
|
||||
|
||||
public void click(final double x, final double y) {
|
||||
if (this.getRange() == 0) {
|
||||
public boolean mouseDown(double x, double y) {
|
||||
this.dragging = false;
|
||||
|
||||
// Clicks to the left or right of the scrollbar don't do anything
|
||||
if (x < displayX || x >= displayX + width) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Clicks to the top or bottom don't do anything either
|
||||
int relY = (int) Math.round(y - displayY);
|
||||
if (relY < 0 || relY >= height) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Do nothing when there's no range, but swallow the event
|
||||
if (getRange() == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int handleYOffset = getHandleYOffset();
|
||||
|
||||
if (relY < handleYOffset) {
|
||||
// Clicks above the handle will page up, repeatedly
|
||||
pageUp();
|
||||
eventRepeater.repeat(this::pageUp);
|
||||
|
||||
} else if (relY < handleYOffset + HANDLE_HEIGHT) {
|
||||
// Clicks on the handle will initiate dragging it
|
||||
this.dragging = true;
|
||||
this.dragYOffset = relY - handleYOffset;
|
||||
} else {
|
||||
// Clicks below the handle will page down, repeatedly
|
||||
pageDown();
|
||||
eventRepeater.repeat(this::pageDown);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean mouseUp(double x, double y) {
|
||||
this.dragging = false;
|
||||
this.eventRepeater.stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
public void mouseDragged(double x, double y) {
|
||||
if (this.getRange() == 0 || !this.dragging || this.eventRepeater.isRepeating()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (x > this.displayX && x <= this.displayX + this.width) {
|
||||
if (y > this.displayY && y <= this.displayY + this.height) {
|
||||
this.currentScroll = (int) (y - this.displayY);
|
||||
this.currentScroll = this.minScroll + ((this.currentScroll * 2 * this.getRange() / this.height));
|
||||
this.currentScroll = (this.currentScroll + 1) >> 1;
|
||||
this.applyRange();
|
||||
}
|
||||
}
|
||||
// Compute the position of the mouse (adjusted for where it grabbed the handle,
|
||||
// so as if it grabbed
|
||||
// the upper edge of it) within the scrollable area of the track (minus the
|
||||
// handle height).
|
||||
double handleUpperEdgeY = y - this.displayY - this.dragYOffset;
|
||||
double availableHeight = this.height - HANDLE_HEIGHT;
|
||||
double position = MathHelper.clamp(handleUpperEdgeY / availableHeight, 0.0, 1.0);
|
||||
|
||||
this.currentScroll = this.minScroll + (int) Math.round(position * this.getRange());
|
||||
this.applyRange();
|
||||
}
|
||||
|
||||
public void wheel(double delta) {
|
||||
// Do nothing when there's no range
|
||||
if (getRange() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
delta = Math.max(Math.min(-delta, 1), -1);
|
||||
this.currentScroll += delta * this.pageSize;
|
||||
this.applyRange();
|
||||
}
|
||||
|
||||
/**
|
||||
* Ticks the scrollbar for the purposes of input-repeats (since mouse-downs are
|
||||
* not repeat-triggered), used to repeatedly page-up or page-down when the mouse
|
||||
* is held in the area above or below the scrollbar handle.
|
||||
*/
|
||||
public void tick() {
|
||||
this.eventRepeater.tick();
|
||||
}
|
||||
|
||||
private void pageUp() {
|
||||
this.currentScroll -= this.pageSize;
|
||||
this.applyRange();
|
||||
}
|
||||
|
||||
private void pageDown() {
|
||||
this.currentScroll += this.pageSize;
|
||||
this.applyRange();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.widget.button.Button;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
@@ -47,6 +48,7 @@ import appeng.api.config.StorageFilter;
|
||||
import appeng.api.config.TerminalStyle;
|
||||
import appeng.api.config.ViewItems;
|
||||
import appeng.api.config.YesNo;
|
||||
import appeng.client.gui.AEBaseScreen;
|
||||
import appeng.core.localization.ButtonToolTips;
|
||||
import appeng.util.EnumCycler;
|
||||
|
||||
@@ -89,9 +91,11 @@ public class SettingToggleButton<T extends Enum<T>> extends IconButton {
|
||||
registerApp(16 * 7, Settings.CONDENSER_OUTPUT, CondenserOutput.TRASH, ButtonToolTips.CondenserOutput,
|
||||
ButtonToolTips.Trash);
|
||||
registerApp(16 * 7 + 1, Settings.CONDENSER_OUTPUT, CondenserOutput.MATTER_BALLS,
|
||||
ButtonToolTips.CondenserOutput, ButtonToolTips.MatterBalls);
|
||||
ButtonToolTips.CondenserOutput,
|
||||
ButtonToolTips.MatterBalls.text(CondenserOutput.MATTER_BALLS.requiredPower));
|
||||
registerApp(16 * 7 + 2, Settings.CONDENSER_OUTPUT, CondenserOutput.SINGULARITY,
|
||||
ButtonToolTips.CondenserOutput, ButtonToolTips.Singularity);
|
||||
ButtonToolTips.CondenserOutput,
|
||||
ButtonToolTips.Singularity.text(CondenserOutput.SINGULARITY.requiredPower));
|
||||
|
||||
registerApp(16 * 9 + 1, Settings.ACCESS, AccessRestriction.READ, ButtonToolTips.IOMode,
|
||||
ButtonToolTips.Read);
|
||||
@@ -230,7 +234,13 @@ public class SettingToggleButton<T extends Enum<T>> extends IconButton {
|
||||
}
|
||||
|
||||
private void triggerPress() {
|
||||
boolean backwards = Minecraft.getInstance().mouseHelper.isRightDown();
|
||||
boolean backwards = false;
|
||||
// This isn't great, but we don't get any information about right-clicks
|
||||
// otherwise
|
||||
Screen currentScreen = Minecraft.getInstance().currentScreen;
|
||||
if (currentScreen instanceof AEBaseScreen) {
|
||||
backwards = ((AEBaseScreen<?>) currentScreen).isHandlingRightClick();
|
||||
}
|
||||
onPress.handle(this, backwards);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ public class TabButton extends Button implements ITooltip {
|
||||
public static final ResourceLocation TEXTURE_STATES = new ResourceLocation("appliedenergistics2",
|
||||
"textures/guis/states.png");
|
||||
private final ItemRenderer itemRenderer;
|
||||
private int hideEdge = 0;
|
||||
private boolean hideEdge;
|
||||
private int myIcon = -1;
|
||||
private ItemStack myItem;
|
||||
|
||||
@@ -71,14 +71,17 @@ public class TabButton extends Button implements ITooltip {
|
||||
|
||||
RenderSystem.enableAlphaTest();
|
||||
|
||||
int uv_x = (this.hideEdge > 0 ? 11 : 13);
|
||||
// Selects the button border from the sprite-sheet, where each type occupies a
|
||||
// 2x2 slot
|
||||
int uv_x = 8 + (this.hideEdge ? 0 : 2);
|
||||
int uv_y = 12 + (this.isFocused() ? 2 : 0);
|
||||
|
||||
final int offsetX = this.hideEdge > 0 ? 1 : 0;
|
||||
final int offsetX = this.hideEdge ? 1 : 0;
|
||||
|
||||
blit(matrixStack, this.x, this.y, uv_x * 16, 0, 25, 22);
|
||||
blit(matrixStack, this.x, this.y, uv_x * 16, uv_y * 16, 25, 22);
|
||||
|
||||
if (this.myIcon >= 0) {
|
||||
final int uv_y = this.myIcon / 16;
|
||||
uv_y = this.myIcon / 16;
|
||||
uv_x = this.myIcon - uv_y * 16;
|
||||
|
||||
blit(matrixStack, offsetX + this.x + 3, this.y + 3, uv_x * 16, uv_y * 16, 16, 16);
|
||||
@@ -128,11 +131,11 @@ public class TabButton extends Button implements ITooltip {
|
||||
return this.visible;
|
||||
}
|
||||
|
||||
public int getHideEdge() {
|
||||
public boolean getHideEdge() {
|
||||
return this.hideEdge;
|
||||
}
|
||||
|
||||
public void setHideEdge(final int hideEdge) {
|
||||
public void setHideEdge(final boolean hideEdge) {
|
||||
this.hideEdge = hideEdge;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package appeng.client.gui.widgets;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
/**
|
||||
* Displays a small icon that shows validation errors for some input control.
|
||||
*/
|
||||
public class ValidationIcon extends IconButton {
|
||||
|
||||
private final List<ITextComponent> tooltip = new ArrayList<>();
|
||||
|
||||
private boolean valid;
|
||||
|
||||
public ValidationIcon(int x, int y) {
|
||||
super(x, y, btn -> {
|
||||
});
|
||||
setDisableBackground(true);
|
||||
setDisableClickSound(true);
|
||||
setHalfSize(true);
|
||||
}
|
||||
|
||||
public void setValid(boolean valid) {
|
||||
setVisibility(!valid);
|
||||
if (valid) {
|
||||
this.tooltip.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public void setTooltip(List<ITextComponent> lines) {
|
||||
this.tooltip.clear();
|
||||
this.tooltip.addAll(lines);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getIconIndex() {
|
||||
return 16 * 8;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean changeFocus(boolean flag) {
|
||||
return false; // Cannot focus this element
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderToolTip(MatrixStack matrices, int mouseX, int mouseY) {
|
||||
if (this.tooltip.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Minecraft client = Minecraft.getInstance();
|
||||
Screen screen = client.currentScreen;
|
||||
if (screen == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
screen.func_243308_b(matrices, this.tooltip, x, y);
|
||||
}
|
||||
}
|
||||
@@ -41,11 +41,6 @@ import appeng.fluids.util.FluidSorters;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.prioritylist.IPartitionList;
|
||||
|
||||
/**
|
||||
* @author BrockWS
|
||||
* @version rv6 - 22/05/2018
|
||||
* @since rv6 22/05/2018
|
||||
*/
|
||||
public class FluidRepo {
|
||||
private final IItemList<IAEFluidStack> list = Api.instance().storage().getStorageChannel(IFluidStorageChannel.class)
|
||||
.createList();
|
||||
|
||||
@@ -21,23 +21,22 @@ package appeng.client.me;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.inventory.container.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.items.SlotItemHandler;
|
||||
|
||||
import appeng.api.storage.data.IAEFluidStack;
|
||||
import appeng.fluids.container.slots.IMEFluidSlot;
|
||||
|
||||
/**
|
||||
* @author BrockWS
|
||||
* @version rv6 - 22/05/2018
|
||||
* @since rv6 22/05/2018
|
||||
*/
|
||||
public class SlotFluidME extends SlotItemHandler implements IMEFluidSlot {
|
||||
public class SlotFluidME extends Slot implements IMEFluidSlot {
|
||||
|
||||
private InternalFluidSlotME slot;
|
||||
private static final IInventory EMPTY_INVENTORY = new Inventory(0);
|
||||
|
||||
private final InternalFluidSlotME slot;
|
||||
|
||||
public SlotFluidME(InternalFluidSlotME slot) {
|
||||
super(null, 0, slot.getxPosition(), slot.getyPosition());
|
||||
super(EMPTY_INVENTORY, 0, slot.getxPosition(), slot.getyPosition());
|
||||
this.slot = slot;
|
||||
}
|
||||
|
||||
@@ -50,7 +49,7 @@ public class SlotFluidME extends SlotItemHandler implements IMEFluidSlot {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isItemValid(final ItemStack par1ItemStack) {
|
||||
public boolean isItemValid(final ItemStack stack) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -69,7 +68,7 @@ public class SlotFluidME extends SlotItemHandler implements IMEFluidSlot {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putStack(final ItemStack par1ItemStack) {
|
||||
public void putStack(final ItemStack stack) {
|
||||
|
||||
}
|
||||
|
||||
@@ -85,7 +84,7 @@ public class SlotFluidME extends SlotItemHandler implements IMEFluidSlot {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canTakeStack(final PlayerEntity par1PlayerEntity) {
|
||||
public boolean canTakeStack(final PlayerEntity player) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,23 +19,27 @@
|
||||
package appeng.client.me;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.inventory.container.Slot;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraftforge.items.SlotItemHandler;
|
||||
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
|
||||
public class SlotME extends SlotItemHandler {
|
||||
public class SlotME extends Slot {
|
||||
|
||||
private final InternalSlotME mySlot;
|
||||
private static final IInventory EMPTY_INVENTORY = new Inventory(0);
|
||||
|
||||
public SlotME(final InternalSlotME me) {
|
||||
super(null, 0, me.getxPosition(), me.getyPosition());
|
||||
this.mySlot = me;
|
||||
private final InternalSlotME slot;
|
||||
|
||||
public SlotME(final InternalSlotME slot) {
|
||||
super(EMPTY_INVENTORY, 0, slot.getxPosition(), slot.getyPosition());
|
||||
this.slot = slot;
|
||||
}
|
||||
|
||||
public IAEItemStack getAEStack() {
|
||||
if (this.mySlot.hasPower()) {
|
||||
return this.mySlot.getAEStack();
|
||||
if (this.slot.hasPower()) {
|
||||
return this.slot.getAEStack();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -47,15 +51,15 @@ public class SlotME extends SlotItemHandler {
|
||||
|
||||
@Override
|
||||
public ItemStack getStack() {
|
||||
if (this.mySlot.hasPower()) {
|
||||
return this.mySlot.getStack();
|
||||
if (this.slot.hasPower()) {
|
||||
return this.slot.getStack();
|
||||
}
|
||||
return ItemStack.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getHasStack() {
|
||||
if (this.mySlot.hasPower()) {
|
||||
if (this.slot.hasPower()) {
|
||||
return !this.getStack().isEmpty();
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -47,8 +47,8 @@ public abstract class DelegateBakedModel implements IBakedModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean func_230044_c_() {
|
||||
return baseModel.func_230044_c_();
|
||||
public boolean isSideLit() {
|
||||
return baseModel.isSideLit();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -60,7 +60,7 @@ public class DummyFluidBakedModel implements IBakedModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean func_230044_c_() {
|
||||
public boolean isSideLit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,8 +73,8 @@ public class DummyFluidDispatcherBakedModel extends DelegateBakedModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean func_230044_c_() {
|
||||
return getBaseModel().func_230044_c_();
|
||||
public boolean isSideLit() {
|
||||
return getBaseModel().isSideLit();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -86,7 +86,7 @@ public class DummyFluidDispatcherBakedModel extends DelegateBakedModel {
|
||||
public ItemOverrideList getOverrides() {
|
||||
return new ItemOverrideList() {
|
||||
@Override
|
||||
public IBakedModel func_239290_a_(IBakedModel originalModel, ItemStack stack, ClientWorld world,
|
||||
public IBakedModel getOverrideModel(IBakedModel originalModel, ItemStack stack, ClientWorld world,
|
||||
LivingEntity entity) {
|
||||
if (!(stack.getItem() instanceof FluidDummyItem)) {
|
||||
return originalModel;
|
||||
|
||||
@@ -80,7 +80,7 @@ public class FacadeBakedItemModel extends DelegateBakedModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean func_230044_c_() {
|
||||
public boolean isSideLit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ public class FacadeDispatcherBakedModel extends DelegateBakedModel {
|
||||
public ItemOverrideList getOverrides() {
|
||||
return new ItemOverrideList() {
|
||||
@Override
|
||||
public IBakedModel func_239290_a_(IBakedModel originalModel, ItemStack stack, ClientWorld world,
|
||||
public IBakedModel getOverrideModel(IBakedModel originalModel, ItemStack stack, ClientWorld world,
|
||||
LivingEntity entity) {
|
||||
if (!(stack.getItem() instanceof FacadeItem)) {
|
||||
return originalModel;
|
||||
|
||||
@@ -342,7 +342,7 @@ class CableBuilder {
|
||||
this.addBigCoveredCableSizedCube(facing, cubeBuilder);
|
||||
|
||||
// Render the channel indicators brightly lit at night
|
||||
cubeBuilder.setRenderFullBright(true);
|
||||
cubeBuilder.setEmissiveMaterial(true);
|
||||
|
||||
cubeBuilder.setTexture(oddChannel);
|
||||
cubeBuilder.setColorRGB(cableColor.blackVariant);
|
||||
@@ -353,14 +353,14 @@ class CableBuilder {
|
||||
this.addBigCoveredCableSizedCube(facing, cubeBuilder);
|
||||
|
||||
// Reset back to normal rendering for the rest
|
||||
cubeBuilder.setRenderFullBright(false);
|
||||
cubeBuilder.setEmissiveMaterial(false);
|
||||
cubeBuilder.setTexture(texture);
|
||||
}
|
||||
|
||||
addCoveredCableSizedCube(facing, cubeBuilder);
|
||||
|
||||
// Render the channel indicators brightly lit at night
|
||||
cubeBuilder.setRenderFullBright(true);
|
||||
cubeBuilder.setEmissiveMaterial(true);
|
||||
|
||||
cubeBuilder.setTexture(oddChannel);
|
||||
cubeBuilder.setColorRGB(cableColor.blackVariant);
|
||||
@@ -369,6 +369,9 @@ class CableBuilder {
|
||||
cubeBuilder.setTexture(evenChannel);
|
||||
cubeBuilder.setColorRGB(cableColor.whiteVariant);
|
||||
addCoveredCableSizedCube(facing, cubeBuilder);
|
||||
|
||||
// Reset back to default
|
||||
cubeBuilder.setEmissiveMaterial(false);
|
||||
}
|
||||
|
||||
public void addStraightSmartConnection(Direction facing, AEColor cableColor, int channels,
|
||||
@@ -386,7 +389,7 @@ class CableBuilder {
|
||||
TextureAtlasSprite evenChannel = this.smartCableTextures.getEvenTextureForChannels(channels);
|
||||
|
||||
// Render the channel indicators brightly lit at night
|
||||
cubeBuilder.setRenderFullBright(true);
|
||||
cubeBuilder.setEmissiveMaterial(true);
|
||||
|
||||
cubeBuilder.setTexture(oddChannel);
|
||||
cubeBuilder.setColorRGB(cableColor.blackVariant);
|
||||
@@ -395,6 +398,9 @@ class CableBuilder {
|
||||
cubeBuilder.setTexture(evenChannel);
|
||||
cubeBuilder.setColorRGB(cableColor.whiteVariant);
|
||||
addStraightCoveredCableSizedCube(facing, cubeBuilder);
|
||||
|
||||
// Reset back to default
|
||||
cubeBuilder.setEmissiveMaterial(false);
|
||||
}
|
||||
|
||||
public void addConstrainedSmartConnection(Direction facing, AEColor cableColor, int distanceFromEdge, int channels,
|
||||
@@ -417,7 +423,7 @@ class CableBuilder {
|
||||
TextureAtlasSprite evenChannel = this.smartCableTextures.getEvenTextureForChannels(channels);
|
||||
|
||||
// Render the channel indicators brightly lit at night
|
||||
cubeBuilder.setRenderFullBright(true);
|
||||
cubeBuilder.setEmissiveMaterial(true);
|
||||
|
||||
cubeBuilder.setTexture(oddChannel);
|
||||
cubeBuilder.setColorRGB(cableColor.blackVariant);
|
||||
@@ -426,6 +432,9 @@ class CableBuilder {
|
||||
cubeBuilder.setTexture(evenChannel);
|
||||
cubeBuilder.setColorRGB(cableColor.whiteVariant);
|
||||
addCoveredCableSizedCube(facing, distanceFromEdge, cubeBuilder);
|
||||
|
||||
// Reset back to default
|
||||
cubeBuilder.setEmissiveMaterial(false);
|
||||
}
|
||||
|
||||
public void addDenseCoveredConnection(Direction facing, AEColor cableColor, AECableType connectionType,
|
||||
@@ -449,7 +458,7 @@ class CableBuilder {
|
||||
addDenseCableSizedCube(facing, cubeBuilder);
|
||||
|
||||
// Reset back to normal rendering for the rest
|
||||
cubeBuilder.setRenderFullBright(false);
|
||||
cubeBuilder.setEmissiveMaterial(false);
|
||||
cubeBuilder.setTexture(texture);
|
||||
}
|
||||
|
||||
@@ -485,7 +494,7 @@ class CableBuilder {
|
||||
TextureAtlasSprite evenChannel = this.smartCableTextures.getEvenTextureForChannels(channels);
|
||||
|
||||
// Render the channel indicators brightly lit at night
|
||||
cubeBuilder.setRenderFullBright(true);
|
||||
cubeBuilder.setEmissiveMaterial(true);
|
||||
|
||||
cubeBuilder.setTexture(oddChannel);
|
||||
cubeBuilder.setColorRGB(cableColor.blackVariant);
|
||||
@@ -496,7 +505,7 @@ class CableBuilder {
|
||||
addDenseCableSizedCube(facing, cubeBuilder);
|
||||
|
||||
// Reset back to normal rendering for the rest
|
||||
cubeBuilder.setRenderFullBright(false);
|
||||
cubeBuilder.setEmissiveMaterial(false);
|
||||
cubeBuilder.setTexture(texture);
|
||||
}
|
||||
|
||||
@@ -529,7 +538,7 @@ class CableBuilder {
|
||||
TextureAtlasSprite evenChannel = this.smartCableTextures.getEvenTextureForChannels(channels);
|
||||
|
||||
// Render the channel indicators brightly lit at night
|
||||
cubeBuilder.setRenderFullBright(true);
|
||||
cubeBuilder.setEmissiveMaterial(true);
|
||||
|
||||
cubeBuilder.setTexture(oddChannel);
|
||||
cubeBuilder.setColorRGB(cableColor.blackVariant);
|
||||
@@ -538,6 +547,9 @@ class CableBuilder {
|
||||
cubeBuilder.setTexture(evenChannel);
|
||||
cubeBuilder.setColorRGB(cableColor.whiteVariant);
|
||||
addStraightDenseCableSizedCube(facing, cubeBuilder);
|
||||
|
||||
// Reset back to default
|
||||
cubeBuilder.setEmissiveMaterial(false);
|
||||
}
|
||||
|
||||
private static void addDenseCableSizedCube(Direction facing, CubeBuilder cubeBuilder) {
|
||||
|
||||
@@ -21,7 +21,6 @@ package appeng.client.render.cablebus;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -30,6 +29,11 @@ import java.util.Random;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
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.BlockState;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.client.renderer.model.BakedQuad;
|
||||
@@ -50,7 +54,10 @@ import appeng.api.util.AEColor;
|
||||
|
||||
public class CableBusBakedModel implements IBakedModel {
|
||||
|
||||
private static final Map<CableBusRenderState, List<BakedQuad>> CABLE_MODEL_CACHE = new HashMap<>();
|
||||
// The number of quads overall that will be cached
|
||||
private static final int CACHE_QUAD_COUNT = 5000;
|
||||
|
||||
private final LoadingCache<CableBusRenderState, List<BakedQuad>> cableModelCache;
|
||||
|
||||
private final CableBuilder cableBuilder;
|
||||
|
||||
@@ -66,6 +73,17 @@ public class CableBusBakedModel implements IBakedModel {
|
||||
this.facadeBuilder = facadeBuilder;
|
||||
this.partModels = partModels;
|
||||
this.particleTexture = particleTexture;
|
||||
this.cableModelCache = CacheBuilder.newBuilder()//
|
||||
.maximumWeight(CACHE_QUAD_COUNT)//
|
||||
.weigher((Weigher<CableBusRenderState, List<BakedQuad>>) (key, value) -> value.size())//
|
||||
.build(new CacheLoader<CableBusRenderState, List<BakedQuad>>() {
|
||||
@Override
|
||||
public List<BakedQuad> load(CableBusRenderState renderState) {
|
||||
final List<BakedQuad> model = new ArrayList<>();
|
||||
addCableQuads(renderState, model);
|
||||
return model;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -92,11 +110,7 @@ public class CableBusBakedModel implements IBakedModel {
|
||||
if (layer == RenderType.getCutout()) {
|
||||
|
||||
// First, handle the cable at the center of the cable bus
|
||||
final List<BakedQuad> cableModel = CABLE_MODEL_CACHE.computeIfAbsent(renderState, k -> {
|
||||
final List<BakedQuad> model = new ArrayList<>();
|
||||
this.addCableQuads(renderState, model);
|
||||
return model;
|
||||
});
|
||||
final List<BakedQuad> cableModel = cableModelCache.getUnchecked(renderState);
|
||||
quads.addAll(cableModel);
|
||||
|
||||
// Then handle attachments
|
||||
@@ -128,6 +142,7 @@ public class CableBusBakedModel implements IBakedModel {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.facadeBuilder.buildFacadeQuads(layer, renderState, rand, quads, this.partModels::get);
|
||||
|
||||
return quads;
|
||||
@@ -313,12 +328,12 @@ public class CableBusBakedModel implements IBakedModel {
|
||||
|
||||
@Override
|
||||
public boolean isGui3d() {
|
||||
return false;
|
||||
return false; // This model is never used in an UI
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean func_230044_c_() {
|
||||
return false;// TODO
|
||||
public boolean isSideLit() {
|
||||
return false; // This model is never used in an UI
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -341,8 +356,4 @@ public class CableBusBakedModel implements IBakedModel {
|
||||
return ItemOverrideList.EMPTY;
|
||||
}
|
||||
|
||||
public static void clearCache() {
|
||||
CABLE_MODEL_CACHE.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,9 @@
|
||||
|
||||
package appeng.client.render.cablebus;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
@@ -37,6 +39,7 @@ import net.minecraftforge.client.model.IModelConfiguration;
|
||||
import appeng.api.util.AEColor;
|
||||
import appeng.client.render.BasicUnbakedModel;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.AppEng;
|
||||
import appeng.core.features.registries.PartModels;
|
||||
|
||||
/**
|
||||
@@ -44,6 +47,8 @@ import appeng.core.features.registries.PartModels;
|
||||
*/
|
||||
public class CableBusModel implements BasicUnbakedModel<CableBusModel> {
|
||||
|
||||
public static final ResourceLocation TRANSLUCENT_FACADE_MODEL = AppEng.makeId("part/translucent_facade");
|
||||
|
||||
private final PartModels partModels;
|
||||
|
||||
public CableBusModel(PartModels partModels) {
|
||||
@@ -53,7 +58,9 @@ public class CableBusModel implements BasicUnbakedModel<CableBusModel> {
|
||||
@Override
|
||||
public Collection<ResourceLocation> getModelDependencies() {
|
||||
partModels.setInitialized(true);
|
||||
return partModels.getModels();
|
||||
List<ResourceLocation> models = new ArrayList<>(partModels.getModels());
|
||||
models.add(TRANSLUCENT_FACADE_MODEL);
|
||||
return models;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -68,7 +75,11 @@ public class CableBusModel implements BasicUnbakedModel<CableBusModel> {
|
||||
Map<ResourceLocation, IBakedModel> partModels = this.loadPartModels(bakery, spriteGetter, modelTransform);
|
||||
|
||||
CableBuilder cableBuilder = new CableBuilder(spriteGetter);
|
||||
FacadeBuilder facadeBuilder = new FacadeBuilder();
|
||||
|
||||
IBakedModel translucentFacadeModel = bakery.getBakedModel(TRANSLUCENT_FACADE_MODEL, modelTransform,
|
||||
spriteGetter);
|
||||
|
||||
FacadeBuilder facadeBuilder = new FacadeBuilder(translucentFacadeModel);
|
||||
|
||||
// This should normally not be used, but we *have* to provide a particle texture
|
||||
// or otherwise damage models will
|
||||
|
||||
@@ -18,7 +18,6 @@ public class CableBusModelLoader implements IModelLoader<CableBusModel> {
|
||||
|
||||
@Override
|
||||
public void onResourceManagerReload(IResourceManager resourceManager) {
|
||||
CableBusBakedModel.clearCache();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -52,7 +52,7 @@ public class CubeBuilder {
|
||||
|
||||
private boolean useStandardUV = false;
|
||||
|
||||
private boolean renderFullBright;
|
||||
private boolean emissiveMaterial;
|
||||
|
||||
public CubeBuilder(List<BakedQuad> output) {
|
||||
this.output = output;
|
||||
@@ -379,7 +379,7 @@ public class CubeBuilder {
|
||||
if (e.getIndex() == 0) {
|
||||
builder.put(i, u, v);
|
||||
break;
|
||||
} else if (e.getIndex() == 2 && renderFullBright) {
|
||||
} else if (e.getIndex() == 2 && emissiveMaterial) {
|
||||
// Force Brightness to 15, this is for full bright mode
|
||||
// this vertex element will only be present in that case
|
||||
final float lightMapU = (float) (15 * 0x20) / 0xFFFF;
|
||||
@@ -434,8 +434,8 @@ public class CubeBuilder {
|
||||
this.setColorRGB((int) (r * 255) << 16 | (int) (g * 255) << 8 | (int) (b * 255));
|
||||
}
|
||||
|
||||
public void setRenderFullBright(boolean renderFullBright) {
|
||||
this.renderFullBright = renderFullBright;
|
||||
public void setEmissiveMaterial(boolean renderFullBright) {
|
||||
this.emissiveMaterial = renderFullBright;
|
||||
}
|
||||
|
||||
public void setCustomUv(Direction facing, float u1, float v1, float u2, float v2) {
|
||||
|
||||
@@ -20,6 +20,7 @@ package appeng.client.render.cablebus;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
@@ -29,6 +30,8 @@ import java.util.function.Function;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.BlockRendererDispatcher;
|
||||
@@ -88,6 +91,9 @@ public class FacadeBuilder {
|
||||
new AxisAlignedBB(0.0, 0.0, 0.0, THIN_THICKNESS, 1.0, 1.0),
|
||||
new AxisAlignedBB(1.0 - THIN_THICKNESS, 0.0, 0.0, 1.0, 1.0, 1.0) };
|
||||
|
||||
// Pre-rotated transparent facade quads
|
||||
private final Map<Direction, List<BakedQuad>> transparentFacadeQuads;
|
||||
|
||||
private final ThreadLocal<BakedPipeline> pipelines = ThreadLocal.withInitial(() -> BakedPipeline.builder()
|
||||
// Clamper is responsible for clamping the vertex to the bounds specified.
|
||||
.addElement("clamper", QuadClamper.FACTORY)
|
||||
@@ -104,6 +110,29 @@ public class FacadeBuilder {
|
||||
);
|
||||
private final ThreadLocal<Quad> collectors = ThreadLocal.withInitial(Quad::new);
|
||||
|
||||
public FacadeBuilder() {
|
||||
// This constructor is used for item models where transparent facades are not a
|
||||
// concern
|
||||
this.transparentFacadeQuads = new EnumMap<>(Direction.class);
|
||||
for (Direction facing : Direction.values()) {
|
||||
this.transparentFacadeQuads.put(facing, Collections.emptyList());
|
||||
}
|
||||
}
|
||||
|
||||
public FacadeBuilder(IBakedModel transparentFacadeModel) {
|
||||
// Pre-rotate the transparent facade model to all possible sides so that we can
|
||||
// add it quicker later
|
||||
List<BakedQuad> partQuads = transparentFacadeModel.getQuads(null, null, new Random(), EmptyModelData.INSTANCE);
|
||||
this.transparentFacadeQuads = new EnumMap<>(Direction.class);
|
||||
|
||||
for (Direction facing : Direction.values()) {
|
||||
// Rotate quads accordingly
|
||||
QuadRotator rotator = new QuadRotator();
|
||||
List<BakedQuad> rotated = rotator.rotateQuads(partQuads, facing, Direction.UP);
|
||||
this.transparentFacadeQuads.put(facing, ImmutableList.copyOf(rotated));
|
||||
}
|
||||
}
|
||||
|
||||
public void buildFacadeQuads(RenderType layer, CableBusRenderState renderState, Random rand, List<BakedQuad> quads,
|
||||
Function<ResourceLocation, IBakedModel> modelLookup) {
|
||||
BakedPipeline pipeline = this.pipelines.get();
|
||||
@@ -130,14 +159,20 @@ public class FacadeBuilder {
|
||||
Direction.UP));
|
||||
}
|
||||
}
|
||||
// If we are forcing transparency and this isn't the Translucent layer.
|
||||
if (transparent && layer != RenderType.getTranslucent()) {
|
||||
|
||||
// When we're forcing transparent facades, add a "border" model that indicates
|
||||
// where the facade is,
|
||||
// But otherwise skip the rest.
|
||||
if (transparent) {
|
||||
if (layer != RenderType.getCutout()) {
|
||||
quads.addAll(transparentFacadeQuads.get(side));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
BlockState blockState = facadeRenderState.getSourceBlock();
|
||||
// If we aren't forcing transparency let the block decide if it should render.
|
||||
if (!transparent && layer != null) {
|
||||
if (layer != null) {
|
||||
if (!RenderTypeLookup.canRenderInLayer(blockState, layer)) {
|
||||
continue;
|
||||
}
|
||||
@@ -198,7 +233,7 @@ public class FacadeBuilder {
|
||||
List<BakedQuad> modelQuads = new ArrayList<>();
|
||||
// If we are forcing transparent facades, fake the render layer, and grab all
|
||||
// quads.
|
||||
if (transparent || layer == null) {
|
||||
if (layer == null) {
|
||||
for (RenderType forcedLayer : RenderType.getBlockRenderTypes()) {
|
||||
// Check if the block renders on the layer we want to force.
|
||||
if (RenderTypeLookup.canRenderInLayer(blockState, forcedLayer)) {
|
||||
|
||||
@@ -49,7 +49,7 @@ public class P2PTunnelFrequencyBakedModel implements IDynamicBakedModel {
|
||||
|
||||
cb.setTexture(this.texture);
|
||||
cb.useStandardUV();
|
||||
cb.setRenderFullBright(active);
|
||||
cb.setEmissiveMaterial(active);
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
final int[] offs = QUAD_OFFSETS[i];
|
||||
@@ -70,6 +70,10 @@ public class P2PTunnelFrequencyBakedModel implements IDynamicBakedModel {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Reset back to default
|
||||
cb.setEmissiveMaterial(false);
|
||||
|
||||
return cb.getOutput();
|
||||
}
|
||||
|
||||
@@ -96,7 +100,7 @@ public class P2PTunnelFrequencyBakedModel implements IDynamicBakedModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean func_230044_c_() {
|
||||
public boolean isSideLit() {
|
||||
return false;// TODO
|
||||
}
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ abstract class CraftingCubeBakedModel implements IDynamicBakedModel {
|
||||
return quads;
|
||||
}
|
||||
|
||||
private void addRing(CubeBuilder builder, @Nullable Direction side, EnumSet<Direction> connections) {
|
||||
private void addRing(CubeBuilder builder, Direction side, EnumSet<Direction> connections) {
|
||||
// Fill in the corners
|
||||
builder.setTexture(this.ringCorner);
|
||||
this.addCornerCap(builder, connections, side, Direction.UP, Direction.EAST, Direction.NORTH);
|
||||
@@ -276,7 +276,7 @@ abstract class CraftingCubeBakedModel implements IDynamicBakedModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean func_230044_c_() {
|
||||
public boolean isSideLit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,8 +86,8 @@ public class EncodedPatternBakedModel extends DelegateBakedModel {
|
||||
// This determines diffuse lighting in the UI, and since we want to render
|
||||
// the outputModel in the UI, we need to use it's setting here
|
||||
@Override
|
||||
public boolean func_230044_c_() {
|
||||
return outputModel.func_230044_c_();
|
||||
public boolean isSideLit() {
|
||||
return outputModel.isSideLit();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -112,7 +112,7 @@ public class EncodedPatternBakedModel extends DelegateBakedModel {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IBakedModel func_239290_a_(IBakedModel originalModel, ItemStack stack, @Nullable ClientWorld world,
|
||||
public IBakedModel getOverrideModel(IBakedModel originalModel, ItemStack stack, @Nullable ClientWorld world,
|
||||
@Nullable LivingEntity entity) {
|
||||
boolean shiftHeld = Screen.hasShiftDown();
|
||||
if (shiftHeld) {
|
||||
@@ -122,12 +122,12 @@ public class EncodedPatternBakedModel extends DelegateBakedModel {
|
||||
IBakedModel realModel = Minecraft.getInstance().getItemRenderer().getItemModelMesher()
|
||||
.getItemModel(output);
|
||||
// Give the item model a chance to handle the overrides as well
|
||||
realModel = realModel.getOverrides().func_239290_a_(realModel, output, world, entity);
|
||||
realModel = realModel.getOverrides().getOverrideModel(realModel, output, world, entity);
|
||||
return new ShiftHoldingModelWrapper(getBaseModel(), realModel);
|
||||
}
|
||||
}
|
||||
|
||||
return getBaseModel().getOverrides().func_239290_a_(originalModel, stack, world, entity);
|
||||
return getBaseModel().getOverrides().getOverrideModel(originalModel, stack, world, entity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,8 +51,10 @@ class LightBakedModel extends CraftingCubeBakedModel {
|
||||
builder.addCube(x1, y1, z1, x2, y2, z2);
|
||||
|
||||
boolean powered = state.get(AbstractCraftingUnitBlock.POWERED);
|
||||
builder.setRenderFullBright(powered);
|
||||
builder.setEmissiveMaterial(powered);
|
||||
builder.setTexture(this.lightTexture);
|
||||
builder.addCube(x1, y1, z1, x2, y2, z2);
|
||||
// Reset back to default
|
||||
builder.setEmissiveMaterial(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ public class MonitorBakedModel extends CraftingCubeBakedModel {
|
||||
AEColor color = getColor(modelData);
|
||||
boolean powered = state.get(CraftingMonitorBlock.POWERED);
|
||||
|
||||
builder.setRenderFullBright(powered);
|
||||
builder.setEmissiveMaterial(powered);
|
||||
|
||||
builder.setColorRGB(color.whiteVariant);
|
||||
builder.setTexture(this.lightBrightTexture);
|
||||
@@ -92,6 +92,8 @@ public class MonitorBakedModel extends CraftingCubeBakedModel {
|
||||
builder.setTexture(this.lightDarkTexture);
|
||||
builder.addCube(x1, y1, z1, x2, y2, z2);
|
||||
|
||||
// Reset back to default
|
||||
builder.setEmissiveMaterial(false);
|
||||
}
|
||||
|
||||
private static AEColor getColor(IModelData modelData) {
|
||||
|
||||
@@ -107,7 +107,7 @@ public class AutoRotatingBakedModel extends DelegateBakedModel {
|
||||
// when piping it
|
||||
// to the AO lighter, thus fixing our problem.
|
||||
BakedQuad packedQuad = new BakedQuad(unpackedQuad.getVertexData(), quad.getTintIndex(),
|
||||
unpackedQuad.getFace(), quad.func_187508_a(), quad.func_239287_f_());
|
||||
unpackedQuad.getFace(), quad.getSprite(), quad.applyDiffuseLighting());
|
||||
rotated.add(packedQuad);
|
||||
}
|
||||
return rotated;
|
||||
|
||||
@@ -120,7 +120,7 @@ class BiometricCardBakedModel implements IBakedModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean func_230044_c_() {
|
||||
public boolean isSideLit() {
|
||||
return false;// TODO
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ class BiometricCardBakedModel implements IBakedModel {
|
||||
public ItemOverrideList getOverrides() {
|
||||
return new ItemOverrideList() {
|
||||
@Override
|
||||
public IBakedModel func_239290_a_(IBakedModel originalModel, ItemStack stack, ClientWorld world,
|
||||
public IBakedModel getOverrideModel(IBakedModel originalModel, ItemStack stack, ClientWorld world,
|
||||
LivingEntity entity) {
|
||||
String username = "";
|
||||
if (stack.getItem() instanceof IBiometricCard) {
|
||||
|
||||
@@ -50,19 +50,19 @@ class ColorApplicatorBakedModel implements IBakedModel {
|
||||
for (BakedQuad quad : quads) {
|
||||
int tint;
|
||||
|
||||
if (quad.func_187508_a() == texDark) {
|
||||
if (quad.getSprite() == texDark) {
|
||||
tint = 1;
|
||||
} else if (quad.func_187508_a() == texMedium) {
|
||||
} else if (quad.getSprite() == texMedium) {
|
||||
tint = 2;
|
||||
} else if (quad.func_187508_a() == texBright) {
|
||||
} else if (quad.getSprite() == texBright) {
|
||||
tint = 3;
|
||||
} else {
|
||||
result.add(quad);
|
||||
continue;
|
||||
}
|
||||
|
||||
BakedQuad newQuad = new BakedQuad(quad.getVertexData(), tint, quad.getFace(), quad.func_187508_a(),
|
||||
quad.func_239287_f_());
|
||||
BakedQuad newQuad = new BakedQuad(quad.getVertexData(), tint, quad.getFace(), quad.getSprite(),
|
||||
quad.applyDiffuseLighting());
|
||||
result.add(newQuad);
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ class ColorApplicatorBakedModel implements IBakedModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean func_230044_c_() {
|
||||
public boolean isSideLit() {
|
||||
return false;// TODO
|
||||
}
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ class GlassBakedModel implements IDynamicBakedModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean func_230044_c_() {
|
||||
public boolean isSideLit() {
|
||||
// TODO: Forge: Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ class MemoryCardBakedModel implements IBakedModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean func_230044_c_() {
|
||||
public boolean isSideLit() {
|
||||
return false;// TODO
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ class MemoryCardBakedModel implements IBakedModel {
|
||||
public ItemOverrideList getOverrides() {
|
||||
return new ItemOverrideList() {
|
||||
@Override
|
||||
public IBakedModel func_239290_a_(IBakedModel originalModel, ItemStack stack, ClientWorld world,
|
||||
public IBakedModel getOverrideModel(IBakedModel originalModel, ItemStack stack, ClientWorld world,
|
||||
LivingEntity entity) {
|
||||
try {
|
||||
if (stack.getItem() instanceof IMemoryCard) {
|
||||
|
||||
@@ -122,7 +122,7 @@ public class SkyCompassBakedModel implements IDynamicBakedModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean func_230044_c_() {
|
||||
public boolean isSideLit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ public class SkyCompassBakedModel implements IDynamicBakedModel {
|
||||
*/
|
||||
return new ItemOverrideList() {
|
||||
@Override
|
||||
public IBakedModel func_239290_a_(IBakedModel originalModel, ItemStack stack, @Nullable ClientWorld world,
|
||||
public IBakedModel getOverrideModel(IBakedModel originalModel, ItemStack stack, @Nullable ClientWorld world,
|
||||
@Nullable LivingEntity entity) {
|
||||
// FIXME: This check prevents compasses being held by OTHERS from getting the
|
||||
// rotation, BUT do we actually still need this???
|
||||
|
||||
@@ -117,7 +117,7 @@ class SpatialPylonBakedModel implements IDynamicBakedModel {
|
||||
|
||||
if ((flags
|
||||
& SpatialPylonTileEntity.DISPLAY_POWERED_ENABLED) == SpatialPylonTileEntity.DISPLAY_POWERED_ENABLED) {
|
||||
builder.setRenderFullBright(true);
|
||||
builder.setEmissiveMaterial(true);
|
||||
}
|
||||
|
||||
builder.setTextures(this.textures.get(getTextureTypeFromSideInside(flags, ori, Direction.UP)),
|
||||
@@ -135,6 +135,9 @@ class SpatialPylonBakedModel implements IDynamicBakedModel {
|
||||
builder.addCube(0, 0, 0, 16, 16, 16);
|
||||
}
|
||||
|
||||
// Reset back to default
|
||||
builder.setEmissiveMaterial(false);
|
||||
|
||||
return builder.getOutput();
|
||||
}
|
||||
|
||||
@@ -178,7 +181,7 @@ class SpatialPylonBakedModel implements IDynamicBakedModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean func_230044_c_() {
|
||||
public boolean isSideLit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -142,14 +142,14 @@ public class ChestTileEntityRenderer extends TileEntityRenderer<ChestTileEntity>
|
||||
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand,
|
||||
@Nonnull IModelData extraData) {
|
||||
if (side != null) {
|
||||
side = r.rotate(side); // This fixes the incorrect lightmap position
|
||||
side = r.resultingRotate(side); // This fixes the incorrect lightmap position
|
||||
}
|
||||
List<BakedQuad> quads = new ArrayList<>(super.getQuads(state, side, rand, extraData));
|
||||
|
||||
for (int i = 0; i < quads.size(); i++) {
|
||||
BakedQuad quad = quads.get(i);
|
||||
quads.set(i, new BakedQuad(quad.getVertexData(), quad.getTintIndex(), r.rotate(quad.getFace()),
|
||||
quad.func_187508_a(), quad.func_239287_f_()));
|
||||
quad.getSprite(), quad.applyDiffuseLighting()));
|
||||
}
|
||||
|
||||
return quads;
|
||||
|
||||
@@ -65,10 +65,8 @@ import appeng.container.slot.PlayerInvSlot;
|
||||
import appeng.core.AELog;
|
||||
import appeng.core.Api;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.ConfigValuePacket;
|
||||
import appeng.core.sync.packets.InventoryActionPacket;
|
||||
import appeng.core.sync.packets.TargetItemStackPacket;
|
||||
import appeng.helpers.ICustomNameObject;
|
||||
import appeng.helpers.InventoryAction;
|
||||
import appeng.me.helpers.PlayerSource;
|
||||
import appeng.util.InventoryAdaptor;
|
||||
@@ -86,11 +84,9 @@ public abstract class AEBaseContainer extends Container {
|
||||
private final IGuiItemObject obj;
|
||||
private final HashMap<Integer, SyncData> syncData = new HashMap<>();
|
||||
private boolean isContainerValid = true;
|
||||
private String customName;
|
||||
private ContainerLocator locator;
|
||||
private IMEInventoryHandler<IAEItemStack> cellInv;
|
||||
private IEnergySource powerSrc;
|
||||
private boolean sentCustomName;
|
||||
private int ticksSinceCheck = 900;
|
||||
private IAEItemStack clientRequestedTargetItem = null;
|
||||
|
||||
@@ -297,9 +293,7 @@ public abstract class AEBaseContainer extends Container {
|
||||
|
||||
@Override
|
||||
public void detectAndSendChanges() {
|
||||
this.sendCustomName();
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
if (this.tileEntity != null
|
||||
&& this.tileEntity.getWorld().getTileEntity(this.tileEntity.getPos()) != this.tileEntity) {
|
||||
this.setValidContainer(false);
|
||||
@@ -866,43 +860,6 @@ public abstract class AEBaseContainer extends Container {
|
||||
this.detectAndSendChanges();
|
||||
}
|
||||
|
||||
private void sendCustomName() {
|
||||
// FIXME: Trash this, this is handled by NamedContainerProvider now
|
||||
if (!this.sentCustomName) {
|
||||
this.sentCustomName = true;
|
||||
if (Platform.isServer()) {
|
||||
ICustomNameObject name = null;
|
||||
|
||||
if (this.part instanceof ICustomNameObject) {
|
||||
name = (ICustomNameObject) this.part;
|
||||
}
|
||||
|
||||
if (this.tileEntity instanceof ICustomNameObject) {
|
||||
name = (ICustomNameObject) this.tileEntity;
|
||||
}
|
||||
|
||||
if (this.obj instanceof ICustomNameObject) {
|
||||
name = (ICustomNameObject) this.obj;
|
||||
}
|
||||
|
||||
if (this instanceof ICustomNameObject) {
|
||||
name = (ICustomNameObject) this;
|
||||
}
|
||||
|
||||
if (name != null) {
|
||||
if (name.hasCustomInventoryName()) {
|
||||
this.setCustomName(name.getCustomInventoryName().getString());
|
||||
}
|
||||
|
||||
if (this.getCustomName() != null) {
|
||||
NetworkHandler.instance().sendTo(new ConfigValuePacket("CustomName", this.getCustomName()),
|
||||
(ServerPlayerEntity) this.getPlayerInventory().player);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void swapSlotContents(final int slotA, final int slotB) {
|
||||
final Slot a = this.getSlot(slotA);
|
||||
final Slot b = this.getSlot(slotB);
|
||||
@@ -992,14 +949,6 @@ public abstract class AEBaseContainer extends Container {
|
||||
this.cellInv = cellInv;
|
||||
}
|
||||
|
||||
public String getCustomName() {
|
||||
return this.customName;
|
||||
}
|
||||
|
||||
public void setCustomName(final String customName) {
|
||||
this.customName = customName;
|
||||
}
|
||||
|
||||
public PlayerInventory getPlayerInventory() {
|
||||
return this.invPlayer;
|
||||
}
|
||||
@@ -1028,4 +977,18 @@ public abstract class AEBaseContainer extends Container {
|
||||
this.powerSrc = powerSrc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this container instance lives on the client.
|
||||
*/
|
||||
protected boolean isClient() {
|
||||
return invPlayer.player.getEntityWorld().isRemote();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this container instance lives on the server.
|
||||
*/
|
||||
protected boolean isServer() {
|
||||
return !isClient();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public final class ContainerLocator {
|
||||
private final AEPartLocation side;
|
||||
|
||||
private ContainerLocator(Type type, int itemIndex, World world, BlockPos blockPos, AEPartLocation side) {
|
||||
this(type, itemIndex, world.func_234923_W_().func_240901_a_(), blockPos, side);
|
||||
this(type, itemIndex, world.getDimensionKey().getLocation(), blockPos, side);
|
||||
}
|
||||
|
||||
private ContainerLocator(Type type, int itemIndex, ResourceLocation worldId, BlockPos blockPos,
|
||||
|
||||
@@ -89,6 +89,8 @@ public class SyncData {
|
||||
NetworkHandler.instance().sendTo(new ConfigValuePacket("SyncDat." + this.channel, json),
|
||||
(ServerPlayerEntity) o);
|
||||
}
|
||||
this.clientVersion = val;
|
||||
return;
|
||||
}
|
||||
|
||||
// Types other than ITextComponent must be non-null
|
||||
@@ -127,7 +129,7 @@ public class SyncData {
|
||||
String json = (String) val;
|
||||
ITextComponent text = null;
|
||||
if (!json.isEmpty()) {
|
||||
text = ITextComponent.Serializer.func_240643_a_((String) val);
|
||||
text = ITextComponent.Serializer.getComponentFromJson((String) val);
|
||||
}
|
||||
this.updateTextComponent(text);
|
||||
} else {
|
||||
|
||||
@@ -49,7 +49,6 @@ import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.core.Api;
|
||||
import appeng.tile.misc.CellWorkbenchTileEntity;
|
||||
import appeng.util.EnumCycler;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.helpers.ItemHandlerUtil;
|
||||
import appeng.util.inv.WrapperSupplierItemHandler;
|
||||
import appeng.util.iterators.NullIterator;
|
||||
@@ -143,7 +142,7 @@ public class CellWorkbenchContainer extends UpgradeableContainer {
|
||||
@Override
|
||||
public void detectAndSendChanges() {
|
||||
final ItemStack is = this.workBench.getInventoryByName("cell").getStackInSlot(0);
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
for (final IContainerListener listener : this.listeners) {
|
||||
if (this.prevStack != is) {
|
||||
// if the bars changed an item was probably made, so just send shit!
|
||||
|
||||
@@ -33,7 +33,6 @@ import appeng.container.interfaces.IProgressProvider;
|
||||
import appeng.container.slot.OutputSlot;
|
||||
import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.tile.misc.CondenserTileEntity;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class CondenserContainer extends AEBaseContainer implements IProgressProvider {
|
||||
|
||||
@@ -75,13 +74,13 @@ public class CondenserContainer extends AEBaseContainer implements IProgressProv
|
||||
|
||||
@Override
|
||||
public void detectAndSendChanges() {
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
final double maxStorage = this.condenser.getStorage();
|
||||
final double requiredEnergy = this.condenser.getRequiredPower();
|
||||
|
||||
this.requiredEnergy = requiredEnergy == 0 ? (int) maxStorage : (int) Math.min(requiredEnergy, maxStorage);
|
||||
this.storedPower = (int) this.condenser.getStoredPower();
|
||||
this.setOutput((CondenserOutput) this.condenser.getConfigManager().getSetting(Settings.CONDENSER_OUTPUT));
|
||||
this.output = (CondenserOutput) this.condenser.getConfigManager().getSetting(Settings.CONDENSER_OUTPUT);
|
||||
}
|
||||
|
||||
super.detectAndSendChanges();
|
||||
@@ -101,7 +100,4 @@ public class CondenserContainer extends AEBaseContainer implements IProgressProv
|
||||
return this.output;
|
||||
}
|
||||
|
||||
private void setOutput(final CondenserOutput output) {
|
||||
this.output = output;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package appeng.container.implementations;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
@@ -11,8 +13,6 @@ import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraft.util.text.TranslationTextComponent;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.network.NetworkHooks;
|
||||
|
||||
import appeng.api.config.SecurityPermissions;
|
||||
@@ -43,6 +43,8 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
|
||||
|
||||
private final SecurityPermissions requiredPermission;
|
||||
|
||||
private Function<I, ITextComponent> containerTitleStrategy = this::getDefaultContainerTitle;
|
||||
|
||||
public ContainerHelper(ContainerFactory<C, I> factory, Class<I> interfaceClass) {
|
||||
this(factory, interfaceClass, null);
|
||||
}
|
||||
@@ -54,19 +56,47 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a custom strategy for obtaining a custom container name.
|
||||
*
|
||||
* The stratgy should return {@link StringTextComponent#EMPTY} if there's no
|
||||
* custom name.
|
||||
*/
|
||||
public ContainerHelper<C, I> withContainerTitle(Function<I, ITextComponent> containerTitleStrategy) {
|
||||
this.containerTitleStrategy = containerTitleStrategy;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a container that is based around a single tile entity. The tile
|
||||
* entity's position is encoded in the packet buffer.
|
||||
*/
|
||||
public C fromNetwork(int windowId, PlayerInventory inv, PacketBuffer packetBuf) {
|
||||
return fromNetwork(windowId, inv, packetBuf, (accessObj, container, buffer) -> {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #open}, but allows or additional data to be read from the
|
||||
* packet, and passed onto the container.
|
||||
*/
|
||||
public C fromNetwork(int windowId, PlayerInventory inv, PacketBuffer packetBuf,
|
||||
InitialDataDeserializer<C, I> initialDataDeserializer) {
|
||||
I host = getHostFromLocator(inv.player, ContainerLocator.read(packetBuf));
|
||||
if (host != null) {
|
||||
return factory.create(windowId, inv, host);
|
||||
C container = factory.create(windowId, inv, host);
|
||||
initialDataDeserializer.deserializeInitialData(host, container, packetBuf);
|
||||
return container;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean open(PlayerEntity player, ContainerLocator locator) {
|
||||
return open(player, locator, (accessObj, buffer) -> {
|
||||
});
|
||||
}
|
||||
|
||||
public boolean open(PlayerEntity player, ContainerLocator locator, InitialDataSerializer<I> initialDataSerializer) {
|
||||
if (!(player instanceof ServerPlayerEntity)) {
|
||||
// Cannot open containers on the client or for non-players
|
||||
// FIXME logging?
|
||||
@@ -83,7 +113,7 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
|
||||
return false;
|
||||
}
|
||||
|
||||
ITextComponent title = findContainerTitle(player.world, locator, accessInterface);
|
||||
ITextComponent title = containerTitleStrategy.apply(accessInterface);
|
||||
|
||||
INamedContainerProvider container = new SimpleNamedContainerProvider((wnd, p, pl) -> {
|
||||
C c = factory.create(wnd, p, accessInterface);
|
||||
@@ -92,34 +122,14 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
|
||||
c.setLocator(locator);
|
||||
return c;
|
||||
}, title);
|
||||
NetworkHooks.openGui((ServerPlayerEntity) player, container, locator::write);
|
||||
NetworkHooks.openGui((ServerPlayerEntity) player, container, buffer -> {
|
||||
locator.write(buffer);
|
||||
initialDataSerializer.serializeInitialData(accessInterface, buffer);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private ITextComponent findContainerTitle(World world, ContainerLocator locator, I accessInterface) {
|
||||
|
||||
if (accessInterface instanceof ICustomNameObject) {
|
||||
ICustomNameObject customNameObject = (ICustomNameObject) accessInterface;
|
||||
if (customNameObject.hasCustomInventoryName()) {
|
||||
return customNameObject.getCustomInventoryName();
|
||||
}
|
||||
}
|
||||
|
||||
// Use block name at position
|
||||
// FIXME: this is not right, we'd need to check the part's item stack, or custom
|
||||
// naming interface impl
|
||||
// FIXME: Should move this up, because at this point, it's hard to know where
|
||||
// the terminal host came from (part or tile)
|
||||
if (locator.hasBlockPos()) {
|
||||
return new TranslationTextComponent(
|
||||
world.getBlockState(locator.getBlockPos()).getBlock().getTranslationKey());
|
||||
}
|
||||
|
||||
return new StringTextComponent("Unknown");
|
||||
|
||||
}
|
||||
|
||||
private I getHostFromLocator(PlayerEntity player, ContainerLocator locator) {
|
||||
if (locator.hasItemIndex()) {
|
||||
return getHostFromPlayerInventory(player, locator);
|
||||
@@ -196,6 +206,24 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
|
||||
C create(int windowId, PlayerInventory playerInv, I accessObj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy used to serialize initial data for opening the container on the
|
||||
* client-side into the packet that is sent to the client.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface InitialDataSerializer<I> {
|
||||
void serializeInitialData(I host, PacketBuffer buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategy used to deserialize initial data for opening the container on the
|
||||
* client-side from the packet received by the server.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface InitialDataDeserializer<C, I> {
|
||||
void deserializeInitialData(I host, C container, PacketBuffer buffer);
|
||||
}
|
||||
|
||||
private boolean checkPermission(PlayerEntity player, Object accessInterface) {
|
||||
|
||||
if (requiredPermission != null) {
|
||||
@@ -206,4 +234,15 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
|
||||
|
||||
}
|
||||
|
||||
private ITextComponent getDefaultContainerTitle(I accessInterface) {
|
||||
if (accessInterface instanceof ICustomNameObject) {
|
||||
ICustomNameObject customNameObject = (ICustomNameObject) accessInterface;
|
||||
if (customNameObject.hasCustomInventoryName()) {
|
||||
return customNameObject.getCustomInventoryName();
|
||||
}
|
||||
}
|
||||
|
||||
return StringTextComponent.EMPTY;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,14 +19,8 @@
|
||||
package appeng.container.implementations;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
@@ -66,9 +60,8 @@ import appeng.me.helpers.PlayerSource;
|
||||
import appeng.parts.reporting.CraftingTerminalPart;
|
||||
import appeng.parts.reporting.PatternTerminalPart;
|
||||
import appeng.parts.reporting.TerminalPart;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class CraftConfirmContainer extends AEBaseContainer {
|
||||
public class CraftConfirmContainer extends AEBaseContainer implements CraftingCPUCyclingContainer {
|
||||
|
||||
public static ContainerType<CraftConfirmContainer> TYPE;
|
||||
|
||||
@@ -83,98 +76,51 @@ public class CraftConfirmContainer extends AEBaseContainer {
|
||||
return helper.open(player, locator);
|
||||
}
|
||||
|
||||
private final ArrayList<CraftingCPURecord> cpus = new ArrayList<>();
|
||||
private final CraftingCPUCycler cpuCycler;
|
||||
|
||||
private ICraftingCPU selectedCpu;
|
||||
|
||||
private Future<ICraftingJob> job;
|
||||
private ICraftingJob result;
|
||||
@GuiSync(0)
|
||||
public long bytesUsed;
|
||||
@GuiSync(1)
|
||||
public long cpuBytesAvail;
|
||||
@GuiSync(2)
|
||||
public int cpuCoProcessors;
|
||||
@GuiSync(3)
|
||||
public boolean autoStart = false;
|
||||
@GuiSync(4)
|
||||
public boolean simulation = true;
|
||||
@GuiSync(5)
|
||||
public int selectedCpu = -1;
|
||||
|
||||
// Indicates whether any CPUs are available
|
||||
@GuiSync(6)
|
||||
public boolean noCPU = true;
|
||||
|
||||
// Properties of the currently selected crafting CPU, this can be null
|
||||
// if no CPUs are available, or if an automatic one is selected
|
||||
@GuiSync(1)
|
||||
public long cpuBytesAvail;
|
||||
@GuiSync(2)
|
||||
public int cpuCoProcessors;
|
||||
@GuiSync(7)
|
||||
public ITextComponent myName;
|
||||
public ITextComponent cpuName;
|
||||
|
||||
public CraftConfirmContainer(int id, PlayerInventory ip, ITerminalHost te) {
|
||||
super(TYPE, id, ip, te);
|
||||
this.cpuCycler = new CraftingCPUCycler(this::cpuMatches, this::onCPUSelectionChanged);
|
||||
// A player can select no crafting CPU to use a suitable one automatically
|
||||
this.cpuCycler.setAllowNoSelection(true);
|
||||
}
|
||||
|
||||
public void cycleCpu(final boolean next) {
|
||||
if (next) {
|
||||
this.setSelectedCpu(this.getSelectedCpu() + 1);
|
||||
} else {
|
||||
this.setSelectedCpu(this.getSelectedCpu() - 1);
|
||||
}
|
||||
|
||||
if (this.getSelectedCpu() < -1) {
|
||||
this.setSelectedCpu(this.cpus.size() - 1);
|
||||
} else if (this.getSelectedCpu() >= this.cpus.size()) {
|
||||
this.setSelectedCpu(-1);
|
||||
}
|
||||
|
||||
if (this.getSelectedCpu() == -1) {
|
||||
this.setCpuAvailableBytes(0);
|
||||
this.setCpuCoProcessors(0);
|
||||
this.setName(null);
|
||||
} else {
|
||||
CraftingCPURecord cpu = this.cpus.get(this.getSelectedCpu());
|
||||
this.setName(cpu.getName());
|
||||
this.setCpuAvailableBytes(cpu.getSize());
|
||||
this.setCpuCoProcessors(cpu.getProcessors());
|
||||
}
|
||||
@Override
|
||||
public void cycleSelectedCPU(final boolean next) {
|
||||
this.cpuCycler.cycleCpu(next);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detectAndSendChanges() {
|
||||
if (Platform.isClient()) {
|
||||
if (isClient()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ICraftingGrid cc = this.getGrid().getCache(ICraftingGrid.class);
|
||||
final ImmutableSet<ICraftingCPU> cpuSet = cc.getCpus();
|
||||
|
||||
int matches = 0;
|
||||
boolean changed = false;
|
||||
for (final ICraftingCPU c : cpuSet) {
|
||||
boolean found = false;
|
||||
for (final CraftingCPURecord ccr : this.cpus) {
|
||||
if (ccr.getCpu() == c) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final boolean matched = this.cpuMatches(c);
|
||||
|
||||
if (matched) {
|
||||
matches++;
|
||||
}
|
||||
|
||||
if (found == !matched) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed || this.cpus.size() != matches) {
|
||||
this.cpus.clear();
|
||||
for (final ICraftingCPU c : cpuSet) {
|
||||
if (this.cpuMatches(c)) {
|
||||
this.cpus.add(new CraftingCPURecord(c.getAvailableStorage(), c.getCoProcessors(), c));
|
||||
}
|
||||
}
|
||||
|
||||
this.sendCPUs();
|
||||
}
|
||||
|
||||
this.setNoCPU(this.cpus.isEmpty());
|
||||
this.cpuCycler.detectAndSendChanges(this.getGrid());
|
||||
|
||||
super.detectAndSendChanges();
|
||||
|
||||
@@ -278,22 +224,6 @@ public class CraftConfirmContainer extends AEBaseContainer {
|
||||
return c.getAvailableStorage() >= this.getUsedBytes() && !c.isBusy();
|
||||
}
|
||||
|
||||
private void sendCPUs() {
|
||||
Collections.sort(this.cpus);
|
||||
|
||||
if (this.getSelectedCpu() >= this.cpus.size()) {
|
||||
this.setSelectedCpu(-1);
|
||||
this.setCpuAvailableBytes(0);
|
||||
this.setCpuCoProcessors(0);
|
||||
this.setName(null);
|
||||
} else if (this.getSelectedCpu() != -1) {
|
||||
CraftingCPURecord cpu = this.cpus.get(this.getSelectedCpu());
|
||||
this.setName(cpu.getName());
|
||||
this.setCpuAvailableBytes(cpu.getSize());
|
||||
this.setCpuCoProcessors(cpu.getProcessors());
|
||||
}
|
||||
}
|
||||
|
||||
public void startJob() {
|
||||
ContainerType<?> originalGui = null;
|
||||
|
||||
@@ -316,9 +246,7 @@ public class CraftConfirmContainer extends AEBaseContainer {
|
||||
|
||||
if (this.result != null && !this.isSimulation()) {
|
||||
final ICraftingGrid cc = this.getGrid().getCache(ICraftingGrid.class);
|
||||
final ICraftingLink g = cc.submitJob(this.result, null,
|
||||
this.getSelectedCpu() == -1 ? null : this.cpus.get(this.getSelectedCpu()).getCpu(), true,
|
||||
this.getActionSrc());
|
||||
final ICraftingLink g = cc.submitJob(this.result, null, this.selectedCpu, true, this.getActionSrc());
|
||||
this.setAutoStart(false);
|
||||
if (g != null && originalGui != null && this.getLocator() != null) {
|
||||
ContainerOpener.openContainer(originalGui, getPlayerInventory().player, getLocator());
|
||||
@@ -348,6 +276,22 @@ public class CraftConfirmContainer extends AEBaseContainer {
|
||||
}
|
||||
}
|
||||
|
||||
private void onCPUSelectionChanged(CraftingCPURecord cpuRecord, boolean cpusAvailable) {
|
||||
noCPU = !cpusAvailable;
|
||||
|
||||
if (cpuRecord == null) {
|
||||
cpuBytesAvail = 0;
|
||||
cpuCoProcessors = 0;
|
||||
cpuName = null;
|
||||
selectedCpu = null;
|
||||
} else {
|
||||
cpuBytesAvail = cpuRecord.getSize();
|
||||
cpuCoProcessors = cpuRecord.getProcessors();
|
||||
cpuName = cpuRecord.getName();
|
||||
selectedCpu = cpuRecord.getCpu();
|
||||
}
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
return this.getPlayerInv().player.world;
|
||||
}
|
||||
@@ -372,42 +316,18 @@ public class CraftConfirmContainer extends AEBaseContainer {
|
||||
return this.cpuBytesAvail;
|
||||
}
|
||||
|
||||
private void setCpuAvailableBytes(final long cpuBytesAvail) {
|
||||
this.cpuBytesAvail = cpuBytesAvail;
|
||||
}
|
||||
|
||||
public int getCpuCoProcessors() {
|
||||
return this.cpuCoProcessors;
|
||||
}
|
||||
|
||||
private void setCpuCoProcessors(final int cpuCoProcessors) {
|
||||
this.cpuCoProcessors = cpuCoProcessors;
|
||||
}
|
||||
|
||||
public int getSelectedCpu() {
|
||||
return this.selectedCpu;
|
||||
}
|
||||
|
||||
private void setSelectedCpu(final int selectedCpu) {
|
||||
this.selectedCpu = selectedCpu;
|
||||
}
|
||||
|
||||
public ITextComponent getName() {
|
||||
return this.myName;
|
||||
}
|
||||
|
||||
private void setName(@Nullable final ITextComponent myName) {
|
||||
this.myName = myName;
|
||||
return this.cpuName;
|
||||
}
|
||||
|
||||
public boolean hasNoCPU() {
|
||||
return this.noCPU;
|
||||
}
|
||||
|
||||
private void setNoCPU(final boolean noCPU) {
|
||||
this.noCPU = noCPU;
|
||||
}
|
||||
|
||||
public boolean isSimulation() {
|
||||
return this.simulation;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.inventory.container.ContainerType;
|
||||
import net.minecraft.inventory.container.IContainerListener;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
|
||||
import appeng.api.config.SecurityPermissions;
|
||||
import appeng.api.networking.IGrid;
|
||||
@@ -46,24 +46,28 @@ import appeng.core.Api;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.ConfigValuePacket;
|
||||
import appeng.core.sync.packets.MEInventoryUpdatePacket;
|
||||
import appeng.helpers.ICustomNameObject;
|
||||
import appeng.me.cluster.implementations.CraftingCPUCluster;
|
||||
import appeng.tile.crafting.CraftingTileEntity;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class CraftingCPUContainer extends AEBaseContainer
|
||||
implements IMEMonitorHandlerReceiver<IAEItemStack>, ICustomNameObject {
|
||||
public class CraftingCPUContainer extends AEBaseContainer implements IMEMonitorHandlerReceiver<IAEItemStack> {
|
||||
|
||||
public static ContainerType<CraftingCPUContainer> TYPE;
|
||||
|
||||
private static final ContainerHelper<CraftingCPUContainer, CraftingTileEntity> helper = new ContainerHelper<>(
|
||||
CraftingCPUContainer::new, CraftingTileEntity.class, SecurityPermissions.CRAFT);
|
||||
CraftingCPUContainer::new, CraftingTileEntity.class, SecurityPermissions.CRAFT)
|
||||
.withContainerTitle(craftingTileEntity -> {
|
||||
// Use the cluster's custom name instead of the right-clicked block entities one
|
||||
CraftingCPUCluster cluster = craftingTileEntity.getCluster();
|
||||
if (cluster != null && cluster.getName() != null) {
|
||||
return cluster.getName();
|
||||
}
|
||||
return StringTextComponent.EMPTY;
|
||||
});
|
||||
|
||||
private final IItemList<IAEItemStack> list = Api.instance().storage().getStorageChannel(IItemStorageChannel.class)
|
||||
.createList();
|
||||
private IGrid network;
|
||||
private final IGrid network;
|
||||
private CraftingCPUCluster monitor = null;
|
||||
private ITextComponent cpuName = null;
|
||||
|
||||
@GuiSync(0)
|
||||
public long eta = -1;
|
||||
@@ -77,14 +81,16 @@ public class CraftingCPUContainer extends AEBaseContainer
|
||||
final IActionHost host = (IActionHost) (te instanceof IActionHost ? te : null);
|
||||
|
||||
if (host != null && host.getActionableNode() != null) {
|
||||
this.setNetwork(host.getActionableNode().getGrid());
|
||||
this.network = host.getActionableNode().getGrid();
|
||||
} else {
|
||||
this.network = null;
|
||||
}
|
||||
|
||||
if (te instanceof CraftingTileEntity) {
|
||||
this.setCPU(((CraftingTileEntity) te).getCluster());
|
||||
}
|
||||
|
||||
if (this.getNetwork() == null && Platform.isServer()) {
|
||||
if (this.getNetwork() == null && isServer()) {
|
||||
this.setValidContainer(false);
|
||||
}
|
||||
}
|
||||
@@ -114,15 +120,13 @@ public class CraftingCPUContainer extends AEBaseContainer
|
||||
}
|
||||
|
||||
if (c instanceof CraftingCPUCluster) {
|
||||
this.cpuName = c.getName();
|
||||
this.setMonitor((CraftingCPUCluster) c);
|
||||
this.monitor = (CraftingCPUCluster) c;
|
||||
this.list.resetStatus();
|
||||
this.getMonitor().getListOfItem(this.list, CraftingItemList.ALL);
|
||||
this.getMonitor().addListener(this, null);
|
||||
this.setEstimatedTime(0);
|
||||
} else {
|
||||
this.setMonitor(null);
|
||||
this.cpuName = null;
|
||||
this.monitor = null;
|
||||
this.setEstimatedTime(-1);
|
||||
}
|
||||
}
|
||||
@@ -153,7 +157,7 @@ public class CraftingCPUContainer extends AEBaseContainer
|
||||
|
||||
@Override
|
||||
public void detectAndSendChanges() {
|
||||
if (Platform.isServer() && this.getMonitor() != null && !this.list.isEmpty()) {
|
||||
if (isServer() && this.getMonitor() != null && !this.list.isEmpty()) {
|
||||
try {
|
||||
if (this.getEstimatedTime() >= 0) {
|
||||
final long elapsedTime = this.getMonitor().getElapsedTime();
|
||||
@@ -218,16 +222,6 @@ public class CraftingCPUContainer extends AEBaseContainer
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITextComponent getCustomInventoryName() {
|
||||
return this.cpuName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasCustomInventoryName() {
|
||||
return this.cpuName != null;
|
||||
}
|
||||
|
||||
public long getEstimatedTime() {
|
||||
return this.eta;
|
||||
}
|
||||
@@ -240,15 +234,8 @@ public class CraftingCPUContainer extends AEBaseContainer
|
||||
return this.monitor;
|
||||
}
|
||||
|
||||
private void setMonitor(final CraftingCPUCluster monitor) {
|
||||
this.monitor = monitor;
|
||||
}
|
||||
|
||||
IGrid getNetwork() {
|
||||
return this.network;
|
||||
}
|
||||
|
||||
private void setNetwork(final IGrid network) {
|
||||
this.network = network;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
package appeng.container.implementations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.crafting.ICraftingCPU;
|
||||
import appeng.api.networking.crafting.ICraftingGrid;
|
||||
|
||||
/**
|
||||
* Utility class for dialogs that can cycle through crafting CPUs
|
||||
*/
|
||||
class CraftingCPUCycler {
|
||||
|
||||
@FunctionalInterface
|
||||
public interface ChangeListener {
|
||||
void onChange(CraftingCPURecord selectedCpu, boolean cpusAvailable);
|
||||
}
|
||||
|
||||
private final Predicate<ICraftingCPU> cpuFilter;
|
||||
private final ChangeListener changeListener;
|
||||
private final List<CraftingCPURecord> cpus = new ArrayList<>();
|
||||
private int selectedCpu = -1;
|
||||
private boolean initialDataSent = false;
|
||||
private boolean allowNoSelection;
|
||||
|
||||
public CraftingCPUCycler(Predicate<ICraftingCPU> cpuFilter, ChangeListener changeListener) {
|
||||
this.cpuFilter = cpuFilter;
|
||||
this.changeListener = changeListener;
|
||||
}
|
||||
|
||||
public void detectAndSendChanges(IGrid network) {
|
||||
final ICraftingGrid cc = network.getCache(ICraftingGrid.class);
|
||||
final ImmutableSet<ICraftingCPU> cpuSet = cc.getCpus();
|
||||
|
||||
int matches = 0;
|
||||
boolean changed = !initialDataSent;
|
||||
initialDataSent = true;
|
||||
for (final ICraftingCPU c : cpuSet) {
|
||||
boolean found = false;
|
||||
for (final CraftingCPURecord ccr : this.cpus) {
|
||||
if (ccr.getCpu() == c) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final boolean matched = this.cpuFilter.test(c);
|
||||
|
||||
if (matched) {
|
||||
matches++;
|
||||
}
|
||||
|
||||
if (found == !matched) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed || this.cpus.size() != matches) {
|
||||
this.cpus.clear();
|
||||
for (final ICraftingCPU c : cpuSet) {
|
||||
if (this.cpuFilter.test(c)) {
|
||||
this.cpus.add(new CraftingCPURecord(c.getAvailableStorage(), c.getCoProcessors(), c));
|
||||
}
|
||||
}
|
||||
|
||||
// Sort and assign numeric IDs in case they have no names
|
||||
Collections.sort(this.cpus);
|
||||
for (int i = 0; i < this.cpus.size(); i++) {
|
||||
CraftingCPURecord cpu = cpus.get(i);
|
||||
if (cpu.getName() == null) {
|
||||
cpu.setName(new StringTextComponent("#" + (i + 1)));
|
||||
}
|
||||
}
|
||||
|
||||
this.notifyListener();
|
||||
}
|
||||
}
|
||||
|
||||
public void cycleCpu(final boolean next) {
|
||||
if (next) {
|
||||
this.selectedCpu++;
|
||||
} else {
|
||||
this.selectedCpu--;
|
||||
}
|
||||
|
||||
// If "no CPU" is a valid selection, then -1 is the first potential item
|
||||
int lowerLimit = this.allowNoSelection ? -1 : 0;
|
||||
|
||||
if (this.selectedCpu < lowerLimit) {
|
||||
this.selectedCpu = this.cpus.size() - 1;
|
||||
} else if (this.selectedCpu >= this.cpus.size()) {
|
||||
this.selectedCpu = lowerLimit;
|
||||
}
|
||||
|
||||
this.notifyListener();
|
||||
}
|
||||
|
||||
public boolean isAllowNoSelection() {
|
||||
return allowNoSelection;
|
||||
}
|
||||
|
||||
public void setAllowNoSelection(boolean allowNoSelection) {
|
||||
this.allowNoSelection = allowNoSelection;
|
||||
}
|
||||
|
||||
private void notifyListener() {
|
||||
if (this.selectedCpu >= this.cpus.size()) {
|
||||
this.selectedCpu = -1;
|
||||
}
|
||||
|
||||
// Force the selected CPU to the first available CPU unless no-selection is
|
||||
// explicitly allowed
|
||||
if (!this.allowNoSelection && this.selectedCpu == -1 && !this.cpus.isEmpty()) {
|
||||
this.selectedCpu = 0;
|
||||
}
|
||||
|
||||
if (this.selectedCpu != -1) {
|
||||
this.changeListener.onChange(this.cpus.get(this.selectedCpu), true);
|
||||
} else {
|
||||
this.changeListener.onChange(null, !this.cpus.isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package appeng.container.implementations;
|
||||
|
||||
/**
|
||||
* Implemented on screens that show information about a crafting CPU and allow
|
||||
* the CPU to be cycled. Is triggered by receiving a config value packet with
|
||||
* name <code>Terminal.Cpu</code>.
|
||||
*/
|
||||
public interface CraftingCPUCyclingContainer {
|
||||
|
||||
void cycleSelectedCPU(boolean forward);
|
||||
|
||||
}
|
||||
@@ -25,16 +25,16 @@ import net.minecraft.util.text.ITextComponent;
|
||||
import appeng.api.networking.crafting.ICraftingCPU;
|
||||
|
||||
public class CraftingCPURecord implements Comparable<CraftingCPURecord> {
|
||||
private final ITextComponent myName;
|
||||
private final ICraftingCPU cpu;
|
||||
private final long size;
|
||||
private final int processors;
|
||||
private ITextComponent name;
|
||||
|
||||
public CraftingCPURecord(final long size, final int coProcessors, final ICraftingCPU server) {
|
||||
this.size = size;
|
||||
this.processors = coProcessors;
|
||||
this.cpu = server;
|
||||
this.myName = server.getName();
|
||||
this.name = server.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -50,10 +50,6 @@ public class CraftingCPURecord implements Comparable<CraftingCPURecord> {
|
||||
return this.cpu;
|
||||
}
|
||||
|
||||
ITextComponent getName() {
|
||||
return this.myName;
|
||||
}
|
||||
|
||||
int getProcessors() {
|
||||
return this.processors;
|
||||
}
|
||||
@@ -61,4 +57,13 @@ public class CraftingCPURecord implements Comparable<CraftingCPURecord> {
|
||||
long getSize() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
public ITextComponent getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(ITextComponent name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,12 +18,6 @@
|
||||
|
||||
package appeng.container.implementations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.inventory.container.ContainerType;
|
||||
@@ -31,14 +25,13 @@ import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
import appeng.api.config.SecurityPermissions;
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.crafting.ICraftingCPU;
|
||||
import appeng.api.networking.crafting.ICraftingGrid;
|
||||
import appeng.api.storage.ITerminalHost;
|
||||
import appeng.container.ContainerLocator;
|
||||
import appeng.container.guisync.GuiSync;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class CraftingStatusContainer extends CraftingCPUContainer {
|
||||
public class CraftingStatusContainer extends CraftingCPUContainer implements CraftingCPUCyclingContainer {
|
||||
|
||||
public static ContainerType<CraftingStatusContainer> TYPE;
|
||||
|
||||
@@ -53,13 +46,13 @@ public class CraftingStatusContainer extends CraftingCPUContainer {
|
||||
return helper.open(player, locator);
|
||||
}
|
||||
|
||||
private final List<CraftingCPURecord> cpus = new ArrayList<>();
|
||||
@GuiSync(5)
|
||||
public int selectedCpu = -1;
|
||||
private final CraftingCPUCycler cpuCycler = new CraftingCPUCycler(this::cpuMatches, this::onCPUSelectionChanged);
|
||||
|
||||
@GuiSync(6)
|
||||
public boolean noCPU = true;
|
||||
|
||||
@GuiSync(7)
|
||||
public ITextComponent myName;
|
||||
public ITextComponent cpuName;
|
||||
|
||||
public CraftingStatusContainer(int id, final PlayerInventory ip, final ITerminalHost te) {
|
||||
super(TYPE, id, ip, te);
|
||||
@@ -67,43 +60,9 @@ public class CraftingStatusContainer extends CraftingCPUContainer {
|
||||
|
||||
@Override
|
||||
public void detectAndSendChanges() {
|
||||
if (Platform.isServer() && this.getNetwork() != null) {
|
||||
final ICraftingGrid cc = this.getNetwork().getCache(ICraftingGrid.class);
|
||||
final ImmutableSet<ICraftingCPU> cpuSet = cc.getCpus();
|
||||
|
||||
int matches = 0;
|
||||
boolean changed = false;
|
||||
for (final ICraftingCPU c : cpuSet) {
|
||||
boolean found = false;
|
||||
for (final CraftingCPURecord ccr : this.cpus) {
|
||||
if (ccr.getCpu() == c) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
final boolean matched = this.cpuMatches(c);
|
||||
|
||||
if (matched) {
|
||||
matches++;
|
||||
}
|
||||
|
||||
if (found == !matched) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed || this.cpus.size() != matches) {
|
||||
this.cpus.clear();
|
||||
for (final ICraftingCPU c : cpuSet) {
|
||||
if (this.cpuMatches(c)) {
|
||||
this.cpus.add(new CraftingCPURecord(c.getAvailableStorage(), c.getCoProcessors(), c));
|
||||
}
|
||||
}
|
||||
|
||||
this.sendCPUs();
|
||||
}
|
||||
|
||||
this.noCPU = this.cpus.isEmpty();
|
||||
IGrid network = this.getNetwork();
|
||||
if (isServer() && network != null) {
|
||||
cpuCycler.detectAndSendChanges(network);
|
||||
}
|
||||
|
||||
super.detectAndSendChanges();
|
||||
@@ -113,52 +72,20 @@ public class CraftingStatusContainer extends CraftingCPUContainer {
|
||||
return c.isBusy();
|
||||
}
|
||||
|
||||
private void sendCPUs() {
|
||||
Collections.sort(this.cpus);
|
||||
|
||||
if (this.selectedCpu >= this.cpus.size()) {
|
||||
this.selectedCpu = -1;
|
||||
this.myName = null;
|
||||
} else if (this.selectedCpu != -1) {
|
||||
this.myName = this.cpus.get(this.selectedCpu).getName();
|
||||
}
|
||||
|
||||
if (this.selectedCpu == -1 && this.cpus.size() > 0) {
|
||||
this.selectedCpu = 0;
|
||||
}
|
||||
|
||||
if (this.selectedCpu != -1) {
|
||||
if (this.cpus.get(this.selectedCpu).getCpu() != this.getMonitor()) {
|
||||
this.setCPU(this.cpus.get(this.selectedCpu).getCpu());
|
||||
}
|
||||
private void onCPUSelectionChanged(CraftingCPURecord cpuRecord, boolean cpusAvailable) {
|
||||
noCPU = !cpusAvailable;
|
||||
if (cpuRecord == null) {
|
||||
cpuName = null;
|
||||
setCPU(null);
|
||||
} else {
|
||||
this.setCPU(null);
|
||||
cpuName = cpuRecord.getName();
|
||||
setCPU(cpuRecord.getCpu());
|
||||
}
|
||||
}
|
||||
|
||||
public void cycleCpu(final boolean next) {
|
||||
if (next) {
|
||||
this.selectedCpu++;
|
||||
} else {
|
||||
this.selectedCpu--;
|
||||
}
|
||||
|
||||
if (this.selectedCpu < -1) {
|
||||
this.selectedCpu = this.cpus.size() - 1;
|
||||
} else if (this.selectedCpu >= this.cpus.size()) {
|
||||
this.selectedCpu = -1;
|
||||
}
|
||||
|
||||
if (this.selectedCpu == -1 && this.cpus.size() > 0) {
|
||||
this.selectedCpu = 0;
|
||||
}
|
||||
|
||||
if (this.selectedCpu == -1) {
|
||||
this.myName = null;
|
||||
this.setCPU(null);
|
||||
} else {
|
||||
this.myName = this.cpus.get(this.selectedCpu).getName();
|
||||
this.setCPU(this.cpus.get(this.selectedCpu).getCpu());
|
||||
}
|
||||
@Override
|
||||
public void cycleSelectedCPU(boolean forward) {
|
||||
this.cpuCycler.cycleCpu(forward);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ import appeng.container.slot.FakeTypeOnlySlot;
|
||||
import appeng.container.slot.OptionalTypeOnlyFakeSlot;
|
||||
import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.parts.automation.FormationPlanePart;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class FormationPlaneContainer extends UpgradeableContainer {
|
||||
|
||||
@@ -107,7 +106,7 @@ public class FormationPlaneContainer extends UpgradeableContainer {
|
||||
public void detectAndSendChanges() {
|
||||
this.verifyPermissions(SecurityPermissions.BUILD, false);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.setFuzzyMode((FuzzyMode) this.getUpgradeable().getConfigManager().getSetting(Settings.FUZZY_MODE));
|
||||
this.setPlaceMode((YesNo) this.getUpgradeable().getConfigManager().getSetting(Settings.PLACE_BLOCK));
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ import appeng.container.guisync.GuiSync;
|
||||
import appeng.container.slot.OutputSlot;
|
||||
import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.tile.storage.IOPortTileEntity;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class IOPortContainer extends UpgradeableContainer {
|
||||
|
||||
@@ -111,7 +110,7 @@ public class IOPortContainer extends UpgradeableContainer {
|
||||
public void detectAndSendChanges() {
|
||||
this.verifyPermissions(SecurityPermissions.BUILD, false);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.setOperationMode(
|
||||
(OperationMode) this.getUpgradeable().getConfigManager().getSetting(Settings.OPERATION_MODE));
|
||||
this.setFullMode(
|
||||
|
||||
@@ -35,7 +35,6 @@ import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.core.Api;
|
||||
import appeng.tile.misc.InscriberRecipes;
|
||||
import appeng.tile.misc.InscriberTileEntity;
|
||||
import appeng.util.Platform;
|
||||
|
||||
/**
|
||||
* @author AlgorithmX2
|
||||
@@ -119,7 +118,7 @@ public class InscriberContainer extends UpgradeableContainer implements IProgres
|
||||
public void detectAndSendChanges() {
|
||||
this.standardDetectAndSendChanges();
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.maxProcessingTime = this.ti.getMaxProcessingTime();
|
||||
this.processingTime = this.ti.getProcessingTime();
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ import appeng.api.networking.security.IActionHost;
|
||||
import appeng.container.AEBaseContainer;
|
||||
import appeng.container.ContainerLocator;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.CompressedNBTPacket;
|
||||
import appeng.core.sync.packets.MEInterfaceUpdatePacket;
|
||||
import appeng.helpers.DualityInterface;
|
||||
import appeng.helpers.IInterfaceHost;
|
||||
import appeng.helpers.InventoryAction;
|
||||
@@ -52,7 +52,6 @@ import appeng.parts.reporting.InterfaceTerminalPart;
|
||||
import appeng.tile.inventory.AppEngInternalInventory;
|
||||
import appeng.tile.misc.InterfaceTileEntity;
|
||||
import appeng.util.InventoryAdaptor;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.helpers.ItemHandlerUtil;
|
||||
import appeng.util.inv.AdaptorItemHandler;
|
||||
import appeng.util.inv.WrapperCursorItemHandler;
|
||||
@@ -88,7 +87,7 @@ public final class InterfaceTerminalContainer extends AEBaseContainer {
|
||||
public InterfaceTerminalContainer(int id, final PlayerInventory ip, final InterfaceTerminalPart anchor) {
|
||||
super(TYPE, id, ip, anchor);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.grid = anchor.getActionableNode().getGrid();
|
||||
}
|
||||
|
||||
@@ -97,7 +96,7 @@ public final class InterfaceTerminalContainer extends AEBaseContainer {
|
||||
|
||||
@Override
|
||||
public void detectAndSendChanges() {
|
||||
if (Platform.isClient()) {
|
||||
if (isClient()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -177,7 +176,7 @@ public final class InterfaceTerminalContainer extends AEBaseContainer {
|
||||
|
||||
if (!this.data.isEmpty()) {
|
||||
try {
|
||||
NetworkHandler.instance().sendTo(new CompressedNBTPacket(this.data),
|
||||
NetworkHandler.instance().sendTo(new MEInterfaceUpdatePacket(this.data),
|
||||
(ServerPlayerEntity) this.getPlayerInv().player);
|
||||
} catch (final IOException e) {
|
||||
// :P
|
||||
|
||||
@@ -22,8 +22,6 @@ import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.inventory.container.ContainerType;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.items.IItemHandler;
|
||||
|
||||
import appeng.api.config.FuzzyMode;
|
||||
@@ -32,13 +30,13 @@ import appeng.api.config.RedstoneMode;
|
||||
import appeng.api.config.SecurityPermissions;
|
||||
import appeng.api.config.Settings;
|
||||
import appeng.api.config.YesNo;
|
||||
import appeng.client.gui.implementations.NumberEntryWidget;
|
||||
import appeng.container.ContainerLocator;
|
||||
import appeng.container.guisync.GuiSync;
|
||||
import appeng.container.slot.FakeTypeOnlySlot;
|
||||
import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.ConfigValuePacket;
|
||||
import appeng.parts.automation.LevelEmitterPart;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class LevelEmitterContainer extends UpgradeableContainer {
|
||||
|
||||
@@ -48,38 +46,46 @@ public class LevelEmitterContainer extends UpgradeableContainer {
|
||||
LevelEmitterContainer::new, LevelEmitterPart.class, SecurityPermissions.BUILD);
|
||||
|
||||
public static LevelEmitterContainer fromNetwork(int windowId, PlayerInventory inv, PacketBuffer buf) {
|
||||
return helper.fromNetwork(windowId, inv, buf);
|
||||
return helper.fromNetwork(windowId, inv, buf, (host, container, buffer) -> {
|
||||
container.reportingValue = buffer.readVarLong();
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean open(PlayerEntity player, ContainerLocator locator) {
|
||||
return helper.open(player, locator);
|
||||
return helper.open(player, locator, (host, buffer) -> {
|
||||
buffer.writeVarLong(host.getReportingValue());
|
||||
});
|
||||
}
|
||||
|
||||
private final LevelEmitterPart lvlEmitter;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
private NumberEntryWidget textField;
|
||||
@GuiSync(2)
|
||||
public LevelType lvType;
|
||||
@GuiSync(3)
|
||||
public long EmitterValue = -1;
|
||||
@GuiSync(4)
|
||||
public YesNo cmType;
|
||||
|
||||
// Only synced once on container-open, and only used on client
|
||||
private long reportingValue;
|
||||
|
||||
public LevelEmitterContainer(int id, final PlayerInventory ip, final LevelEmitterPart te) {
|
||||
super(TYPE, id, ip, te);
|
||||
this.lvlEmitter = te;
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void setTextField(final NumberEntryWidget level) {
|
||||
this.textField = level;
|
||||
this.textField.setValue(this.EmitterValue);
|
||||
public long getReportingValue() {
|
||||
return reportingValue;
|
||||
}
|
||||
|
||||
public void setLevel(final long l, final PlayerEntity player) {
|
||||
this.lvlEmitter.setReportingValue(l);
|
||||
this.EmitterValue = l;
|
||||
public void setReportingValue(long reportingValue) {
|
||||
if (isClient()) {
|
||||
if (reportingValue != this.reportingValue) {
|
||||
this.reportingValue = reportingValue;
|
||||
NetworkHandler.instance()
|
||||
.sendToServer(new ConfigValuePacket("LevelEmitter.Value", String.valueOf(reportingValue)));
|
||||
}
|
||||
} else {
|
||||
this.lvlEmitter.setReportingValue(reportingValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -115,7 +121,6 @@ public class LevelEmitterContainer extends UpgradeableContainer {
|
||||
|
||||
@Override
|
||||
public int availableUpgrades() {
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -123,8 +128,7 @@ public class LevelEmitterContainer extends UpgradeableContainer {
|
||||
public void detectAndSendChanges() {
|
||||
this.verifyPermissions(SecurityPermissions.BUILD, false);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
this.EmitterValue = this.lvlEmitter.getReportingValue();
|
||||
if (isServer()) {
|
||||
this.setCraftingMode(
|
||||
(YesNo) this.getUpgradeable().getConfigManager().getSetting(Settings.CRAFT_VIA_REDSTONE));
|
||||
this.setLevelMode((LevelType) this.getUpgradeable().getConfigManager().getSetting(Settings.LEVEL_TYPE));
|
||||
@@ -136,15 +140,6 @@ public class LevelEmitterContainer extends UpgradeableContainer {
|
||||
this.standardDetectAndSendChanges();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(final String field, final Object oldValue, final Object newValue) {
|
||||
if (field.equals("EmitterValue")) {
|
||||
if (this.textField != null) {
|
||||
this.textField.setValue(this.EmitterValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public YesNo getCraftingMode() {
|
||||
return this.cmType;
|
||||
@@ -162,4 +157,5 @@ public class LevelEmitterContainer extends UpgradeableContainer {
|
||||
private void setLevelMode(final LevelType lvType) {
|
||||
this.lvType = lvType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -46,6 +46,8 @@ import appeng.api.implementations.tiles.IViewCellStorage;
|
||||
import appeng.api.networking.IGrid;
|
||||
import appeng.api.networking.IGridHost;
|
||||
import appeng.api.networking.IGridNode;
|
||||
import appeng.api.networking.crafting.ICraftingCPU;
|
||||
import appeng.api.networking.crafting.ICraftingGrid;
|
||||
import appeng.api.networking.energy.IEnergyGrid;
|
||||
import appeng.api.networking.energy.IEnergySource;
|
||||
import appeng.api.networking.security.IActionHost;
|
||||
@@ -73,7 +75,6 @@ import appeng.core.sync.packets.MEInventoryUpdatePacket;
|
||||
import appeng.me.helpers.ChannelPowerSrc;
|
||||
import appeng.util.ConfigManager;
|
||||
import appeng.util.IConfigManagerHost;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class MEMonitorableContainer extends AEBaseContainer
|
||||
implements IConfigManagerHost, IConfigurableObject, IMEMonitorHandlerReceiver<IAEItemStack> {
|
||||
@@ -101,6 +102,13 @@ public class MEMonitorableContainer extends AEBaseContainer
|
||||
public boolean canAccessViewCells = false;
|
||||
@GuiSync(98)
|
||||
public boolean hasPower = false;
|
||||
/**
|
||||
* The number of active crafting jobs in the network. -1 means unknown and will
|
||||
* hide the label on the screen.
|
||||
*/
|
||||
@GuiSync(100)
|
||||
public int activeCraftingJobs = -1;
|
||||
|
||||
private IConfigManagerHost gui;
|
||||
private IConfigManager serverCM;
|
||||
private IGridNode networkNode;
|
||||
@@ -122,7 +130,7 @@ public class MEMonitorableContainer extends AEBaseContainer
|
||||
this.clientCM.registerSetting(Settings.VIEW_MODE, ViewItems.ALL);
|
||||
this.clientCM.registerSetting(Settings.SORT_DIRECTION, SortDir.ASCENDING);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.serverCM = monitorable.getConfigManager();
|
||||
|
||||
this.monitor = monitorable
|
||||
@@ -183,12 +191,14 @@ public class MEMonitorableContainer extends AEBaseContainer
|
||||
|
||||
@Override
|
||||
public void detectAndSendChanges() {
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
if (this.monitor != this.host
|
||||
.getInventory(Api.instance().storage().getStorageChannel(IItemStorageChannel.class))) {
|
||||
this.setValidContainer(false);
|
||||
}
|
||||
|
||||
this.updateActiveCraftingJobs();
|
||||
|
||||
for (final Settings set : this.serverCM.getSettings()) {
|
||||
final Enum<?> sideLocal = this.serverCM.getSetting(set);
|
||||
final Enum<?> sideRemote = this.clientCM.getSetting(set);
|
||||
@@ -286,8 +296,38 @@ public class MEMonitorableContainer extends AEBaseContainer
|
||||
this.queueInventory(c);
|
||||
}
|
||||
|
||||
private void updateActiveCraftingJobs() {
|
||||
IGridNode hostNode = networkNode;
|
||||
if (hostNode == null) {
|
||||
// Wireless terminals do not directly expose the target grid (even though they
|
||||
// have one)
|
||||
if (host instanceof IActionHost) {
|
||||
hostNode = ((IActionHost) host).getActionableNode();
|
||||
}
|
||||
}
|
||||
IGrid grid = null;
|
||||
if (hostNode != null) {
|
||||
grid = hostNode.getGrid();
|
||||
}
|
||||
|
||||
if (grid == null) {
|
||||
// No grid to query crafting jobs from
|
||||
this.activeCraftingJobs = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
int activeJobs = 0;
|
||||
ICraftingGrid craftingGrid = grid.getCache(ICraftingGrid.class);
|
||||
for (ICraftingCPU cpus : craftingGrid.getCpus()) {
|
||||
if (cpus.isBusy()) {
|
||||
activeJobs++;
|
||||
}
|
||||
}
|
||||
this.activeCraftingJobs = activeJobs;
|
||||
}
|
||||
|
||||
private void queueInventory(final IContainerListener c) {
|
||||
if (Platform.isServer() && c instanceof PlayerEntity && this.monitor != null) {
|
||||
if (isServer() && c instanceof PlayerEntity && this.monitor != null) {
|
||||
try {
|
||||
MEInventoryUpdatePacket piu = new MEInventoryUpdatePacket();
|
||||
final IItemList<IAEItemStack> monitorCache = this.monitor.getStorageList();
|
||||
@@ -356,7 +396,7 @@ public class MEMonitorableContainer extends AEBaseContainer
|
||||
|
||||
@Override
|
||||
public IConfigManager getConfigManager() {
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
return this.serverCM;
|
||||
}
|
||||
return this.clientCM;
|
||||
|
||||
@@ -41,7 +41,6 @@ import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.core.Api;
|
||||
import appeng.items.misc.EncodedPatternItem;
|
||||
import appeng.tile.crafting.MolecularAssemblerTileEntity;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class MolecularAssemblerContainer extends UpgradeableContainer implements IProgressProvider {
|
||||
|
||||
@@ -147,7 +146,7 @@ public class MolecularAssemblerContainer extends UpgradeableContainer implements
|
||||
public void detectAndSendChanges() {
|
||||
this.verifyPermissions(SecurityPermissions.BUILD, false);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.setRedStoneMode(
|
||||
(RedstoneMode) this.getUpgradeable().getConfigManager().getSetting(Settings.REDSTONE_CONTROLLED));
|
||||
}
|
||||
|
||||
@@ -43,7 +43,6 @@ import appeng.container.guisync.GuiSync;
|
||||
import appeng.core.Api;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.MEInventoryUpdatePacket;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.item.AEItemStack;
|
||||
|
||||
public class NetworkStatusContainer extends AEBaseContainer {
|
||||
@@ -83,7 +82,7 @@ public class NetworkStatusContainer extends AEBaseContainer {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.network == null && Platform.isServer()) {
|
||||
if (this.network == null && isServer()) {
|
||||
this.setValidContainer(false);
|
||||
}
|
||||
}
|
||||
@@ -100,7 +99,7 @@ public class NetworkStatusContainer extends AEBaseContainer {
|
||||
@Override
|
||||
public void detectAndSendChanges() {
|
||||
this.delay++;
|
||||
if (Platform.isServer() && this.delay > 15 && this.network != null) {
|
||||
if (isServer() && this.delay > 15 && this.network != null) {
|
||||
this.delay = 0;
|
||||
|
||||
final IEnergyGrid eg = this.network.getCache(IEnergyGrid.class);
|
||||
|
||||
@@ -261,13 +261,19 @@ public class PatternTermContainer extends MEMonitorableContainer
|
||||
return new ItemStack[] { out };
|
||||
}
|
||||
} else {
|
||||
boolean hasValue = false;
|
||||
final ItemStack[] list = new ItemStack[3];
|
||||
|
||||
for (int i = 0; i < this.outputSlots.length; i++) {
|
||||
final ItemStack out = this.outputSlots[i].getStack();
|
||||
list[i] = out;
|
||||
if (!out.isEmpty()) {
|
||||
hasValue = true;
|
||||
}
|
||||
}
|
||||
if (hasValue) {
|
||||
return list;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -285,9 +291,9 @@ public class PatternTermContainer extends MEMonitorableContainer
|
||||
@Override
|
||||
public boolean isSlotEnabled(final int idx) {
|
||||
if (idx == 1) {
|
||||
return Platform.isServer() ? !this.getPatternTerminal().isCraftingRecipe() : !this.isCraftingMode();
|
||||
return isServer() ? !this.getPatternTerminal().isCraftingRecipe() : !this.isCraftingMode();
|
||||
} else if (idx == 2) {
|
||||
return Platform.isServer() ? this.getPatternTerminal().isCraftingRecipe() : this.isCraftingMode();
|
||||
return isServer() ? this.getPatternTerminal().isCraftingRecipe() : this.isCraftingMode();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -389,7 +395,7 @@ public class PatternTermContainer extends MEMonitorableContainer
|
||||
@Override
|
||||
public void detectAndSendChanges() {
|
||||
super.detectAndSendChanges();
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
if (this.isCraftingMode() != this.getPatternTerminal().isCraftingRecipe()) {
|
||||
this.setCraftingMode(this.getPatternTerminal().isCraftingRecipe());
|
||||
this.updateOrderOfOutputSlots();
|
||||
@@ -411,7 +417,7 @@ public class PatternTermContainer extends MEMonitorableContainer
|
||||
|
||||
@Override
|
||||
public void onSlotChange(final Slot s) {
|
||||
if (s == this.patternSlotOUT && Platform.isServer()) {
|
||||
if (s == this.patternSlotOUT && isServer()) {
|
||||
for (final IContainerListener listener : this.listeners) {
|
||||
for (final Slot slot : this.inventorySlots) {
|
||||
if (slot instanceof OptionalFakeSlot || slot instanceof FakeCraftingMatrixSlot) {
|
||||
@@ -425,7 +431,7 @@ public class PatternTermContainer extends MEMonitorableContainer
|
||||
this.detectAndSendChanges();
|
||||
}
|
||||
|
||||
if (s == this.craftSlot && Platform.isClient()) {
|
||||
if (s == this.craftSlot && isClient()) {
|
||||
this.getAndUpdateOutput();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,17 +23,14 @@ import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.inventory.container.ContainerType;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
import appeng.api.config.SecurityPermissions;
|
||||
import appeng.api.parts.IPart;
|
||||
import appeng.client.gui.implementations.NumberEntryWidget;
|
||||
import appeng.container.AEBaseContainer;
|
||||
import appeng.container.ContainerLocator;
|
||||
import appeng.container.guisync.GuiSync;
|
||||
import appeng.core.sync.network.NetworkHandler;
|
||||
import appeng.core.sync.packets.ConfigValuePacket;
|
||||
import appeng.helpers.IPriorityHost;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class PriorityContainer extends AEBaseContainer {
|
||||
|
||||
@@ -43,60 +40,53 @@ public class PriorityContainer extends AEBaseContainer {
|
||||
PriorityContainer::new, IPriorityHost.class, SecurityPermissions.BUILD);
|
||||
|
||||
public static PriorityContainer fromNetwork(int windowId, PlayerInventory inv, PacketBuffer buf) {
|
||||
return helper.fromNetwork(windowId, inv, buf);
|
||||
return helper.fromNetwork(windowId, inv, buf, (host, container, buffer) -> {
|
||||
container.priorityValue = buffer.readVarInt();
|
||||
});
|
||||
}
|
||||
|
||||
public static boolean open(PlayerEntity player, ContainerLocator locator) {
|
||||
return helper.open(player, locator);
|
||||
return helper.open(player, locator, (host, buffer) -> buffer.writeVarInt(host.getPriority()));
|
||||
}
|
||||
|
||||
private final IPriorityHost priHost;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
private NumberEntryWidget textField;
|
||||
|
||||
@GuiSync(2)
|
||||
public long PriorityValue = -1;
|
||||
private int priorityValue;
|
||||
|
||||
public PriorityContainer(int id, final PlayerInventory ip, final IPriorityHost te) {
|
||||
super(TYPE, id, ip, (TileEntity) (te instanceof TileEntity ? te : null),
|
||||
(IPart) (te instanceof IPart ? te : null));
|
||||
this.priHost = te;
|
||||
this.priorityValue = te.getPriority();
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void setTextField(final NumberEntryWidget level) {
|
||||
this.textField = level;
|
||||
this.textField.setValue(this.PriorityValue, true);
|
||||
}
|
||||
|
||||
public void setPriority(final int newValue, final PlayerEntity player) {
|
||||
this.priHost.setPriority(newValue);
|
||||
this.PriorityValue = newValue;
|
||||
public void setPriority(final int newValue) {
|
||||
if (newValue != priorityValue) {
|
||||
if (isClient()) {
|
||||
// If for whatever reason the client enters the value first, do not update based
|
||||
// on incoming server data
|
||||
this.priorityValue = newValue;
|
||||
NetworkHandler.instance()
|
||||
.sendToServer(new ConfigValuePacket("PriorityHost.Priority", String.valueOf(newValue)));
|
||||
} else {
|
||||
this.priHost.setPriority(newValue);
|
||||
this.priorityValue = newValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detectAndSendChanges() {
|
||||
super.detectAndSendChanges();
|
||||
this.verifyPermissions(SecurityPermissions.BUILD, false);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
this.PriorityValue = this.priHost.getPriority();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(final String field, final Object oldValue, final Object newValue) {
|
||||
if (field.equals("PriorityValue")) {
|
||||
if (this.textField != null) {
|
||||
this.textField.setValue(this.PriorityValue, true);
|
||||
}
|
||||
}
|
||||
|
||||
super.onUpdate(field, oldValue, newValue);
|
||||
public int getPriorityValue() {
|
||||
return priorityValue;
|
||||
}
|
||||
|
||||
public IPriorityHost getPriorityHost() {
|
||||
return this.priHost;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ import appeng.core.Api;
|
||||
import appeng.items.contents.QuartzKnifeObj;
|
||||
import appeng.items.materials.MaterialItem;
|
||||
import appeng.tile.inventory.AppEngInternalInventory;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class QuartzKnifeContainer extends AEBaseContainer {
|
||||
|
||||
@@ -148,7 +147,7 @@ public class QuartzKnifeContainer extends AEBaseContainer {
|
||||
}
|
||||
|
||||
private void makePlate() {
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
if (!this.getItemHandler().extractItem(0, 1, false).isEmpty()) {
|
||||
final ItemStack item = QuartzKnifeContainer.this.toolInv.getItemStack();
|
||||
final ItemStack before = item.copy();
|
||||
|
||||
@@ -35,7 +35,6 @@ import appeng.container.guisync.GuiSync;
|
||||
import appeng.container.slot.OutputSlot;
|
||||
import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.tile.spatial.SpatialIOPortTileEntity;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class SpatialIOPortContainer extends AEBaseContainer {
|
||||
|
||||
@@ -65,7 +64,7 @@ public class SpatialIOPortContainer extends AEBaseContainer {
|
||||
public SpatialIOPortContainer(int id, final PlayerInventory ip, final SpatialIOPortTileEntity spatialIOPort) {
|
||||
super(TYPE, id, ip, spatialIOPort, null);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.network = spatialIOPort.getGridNode(AEPartLocation.INTERNAL).getGrid();
|
||||
}
|
||||
|
||||
@@ -89,7 +88,7 @@ public class SpatialIOPortContainer extends AEBaseContainer {
|
||||
public void detectAndSendChanges() {
|
||||
this.verifyPermissions(SecurityPermissions.BUILD, false);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.delay++;
|
||||
if (this.delay > 15 && this.network != null) {
|
||||
this.delay = 0;
|
||||
|
||||
@@ -44,7 +44,6 @@ import appeng.container.slot.OptionalTypeOnlyFakeSlot;
|
||||
import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.core.Api;
|
||||
import appeng.parts.misc.StorageBusPart;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.helpers.ItemHandlerUtil;
|
||||
import appeng.util.iterators.NullIterator;
|
||||
|
||||
@@ -124,7 +123,7 @@ public class StorageBusContainer extends UpgradeableContainer {
|
||||
public void detectAndSendChanges() {
|
||||
this.verifyPermissions(SecurityPermissions.BUILD, false);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.setFuzzyMode((FuzzyMode) this.getUpgradeable().getConfigManager().getSetting(Settings.FUZZY_MODE));
|
||||
this.setReadWriteMode(
|
||||
(AccessRestriction) this.getUpgradeable().getConfigManager().getSetting(Settings.ACCESS));
|
||||
|
||||
@@ -51,7 +51,6 @@ import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.items.contents.NetworkToolViewer;
|
||||
import appeng.items.tools.NetworkToolItem;
|
||||
import appeng.parts.automation.ExportBusPart;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class UpgradeableContainer extends AEBaseContainer implements IOptionalSlotHost {
|
||||
|
||||
@@ -199,7 +198,7 @@ public class UpgradeableContainer extends AEBaseContainer implements IOptionalSl
|
||||
public void detectAndSendChanges() {
|
||||
this.verifyPermissions(SecurityPermissions.BUILD, false);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
final IConfigManager cm = this.getUpgradeable().getConfigManager();
|
||||
this.loadSettingsFromHost(cm);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import appeng.container.guisync.GuiSync;
|
||||
import appeng.container.interfaces.IProgressProvider;
|
||||
import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.tile.misc.VibrationChamberTileEntity;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class VibrationChamberContainer extends AEBaseContainer implements IProgressProvider {
|
||||
|
||||
@@ -65,7 +64,7 @@ public class VibrationChamberContainer extends AEBaseContainer implements IProgr
|
||||
|
||||
@Override
|
||||
public void detectAndSendChanges() {
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.remainingBurnTime = this.vibrationChamber.getMaxBurnTime() <= 0 ? 0
|
||||
: (int) (100.0 * this.vibrationChamber.getBurnTime() / this.vibrationChamber.getMaxBurnTime());
|
||||
this.burnSpeed = this.remainingBurnTime <= 0 ? 0 : this.vibrationChamber.getBurnSpeed();
|
||||
|
||||
@@ -28,7 +28,6 @@ import appeng.container.ContainerLocator;
|
||||
import appeng.core.AEConfig;
|
||||
import appeng.core.localization.PlayerMessages;
|
||||
import appeng.helpers.WirelessTerminalGuiObject;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class WirelessTermContainer extends MEPortableCellContainer {
|
||||
|
||||
@@ -57,7 +56,7 @@ public class WirelessTermContainer extends MEPortableCellContainer {
|
||||
super.detectAndSendChanges();
|
||||
|
||||
if (!this.wirelessTerminalGUIObject.rangeCheck()) {
|
||||
if (Platform.isServer() && this.isValidContainer()) {
|
||||
if (isServer() && this.isValidContainer()) {
|
||||
this.getPlayerInv().player.sendMessage(PlayerMessages.OutOfRange.get(), Util.DUMMY_UUID);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@ import java.util.Set;
|
||||
import java.util.function.DoubleSupplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
@@ -393,6 +395,15 @@ public final class AEConfig {
|
||||
return this.meteoriteDimensionWhitelist;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getImprovedFluidTag() {
|
||||
return Strings.emptyToNull(COMMON.improvedFluidTag.get());
|
||||
}
|
||||
|
||||
public float getImprovedFluidMultiplier() {
|
||||
return COMMON.improvedFluidMultiplier.get().floatValue();
|
||||
}
|
||||
|
||||
// Setters keep visibility as low as possible.
|
||||
|
||||
private static class ClientConfig {
|
||||
@@ -507,6 +518,11 @@ public final class AEConfig {
|
||||
public final ConfigValue<Integer> condenserMatterBallsPower;
|
||||
public final ConfigValue<Integer> condenserSingularityPower;
|
||||
|
||||
// In-World Purification
|
||||
// Settings for improved speed depending on fluid the crystal is in
|
||||
public final ConfigValue<String> improvedFluidTag;
|
||||
public final ConfigValue<Double> improvedFluidMultiplier;
|
||||
|
||||
public final Map<TickRates, ConfigValue<Integer>> tickRateMin = new HashMap<>();
|
||||
public final Map<TickRates, ConfigValue<Integer>> tickRateMax = new HashMap<>();
|
||||
|
||||
@@ -579,7 +595,7 @@ public final class AEConfig {
|
||||
this.spawnChargedChance = builder.defineInRange("spawnChargedChance", 0.08, 0.0, 1.0);
|
||||
this.meteoriteMaximumSpawnHeight = builder.define("meteoriteMaximumSpawnHeight", 180);
|
||||
List<String> defaultDimensionWhitelist = new ArrayList<>();
|
||||
defaultDimensionWhitelist.add(World.field_234918_g_.getRegistryName().toString());
|
||||
defaultDimensionWhitelist.add(World.OVERWORLD.getRegistryName().toString());
|
||||
this.meteoriteDimensionWhitelist = builder.defineList("meteoriteDimensionWhitelist",
|
||||
defaultDimensionWhitelist, obj -> true);
|
||||
|
||||
@@ -617,6 +633,17 @@ public final class AEConfig {
|
||||
tickRateMax.put(tickRate, builder.define(tickRate.name() + "Max", tickRate.getDefaultMax()));
|
||||
}
|
||||
builder.pop();
|
||||
|
||||
builder.comment("Settings for in-world purification of crystals.").push("inWorldPurification");
|
||||
|
||||
improvedFluidTag = builder.comment(
|
||||
"A fluid tag that identifies fluids that improve crystal purification speed. Does not affect purification with water/lava.")
|
||||
.define("improvedFluidTag", "");
|
||||
improvedFluidMultiplier = builder
|
||||
.comment("The speed multiplier to use when the crystals are submerged in the improved fluid.")
|
||||
.defineInRange("improvedFluidMultiplier", 2.0, 1.0, 10.0);
|
||||
|
||||
builder.pop();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public final class AppEngBootstrap {
|
||||
public synchronized static void enhanceBiomes() {
|
||||
// add to all standard biomes
|
||||
// TODO: This means we'll not add these things to newly created biomes
|
||||
WorldGenRegistries.field_243657_i.forEach(b -> {
|
||||
WorldGenRegistries.BIOME.forEach(b -> {
|
||||
addMeteoriteWorldGen(b);
|
||||
addQuartzWorldGen(b, quartzOreFeature, chargedQuartzOreFeature);
|
||||
});
|
||||
|
||||
@@ -22,7 +22,6 @@ import java.util.function.Supplier;
|
||||
|
||||
import net.minecraft.advancements.CriteriaTriggers;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.ScreenManager;
|
||||
import net.minecraft.client.particle.ParticleManager;
|
||||
@@ -33,17 +32,7 @@ import net.minecraft.item.crafting.IRecipeSerializer;
|
||||
import net.minecraft.particles.ParticleType;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.WorldGenRegistries;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.gen.GenerationStage;
|
||||
import net.minecraft.world.gen.feature.Feature;
|
||||
import net.minecraft.world.gen.feature.IFeatureConfig;
|
||||
import net.minecraft.world.gen.feature.OreFeatureConfig;
|
||||
import net.minecraft.world.gen.feature.structure.Structure;
|
||||
import net.minecraft.world.gen.placement.IPlacementConfig;
|
||||
import net.minecraft.world.gen.placement.Placement;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.client.event.ColorHandlerEvent;
|
||||
@@ -62,14 +51,12 @@ import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.minecraftforge.fml.loading.FMLEnvironment;
|
||||
import net.minecraftforge.fml.network.IContainerFactory;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
import net.minecraftforge.registries.IForgeRegistry;
|
||||
|
||||
import appeng.api.config.Upgrades;
|
||||
import appeng.api.definitions.IBlocks;
|
||||
import appeng.api.definitions.IItems;
|
||||
import appeng.api.definitions.IParts;
|
||||
import appeng.api.features.AEFeature;
|
||||
import appeng.api.features.IRegistryContainer;
|
||||
import appeng.api.features.IWirelessTermHandler;
|
||||
import appeng.api.features.IWorldGen;
|
||||
@@ -219,15 +206,8 @@ import appeng.recipes.game.FacadeRecipe;
|
||||
import appeng.recipes.handlers.GrinderRecipeSerializer;
|
||||
import appeng.recipes.handlers.InscriberRecipeSerializer;
|
||||
import appeng.server.AECommand;
|
||||
import appeng.spatial.SpatialStorageBiome;
|
||||
import appeng.spatial.SpatialStorageChunkGenerator;
|
||||
import appeng.spatial.SpatialStorageDimensionIds;
|
||||
import appeng.tile.AEBaseTileEntity;
|
||||
import appeng.tile.crafting.MolecularAssemblerRenderer;
|
||||
import appeng.worldgen.ChargedQuartzOreConfig;
|
||||
import appeng.worldgen.ChargedQuartzOreFeature;
|
||||
import appeng.worldgen.meteorite.MeteoriteStructure;
|
||||
import appeng.worldgen.meteorite.MeteoriteStructurePiece;
|
||||
|
||||
final class Registration {
|
||||
|
||||
@@ -672,7 +652,7 @@ final class Registration {
|
||||
* world gen
|
||||
*/
|
||||
for (final IWorldGen.WorldGenType type : IWorldGen.WorldGenType.values()) {
|
||||
registries.worldgen().disableWorldGenForDimension(type, World.field_234919_h_.getRegistryName());
|
||||
registries.worldgen().disableWorldGenForDimension(type, World.THE_NETHER.getRegistryName());
|
||||
}
|
||||
|
||||
// whitelist from config
|
||||
|
||||
@@ -115,7 +115,12 @@ public class ApiCrafting implements ICraftingHelper {
|
||||
// We use the shared itemstack for an identity lookup.
|
||||
IAEItemStack ais = Api.instance().storage().getStorageChannel(IItemStorageChannel.class).createStack(is);
|
||||
|
||||
return new CraftingPatternDetails(ais, world);
|
||||
try {
|
||||
return new CraftingPatternDetails(ais, world);
|
||||
} catch (IllegalStateException e) {
|
||||
AELog.warn("Could not decode an invalid pattern %s: %s", is, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean attemptRecovery(EncodedPatternItem patternItem, ItemStack itemStack, World world) {
|
||||
|
||||
@@ -20,7 +20,9 @@ package appeng.core.api.definitions;
|
||||
|
||||
import static appeng.block.AEBaseBlock.defaultProps;
|
||||
|
||||
import net.minecraft.block.AbstractBlock;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.block.DispenserBlock;
|
||||
import net.minecraft.block.SlabBlock;
|
||||
import net.minecraft.block.SoundType;
|
||||
@@ -28,6 +30,7 @@ import net.minecraft.block.StairsBlock;
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.client.renderer.RenderType;
|
||||
import net.minecraft.entity.EntityClassification;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.common.ToolType;
|
||||
@@ -262,18 +265,20 @@ public final class ApiBlocks implements IBlocks {
|
||||
this.chiseledQuartzBlock = deco.block("chiseled_quartz_block", () -> new AEDecorativeBlock(QUARTZ_PROPERTIES))
|
||||
.build();
|
||||
|
||||
this.quartzGlass = registry.features(AEFeature.QUARTZ_GLASS)
|
||||
.block("quartz_glass", () -> new QuartzGlassBlock(defaultProps(Material.GLASS).notSolid()))
|
||||
.rendering(new BlockRenderingCustomizer() {
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
|
||||
rendering.renderType(RenderType.getCutout());
|
||||
}
|
||||
}).build();
|
||||
AbstractBlock.IExtendedPositionPredicate<EntityType<?>> neverAllowSpawn = (p1, p2, p3, p4) -> false;
|
||||
this.quartzGlass = registry.features(AEFeature.QUARTZ_GLASS).block("quartz_glass", () -> {
|
||||
return new QuartzGlassBlock(defaultProps(Material.GLASS).notSolid().setAllowsSpawn(neverAllowSpawn));
|
||||
}).rendering(new BlockRenderingCustomizer() {
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void customize(IBlockRendering rendering, IItemRendering itemRendering) {
|
||||
rendering.renderType(RenderType.getCutout());
|
||||
}
|
||||
}).build();
|
||||
this.quartzVibrantGlass = deco
|
||||
.block("quartz_vibrant_glass",
|
||||
() -> new QuartzLampBlock(defaultProps(Material.GLASS).setLightLevel(b -> 15).notSolid()))
|
||||
() -> new QuartzLampBlock(defaultProps(Material.GLASS).setLightLevel(b -> 15).notSolid()
|
||||
.setAllowsSpawn(neverAllowSpawn)))
|
||||
.addFeatures(AEFeature.DECORATIVE_LIGHTS, AEFeature.QUARTZ_GLASS)
|
||||
.rendering(new BlockRenderingCustomizer() {
|
||||
@Override
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user