Compare commits
150 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5da5315a5b | |||
| f3c44c64c2 | |||
| b8f48407cd | |||
| 489b0f635e | |||
| e6fb553a53 | |||
| cacd824db3 | |||
| 876bb52087 | |||
| 1b4969c8e7 | |||
| f2427ee347 | |||
| 4aa9c92a68 | |||
| 971a9d22e8 | |||
| b5a90357c0 | |||
| 5be0adbc89 | |||
| d8e5f4fed5 | |||
| 47dfc19b7c | |||
| 45f5851079 | |||
| 76efe6026d | |||
| 4e03cbd356 | |||
| ce058b006c | |||
| 9005db6f1c | |||
| 58afe755b8 | |||
| f368f9dac2 | |||
| e5b45d51cc | |||
| 5a1d5356d1 | |||
| 5aef82b9ef | |||
| 483f93f977 | |||
| 1759f92164 | |||
| e50c13e570 | |||
| c0575e11b0 | |||
| 749dd35f88 | |||
| ca79a377bd | |||
| 475c8ff5a1 | |||
| 5b3ccf26d0 | |||
| e73dbe4891 | |||
| 38244000c9 | |||
| d87ff9d1e7 | |||
| 4ba97ec899 | |||
| 0147e1ddfb | |||
| 621d2ee715 | |||
| 31ecdfbe0a | |||
| f0bfbfec48 | |||
| 06a8843a65 | |||
| d07937fa93 | |||
| 65f58913a4 | |||
| 2bca23d75d | |||
| b47543d166 | |||
| a340925d98 | |||
| b8e53adf40 | |||
| 44544c598f | |||
| 0be7322c2c | |||
| a521e827db | |||
| bcee2ec427 | |||
| 17648633fe | |||
| fcbebd4ffc | |||
| 9e41d543f5 | |||
| 81cc0b804d | |||
| e1fc9908b3 | |||
| 9ed1535477 | |||
| 1ef345d4a4 | |||
| ff7d1b9719 | |||
| 88c9370e4f | |||
| f2aae3ef0f | |||
| 12739f1e66 | |||
| 81d2170ada | |||
| 0f469e9df6 | |||
| 0f34f09b32 | |||
| 8e54a8fed9 | |||
| ca007a3737 | |||
| 92b6650022 | |||
| e1cd3bba25 | |||
| 689bf6e8d9 | |||
| c8a5049d71 | |||
| 10a1a6d855 | |||
| d9bb81a00f | |||
| 39e038d916 | |||
| 575a625f75 | |||
| 89ea923c43 | |||
| 5d818eb03e | |||
| 12ca8d109a | |||
| e34126458b | |||
| 0ac918c363 | |||
| b6160e40bc | |||
| cf103b06c1 | |||
| f0d0595c8f | |||
| b756d68be1 | |||
| 60b07e5ca5 | |||
| 7c99fca789 | |||
| ab393b0ed1 | |||
| 957bc4c5cc | |||
| 133ed1f09d | |||
| e90dd2f9c6 | |||
| 9719c7ffc3 | |||
| 319d92a371 | |||
| db9ec2b070 | |||
| 5d33005aaf | |||
| 87cf070b33 | |||
| 3a0552c56e | |||
| b1a55f3a79 | |||
| 226e9596ee | |||
| 5cab9c8799 | |||
| 1d2ac29742 | |||
| cbe6012b98 | |||
| 8a0dd192e5 | |||
| 1842febf86 | |||
| a97b35f3d0 | |||
| 00d4c20d9f | |||
| d2b69671f5 | |||
| 1394ab0863 | |||
| 5efc085693 | |||
| 359e3f7e63 | |||
| fa3e41e687 | |||
| 4e86c92720 | |||
| 159f4c7f14 | |||
| aff94cec8c | |||
| 07dfa3db2e | |||
| e0e139900f | |||
| 9942f2d32c | |||
| 858826d1fa | |||
| 90ad345672 | |||
| 9a81ebfa50 | |||
| da9fa3d697 | |||
| ee7fe9f40d | |||
| 2184d03d0b | |||
| cae1621613 | |||
| e8574d03ea | |||
| d28f33d198 | |||
| 7df5bf4076 | |||
| 66760865a3 | |||
| e4a08ba99d | |||
| f11e9e2a4c | |||
| 7a469c1a1d | |||
| e256a4f664 | |||
| 73cc3f8998 | |||
| 9c9a49f9e7 | |||
| 44c0931c02 | |||
| 874f46ed4d | |||
| b7949e4134 | |||
| ea95913ec8 | |||
| 423ab81813 | |||
| d82c713112 | |||
| 45cbc40177 | |||
| 33d7f02323 | |||
| 4e42b17e81 | |||
| 0e7e9313ee | |||
| 2bba843313 | |||
| a0949297d5 | |||
| 420fb272b4 | |||
| fc0f8eab56 | |||
| 41b7900706 | |||
| 7656157b0d |
@@ -21,7 +21,9 @@ jobs:
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
|
||||
- name: Build with Gradle
|
||||
- name: Generate Resources
|
||||
run: ./gradlew generateData
|
||||
- name: Build
|
||||
run: ./gradlew build
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
|
||||
@@ -2,7 +2,8 @@ name: 'Build PRs'
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
branches:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
@@ -23,10 +23,14 @@ jobs:
|
||||
run: chmod +x gradlew
|
||||
- name: Validate no assets
|
||||
run: test ! -d ./src/generated
|
||||
- name: Generate resources
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: ./gradlew generateData
|
||||
- name: Build with Gradle
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: ./gradlew generateData build
|
||||
run: ./gradlew build
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
|
||||
@@ -72,19 +72,41 @@ 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'
|
||||
}
|
||||
}
|
||||
|
||||
// Required for libblockattributes
|
||||
maven {
|
||||
name = "BuildCraft"
|
||||
url = "https://mod-buildcraft.com/maven"
|
||||
content {
|
||||
includeGroup "alexiil.mc.lib"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
When compiling against the AE2 API you can use gradle dependencies, just add
|
||||
|
||||
dependencies {
|
||||
compileOnly "appeng:appliedenergistics2:VERSION:api"
|
||||
modCompileOnly "appeng:appliedenergistics2-fabric:VERSION:api"
|
||||
|
||||
// Include only if you want AE2 at runtime
|
||||
modRuntimeOnly "appeng:appliedenergistics2-fabric:VERSION"
|
||||
}
|
||||
|
||||
or add the `compileOnly` line to your existing dependencies task to your build.gradle.
|
||||
|
||||
+178
-48
@@ -47,6 +47,47 @@ repositories {
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
|
||||
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||
|
||||
//Fabric api
|
||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_version}"
|
||||
|
||||
modImplementation "alexiil.mc.lib:libblockattributes-core:${libblockattributes_version}"
|
||||
modImplementation "alexiil.mc.lib:libblockattributes-items:${libblockattributes_version}"
|
||||
modImplementation "alexiil.mc.lib:libblockattributes-fluids:${libblockattributes_version}"
|
||||
include "alexiil.mc.lib:libblockattributes-core:${libblockattributes_version}"
|
||||
include "alexiil.mc.lib:libblockattributes-items:${libblockattributes_version}"
|
||||
include "alexiil.mc.lib:libblockattributes-fluids:${libblockattributes_version}"
|
||||
|
||||
// Energy API
|
||||
modApi "teamreborn:energy:${tr_energy_version}"
|
||||
include "teamreborn:energy:${tr_energy_version}"
|
||||
|
||||
modCompileOnly("me.shedaniel:RoughlyEnoughItems:${rei_version}") {
|
||||
exclude group: "net.fabricmc.fabric-api"
|
||||
}
|
||||
modCompileOnly("mcp.mobius.waila:Hwyla:1.16.1-1.9.22-75") {
|
||||
exclude group: "net.fabricmc.fabric-api"
|
||||
}
|
||||
modRuntime("me.shedaniel:RoughlyEnoughItems:${rei_version}") {
|
||||
exclude group: "net.fabricmc.fabric-api"
|
||||
}
|
||||
modRuntime("TechReborn:TechReborn-1.16:3.5.1+build.101") {
|
||||
exclude group: "net.fabricmc.fabric-api"
|
||||
}
|
||||
// modRuntimeOnly "mcp.mobius.waila:Hwyla:1.16.1-1.9.22-75"
|
||||
|
||||
implementation 'com.google.code.findbugs:jsr305:3.0.2'
|
||||
|
||||
// unit test dependencies
|
||||
testCompile "junit:junit:4.13"
|
||||
}
|
||||
group = artifact_group
|
||||
archivesBaseName = artifact_basename
|
||||
|
||||
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_1_8
|
||||
compileJava {
|
||||
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_1_8
|
||||
@@ -59,7 +100,9 @@ tasks.withType(JavaCompile) {
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
|
||||
// Create version number
|
||||
///////////////////
|
||||
// Version Number
|
||||
|
||||
ext.pr = System.getenv('PR_NUMBER') ?: ""
|
||||
if (ext.pr) {
|
||||
version = version + "+pr." + ext.pr
|
||||
@@ -81,9 +124,8 @@ if (ext.tag && ext.tag.startsWith("fabric/v")) {
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
@@ -119,51 +161,12 @@ configurations {
|
||||
siteexportRuntime.extendsFrom(runtimeClasspath)
|
||||
}
|
||||
|
||||
apply from: 'gradle/scripts/spotless.gradle'
|
||||
|
||||
////////////////////
|
||||
// Forge/Minecraft
|
||||
minecraft {
|
||||
accessWidener "src/main/resources/appliedenergistics2.accesswidener"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft "com.mojang:minecraft:${project.minecraft_version}"
|
||||
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
|
||||
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
|
||||
|
||||
//Fabric api
|
||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_version}"
|
||||
|
||||
modImplementation "alexiil.mc.lib:libblockattributes-core:${libblockattributes_version}"
|
||||
modImplementation "alexiil.mc.lib:libblockattributes-items:${libblockattributes_version}"
|
||||
modImplementation "alexiil.mc.lib:libblockattributes-fluids:${libblockattributes_version}"
|
||||
include "alexiil.mc.lib:libblockattributes-core:${libblockattributes_version}"
|
||||
include "alexiil.mc.lib:libblockattributes-items:${libblockattributes_version}"
|
||||
include "alexiil.mc.lib:libblockattributes-fluids:${libblockattributes_version}"
|
||||
|
||||
// Energy API
|
||||
modApi "teamreborn:energy:${tr_energy_version}"
|
||||
include "teamreborn:energy:${tr_energy_version}"
|
||||
|
||||
modCompileOnly("me.shedaniel:RoughlyEnoughItems:5.0.2-unstable") {
|
||||
exclude group: "net.fabricmc.fabric-api"
|
||||
}
|
||||
modCompileOnly("mcp.mobius.waila:Hwyla:1.16.1-1.9.22-75") {
|
||||
exclude group: "net.fabricmc.fabric-api"
|
||||
}
|
||||
modRuntime("me.shedaniel:RoughlyEnoughItems:5.0.2-unstable") {
|
||||
exclude group: "net.fabricmc.fabric-api"
|
||||
}
|
||||
modRuntime("TechReborn:TechReborn-1.16:3.5.1+build.101") {
|
||||
exclude group: "net.fabricmc.fabric-api"
|
||||
}
|
||||
// modRuntimeOnly "mcp.mobius.waila:Hwyla:1.16.1-1.9.22-75"
|
||||
|
||||
implementation 'com.google.code.findbugs:jsr305:3.0.2'
|
||||
|
||||
// unit test dependencies
|
||||
testCompile "junit:junit:4.13"
|
||||
}
|
||||
|
||||
processResources {
|
||||
inputs.property "version", project.version
|
||||
|
||||
@@ -177,10 +180,76 @@ processResources {
|
||||
}
|
||||
}
|
||||
|
||||
apply from: 'gradle/scripts/artifacts.gradle'
|
||||
apply from: 'gradle/scripts/curseforge.gradle'
|
||||
//////////////
|
||||
// Aritfacts
|
||||
processResources {
|
||||
exclude '.cache'
|
||||
}
|
||||
|
||||
// configure the maven publication
|
||||
jar {
|
||||
finalizedBy 'remapJar'
|
||||
|
||||
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
|
||||
}
|
||||
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
|
||||
// if it is present.
|
||||
// If you remove this task, sources will not be generated.
|
||||
task sourcesJar(type: Jar, dependsOn: classes) {
|
||||
classifier = "sources"
|
||||
from sourceSets.main.allSource
|
||||
from sourceSets.api.allSource
|
||||
}
|
||||
|
||||
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 {
|
||||
if (!version.endsWith("-SNAPSHOT")) {
|
||||
publications {
|
||||
@@ -239,3 +308,64 @@ task runSiteExport(type: RunClientTask, dependsOn: downloadAssets, group: "ae2",
|
||||
classpath sourceSets.main.output
|
||||
classpath sourceSets.siteexport.output
|
||||
}
|
||||
|
||||
/////////////
|
||||
// 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") && !version.endsWith("-SNAPSHOT")) {
|
||||
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
|
||||
addGameVersion project.minecraft_version
|
||||
addGameVersion "Fabric"
|
||||
mainArtifact(remapJar.archiveFile) {
|
||||
displayName = "${project.version} [FABRIC]"
|
||||
}
|
||||
}
|
||||
options {
|
||||
forgeGradleIntegration = false
|
||||
}
|
||||
afterEvaluate {
|
||||
tasks.getByName("curseforge${project.curseforge_project}").dependsOn remapJar
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////
|
||||
// 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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-11
@@ -3,28 +3,24 @@ version=0.0.0-SNAPSHOT
|
||||
artifact_group=appeng
|
||||
artifact_basename=appliedenergistics2-fabric
|
||||
|
||||
kotlin.code.style=official
|
||||
org.gradle.jvmargs=-Xmx2G
|
||||
|
||||
# Fabric Properties
|
||||
# Check these on https://modmuss50.me/fabric.html
|
||||
|
||||
minecraft_version=1.16.2
|
||||
yarn_mappings=1.16.2+build.6
|
||||
loader_version=0.9.1+build.205
|
||||
minecraft_version=1.16.3
|
||||
yarn_mappings=1.16.3+build.11
|
||||
loader_version=0.9.3+build.207
|
||||
|
||||
#Fabric api
|
||||
fabric_version=0.17.2+build.396-1.16
|
||||
fabric_version=0.21.0+build.407-1.16
|
||||
|
||||
loom_version=0.4-SNAPSHOT
|
||||
|
||||
# Kotlin
|
||||
kotlin_version=1.3.61
|
||||
fabric_kotlin_version=1.3.61+build.1
|
||||
loom_version=0.5-SNAPSHOT
|
||||
|
||||
# Dependencies
|
||||
libblockattributes_version=0.8.0-pre.18
|
||||
libblockattributes_version=0.8.0
|
||||
tr_energy_version=0.1.0
|
||||
rei_version=5.2.10
|
||||
|
||||
#########################################################
|
||||
# Deployment #
|
||||
|
||||
@@ -1,78 +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 'remapJar'
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
|
||||
// if it is present.
|
||||
// If you remove this task, sources will not be generated.
|
||||
task sourcesJar(type: Jar, dependsOn: classes) {
|
||||
classifier = "sources"
|
||||
from sourceSets.main.allSource
|
||||
from sourceSets.api.allSource
|
||||
}
|
||||
|
||||
task apiJar(type: Jar) {
|
||||
classifier = "api"
|
||||
from sourceSets.api.output
|
||||
include "appeng/api/**"
|
||||
}
|
||||
|
||||
artifacts {
|
||||
archives javadocJar
|
||||
archives sourcesJar
|
||||
archives apiJar
|
||||
}
|
||||
@@ -1,50 +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") && !version.endsWith("-SNAPSHOT")) {
|
||||
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
|
||||
addGameVersion project.minecraft_version
|
||||
addGameVersion "Fabric"
|
||||
mainArtifact(remapJar.archiveFile) {
|
||||
displayName = "${project.version} [FABRIC]"
|
||||
}
|
||||
}
|
||||
options {
|
||||
forgeGradleIntegration = false
|
||||
}
|
||||
afterEvaluate {
|
||||
tasks.getByName("curseforge${project.curseforge_project}").dependsOn remapJar
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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'])
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,6 @@ pluginManagement {
|
||||
|
||||
plugins {
|
||||
id "fabric-loom" version loom_version
|
||||
id "org.jetbrains.kotlin.jvm" version kotlin_version
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -53,10 +53,10 @@ 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.
|
||||
* @throws IllegalArgumentException If either in or out contain only empty
|
||||
* ItemStacks.
|
||||
*/
|
||||
ItemStack encodeProcessingPattern(@Nullable ItemStack stack, ItemStack[] in, ItemStack[] out);
|
||||
|
||||
|
||||
@@ -82,11 +82,6 @@ public interface IRegistryContainer {
|
||||
*/
|
||||
IPlayerRegistry players();
|
||||
|
||||
/**
|
||||
* get access to the world-gen api.
|
||||
*/
|
||||
IWorldGen worldgen();
|
||||
|
||||
/**
|
||||
* Register your IPart models before using them.
|
||||
*/
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013 AlgorithmX2
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package appeng.api.features;
|
||||
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public interface IWorldGen {
|
||||
|
||||
void enableWorldGenForDimension(WorldGenType type, Identifier dimID);
|
||||
|
||||
void disableWorldGenForDimension(WorldGenType type, Identifier dimID);
|
||||
|
||||
boolean isWorldGenEnabled(WorldGenType type, ServerWorld w);
|
||||
|
||||
enum WorldGenType {
|
||||
CERTUS_QUARTZ, CHARGED_CERTUS_QUARTZ, METEORITES
|
||||
}
|
||||
}
|
||||
@@ -23,13 +23,23 @@
|
||||
|
||||
package appeng.api.implementations.items;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.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);
|
||||
|
||||
|
||||
@@ -4,6 +4,9 @@ import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import net.fabricmc.loader.api.entrypoint.PreLaunchEntrypoint;
|
||||
import net.minecraft.Bootstrap;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
@@ -11,16 +14,22 @@ import net.minecraft.data.DataGenerator;
|
||||
import appeng.data.providers.loot.BlockDropProvider;
|
||||
import appeng.data.providers.recipes.SlabStairRecipes;
|
||||
import appeng.data.providers.tags.ConventionTagProvider;
|
||||
import appeng.data.providers.tags.ToolTagProviders;
|
||||
|
||||
public class Entrypoint implements PreLaunchEntrypoint {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
public static void dump() throws Exception {
|
||||
Path output = Paths.get("../src/generated/resources");
|
||||
|
||||
LOGGER.info("Writing generated resources to {}", output.toAbsolutePath());
|
||||
|
||||
DataGenerator generator = new DataGenerator(output, Collections.emptyList());
|
||||
generator.install(new BlockDropProvider(output));
|
||||
generator.install(new SlabStairRecipes(output));
|
||||
generator.install(new ConventionTagProvider(output));
|
||||
generator.install(new ToolTagProviders(output));
|
||||
generator.run();
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import appeng.core.AppEng;
|
||||
public class ConventionTagProvider extends TagProvider {
|
||||
|
||||
public ConventionTagProvider(Path outputPath) {
|
||||
super(outputPath);
|
||||
super("c", outputPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,15 +24,17 @@ import appeng.data.providers.IAE2DataProvider;
|
||||
public abstract class TagProvider implements IAE2DataProvider {
|
||||
|
||||
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
|
||||
protected static final String CONVENTION_NAMESPACE = "c";
|
||||
protected static final String TYPE_ITEMS = "items";
|
||||
protected static final String TYPE_BLOCKS = "blocks";
|
||||
|
||||
private final String defaultNamespace;
|
||||
|
||||
private final Path outputPath;
|
||||
|
||||
private DataCache cache;
|
||||
|
||||
protected TagProvider(Path outputPath) {
|
||||
protected TagProvider(String defaultNamespace, Path outputPath) {
|
||||
this.defaultNamespace = defaultNamespace;
|
||||
this.outputPath = outputPath;
|
||||
}
|
||||
|
||||
@@ -49,15 +51,19 @@ public abstract class TagProvider implements IAE2DataProvider {
|
||||
protected abstract void generate() throws IOException;
|
||||
|
||||
protected void addItemTag(String name, ItemConvertible... items) throws IOException {
|
||||
Identifier id = parseId(name);
|
||||
|
||||
List<String> itemIds = Arrays.stream(items).map(ItemConvertible::asItem).map(Registry.ITEM::getId)
|
||||
.map(Identifier::toString).collect(Collectors.toList());
|
||||
writeTagFile(CONVENTION_NAMESPACE, TYPE_ITEMS, name, itemIds);
|
||||
writeTagFile(id.getNamespace(), TYPE_ITEMS, id.getPath(), itemIds);
|
||||
}
|
||||
|
||||
protected void addBlockTag(String name, Block... blocks) throws IOException {
|
||||
Identifier id = parseId(name);
|
||||
|
||||
List<String> itemIds = Arrays.stream(blocks).map(Registry.BLOCK::getId).map(Identifier::toString)
|
||||
.collect(Collectors.toList());
|
||||
writeTagFile(CONVENTION_NAMESPACE, TYPE_BLOCKS, name, itemIds);
|
||||
writeTagFile(id.getNamespace(), TYPE_BLOCKS, id.getPath(), itemIds);
|
||||
}
|
||||
|
||||
protected void writeTagFile(String namespace, String tagType, String tagName, List<String> entries)
|
||||
@@ -75,7 +81,15 @@ public abstract class TagProvider implements IAE2DataProvider {
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return AppEng.MOD_NAME + " Convention Tags";
|
||||
return AppEng.MOD_NAME + " Tags (" + defaultNamespace + ")";
|
||||
}
|
||||
|
||||
private Identifier parseId(String name) {
|
||||
if (name.contains(":")) {
|
||||
return new Identifier(name);
|
||||
} else {
|
||||
return new Identifier(defaultNamespace, name);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package appeng.data.providers.tags;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import appeng.core.AppEng;
|
||||
|
||||
public class ToolTagProviders extends TagProvider {
|
||||
|
||||
public ToolTagProviders(Path outputPath) {
|
||||
super("fabric", outputPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void generate() throws IOException {
|
||||
addItemTag("axes", ITEMS.netherQuartzAxe(), ITEMS.certusQuartzAxe());
|
||||
addItemTag("hoes", ITEMS.netherQuartzHoe(), ITEMS.certusQuartzHoe());
|
||||
addItemTag("pickaxes", ITEMS.netherQuartzPick(), ITEMS.certusQuartzPick());
|
||||
addItemTag("shovels", ITEMS.netherQuartzShovel(), ITEMS.certusQuartzShovel());
|
||||
addItemTag("swords", ITEMS.netherQuartzSword(), ITEMS.certusQuartzSword());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return AppEng.MOD_NAME + " Tool Tags";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -48,7 +48,7 @@ public final class MEAttributes {
|
||||
return null;
|
||||
}
|
||||
|
||||
return attribute.getFirstOrNull(world, be.getPos().offset(side), SearchOptions.inDirection(side.getOpposite()));
|
||||
return attribute.getFirstOrNull(world, be.getPos(), SearchOptions.inDirection(side.getOpposite()));
|
||||
}
|
||||
|
||||
// Convenience function to get an attribute of the block that is in front of a
|
||||
|
||||
@@ -232,7 +232,7 @@ public abstract class AEBaseTileBlock<T extends AEBaseBlockEntity> extends AEBas
|
||||
Platform.spawnDrops(world, pos, itemsToDrop);
|
||||
}
|
||||
|
||||
return ActionResult.FAIL;
|
||||
return ActionResult.SUCCESS;
|
||||
}
|
||||
|
||||
if (heldItem.getItem() instanceof IMemoryCard && !(this instanceof CableBusBlock)) {
|
||||
|
||||
@@ -161,4 +161,9 @@ public class CrankBlock extends AEBaseTileBlock<CrankBlockEntity> {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasCustomRotation() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,8 @@ import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.ItemGroup;
|
||||
import net.minecraft.item.ItemPlacementContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.state.StateManager;
|
||||
import net.minecraft.state.property.IntProperty;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.DyeColor;
|
||||
import net.minecraft.util.Hand;
|
||||
@@ -80,8 +82,12 @@ public class CableBusBlock extends AEBaseTileBlock<CableBusBlockEntity> implemen
|
||||
|
||||
private static final ICableBusContainer NULL_CABLE_BUS = new NullCableBusContainer();
|
||||
|
||||
private static final IntProperty LIGHT_LEVEL = IntProperty.of("light_level", 0, 15);
|
||||
|
||||
public CableBusBlock() {
|
||||
super(defaultProps(AEMaterials.GLASS).nonOpaque().dropsNothing().dynamicBounds());
|
||||
super(defaultProps(AEMaterials.GLASS).nonOpaque().dropsNothing().dynamicBounds()
|
||||
.luminance(state -> state.get(LIGHT_LEVEL)));
|
||||
setDefaultState(getDefaultState().with(LIGHT_LEVEL, 0));
|
||||
}
|
||||
|
||||
static {
|
||||
@@ -134,16 +140,13 @@ public class CableBusBlock extends AEBaseTileBlock<CableBusBlockEntity> implemen
|
||||
// OPPOSITE!?
|
||||
}
|
||||
|
||||
// FIXME Dynamic light seems unsupported (?) Must maybe use blockstates... :|
|
||||
// FIXME FABRIC @Override
|
||||
// FIXME FABRIC public int getLightValue(final BlockState state, final BlockView world, final BlockPos pos) {
|
||||
// FIXME FABRIC if (state.getBlock() != this) {
|
||||
// FIXME FABRIC return state.getLuminance();
|
||||
// FIXME FABRIC }
|
||||
// FIXME FABRIC return this.cb(world, pos).getLightValue();
|
||||
// FIXME FABRIC }
|
||||
@Override
|
||||
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
|
||||
super.appendProperties(builder);
|
||||
builder.add(LIGHT_LEVEL);
|
||||
}
|
||||
|
||||
// FIXME: Must hook isClimbing ourselves
|
||||
// FIXME: Must hook isClimbing ourselves
|
||||
// FIXME FABRIC @Override
|
||||
// FIXME FABRIC public boolean isLadder(BlockState state, WorldView world, BlockPos pos, LivingEntity entity) {
|
||||
// FIXME FABRIC return this.cb(world, pos).isLadder(entity);
|
||||
@@ -399,4 +402,13 @@ public class CableBusBlock extends AEBaseTileBlock<CableBusBlockEntity> implemen
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockState updateBlockStateFromTileEntity(BlockState currentState, CableBusBlockEntity te) {
|
||||
if (currentState.getBlock() != this) {
|
||||
return currentState;
|
||||
}
|
||||
int lightLevel = te.getCableBus().getLightValue();
|
||||
return super.updateBlockStateFromTileEntity(currentState, te).with(LIGHT_LEVEL, lightLevel);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -38,11 +38,11 @@ import appeng.helpers.Splotch;
|
||||
*/
|
||||
class PaintSplotchesBakedModel implements BakedModel, FabricBakedModel {
|
||||
|
||||
private static final SpriteIdentifier TEXTURE_PAINT1 = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
private static final SpriteIdentifier TEXTURE_PAINT1 = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE,
|
||||
new Identifier(AppEng.MOD_ID, "block/paint1"));
|
||||
private static final SpriteIdentifier TEXTURE_PAINT2 = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
private static final SpriteIdentifier TEXTURE_PAINT2 = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE,
|
||||
new Identifier(AppEng.MOD_ID, "block/paint2"));
|
||||
private static final SpriteIdentifier TEXTURE_PAINT3 = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
private static final SpriteIdentifier TEXTURE_PAINT3 = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE,
|
||||
new Identifier(AppEng.MOD_ID, "block/paint3"));
|
||||
|
||||
private final Sprite[] textures;
|
||||
|
||||
@@ -36,18 +36,18 @@ import appeng.core.AppEng;
|
||||
|
||||
class QnbFormedBakedModel implements BakedModel, FabricBakedModel {
|
||||
|
||||
private static final SpriteIdentifier TEXTURE_LINK = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
private static final SpriteIdentifier TEXTURE_LINK = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE,
|
||||
new Identifier(AppEng.MOD_ID, "block/quantum_link"));
|
||||
private static final SpriteIdentifier TEXTURE_RING = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
private static final SpriteIdentifier TEXTURE_RING = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE,
|
||||
new Identifier(AppEng.MOD_ID, "block/quantum_ring"));
|
||||
private static final SpriteIdentifier TEXTURE_RING_LIGHT = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
new Identifier(AppEng.MOD_ID, "block/quantum_ring_light"));
|
||||
private static final SpriteIdentifier TEXTURE_RING_LIGHT = new SpriteIdentifier(
|
||||
SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier(AppEng.MOD_ID, "block/quantum_ring_light"));
|
||||
private static final SpriteIdentifier TEXTURE_RING_LIGHT_CORNER = new SpriteIdentifier(
|
||||
SpriteAtlasTexture.BLOCK_ATLAS_TEX, new Identifier(AppEng.MOD_ID, "block/quantum_ring_light_corner"));
|
||||
private static final SpriteIdentifier TEXTURE_CABLE_GLASS = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
new Identifier(AppEng.MOD_ID, "part/cable/glass/transparent"));
|
||||
SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier(AppEng.MOD_ID, "block/quantum_ring_light_corner"));
|
||||
private static final SpriteIdentifier TEXTURE_CABLE_GLASS = new SpriteIdentifier(
|
||||
SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier(AppEng.MOD_ID, "part/cable/glass/transparent"));
|
||||
private static final SpriteIdentifier TEXTURE_COVERED_CABLE = new SpriteIdentifier(
|
||||
SpriteAtlasTexture.BLOCK_ATLAS_TEX, new Identifier(AppEng.MOD_ID, "part/cable/covered/transparent"));
|
||||
SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, new Identifier(AppEng.MOD_ID, "part/cable/covered/transparent"));
|
||||
|
||||
private static final float DEFAULT_RENDER_MIN = 2.0f;
|
||||
private static final float DEFAULT_RENDER_MAX = 14.0f;
|
||||
|
||||
@@ -11,7 +11,6 @@ import com.google.common.base.Preconditions;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.client.rendereregistry.v1.BlockEntityRendererRegistry;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.entity.BlockEntityType;
|
||||
import net.minecraft.util.Identifier;
|
||||
@@ -19,6 +18,7 @@ import net.minecraft.util.registry.Registry;
|
||||
|
||||
import appeng.api.features.AEFeature;
|
||||
import appeng.block.AEBaseTileBlock;
|
||||
import appeng.bootstrap.components.BlockEntityRendererComponent;
|
||||
import appeng.bootstrap.components.ITileEntityRegistrationComponent;
|
||||
import appeng.bootstrap.definitions.TileEntityDefinition;
|
||||
import appeng.core.AppEng;
|
||||
@@ -115,7 +115,8 @@ public class BlockEntityBuilder<T extends AEBaseBlockEntity> {
|
||||
@Environment(EnvType.CLIENT)
|
||||
private void buildClient() {
|
||||
if (tileEntityRendering.tileEntityRenderer != null) {
|
||||
BlockEntityRendererRegistry.INSTANCE.register(type, tileEntityRendering.tileEntityRenderer);
|
||||
factory.addBootstrapComponent(
|
||||
new BlockEntityRendererComponent<>(type, tileEntityRendering.tileEntityRenderer));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package appeng.bootstrap.components;
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
import net.fabricmc.fabric.api.client.rendereregistry.v1.BlockEntityRendererRegistry;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.block.entity.BlockEntityType;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
|
||||
|
||||
/**
|
||||
* Registers a block entity renderer for a given block entity type. This must
|
||||
* occur late in the client's initialization, since the constructors of our
|
||||
* block entity renderers rely on the client being fully initialized.
|
||||
*/
|
||||
public class BlockEntityRendererComponent<T extends BlockEntity> implements IClientSetupComponent {
|
||||
|
||||
private final BlockEntityType<T> type;
|
||||
|
||||
private final Function<BlockEntityRenderDispatcher, BlockEntityRenderer<T>> renderer;
|
||||
|
||||
public BlockEntityRendererComponent(BlockEntityType<T> type,
|
||||
Function<BlockEntityRenderDispatcher, BlockEntityRenderer<T>> renderer) {
|
||||
this.type = type;
|
||||
this.renderer = renderer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
BlockEntityRendererRegistry.INSTANCE.register(type, renderer);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import javax.annotation.Nonnull;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
|
||||
import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry;
|
||||
import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry;
|
||||
@@ -184,7 +185,9 @@ public final class AppEngClient extends AppEngBase {
|
||||
|
||||
ModelsReloadCallback.EVENT.register(this::onModelsReloaded);
|
||||
|
||||
callDeferredBootstrapComponents(IClientSetupComponent.class, IClientSetupComponent::setup);
|
||||
ClientLifecycleEvents.CLIENT_STARTED.register(client -> {
|
||||
callDeferredBootstrapComponents(IClientSetupComponent.class, IClientSetupComponent::setup);
|
||||
});
|
||||
registerModelProviders();
|
||||
registerParticleRenderers();
|
||||
registerEntityRenderers();
|
||||
|
||||
@@ -28,6 +28,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Stopwatch;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
@@ -58,6 +59,7 @@ import net.minecraft.util.Identifier;
|
||||
import alexiil.mc.lib.attributes.fluid.render.FluidRenderFace;
|
||||
import alexiil.mc.lib.attributes.fluid.render.FluidVolumeRenderer;
|
||||
import alexiil.mc.lib.attributes.fluid.volume.FluidVolume;
|
||||
import me.shedaniel.math.Rectangle;
|
||||
|
||||
import appeng.api.storage.data.IAEFluidStack;
|
||||
import appeng.api.storage.data.IAEItemStack;
|
||||
@@ -104,6 +106,7 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends HandledScr
|
||||
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, Text title) {
|
||||
@@ -282,12 +285,18 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends HandledScr
|
||||
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 AbstractButtonWidget widget = (AbstractButtonWidget) o;
|
||||
if (widget.isMouseOver(xCoord, yCoord)) {
|
||||
return super.mouseClicked(xCoord, yCoord, 0);
|
||||
handlingRightClick = true;
|
||||
try {
|
||||
for (final Object o : this.buttons) {
|
||||
final AbstractButtonWidget widget = (AbstractButtonWidget) o;
|
||||
if (widget.isMouseOver(xCoord, yCoord)) {
|
||||
return super.mouseClicked(xCoord, yCoord, 0);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
handlingRightClick = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,22 +307,36 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends HandledScr
|
||||
}
|
||||
}
|
||||
|
||||
if (this.getScrollBar() != null) {
|
||||
this.getScrollBar().click(xCoord - this.x, yCoord - this.y);
|
||||
// Forward left mouse button down events to the scrollbar
|
||||
if (btn == 0 && this.getScrollBar() != null) {
|
||||
if (this.getScrollBar().mouseDown(xCoord - this.x, yCoord - this.y)) {
|
||||
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.x, mouseY - this.y)) {
|
||||
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.getCursorStack();
|
||||
|
||||
if (this.getScrollBar() != null) {
|
||||
// FIXME: Coordinate system of mouseX/mouseY is unclear
|
||||
this.getScrollBar().click((int) mouseX - this.x, (int) mouseY - this.y);
|
||||
this.getScrollBar().mouseDragged((int) mouseX - this.x, (int) mouseY - this.y);
|
||||
}
|
||||
|
||||
if (slot instanceof FakeSlot && !itemstack.isEmpty()) {
|
||||
@@ -620,15 +643,7 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends HandledScr
|
||||
}
|
||||
|
||||
protected Text getGuiDisplayName(final Text in) {
|
||||
return this.hasCustomInventoryName() ? new LiteralText(this.getInventoryName()) : in;
|
||||
}
|
||||
|
||||
private boolean hasCustomInventoryName() {
|
||||
return this.handler.getCustomName() != null;
|
||||
}
|
||||
|
||||
private String getInventoryName() {
|
||||
return this.handler.getCustomName();
|
||||
return title.getString().isEmpty() ? in : title;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -796,6 +811,11 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends HandledScr
|
||||
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
if (this.getScrollBar() != null) {
|
||||
this.getScrollBar().tick();
|
||||
}
|
||||
|
||||
for (Element child : children) {
|
||||
if (child instanceof ITickingWidget) {
|
||||
((ITickingWidget) child).tick();
|
||||
@@ -803,4 +823,15 @@ public abstract class AEBaseScreen<T extends AEBaseContainer> extends HandledScr
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true while the current event being handled is a click of the right
|
||||
* mouse button.
|
||||
*/
|
||||
public boolean isHandlingRightClick() {
|
||||
return handlingRightClick;
|
||||
}
|
||||
|
||||
public List<Rectangle> getExclusionZones() {
|
||||
return Lists.newArrayList(new Rectangle(x, y, backgroundWidth, backgroundHeight));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,8 +12,6 @@ import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import appeng.client.me.SlotME;
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -21,9 +19,9 @@ import appeng.client.me.SlotME;
|
||||
*/
|
||||
class Size1Slot extends Slot {
|
||||
|
||||
private final SlotME delegate;
|
||||
private final Slot delegate;
|
||||
|
||||
public Size1Slot(SlotME delegate) {
|
||||
public Size1Slot(Slot delegate) {
|
||||
super(delegate.inventory, -1, delegate.x, delegate.y);
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@@ -46,22 +46,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 ButtonWidget(this.x + 128, this.y + 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(ButtonWidget 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
|
||||
@@ -77,23 +83,9 @@ public class CraftAmountScreen extends AEBaseScreen<CraftAmountContainer> {
|
||||
this.bindTexture("guis/craft_amt.png");
|
||||
drawTexture(matrices, offsetX, offsetY, 0, 0, this.backgroundWidth, this.backgroundHeight);
|
||||
|
||||
this.next.active = this.amountToCraft.getValue() > 0;
|
||||
this.next.active = this.amountToCraft.getIntValue().orElse(0) > 0;
|
||||
|
||||
this.amountToCraft.render(matrices, 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";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ import java.util.List;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
@@ -73,10 +75,6 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
|
||||
this.setScrollBar(scrollbar);
|
||||
}
|
||||
|
||||
boolean isAutoStart() {
|
||||
return this.handler.isAutoStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
super.init();
|
||||
@@ -87,12 +85,14 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
|
||||
this.addButton(this.start);
|
||||
|
||||
this.selectCPU = new ButtonWidget(this.x + (219 - 180) / 2, this.y + this.backgroundHeight - 68, 180, 20,
|
||||
GuiText.CraftingCPU.withSuffix(": ").append(GuiText.Automatic.text()), btn -> selectNextCpu());
|
||||
getNextCpuButtonLabel(), btn -> selectNextCpu());
|
||||
this.selectCPU.active = false;
|
||||
this.addButton(this.selectCPU);
|
||||
|
||||
addButton(new ButtonWidget(this.x + 6, this.y + this.backgroundHeight - 25, 50, 20, GuiText.Cancel.text(),
|
||||
btn -> subGui.goBack()));
|
||||
|
||||
this.setScrollBar();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -133,22 +133,22 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
|
||||
}
|
||||
|
||||
private void updateCPUButtonText() {
|
||||
Text btnTextText = GuiText.CraftingCPU.withSuffix(": ").append(GuiText.Automatic.text());
|
||||
if (this.handler.getSelectedCpu() >= 0)// && status.selectedCpu < status.cpus.size() )
|
||||
{
|
||||
if (this.handler.getName() != null) {
|
||||
final String name = this.handler.getName().asTruncatedString(20);
|
||||
btnTextText = GuiText.CraftingCPU.withSuffix(": " + name);
|
||||
} else {
|
||||
btnTextText = GuiText.CraftingCPU.withSuffix(": #" + this.handler.getSelectedCpu());
|
||||
}
|
||||
}
|
||||
this.selectCPU.setMessage(getNextCpuButtonLabel());
|
||||
}
|
||||
|
||||
private Text getNextCpuButtonLabel() {
|
||||
if (this.handler.hasNoCPU()) {
|
||||
btnTextText = GuiText.NoCraftingCPUs.text();
|
||||
return GuiText.NoCraftingCPUs.text();
|
||||
}
|
||||
|
||||
this.selectCPU.setMessage(btnTextText);
|
||||
Text cpuName;
|
||||
if (this.handler.cpuName == null) {
|
||||
cpuName = GuiText.Automatic.text();
|
||||
} else {
|
||||
cpuName = this.handler.cpuName;
|
||||
}
|
||||
|
||||
return GuiText.CraftingCPU.withSuffix(": ").append(cpuName);
|
||||
}
|
||||
|
||||
private boolean isSimulation() {
|
||||
@@ -440,7 +440,7 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
|
||||
@Override
|
||||
public boolean keyPressed(int keyCode, int scanCode, int p_keyPressed_3_) {
|
||||
if (!this.checkHotbarKeys(keyCode, scanCode)) {
|
||||
if (keyCode == 28) {
|
||||
if (keyCode == GLFW.GLFW_KEY_ENTER || keyCode == GLFW.GLFW_KEY_KP_ENTER) {
|
||||
this.start();
|
||||
return true;
|
||||
}
|
||||
@@ -449,7 +449,7 @@ public class CraftConfirmScreen extends AEBaseScreen<CraftConfirmContainer> {
|
||||
}
|
||||
|
||||
private void selectNextCpu() {
|
||||
final boolean backwards = getClient().mouse.wasRightButtonClicked();
|
||||
final boolean backwards = isHandlingRightClick();
|
||||
NetworkHandler.instance().sendToServer(new ConfigValuePacket("Terminal.Cpu", backwards ? "Prev" : "Next"));
|
||||
}
|
||||
|
||||
|
||||
@@ -44,12 +44,12 @@ public class CraftingStatusScreen extends CraftingCPUScreen<CraftingStatusContai
|
||||
super.init();
|
||||
|
||||
this.selectCPU = new ButtonWidget(this.x + 8, this.y + this.backgroundHeight - 25, 150, 20,
|
||||
GuiText.CraftingCPU.withSuffix(": ").append(GuiText.NoCraftingCPUs.text()), btn -> selectNextCpu());
|
||||
getNextCpuButtonLabel(), btn -> selectNextCpu());
|
||||
this.addButton(this.selectCPU);
|
||||
|
||||
subGui.addBackButton(btn -> {
|
||||
addButton(btn);
|
||||
btn.setHideEdge(13);
|
||||
btn.setHideEdge(true);
|
||||
}, 213, -4);
|
||||
}
|
||||
|
||||
@@ -60,23 +60,14 @@ public class CraftingStatusScreen extends CraftingCPUScreen<CraftingStatusContai
|
||||
}
|
||||
|
||||
private void updateCPUButtonText() {
|
||||
Text btnTextText = GuiText.NoCraftingJobs.text();
|
||||
|
||||
if (this.handler.selectedCpu >= 0)// && status.selectedCpu < status.cpus.size() )
|
||||
{
|
||||
if (this.handler.myName != null) {
|
||||
final String name = this.handler.myName.asTruncatedString(20);
|
||||
btnTextText = GuiText.CPUs.withSuffix(": " + name);
|
||||
} else {
|
||||
btnTextText = GuiText.CPUs.withSuffix(": #" + this.handler.selectedCpu);
|
||||
}
|
||||
}
|
||||
this.selectCPU.setMessage(getNextCpuButtonLabel());
|
||||
}
|
||||
|
||||
private Text getNextCpuButtonLabel() {
|
||||
if (this.handler.noCPU) {
|
||||
btnTextText = GuiText.NoCraftingJobs.text();
|
||||
return GuiText.NoCraftingJobs.text();
|
||||
}
|
||||
|
||||
this.selectCPU.setMessage(btnTextText);
|
||||
return GuiText.CraftingCPU.withSuffix(": ").append(handler.cpuName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -84,9 +75,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 = client.mouse.wasRightButtonClicked();
|
||||
final boolean backwards = isHandlingRightClick();
|
||||
NetworkHandler.instance().sendToServer(new ConfigValuePacket("Terminal.Cpu", backwards ? "Prev" : "Next"));
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ public class InterfaceScreen extends UpgradeableScreen<InterfaceContainer> {
|
||||
}
|
||||
|
||||
private void selectNextInterfaceMode() {
|
||||
final boolean backwards = getClient().mouse.wasRightButtonClicked();
|
||||
final boolean backwards = isHandlingRightClick();
|
||||
NetworkHandler.instance().sendToServer(new ConfigButtonPacket(Settings.INTERFACE_TERMINAL, backwards));
|
||||
}
|
||||
|
||||
|
||||
@@ -70,8 +70,7 @@ public class InterfaceTerminalScreen extends AEBaseScreen<InterfaceTerminalConta
|
||||
|
||||
public InterfaceTerminalScreen(InterfaceTerminalContainer container, PlayerInventory playerInventory, Text title) {
|
||||
super(container, playerInventory, title);
|
||||
final Scrollbar scrollbar = new Scrollbar();
|
||||
this.setScrollBar(scrollbar);
|
||||
this.setScrollBar(new Scrollbar().setLeft(175).setTop(18).setHeight(106));
|
||||
this.backgroundWidth = 195;
|
||||
this.backgroundHeight = 222;
|
||||
}
|
||||
@@ -80,16 +79,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.textRenderer, this.x + 104, this.y + 4, 65, 12);
|
||||
this.searchField.setHasBorder(false);
|
||||
this.searchField.setMaxLength(25);
|
||||
this.searchField.setEditableColor(0xFFFFFF);
|
||||
this.searchField.setVisible(true);
|
||||
this.searchField.setFocused(true);
|
||||
this.searchField.setChangedListener(str -> this.refreshList());
|
||||
this.addChild(this.searchField);
|
||||
this.changeFocus(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -128,11 +125,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;
|
||||
}
|
||||
|
||||
@@ -170,11 +164,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
|
||||
|
||||
@@ -34,8 +34,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> {
|
||||
|
||||
@@ -51,15 +49,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);
|
||||
handler.setTextField(this.level);
|
||||
this.level.setValue(handler.getReportingValue());
|
||||
this.level.setOnChange(this::saveReportingValue);
|
||||
this.level.setOnConfirm(this::onClose);
|
||||
|
||||
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(handler::setReportingValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -26,8 +26,11 @@ import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import me.shedaniel.math.Rectangle;
|
||||
|
||||
import appeng.api.config.SearchBoxMode;
|
||||
import appeng.api.config.Settings;
|
||||
import appeng.api.config.SortDir;
|
||||
@@ -49,6 +52,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;
|
||||
@@ -235,7 +239,7 @@ public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBas
|
||||
if (this.viewCell || this instanceof WirelessTermScreen) {
|
||||
this.craftingStatusBtn = this.addButton(new TabButton(this.x + 170, this.y - 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
|
||||
@@ -281,6 +285,8 @@ public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBas
|
||||
craftingGridOffsetX -= 25;
|
||||
craftingGridOffsetY -= 6;
|
||||
|
||||
this.setScrollBar();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -290,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 && handler.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.getHeight() - 16) / 2;
|
||||
StackSizeRenderer.renderSizeLabel(textRenderer, x - this.x, y - this.y,
|
||||
new LiteralText(String.valueOf(handler.activeCraftingJobs)));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -354,6 +370,7 @@ public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBas
|
||||
if (this.searchField != null) {
|
||||
this.searchField.render(matrices, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected String getBackground() {
|
||||
@@ -519,4 +536,14 @@ public class MEMonitorableScreen<T extends MEMonitorableContainer> extends AEBas
|
||||
this.init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Rectangle> getExclusionZones() {
|
||||
List<Rectangle> zones = super.getExclusionZones();
|
||||
// Button toolbar on the left
|
||||
zones.add(new Rectangle(x - 18, y + 8, 18, 160));
|
||||
// View-cells on the right
|
||||
zones.add(new Rectangle(x + 197, y, 46, 128));
|
||||
return zones;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,41 +2,58 @@ 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 net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.DrawableHelper;
|
||||
import net.minecraft.client.gui.Element;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
|
||||
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 DrawableHelper {
|
||||
|
||||
private static final Text INVALID_NUMBER = new TranslatableText("gui.appliedenergistics2.validation.InvalidNumber");
|
||||
private static final String NUMBER_LESS_THAN_MIN_VALUE = "gui.appliedenergistics2.validation.NumberLessThanMinValue";
|
||||
private static final Text PLUS = Text.of("+");
|
||||
private static final Text MINUS = Text.of("-");
|
||||
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<ButtonWidget> 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;
|
||||
@@ -45,27 +62,50 @@ public class NumberEntryWidget implements ITickingWidget {
|
||||
TextRenderer font = parent.getClient().textRenderer;
|
||||
int inputX = parent.getX() + x;
|
||||
int inputY = parent.getY() + y;
|
||||
this.level = new NumberBox(font, inputX, inputY, width, font.fontHeight, type.getInputType(), changeListener);
|
||||
this.level.setHasBorder(false);
|
||||
this.level.setMaxLength(16);
|
||||
this.level.setEditableColor(0xFFFFFF);
|
||||
this.level.setVisible(true);
|
||||
parent.setInitialFocus(this.level);
|
||||
this.textField = new ConfirmableTextField(font, inputX, inputY, width, font.fontHeight, LiteralText.EMPTY);
|
||||
this.textField.setHasBorder(false);
|
||||
this.textField.setMaxLength(16);
|
||||
this.textField.setEditableColor(TEXT_COLOR_NORMAL);
|
||||
this.textField.setVisible(true);
|
||||
this.textField.setSelected(true);
|
||||
parent.setInitialFocus(this.textField);
|
||||
this.textField.setChangedListener(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.active = active;
|
||||
this.textField.active = active;
|
||||
this.buttons.forEach(b -> b.active = active);
|
||||
}
|
||||
|
||||
public void setTextFieldBounds(int x, int y, int width) {
|
||||
this.level.x = parent.getX() + x;
|
||||
this.level.y = parent.getY() + y;
|
||||
this.level.setWidth(width);
|
||||
this.textField.x = parent.getX() + x;
|
||||
this.textField.y = parent.getY() + y;
|
||||
this.textField.setWidth(width);
|
||||
}
|
||||
|
||||
public void setMinValue(long minValue) {
|
||||
this.level.setMinValue(minValue);
|
||||
this.minValue = minValue;
|
||||
validate();
|
||||
}
|
||||
|
||||
public void addButtons(Consumer<Element> addChildren, Consumer<ButtonWidget> addButton) {
|
||||
@@ -78,54 +118,116 @@ public class NumberEntryWidget implements ITickingWidget {
|
||||
int left = parent.getX() + x;
|
||||
int top = parent.getY() + y;
|
||||
|
||||
List<ButtonWidget> buttons = new ArrayList<>(8);
|
||||
List<ButtonWidget> buttons = new ArrayList<>(9);
|
||||
|
||||
buttons.add(new ButtonWidget(left, top, 22, 20, makeLabel(PLUS, a), btn -> addQty(a)));
|
||||
buttons.add(new ButtonWidget(left + 28, top, 28, 20, makeLabel(PLUS, b), btn -> addQty(b)));
|
||||
buttons.add(new ButtonWidget(left + 62, top, 32, 20, makeLabel(PLUS, c), btn -> addQty(c)));
|
||||
buttons.add(new ButtonWidget(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 ButtonWidget(left, top + 42, 22, 20, makeLabel(MINUS, a), btn -> addQty(-a)));
|
||||
buttons.add(new ButtonWidget(left + 28, top + 42, 28, 20, makeLabel(MINUS, b), btn -> addQty(-b)));
|
||||
buttons.add(new ButtonWidget(left + 62, top + 42, 32, 20, makeLabel(MINUS, c), btn -> addQty(-c)));
|
||||
buttons.add(new ButtonWidget(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 matrices, int mouseX, int mouseY, float partialTicks) {
|
||||
this.level.render(matrices, 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.setCursorToEnd();
|
||||
this.textField.setSelectionStart(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<Text> validationErrors = new ArrayList<>();
|
||||
|
||||
String text = textField.getText().trim();
|
||||
try {
|
||||
long value = Long.parseLong(text, 10);
|
||||
if (value < minValue) {
|
||||
validationErrors.add(new TranslatableText(NUMBER_LESS_THAN_MIN_VALUE, minValue));
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
validationErrors.add(INVALID_NUMBER);
|
||||
}
|
||||
|
||||
boolean valid = validationErrors.isEmpty();
|
||||
this.textField.setEditableColor(valid ? TEXT_COLOR_NORMAL : TEXT_COLOR_ERROR);
|
||||
if (this.validationIcon != null) {
|
||||
this.validationIcon.setValid(valid);
|
||||
this.validationIcon.setTooltip(validationErrors);
|
||||
}
|
||||
}
|
||||
|
||||
private Text makeLabel(Text prefix, int amount) {
|
||||
return prefix.copy().append(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 net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.text.Text;
|
||||
@@ -26,8 +28,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> {
|
||||
|
||||
@@ -38,24 +38,38 @@ public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
|
||||
public PriorityScreen(PriorityContainer container, PlayerInventory playerInventory, Text title) {
|
||||
super(container, playerInventory, title);
|
||||
this.subGui = new AESubScreen(this, container.getPriorityHost());
|
||||
|
||||
// This is the effective size of the background image
|
||||
backgroundWidth = 175;
|
||||
backgroundHeight = 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);
|
||||
handler.setTextField(this.priority);
|
||||
this.priority.setValue(this.handler.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()) {
|
||||
handler.setPriority(priority.getAsInt());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -66,13 +80,10 @@ public class PriorityScreen extends AEBaseScreen<PriorityContainer> {
|
||||
@Override
|
||||
public void drawBG(MatrixStack matrices, final int offsetX, final int offsetY, final int mouseX, final int mouseY,
|
||||
float partialTicks) {
|
||||
this.bindTexture(getBackground());
|
||||
this.bindTexture("guis/priority.png");
|
||||
drawTexture(matrices, offsetX, offsetY, 0, 0, this.backgroundWidth, this.backgroundHeight);
|
||||
|
||||
this.priority.render(matrices, mouseX, mouseY, partialTicks);
|
||||
}
|
||||
|
||||
protected String getBackground() {
|
||||
return "guis/priority.png";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,10 +18,14 @@
|
||||
|
||||
package appeng.client.gui.implementations;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import me.shedaniel.math.Rectangle;
|
||||
|
||||
import appeng.api.config.FuzzyMode;
|
||||
import appeng.api.config.RedstoneMode;
|
||||
import appeng.api.config.SchedulingMode;
|
||||
@@ -146,4 +150,11 @@ public class UpgradeableScreen<T extends UpgradeableContainer> extends AEBaseScr
|
||||
return this.bc instanceof ImportBusPart ? GuiText.ImportBus : GuiText.ExportBus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Rectangle> getExclusionZones() {
|
||||
List<Rectangle> zones = super.getExclusionZones();
|
||||
zones.add(new Rectangle(x - 18, y + 8, 18, 60));
|
||||
return zones;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -48,9 +48,9 @@ public class WirelessScreen extends AEBaseScreen<WirelessContainer> {
|
||||
this.textRenderer.draw(matrices, GuiText.inventory.text(), 8, this.backgroundHeight - 96 + 3, 4210752);
|
||||
|
||||
if (handler.getRange() > 0) {
|
||||
final String firstMessage = GuiText.Range.text() + ": " + (handler.getRange() / 10.0) + " m";
|
||||
final String secondMessage = GuiText.PowerUsageRate.text() + ": "
|
||||
+ Platform.formatPowerLong(handler.getDrain(), true);
|
||||
final Text firstMessage = GuiText.Range.withSuffix(": " + (handler.getRange() / 10.0) + " m");
|
||||
final Text secondMessage = GuiText.PowerUsageRate
|
||||
.withSuffix(": " + Platform.formatPowerLong(handler.getDrain(), true));
|
||||
|
||||
final int strWidth = Math.max(this.textRenderer.getWidth(firstMessage),
|
||||
this.textRenderer.getWidth(secondMessage));
|
||||
|
||||
@@ -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.font.TextRenderer;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
public class ConfirmableTextField extends TextFieldWidget {
|
||||
|
||||
private Runnable onConfirm;
|
||||
|
||||
public ConfirmableTextField(TextRenderer fontRenderer, int x, int y, int width, int height, Text text) {
|
||||
super(fontRenderer, x, y, width, height, text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
|
||||
if (isActive() && (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.systems.RenderSystem;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.sound.SoundManager;
|
||||
import net.minecraft.client.texture.TextureManager;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.LiteralText;
|
||||
@@ -33,6 +34,10 @@ public abstract class IconButton extends ButtonWidget implements ITooltip {
|
||||
|
||||
private boolean halfSize = false;
|
||||
|
||||
private boolean disableClickSound = false;
|
||||
|
||||
private boolean disableBackground = false;
|
||||
|
||||
public IconButton(final int x, final int y, PressAction onPress) {
|
||||
super(x, y, 16, 16, LiteralText.EMPTY, onPress);
|
||||
}
|
||||
@@ -42,6 +47,13 @@ public abstract class IconButton extends ButtonWidget implements ITooltip {
|
||||
this.active = vis;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void playDownSound(SoundManager soundManager) {
|
||||
if (!disableClickSound) {
|
||||
super.playDownSound(soundManager);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderButton(MatrixStack matrices, final int mouseX, final int mouseY, float partial) {
|
||||
|
||||
@@ -72,7 +84,9 @@ public abstract class IconButton extends ButtonWidget implements ITooltip {
|
||||
final int uv_y = iconIndex / 16;
|
||||
final int uv_x = iconIndex - uv_y * 16;
|
||||
|
||||
drawTexture(matrices, 0, 0, 256 - 16, 256 - 16, 16, 16);
|
||||
if (!disableBackground) {
|
||||
drawTexture(matrices, 0, 0, 256 - 16, 256 - 16, 16, 16);
|
||||
}
|
||||
drawTexture(matrices, 0, 0, uv_x * 16, uv_y * 16, 16, 16);
|
||||
RenderSystem.popMatrix();
|
||||
} else {
|
||||
@@ -85,12 +99,18 @@ public abstract class IconButton extends ButtonWidget implements ITooltip {
|
||||
final int uv_y = iconIndex / 16;
|
||||
final int uv_x = iconIndex - uv_y * 16;
|
||||
|
||||
drawTexture(matrices, this.x, this.y, 256 - 16, 256 - 16, 16, 16);
|
||||
if (!disableBackground) {
|
||||
drawTexture(matrices, this.x, this.y, 256 - 16, 256 - 16, 16, 16);
|
||||
}
|
||||
drawTexture(matrices, this.x, this.y, uv_x * 16, uv_y * 16, 16, 16);
|
||||
}
|
||||
RenderSystem.enableDepthTest();
|
||||
RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
if (isHovered()) {
|
||||
renderToolTip(matrices, mouseX, mouseY);
|
||||
}
|
||||
}
|
||||
RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
protected abstract int getIconIndex();
|
||||
@@ -133,4 +153,20 @@ public abstract class IconButton extends ButtonWidget 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.font.TextRenderer;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.text.LiteralText;
|
||||
|
||||
public class NumberBox extends TextFieldWidget {
|
||||
|
||||
private final LongConsumer changeListener;
|
||||
|
||||
private long lastValue;
|
||||
|
||||
private long minValue = 0;
|
||||
|
||||
private long maxValue;
|
||||
|
||||
public NumberBox(final TextRenderer 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 LiteralText("0"));
|
||||
this.setText("0");
|
||||
setChangedListener(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,18 +18,74 @@
|
||||
|
||||
package appeng.client.gui.widgets;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import java.time.Duration;
|
||||
|
||||
import net.minecraft.client.gui.DrawableHelper;
|
||||
import net.minecraft.client.util.Rect2i;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.util.Identifier;
|
||||
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 DrawableHelper 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 Identifier TEXTURE = new Identifier("minecraft",
|
||||
"textures/gui/container/creative_inventory/tabs.png");
|
||||
|
||||
/**
|
||||
* Rectangle in the source texture that contains the sprite for an enabled
|
||||
* handle.
|
||||
*/
|
||||
private static final Rect2i ENABLED = new Rect2i(232, 0, HANDLE_WIDTH, HANDLE_HEIGHT);
|
||||
|
||||
/**
|
||||
* Rectangle in the source texture that contains the sprite for a disabled
|
||||
* handle.
|
||||
*/
|
||||
private static final Rect2i DISABLED = new Rect2i(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;
|
||||
|
||||
@@ -37,20 +93,58 @@ public class Scrollbar implements IScrollSource {
|
||||
private int minScroll = 0;
|
||||
private int currentScroll = 0;
|
||||
|
||||
private final DrawableHelper drawable = new DrawableHelper() {
|
||||
};
|
||||
/**
|
||||
* 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) {
|
||||
g.bindTexture("minecraft", "gui/container/creative_inventory/tabs.png");
|
||||
RenderSystem.color4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
setZOffset(g.getZOffset());
|
||||
|
||||
drawable.setZOffset(g.getZOffset());
|
||||
// Draw the track (nice for debugging)
|
||||
// fill(matrices, displayX, displayY, this.displayX + width, this.displayY +
|
||||
// height, 0xffff0000);
|
||||
|
||||
g.bindTexture(TEXTURE);
|
||||
|
||||
int yOffset;
|
||||
Rect2i sourceRect;
|
||||
if (this.getRange() == 0) {
|
||||
drawable.drawTexture(matrices, this.displayX, this.displayY, 232 + this.width, 0, this.width, 15);
|
||||
yOffset = 0;
|
||||
sourceRect = DISABLED;
|
||||
} else {
|
||||
final int offset = (this.currentScroll - this.minScroll) * (this.height - 15) / this.getRange();
|
||||
drawable.drawTexture(matrices, this.displayX, offset + this.displayY, 232, 0, this.width, 15);
|
||||
yOffset = getHandleYOffset();
|
||||
sourceRect = ENABLED;
|
||||
}
|
||||
|
||||
drawTexture(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() {
|
||||
@@ -114,24 +208,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.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
@@ -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 = MinecraftClient.getInstance().mouse.wasRightButtonClicked();
|
||||
boolean backwards = false;
|
||||
// This isn't great, but we don't get any information about right-clicks
|
||||
// otherwise
|
||||
Screen currentScreen = MinecraftClient.getInstance().currentScreen;
|
||||
if (currentScreen instanceof AEBaseScreen) {
|
||||
backwards = ((AEBaseScreen<?>) currentScreen).isHandlingRightClick();
|
||||
}
|
||||
onPress.handle(this, backwards);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ import net.minecraft.util.Identifier;
|
||||
public class TabButton extends ButtonWidget implements ITooltip {
|
||||
public static final Identifier TEXTURE_STATES = new Identifier("appliedenergistics2", "textures/guis/states.png");
|
||||
private final ItemRenderer itemRenderer;
|
||||
private int hideEdge = 0;
|
||||
private boolean hideEdge;
|
||||
private int myIcon = -1;
|
||||
private ItemStack myItem;
|
||||
|
||||
@@ -69,14 +69,17 @@ public class TabButton extends ButtonWidget 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;
|
||||
|
||||
drawTexture(matrices, this.x, this.y, uv_x * 16, 0, 25, 22);
|
||||
drawTexture(matrices, 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;
|
||||
|
||||
drawTexture(matrices, offsetX + this.x + 3, this.y + 3, uv_x * 16, uv_y * 16, 16, 16);
|
||||
@@ -122,11 +125,11 @@ public class TabButton extends ButtonWidget 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,64 @@
|
||||
package appeng.client.gui.widgets;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.gui.screen.Screen;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
/**
|
||||
* Displays a small icon that shows validation errors for some input control.
|
||||
*/
|
||||
public class ValidationIcon extends IconButton {
|
||||
|
||||
private final List<Text> 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<Text> 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;
|
||||
}
|
||||
|
||||
MinecraftClient client = MinecraftClient.getInstance();
|
||||
Screen screen = client.currentScreen;
|
||||
if (screen == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
screen.renderTooltip(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.Inventory;
|
||||
import net.minecraft.inventory.SimpleInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
|
||||
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 Slot implements IMEFluidSlot {
|
||||
|
||||
private static final Inventory EMPTY_INVENTORY = new SimpleInventory(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;
|
||||
}
|
||||
|
||||
@@ -69,7 +68,7 @@ public class SlotFluidME extends Slot implements IMEFluidSlot {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStack(final ItemStack par1ItemStack) {
|
||||
public void setStack(final ItemStack stack) {
|
||||
|
||||
}
|
||||
|
||||
@@ -85,7 +84,7 @@ public class SlotFluidME extends Slot implements IMEFluidSlot {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canTakeItems(final PlayerEntity par1PlayerEntity) {
|
||||
public boolean canTakeItems(final PlayerEntity player) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
package appeng.client.me;
|
||||
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.inventory.Inventory;
|
||||
import net.minecraft.inventory.SimpleInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.screen.slot.Slot;
|
||||
|
||||
@@ -26,16 +28,18 @@ import appeng.api.storage.data.IAEItemStack;
|
||||
|
||||
public class SlotME extends Slot {
|
||||
|
||||
private final InternalSlotME mySlot;
|
||||
private static final Inventory EMPTY_INVENTORY = new SimpleInventory(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 Slot {
|
||||
|
||||
@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 hasStack() {
|
||||
if (this.mySlot.hasPower()) {
|
||||
if (this.slot.hasPower()) {
|
||||
return !this.getStack().isEmpty();
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -104,7 +104,7 @@ class CableBuilder {
|
||||
throw new IllegalStateException("Cable type " + cableType + " does not support connections.");
|
||||
}
|
||||
|
||||
return new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
return new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE,
|
||||
new Identifier(AppEng.MOD_ID, textureFolder + color.name().toLowerCase(Locale.ROOT)));
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ package appeng.client.render.cablebus;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -30,6 +29,10 @@ import java.util.function.Supplier;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.renderer.v1.Renderer;
|
||||
@@ -61,10 +64,15 @@ import appeng.api.util.AEColor;
|
||||
@Environment(EnvType.CLIENT)
|
||||
public class CableBusBakedModel implements BakedModel, FabricBakedModel {
|
||||
|
||||
private static final Mesh EMPTY_MESH = consumer -> {
|
||||
};
|
||||
|
||||
private static final Renderer RENDERER = RendererAccess.INSTANCE.getRenderer();
|
||||
|
||||
// FIXME: This entire cache seems dumb as shit
|
||||
private static final Map<CableBusRenderState, Mesh> CABLE_MODEL_CACHE = new HashMap<>();
|
||||
// The number of meshes overall that will be cached
|
||||
private static final int CACHE_MESH_COUNT = 100;
|
||||
|
||||
private final LoadingCache<CableBusRenderState, Mesh> cableModelCache;
|
||||
|
||||
private final CableBuilder cableBuilder;
|
||||
|
||||
@@ -80,6 +88,15 @@ public class CableBusBakedModel implements BakedModel, FabricBakedModel {
|
||||
this.facadeBuilder = facadeBuilder;
|
||||
this.partModels = partModels;
|
||||
this.particleTexture = particleTexture;
|
||||
this.cableModelCache = CacheBuilder.newBuilder()//
|
||||
.maximumSize(CACHE_MESH_COUNT)//
|
||||
.build(new CacheLoader<CableBusRenderState, Mesh>() {
|
||||
@Override
|
||||
public Mesh load(CableBusRenderState renderState) {
|
||||
Mesh mesh = buildCableModel(renderState);
|
||||
return mesh != null ? mesh : EMPTY_MESH;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -109,8 +126,8 @@ public class CableBusBakedModel implements BakedModel, FabricBakedModel {
|
||||
}
|
||||
|
||||
// First, handle the cable at the center of the cable bus
|
||||
final Mesh cableModel = CABLE_MODEL_CACHE.computeIfAbsent(renderState, this::buildCableModel);
|
||||
if (cableModel != null) {
|
||||
final Mesh cableModel = cableModelCache.getUnchecked(renderState);
|
||||
if (cableModel != EMPTY_MESH) {
|
||||
context.meshConsumer().accept(cableModel);
|
||||
}
|
||||
|
||||
@@ -359,10 +376,6 @@ public class CableBusBakedModel implements BakedModel, FabricBakedModel {
|
||||
return ModelOverrideList.EMPTY;
|
||||
}
|
||||
|
||||
public static void clearCache() {
|
||||
CABLE_MODEL_CACHE.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVanillaAdapter() {
|
||||
return false;
|
||||
|
||||
@@ -23,7 +23,6 @@ public class CableBusModelLoader implements ModelResourceProvider {
|
||||
public UnbakedModel loadModelResource(Identifier resourceId, ModelProviderContext context)
|
||||
throws ModelProviderException {
|
||||
if (CABLE_BUS_MODEL.equals(resourceId)) {
|
||||
CableBusBakedModel.clearCache();
|
||||
return new CableBusModel(partModels);
|
||||
} else {
|
||||
return null;
|
||||
|
||||
@@ -74,7 +74,7 @@ public enum CableCoreType {
|
||||
}
|
||||
|
||||
public SpriteIdentifier getTexture(AEColor color) {
|
||||
return new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
return new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE,
|
||||
new Identifier(AppEng.MOD_ID, this.textureFolder + "/" + color.name().toLowerCase(Locale.ROOT)));
|
||||
}
|
||||
|
||||
|
||||
@@ -258,7 +258,9 @@ public class FacadeBuilder {
|
||||
|
||||
for (Box box : holeStrips) {
|
||||
emitter.fromVanilla(quad.getVertexData(), 0, false);
|
||||
emitter.cullFace(cullFace);
|
||||
// Keep the cull-face for faces that are flush with the outer block-face on the
|
||||
// side the facade is attached to, but clear it for anything that faces inwards
|
||||
emitter.cullFace(cullFace == side ? side : null);
|
||||
emitter.nominalFace(quad.getFace());
|
||||
interpolator.setInputQuad(emitter);
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import appeng.core.AppEng;
|
||||
|
||||
public class P2PTunnelFrequencyModel implements BasicUnbakedModel {
|
||||
|
||||
private static final SpriteIdentifier TEXTURE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
private static final SpriteIdentifier TEXTURE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE,
|
||||
new Identifier(AppEng.MOD_ID, "part/p2p_tunnel_frequency"));
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -24,7 +24,6 @@ import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
|
||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.MutableQuadViewImpl;
|
||||
import net.minecraft.client.util.math.Vector3f;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Quaternion;
|
||||
@@ -93,10 +92,6 @@ public class QuadRotator implements RenderContext.QuadTransform {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME FABRIC: Wait for Grondags response about this one
|
||||
MutableQuadViewImpl quadImpl = (MutableQuadViewImpl) quad;
|
||||
quadImpl.lightFace(rotation.rotate(quad.lightFace()));
|
||||
|
||||
// Transform the nominal face, setting the cull face will also overwrite the
|
||||
// nominialFace,
|
||||
// hence saving both first and the order here.
|
||||
|
||||
@@ -47,7 +47,8 @@ public class SmartCableTextures {
|
||||
new Identifier(AppEng.MOD_ID, "part/cable/smart/channels_12"), //
|
||||
new Identifier(AppEng.MOD_ID, "part/cable/smart/channels_13"), //
|
||||
new Identifier(AppEng.MOD_ID, "part/cable/smart/channels_14")//
|
||||
}).map(e -> new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX, e)).toArray(SpriteIdentifier[]::new);
|
||||
}).map(e -> new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, e))
|
||||
.toArray(SpriteIdentifier[]::new);
|
||||
|
||||
// Textures used to display channels on smart cables. There's two sets of 5
|
||||
// textures each, and
|
||||
|
||||
@@ -115,7 +115,7 @@ public class CraftingCubeModel implements BasicUnbakedModel {
|
||||
}
|
||||
|
||||
private static SpriteIdentifier texture(String name) {
|
||||
return new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
return new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE,
|
||||
new Identifier(AppEng.MOD_ID, "block/crafting/" + name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import appeng.core.AppEng;
|
||||
public class BiometricCardModel implements BasicUnbakedModel {
|
||||
|
||||
public static final Identifier MODEL_BASE = new Identifier(AppEng.MOD_ID, "item/biometric_card_base");
|
||||
private static final SpriteIdentifier TEXTURE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
private static final SpriteIdentifier TEXTURE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE,
|
||||
new Identifier(AppEng.MOD_ID, "item/biometric_card_hash"));
|
||||
|
||||
@Override
|
||||
|
||||
@@ -26,11 +26,11 @@ public class ColorApplicatorModel implements BasicUnbakedModel {
|
||||
|
||||
private static final Identifier MODEL_BASE = new Identifier(AppEng.MOD_ID, "item/color_applicator_colored");
|
||||
|
||||
private static final SpriteIdentifier TEXTURE_DARK = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
private static final SpriteIdentifier TEXTURE_DARK = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE,
|
||||
new Identifier(AppEng.MOD_ID, "item/color_applicator_tip_dark"));
|
||||
private static final SpriteIdentifier TEXTURE_MEDIUM = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
private static final SpriteIdentifier TEXTURE_MEDIUM = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE,
|
||||
new Identifier(AppEng.MOD_ID, "item/color_applicator_tip_medium"));
|
||||
private static final SpriteIdentifier TEXTURE_BRIGHT = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
private static final SpriteIdentifier TEXTURE_BRIGHT = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE,
|
||||
new Identifier(AppEng.MOD_ID, "item/color_applicator_tip_bright"));
|
||||
|
||||
@Override
|
||||
|
||||
@@ -62,13 +62,13 @@ class GlassBakedModel implements BakedModel, FabricBakedModel {
|
||||
private static final byte[][][] OFFSETS = generateOffsets();
|
||||
|
||||
// Alternating textures based on position
|
||||
static final SpriteIdentifier TEXTURE_A = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
static final SpriteIdentifier TEXTURE_A = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE,
|
||||
new Identifier("appliedenergistics2:block/glass/quartz_glass_a"));
|
||||
static final SpriteIdentifier TEXTURE_B = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
static final SpriteIdentifier TEXTURE_B = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE,
|
||||
new Identifier("appliedenergistics2:block/glass/quartz_glass_b"));
|
||||
static final SpriteIdentifier TEXTURE_C = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
static final SpriteIdentifier TEXTURE_C = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE,
|
||||
new Identifier("appliedenergistics2:block/glass/quartz_glass_c"));
|
||||
static final SpriteIdentifier TEXTURE_D = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
static final SpriteIdentifier TEXTURE_D = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE,
|
||||
new Identifier("appliedenergistics2:block/glass/quartz_glass_d"));
|
||||
|
||||
// Frame texture
|
||||
@@ -81,7 +81,7 @@ class GlassBakedModel implements BakedModel, FabricBakedModel {
|
||||
private static SpriteIdentifier[] generateTexturesFrame() {
|
||||
return IntStream.range(1, 16).mapToObj(Integer::toBinaryString).map(s -> Strings.padStart(s, 4, '0'))
|
||||
.map(s -> new Identifier("appliedenergistics2:block/glass/quartz_glass_frame" + s))
|
||||
.map(rl -> new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX, rl))
|
||||
.map(rl -> new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, rl))
|
||||
.toArray(SpriteIdentifier[]::new);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import appeng.core.AppEng;
|
||||
public class MemoryCardModel implements BasicUnbakedModel {
|
||||
|
||||
public static final Identifier MODEL_BASE = new Identifier(AppEng.MOD_ID, "item/memory_card_base");
|
||||
private static final SpriteIdentifier TEXTURE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
private static final SpriteIdentifier TEXTURE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE,
|
||||
new Identifier(AppEng.MOD_ID, "item/memory_card_hash"));
|
||||
|
||||
@Override
|
||||
|
||||
@@ -59,7 +59,7 @@ public class SpatialPylonModel implements BasicUnbakedModel {
|
||||
}
|
||||
|
||||
private static SpriteIdentifier getTexturePath(SpatialPylonTextureType type) {
|
||||
return new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
return new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE,
|
||||
new Identifier(AppEng.MOD_ID, "block/spatial_pylon/" + type.name().toLowerCase(Locale.ROOT)));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package appeng.client.render.tesr;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
@@ -9,12 +11,12 @@ import net.minecraft.client.render.VertexConsumerProvider;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderDispatcher;
|
||||
import net.minecraft.client.render.block.entity.BlockEntityRenderer;
|
||||
import net.minecraft.client.render.item.ItemRenderer;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.render.model.json.ModelTransformation;
|
||||
import net.minecraft.client.texture.Sprite;
|
||||
import net.minecraft.client.texture.SpriteAtlasTexture;
|
||||
import net.minecraft.client.util.SpriteIdentifier;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.item.BlockItem;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.Direction;
|
||||
@@ -36,7 +38,7 @@ public final class InscriberTESR extends BlockEntityRenderer<InscriberBlockEntit
|
||||
|
||||
private static final float ITEM_RENDER_SCALE = 1.0f / 1.2f;
|
||||
|
||||
private static final SpriteIdentifier TEXTURE_INSIDE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEX,
|
||||
private static final SpriteIdentifier TEXTURE_INSIDE = new SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE,
|
||||
new Identifier(AppEng.MOD_ID, "block/inscriber_inside"));
|
||||
|
||||
public static final ImmutableList<SpriteIdentifier> SPRITES = ImmutableList.of(TEXTURE_INSIDE);
|
||||
@@ -197,9 +199,12 @@ public final class InscriberTESR extends BlockEntityRenderer<InscriberBlockEntit
|
||||
|
||||
ItemRenderer itemRenderer = MinecraftClient.getInstance().getItemRenderer();
|
||||
|
||||
// heuristic to scale items down much further than blocks
|
||||
boolean renderAsCube = (stack.getItem() instanceof BlockItem);
|
||||
if (!renderAsCube) {
|
||||
// heuristic to scale items down much further than blocks,
|
||||
// the assumption here is that the generated item models will return their faces
|
||||
// for direction=null, while a block-model will have their faces for
|
||||
// cull-faces, but not direction=null
|
||||
BakedModel model = itemRenderer.getModels().getModel(stack);
|
||||
if (!model.getQuads(null, null, new Random()).isEmpty()) {
|
||||
ms.scale(0.5f, 0.5f, 0.5f);
|
||||
}
|
||||
|
||||
|
||||
@@ -66,10 +66,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.mixins.ScreenHandlerListeners;
|
||||
@@ -88,11 +86,9 @@ public abstract class AEBaseContainer extends ScreenHandler {
|
||||
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;
|
||||
|
||||
@@ -317,9 +313,7 @@ public abstract class AEBaseContainer extends ScreenHandler {
|
||||
|
||||
@Override
|
||||
public void sendContentUpdates() {
|
||||
this.sendCustomName();
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
if (this.tileEntity != null
|
||||
&& this.tileEntity.getWorld().getBlockEntity(this.tileEntity.getPos()) != this.tileEntity) {
|
||||
this.setValidContainer(false);
|
||||
@@ -886,43 +880,6 @@ public abstract class AEBaseContainer extends ScreenHandler {
|
||||
this.sendContentUpdates();
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -1012,14 +969,6 @@ public abstract class AEBaseContainer extends ScreenHandler {
|
||||
this.cellInv = cellInv;
|
||||
}
|
||||
|
||||
public String getCustomName() {
|
||||
return this.customName;
|
||||
}
|
||||
|
||||
public void setCustomName(final String customName) {
|
||||
this.customName = customName;
|
||||
}
|
||||
|
||||
public PlayerInventory getPlayerInventory() {
|
||||
return this.invPlayer;
|
||||
}
|
||||
@@ -1048,4 +997,18 @@ public abstract class AEBaseContainer extends ScreenHandler {
|
||||
this.powerSrc = powerSrc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this container instance lives on the client.
|
||||
*/
|
||||
protected boolean isClient() {
|
||||
return invPlayer.player.getEntityWorld().isClient();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this container instance lives on the server.
|
||||
*/
|
||||
protected boolean isServer() {
|
||||
return !isClient();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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 Text must be non-null
|
||||
|
||||
@@ -50,7 +50,6 @@ import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.core.Api;
|
||||
import appeng.tile.misc.CellWorkbenchBlockEntity;
|
||||
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 sendContentUpdates() {
|
||||
final ItemStack is = this.workBench.getInventoryByName("cell").getInvStack(0);
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
for (final ScreenHandlerListener listener : this.getListeners()) {
|
||||
if (this.prevStack != is) {
|
||||
// if the bars changed an item was probably made, so just send shit!
|
||||
|
||||
@@ -34,7 +34,6 @@ import appeng.container.interfaces.IProgressProvider;
|
||||
import appeng.container.slot.OutputSlot;
|
||||
import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.tile.misc.CondenserBlockEntity;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class CondenserContainer extends AEBaseContainer implements IProgressProvider {
|
||||
|
||||
@@ -76,13 +75,13 @@ public class CondenserContainer extends AEBaseContainer implements IProgressProv
|
||||
|
||||
@Override
|
||||
public void sendContentUpdates() {
|
||||
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.sendContentUpdates();
|
||||
@@ -102,7 +101,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 javax.annotation.Nullable;
|
||||
|
||||
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
|
||||
@@ -12,9 +14,7 @@ import net.minecraft.screen.ScreenHandler;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.LiteralText;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import appeng.api.config.SecurityPermissions;
|
||||
import appeng.api.features.IWirelessTermHandler;
|
||||
@@ -44,6 +44,8 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
|
||||
|
||||
private final SecurityPermissions requiredPermission;
|
||||
|
||||
private Function<I, Text> containerTitleStrategy = this::getDefaultContainerTitle;
|
||||
|
||||
public ContainerHelper(ContainerFactory<C, I> factory, Class<I> interfaceClass) {
|
||||
this(factory, interfaceClass, null);
|
||||
}
|
||||
@@ -55,19 +57,47 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a custom strategy for obtaining a custom container name.
|
||||
* <p>
|
||||
* The stratgy should return {@link LiteralText#EMPTY} if there's no custom
|
||||
* name.
|
||||
*/
|
||||
public ContainerHelper<C, I> withContainerTitle(Function<I, Text> containerTitleStrategy) {
|
||||
this.containerTitleStrategy = containerTitleStrategy;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a container that is based around a single block entity. The tile
|
||||
* entity's position is encoded in the packet buffer.
|
||||
*/
|
||||
public C fromNetwork(int windowId, PlayerInventory inv, PacketByteBuf 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, PacketByteBuf 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?
|
||||
@@ -84,9 +114,9 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
|
||||
return false;
|
||||
}
|
||||
|
||||
Text title = findContainerTitle(player.world, locator, accessInterface);
|
||||
Text title = containerTitleStrategy.apply(accessInterface);
|
||||
|
||||
player.openHandledScreen(new HandlerFactory(locator, title, accessInterface));
|
||||
player.openHandledScreen(new HandlerFactory(locator, title, accessInterface, initialDataSerializer));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -99,15 +129,20 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
|
||||
|
||||
private final Text title;
|
||||
|
||||
public HandlerFactory(ContainerLocator locator, Text title, I accessInterface) {
|
||||
private final InitialDataSerializer<I> initialDataSerializer;
|
||||
|
||||
public HandlerFactory(ContainerLocator locator, Text title, I accessInterface,
|
||||
InitialDataSerializer<I> initialDataSerializer) {
|
||||
this.locator = locator;
|
||||
this.title = title;
|
||||
this.accessInterface = accessInterface;
|
||||
this.initialDataSerializer = initialDataSerializer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeScreenOpeningData(ServerPlayerEntity player, PacketByteBuf buf) {
|
||||
locator.write(buf);
|
||||
initialDataSerializer.serializeInitialData(accessInterface, buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -127,28 +162,6 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
|
||||
|
||||
}
|
||||
|
||||
private Text 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 TranslatableText(world.getBlockState(locator.getBlockPos()).getBlock().getTranslationKey());
|
||||
}
|
||||
|
||||
return new LiteralText("Unknown");
|
||||
|
||||
}
|
||||
|
||||
private I getHostFromLocator(PlayerEntity player, ContainerLocator locator) {
|
||||
if (locator.hasItemIndex()) {
|
||||
return getHostFromPlayerInventory(player, locator);
|
||||
@@ -225,6 +238,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, PacketByteBuf 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, PacketByteBuf buffer);
|
||||
}
|
||||
|
||||
private boolean checkPermission(PlayerEntity player, Object accessInterface) {
|
||||
|
||||
if (requiredPermission != null) {
|
||||
@@ -235,4 +266,15 @@ public final class ContainerHelper<C extends AEBaseContainer, I> {
|
||||
|
||||
}
|
||||
|
||||
private Text getDefaultContainerTitle(I accessInterface) {
|
||||
if (accessInterface instanceof ICustomNameObject) {
|
||||
ICustomNameObject customNameObject = (ICustomNameObject) accessInterface;
|
||||
if (customNameObject.hasCustomInventoryName()) {
|
||||
return customNameObject.getCustomInventoryName();
|
||||
}
|
||||
}
|
||||
|
||||
return LiteralText.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.network.PacketByteBuf;
|
||||
@@ -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 ScreenHandlerType<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 Text myName;
|
||||
public Text 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 sendContentUpdates() {
|
||||
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.sendContentUpdates();
|
||||
|
||||
@@ -277,22 +223,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() {
|
||||
ScreenHandlerType<?> originalGui = null;
|
||||
|
||||
@@ -315,9 +245,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());
|
||||
@@ -347,6 +275,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;
|
||||
}
|
||||
@@ -371,42 +315,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 Text getName() {
|
||||
return this.myName;
|
||||
}
|
||||
|
||||
private void setName(@Nullable final Text 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.network.PacketByteBuf;
|
||||
import net.minecraft.screen.ScreenHandlerListener;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.LiteralText;
|
||||
|
||||
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.CraftingBlockEntity;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class CraftingCPUContainer extends AEBaseContainer
|
||||
implements IMEMonitorHandlerReceiver<IAEItemStack>, ICustomNameObject {
|
||||
public class CraftingCPUContainer extends AEBaseContainer implements IMEMonitorHandlerReceiver<IAEItemStack> {
|
||||
|
||||
public static ScreenHandlerType<CraftingCPUContainer> TYPE;
|
||||
|
||||
private static final ContainerHelper<CraftingCPUContainer, CraftingBlockEntity> helper = new ContainerHelper<>(
|
||||
CraftingCPUContainer::new, CraftingBlockEntity.class, SecurityPermissions.CRAFT);
|
||||
CraftingCPUContainer::new, CraftingBlockEntity.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 LiteralText.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 Text 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 CraftingBlockEntity) {
|
||||
this.setCPU(((CraftingBlockEntity) 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 sendContentUpdates() {
|
||||
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 Text 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.text.LiteralText;
|
||||
|
||||
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 LiteralText("#" + (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.text.Text;
|
||||
import appeng.api.networking.crafting.ICraftingCPU;
|
||||
|
||||
public class CraftingCPURecord implements Comparable<CraftingCPURecord> {
|
||||
private final Text myName;
|
||||
private final ICraftingCPU cpu;
|
||||
private final long size;
|
||||
private final int processors;
|
||||
private Text 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;
|
||||
}
|
||||
|
||||
Text 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 Text getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(Text 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.network.PacketByteBuf;
|
||||
@@ -31,14 +25,13 @@ import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
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 ScreenHandlerType<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 Text myName;
|
||||
public Text 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 sendContentUpdates() {
|
||||
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.sendContentUpdates();
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,7 +36,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 {
|
||||
|
||||
@@ -108,7 +107,7 @@ public class FormationPlaneContainer extends UpgradeableContainer {
|
||||
public void sendContentUpdates() {
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ import appeng.container.guisync.GuiSync;
|
||||
import appeng.container.slot.OutputSlot;
|
||||
import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.tile.storage.IOPortBlockEntity;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class IOPortContainer extends UpgradeableContainer {
|
||||
|
||||
@@ -112,7 +111,7 @@ public class IOPortContainer extends UpgradeableContainer {
|
||||
public void sendContentUpdates() {
|
||||
this.verifyPermissions(SecurityPermissions.BUILD, false);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.setOperationMode(
|
||||
(OperationMode) this.getUpgradeable().getConfigManager().getSetting(Settings.OPERATION_MODE));
|
||||
this.setFullMode(
|
||||
|
||||
@@ -36,7 +36,6 @@ import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.core.Api;
|
||||
import appeng.tile.misc.InscriberBlockEntity;
|
||||
import appeng.tile.misc.InscriberRecipes;
|
||||
import appeng.util.Platform;
|
||||
|
||||
/**
|
||||
* @author AlgorithmX2
|
||||
@@ -120,7 +119,7 @@ public class InscriberContainer extends UpgradeableContainer implements IProgres
|
||||
public void sendContentUpdates() {
|
||||
this.standardDetectAndSendChanges();
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.maxProcessingTime = this.ti.getMaxProcessingTime();
|
||||
this.processingTime = this.ti.getProcessingTime();
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import alexiil.mc.lib.attributes.item.FixedItemInv;
|
||||
import alexiil.mc.lib.attributes.item.LimitedFixedItemInv;
|
||||
import alexiil.mc.lib.attributes.item.SingleItemSlot;
|
||||
|
||||
import appeng.api.config.SecurityPermissions;
|
||||
import appeng.api.config.Settings;
|
||||
@@ -43,7 +45,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;
|
||||
@@ -53,12 +55,9 @@ import appeng.parts.reporting.InterfaceTerminalPart;
|
||||
import appeng.tile.inventory.AppEngInternalInventory;
|
||||
import appeng.tile.misc.InterfaceBlockEntity;
|
||||
import appeng.util.InventoryAdaptor;
|
||||
import appeng.util.Platform;
|
||||
import appeng.util.helpers.ItemHandlerUtil;
|
||||
import appeng.util.inv.AdaptorFixedInv;
|
||||
import appeng.util.inv.WrapperCursorItemHandler;
|
||||
import appeng.util.inv.WrapperFilteredItemHandler;
|
||||
import appeng.util.inv.filter.IAEItemFilter;
|
||||
|
||||
public final class InterfaceTerminalContainer extends AEBaseContainer {
|
||||
|
||||
@@ -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 sendContentUpdates() {
|
||||
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
|
||||
@@ -196,35 +195,37 @@ public final class InterfaceTerminalContainer extends AEBaseContainer {
|
||||
|
||||
final InventoryAdaptor playerHand = new AdaptorFixedInv(new WrapperCursorItemHandler(player.inventory));
|
||||
|
||||
final FixedItemInv theSlot = new WrapperFilteredItemHandler(inv.server.getSubInv(slot, slot + 1),
|
||||
new PatternSlotFilter());
|
||||
final InventoryAdaptor interfaceSlot = new AdaptorFixedInv(theSlot);
|
||||
// Create a wrapper around the targetted slot that will only allow insertions of
|
||||
// patterns
|
||||
LimitedFixedItemInv limitedSlotInv = inv.server.createLimitedFixedInv();
|
||||
limitedSlotInv.getAllRule().filterInserts(this::isValidPattern);
|
||||
SingleItemSlot theSlot = limitedSlotInv.getSlot(slot);
|
||||
|
||||
switch (action) {
|
||||
case PICKUP_OR_SET_DOWN:
|
||||
|
||||
if (hasItemInHand) {
|
||||
ItemStack inSlot = theSlot.getInvStack(0);
|
||||
ItemStack inSlot = theSlot.get();
|
||||
if (inSlot.isEmpty()) {
|
||||
player.inventory.setCursorStack(interfaceSlot.addItems(player.inventory.getCursorStack()));
|
||||
player.inventory.setCursorStack(theSlot.insert(player.inventory.getCursorStack()));
|
||||
} else {
|
||||
inSlot = inSlot.copy();
|
||||
final ItemStack inHand = player.inventory.getCursorStack().copy();
|
||||
|
||||
ItemHandlerUtil.setStackInSlot(theSlot, 0, ItemStack.EMPTY);
|
||||
theSlot.set(ItemStack.EMPTY);
|
||||
player.inventory.setCursorStack(ItemStack.EMPTY);
|
||||
|
||||
player.inventory.setCursorStack(interfaceSlot.addItems(inHand.copy()));
|
||||
player.inventory.setCursorStack(theSlot.insert(inHand.copy()));
|
||||
|
||||
if (player.inventory.getCursorStack().isEmpty()) {
|
||||
player.inventory.setCursorStack(inSlot);
|
||||
} else {
|
||||
player.inventory.setCursorStack(inHand);
|
||||
ItemHandlerUtil.setStackInSlot(theSlot, 0, inSlot);
|
||||
theSlot.set(inSlot);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ItemHandlerUtil.setStackInSlot(theSlot, 0, playerHand.addItems(theSlot.getInvStack(0)));
|
||||
theSlot.set(playerHand.addItems(theSlot.get()));
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -233,18 +234,18 @@ public final class InterfaceTerminalContainer extends AEBaseContainer {
|
||||
if (hasItemInHand) {
|
||||
ItemStack extra = playerHand.removeItems(1, ItemStack.EMPTY, null);
|
||||
if (!extra.isEmpty()) {
|
||||
extra = interfaceSlot.addItems(extra);
|
||||
extra = theSlot.insert(extra);
|
||||
}
|
||||
if (!extra.isEmpty()) {
|
||||
playerHand.addItems(extra);
|
||||
}
|
||||
} else if (!is.isEmpty()) {
|
||||
ItemStack extra = interfaceSlot.removeItems((is.getCount() + 1) / 2, ItemStack.EMPTY, null);
|
||||
ItemStack extra = theSlot.extract((is.getCount() + 1) / 2);
|
||||
if (!extra.isEmpty()) {
|
||||
extra = playerHand.addItems(extra);
|
||||
}
|
||||
if (!extra.isEmpty()) {
|
||||
interfaceSlot.addItems(extra);
|
||||
theSlot.insert(extra);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,8 +253,7 @@ public final class InterfaceTerminalContainer extends AEBaseContainer {
|
||||
case SHIFT_CLICK:
|
||||
|
||||
final InventoryAdaptor playerInv = InventoryAdaptor.getAdaptor(player);
|
||||
|
||||
ItemHandlerUtil.setStackInSlot(theSlot, 0, playerInv.addItems(theSlot.getInvStack(0)));
|
||||
theSlot.set(playerInv.addItems(theSlot.get()));
|
||||
|
||||
break;
|
||||
case MOVE_REGION:
|
||||
@@ -279,6 +279,10 @@ public final class InterfaceTerminalContainer extends AEBaseContainer {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isValidPattern(ItemStack stack) {
|
||||
return !stack.isEmpty() && stack.getItem() instanceof EncodedPatternItem;
|
||||
}
|
||||
|
||||
private void regenList(final CompoundTag data) {
|
||||
this.byId.clear();
|
||||
this.diList.clear();
|
||||
@@ -369,15 +373,4 @@ public final class InterfaceTerminalContainer extends AEBaseContainer {
|
||||
}
|
||||
}
|
||||
|
||||
private static class PatternSlotFilter implements IAEItemFilter {
|
||||
@Override
|
||||
public boolean allowExtract(FixedItemInv inv, int slot, int amount) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean allowInsert(FixedItemInv inv, int slot, ItemStack stack) {
|
||||
return !stack.isEmpty() && stack.getItem() instanceof EncodedPatternItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
|
||||
package appeng.container.implementations;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
@@ -33,13 +31,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 {
|
||||
|
||||
@@ -49,38 +47,46 @@ public class LevelEmitterContainer extends UpgradeableContainer {
|
||||
LevelEmitterContainer::new, LevelEmitterPart.class, SecurityPermissions.BUILD);
|
||||
|
||||
public static LevelEmitterContainer fromNetwork(int windowId, PlayerInventory inv, PacketByteBuf 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;
|
||||
|
||||
@Environment(EnvType.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;
|
||||
}
|
||||
|
||||
@Environment(EnvType.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
|
||||
@@ -116,7 +122,6 @@ public class LevelEmitterContainer extends UpgradeableContainer {
|
||||
|
||||
@Override
|
||||
public int availableUpgrades() {
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -124,8 +129,7 @@ public class LevelEmitterContainer extends UpgradeableContainer {
|
||||
public void sendContentUpdates() {
|
||||
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));
|
||||
@@ -137,15 +141,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;
|
||||
@@ -163,4 +158,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 sendContentUpdates() {
|
||||
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 ScreenHandlerListener 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;
|
||||
|
||||
@@ -42,7 +42,6 @@ import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.core.Api;
|
||||
import appeng.items.misc.EncodedPatternItem;
|
||||
import appeng.tile.crafting.MolecularAssemblerBlockEntity;
|
||||
import appeng.util.Platform;
|
||||
|
||||
public class MolecularAssemblerContainer extends UpgradeableContainer implements IProgressProvider {
|
||||
|
||||
@@ -148,7 +147,7 @@ public class MolecularAssemblerContainer extends UpgradeableContainer implements
|
||||
public void sendContentUpdates() {
|
||||
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 sendContentUpdates() {
|
||||
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);
|
||||
|
||||
@@ -297,9 +297,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;
|
||||
}
|
||||
@@ -401,7 +401,7 @@ public class PatternTermContainer extends MEMonitorableContainer
|
||||
@Override
|
||||
public void sendContentUpdates() {
|
||||
super.sendContentUpdates();
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
if (this.isCraftingMode() != this.getPatternTerminal().isCraftingRecipe()) {
|
||||
this.setCraftingMode(this.getPatternTerminal().isCraftingRecipe());
|
||||
this.updateOrderOfOutputSlots();
|
||||
@@ -423,7 +423,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 ScreenHandlerListener listener : this.getListeners()) {
|
||||
for (int i = 0; i < this.slots.size(); i++) {
|
||||
Slot slot = this.slots.get(i);
|
||||
@@ -438,7 +438,7 @@ public class PatternTermContainer extends MEMonitorableContainer
|
||||
this.sendContentUpdates();
|
||||
}
|
||||
|
||||
if (s == this.craftSlot && Platform.isClient()) {
|
||||
if (s == this.craftSlot && isClient()) {
|
||||
this.getAndUpdateOutput();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
|
||||
package appeng.container.implementations;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.PlayerInventory;
|
||||
@@ -28,12 +26,11 @@ import net.minecraft.screen.ScreenHandlerType;
|
||||
|
||||
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,59 +40,53 @@ public class PriorityContainer extends AEBaseContainer {
|
||||
PriorityContainer::new, IPriorityHost.class, SecurityPermissions.BUILD);
|
||||
|
||||
public static PriorityContainer fromNetwork(int windowId, PlayerInventory inv, PacketByteBuf 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;
|
||||
|
||||
@Environment(EnvType.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, (BlockEntity) (te instanceof BlockEntity ? te : null),
|
||||
(IPart) (te instanceof IPart ? te : null));
|
||||
this.priHost = te;
|
||||
this.priorityValue = te.getPriority();
|
||||
}
|
||||
|
||||
@Environment(EnvType.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 sendContentUpdates() {
|
||||
super.sendContentUpdates();
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,7 +37,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 {
|
||||
|
||||
@@ -142,10 +141,12 @@ public class QuartzKnifeContainer extends AEBaseContainer {
|
||||
}
|
||||
|
||||
private void makePlate() {
|
||||
if (Platform.isServer()) {
|
||||
if (!this.takeStack(1).isEmpty()) {
|
||||
if (isServer()) {
|
||||
if (!inSlot.getSlot(0).extract(1).isEmpty()) {
|
||||
final ItemStack item = QuartzKnifeContainer.this.toolInv.getItemStack();
|
||||
final ItemStack before = item.copy();
|
||||
// FIXME FABRIC: Quartz Knife currently is not damageable due to recipe
|
||||
// remainder concerns
|
||||
item.damage(1, QuartzKnifeContainer.this.getPlayerInv().player, p -> {
|
||||
QuartzKnifeContainer.this.getPlayerInv()
|
||||
.setStack(QuartzKnifeContainer.this.getPlayerInv().selectedSlot, ItemStack.EMPTY);
|
||||
|
||||
@@ -35,7 +35,6 @@ import appeng.container.guisync.GuiSync;
|
||||
import appeng.container.slot.OutputSlot;
|
||||
import appeng.container.slot.RestrictedInputSlot;
|
||||
import appeng.tile.spatial.SpatialIOPortBlockEntity;
|
||||
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 SpatialIOPortBlockEntity 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 sendContentUpdates() {
|
||||
this.verifyPermissions(SecurityPermissions.BUILD, false);
|
||||
|
||||
if (Platform.isServer()) {
|
||||
if (isServer()) {
|
||||
this.delay++;
|
||||
if (this.delay > 15 && this.network != null) {
|
||||
this.delay = 0;
|
||||
|
||||
@@ -45,7 +45,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;
|
||||
|
||||
@@ -125,7 +124,7 @@ public class StorageBusContainer extends UpgradeableContainer {
|
||||
public void sendContentUpdates() {
|
||||
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));
|
||||
|
||||
@@ -52,7 +52,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 {
|
||||
|
||||
@@ -200,7 +199,7 @@ public class UpgradeableContainer extends AEBaseContainer implements IOptionalSl
|
||||
public void sendContentUpdates() {
|
||||
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.VibrationChamberBlockEntity;
|
||||
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 sendContentUpdates() {
|
||||
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.sendContentUpdates();
|
||||
|
||||
if (!this.wirelessTerminalGUIObject.rangeCheck()) {
|
||||
if (Platform.isServer() && this.isValidContainer()) {
|
||||
if (isServer() && this.isValidContainer()) {
|
||||
this.getPlayerInv().player.sendSystemMessage(PlayerMessages.OutOfRange.get(), Util.NIL_UUID);
|
||||
}
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ public class RestrictedInputSlot extends AppEngSlot {
|
||||
case ORE:
|
||||
return GrinderRecipes.isValidIngredient(p.player.world, stack);
|
||||
case FUEL:
|
||||
return FuelRegistry.INSTANCE.get(stack.getItem()) > 0;
|
||||
return FuelRegistry.INSTANCE.get(stack.getItem()) != null;
|
||||
case POWERED_TOOL:
|
||||
return Platform.isChargeable(stack);
|
||||
case QE_SINGULARITY:
|
||||
|
||||
@@ -25,14 +25,14 @@ import java.util.Collection;
|
||||
import java.util.EnumMap;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.DoubleSupplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
|
||||
import appeng.api.config.CondenserOutput;
|
||||
import appeng.api.config.PowerMultiplier;
|
||||
@@ -50,6 +50,7 @@ import appeng.core.config.DoubleOption;
|
||||
import appeng.core.config.EnumOption;
|
||||
import appeng.core.config.IntegerOption;
|
||||
import appeng.core.config.StringListOption;
|
||||
import appeng.core.config.StringOption;
|
||||
import appeng.core.settings.TickRates;
|
||||
import appeng.util.EnumCycler;
|
||||
|
||||
@@ -81,6 +82,13 @@ public final class AEConfig {
|
||||
result.save(); // Save a default file
|
||||
} else {
|
||||
result.load();
|
||||
|
||||
// Re-save immediately to write-out new defaults
|
||||
try {
|
||||
result.save();
|
||||
} catch (Exception e) {
|
||||
AELog.warn(e);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -137,7 +145,6 @@ public final class AEConfig {
|
||||
|
||||
// Meteors
|
||||
private int meteoriteMaximumSpawnHeight;
|
||||
private Set<String> meteoriteDimensionWhitelist;
|
||||
|
||||
// Wireless
|
||||
private double wirelessBaseCost;
|
||||
@@ -175,7 +182,6 @@ public final class AEConfig {
|
||||
this.oreDoublePercentage = (float) commonConfig.oreDoublePercentage.get();
|
||||
|
||||
this.meteoriteMaximumSpawnHeight = commonConfig.meteoriteMaximumSpawnHeight.get();
|
||||
this.meteoriteDimensionWhitelist = new HashSet<>(commonConfig.meteoriteDimensionWhitelist.get());
|
||||
|
||||
this.wirelessBaseCost = commonConfig.wirelessBaseCost.get();
|
||||
this.wirelessCostMultiplier = commonConfig.wirelessCostMultiplier.get();
|
||||
@@ -389,8 +395,21 @@ public final class AEConfig {
|
||||
return this.meteoriteMaximumSpawnHeight;
|
||||
}
|
||||
|
||||
public Set<String> getMeteoriteDimensionWhitelist() {
|
||||
return this.meteoriteDimensionWhitelist;
|
||||
public List<String> getMeteoriteBiomeBlacklist() {
|
||||
return commonConfig.meteoriteBiomeBlacklist.get();
|
||||
}
|
||||
|
||||
public List<String> getQuartzOreBiomeBlacklist() {
|
||||
return commonConfig.quartzOreBiomeBlacklist.get();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getImprovedFluidTag() {
|
||||
return Strings.emptyToNull(commonConfig.improvedFluidTag.get());
|
||||
}
|
||||
|
||||
public float getImprovedFluidMultiplier() {
|
||||
return (float) commonConfig.improvedFluidMultiplier.get();
|
||||
}
|
||||
|
||||
// Setters keep visibility as low as possible.
|
||||
@@ -478,10 +497,11 @@ public final class AEConfig {
|
||||
public final DoubleOption spawnChargedChance;
|
||||
public final IntegerOption quartzOresPerCluster;
|
||||
public final IntegerOption quartzOresClusterAmount;
|
||||
public final StringListOption quartzOreBiomeBlacklist;
|
||||
|
||||
// Meteors
|
||||
public final IntegerOption meteoriteMaximumSpawnHeight;
|
||||
public final StringListOption meteoriteDimensionWhitelist;
|
||||
public final StringListOption meteoriteBiomeBlacklist;
|
||||
|
||||
// Wireless
|
||||
public final DoubleOption wirelessBaseCost;
|
||||
@@ -504,6 +524,11 @@ public final class AEConfig {
|
||||
public final IntegerOption condenserMatterBallsPower;
|
||||
public final IntegerOption condenserSingularityPower;
|
||||
|
||||
// In-World Purification
|
||||
// Settings for improved speed depending on fluid the crystal is in
|
||||
public final StringOption improvedFluidTag;
|
||||
public final DoubleOption improvedFluidMultiplier;
|
||||
|
||||
public final Map<TickRates, IntegerOption> tickRateMin = new HashMap<>();
|
||||
public final Map<TickRates, IntegerOption> tickRateMax = new HashMap<>();
|
||||
|
||||
@@ -562,13 +587,13 @@ public final class AEConfig {
|
||||
|
||||
this.spawnChargedChance = worldGen.addDouble("spawnChargedChance", 0.08, 0.0, 1.0);
|
||||
this.meteoriteMaximumSpawnHeight = worldGen.addInt("meteoriteMaximumSpawnHeight", 180);
|
||||
List<String> defaultDimensionWhitelist = new ArrayList<>();
|
||||
defaultDimensionWhitelist.add(DimensionType.OVERWORLD_REGISTRY_KEY.getValue().toString());
|
||||
this.meteoriteDimensionWhitelist = worldGen.addStringList("meteoriteDimensionWhitelist",
|
||||
defaultDimensionWhitelist);
|
||||
this.meteoriteBiomeBlacklist = worldGen.addStringList("meteoriteBiomeBlacklist", new ArrayList<>(),
|
||||
"Biome IDs in which meteorites should NOT be generated (i.e. minecraft:plains).");
|
||||
|
||||
this.quartzOresPerCluster = worldGen.addInt("quartzOresPerCluster", 4);
|
||||
this.quartzOresClusterAmount = worldGen.addInt("quartzOresClusterAmount", 20);
|
||||
this.quartzOreBiomeBlacklist = worldGen.addStringList("quartzOreBiomeBlacklist", new ArrayList<>(),
|
||||
"Biome IDs in which quartz ores should NOT be generated (i.e. minecraft:plains).");
|
||||
|
||||
ConfigSection wireless = root.subsection("wireless");
|
||||
this.wirelessBaseCost = wireless.addDouble("wirelessBaseCost", 8.0);
|
||||
@@ -598,6 +623,14 @@ public final class AEConfig {
|
||||
tickRateMin.put(tickRate, tickrates.addInt(tickRate.name() + "Min", tickRate.getDefaultMin()));
|
||||
tickRateMax.put(tickRate, tickrates.addInt(tickRate.name() + "Max", tickRate.getDefaultMax()));
|
||||
}
|
||||
|
||||
ConfigSection inWorldPurification = root.subsection("inWorldPurification",
|
||||
"Settings for in-world purification of crystals.");
|
||||
|
||||
improvedFluidTag = inWorldPurification.addString("improvedFluidTag", "",
|
||||
"A fluid tag that identifies fluids that improve crystal purification speed. Does not affect purification with water/lava.");
|
||||
improvedFluidMultiplier = inWorldPurification.addDouble("improvedFluidMultiplier", 2.0, 1.0, 10.0,
|
||||
"The speed multiplier to use when the crystals are submerged in the improved fluid.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,14 +30,8 @@ import net.minecraft.entity.player.PlayerInventory;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.screen.ScreenHandlerType;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
|
||||
import team.reborn.energy.Energy;
|
||||
import team.reborn.energy.EnergyHandler;
|
||||
import team.reborn.energy.EnergyHolder;
|
||||
|
||||
import appeng.api.config.Upgrades;
|
||||
import appeng.api.definitions.IBlocks;
|
||||
@@ -45,8 +39,6 @@ import appeng.api.definitions.IItems;
|
||||
import appeng.api.definitions.IParts;
|
||||
import appeng.api.features.IRegistryContainer;
|
||||
import appeng.api.features.IWirelessTermHandler;
|
||||
import appeng.api.features.IWorldGen;
|
||||
import appeng.api.implementations.items.IAEItemPowerStorage;
|
||||
import appeng.api.movable.IMovableRegistry;
|
||||
import appeng.api.networking.IGridCacheRegistry;
|
||||
import appeng.api.networking.crafting.ICraftingGrid;
|
||||
@@ -57,7 +49,6 @@ import appeng.api.networking.spatial.ISpatialCache;
|
||||
import appeng.api.networking.storage.IStorageGrid;
|
||||
import appeng.api.networking.ticking.ITickManager;
|
||||
import appeng.api.parts.CableRenderMode;
|
||||
import appeng.block.AEBaseBlockItemChargeable;
|
||||
import appeng.bootstrap.IBootstrapComponent;
|
||||
import appeng.bootstrap.components.ITileEntityRegistrationComponent;
|
||||
import appeng.client.render.effects.ParticleTypes;
|
||||
@@ -351,21 +342,6 @@ public abstract class AppEngBase implements AppEng {
|
||||
*/
|
||||
mr.whiteListBlockEntity(AEBaseBlockEntity.class);
|
||||
|
||||
/*
|
||||
* world gen
|
||||
*/
|
||||
for (final IWorldGen.WorldGenType type : IWorldGen.WorldGenType.values()) {
|
||||
// FIXME: registries.worldgen().disableWorldGenForProviderID( type,
|
||||
// StorageWorldProvider.class );
|
||||
|
||||
registries.worldgen().disableWorldGenForDimension(type, DimensionType.THE_NETHER_REGISTRY_KEY.getValue());
|
||||
}
|
||||
|
||||
// whitelist from config
|
||||
for (final String dimension : AEConfig.instance().getMeteoriteDimensionWhitelist()) {
|
||||
registries.worldgen().enableWorldGenForDimension(IWorldGen.WorldGenType.METEORITES,
|
||||
new Identifier(dimension));
|
||||
}
|
||||
}
|
||||
|
||||
protected void registerParticleTypes() {
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
package appeng.core;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.registry.BuiltinRegistries;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
import net.minecraft.util.registry.RegistryKey;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.gen.GenerationStep;
|
||||
import net.minecraft.world.gen.decorator.Decorator;
|
||||
@@ -54,11 +61,21 @@ public final class AppEngBootstrap {
|
||||
ConfiguredFeature<?, ?> quartzOreFeature = registerQuartzOreFeature();
|
||||
ConfiguredFeature<?, ?> chargedQuartzOreFeature = registerChargedQuartzOreFeature();
|
||||
|
||||
// add to all standard biomes
|
||||
// TODO: This means we'll not add these things to newly created biomes
|
||||
BuiltinRegistries.BIOME.forEach(b -> {
|
||||
addMeteoriteWorldGen(b);
|
||||
addQuartzWorldGen(b, quartzOreFeature, chargedQuartzOreFeature);
|
||||
Set<String> meteoriteBiomeBlacklist = new HashSet<>(AEConfig.instance().getMeteoriteBiomeBlacklist());
|
||||
Set<String> quartzOreBiomeBlacklist = new HashSet<>(AEConfig.instance().getQuartzOreBiomeBlacklist());
|
||||
|
||||
// Add features to all existing biomes
|
||||
for (Map.Entry<RegistryKey<Biome>, Biome> entry : BuiltinRegistries.BIOME.getEntries()) {
|
||||
Identifier id = entry.getKey().getValue();
|
||||
Biome b = entry.getValue();
|
||||
addMeteoriteWorldGen(id, b, meteoriteBiomeBlacklist);
|
||||
addQuartzWorldGen(id, b, quartzOreFeature, chargedQuartzOreFeature, quartzOreBiomeBlacklist);
|
||||
}
|
||||
|
||||
// Listen to added biomes for post-processing
|
||||
RegistryEntryAddedCallback.event(BuiltinRegistries.BIOME).register((i, id, biome) -> {
|
||||
addMeteoriteWorldGen(id, biome, meteoriteBiomeBlacklist);
|
||||
addQuartzWorldGen(id, biome, quartzOreFeature, chargedQuartzOreFeature, quartzOreBiomeBlacklist);
|
||||
});
|
||||
|
||||
registerDimension();
|
||||
@@ -78,12 +95,19 @@ public final class AppEngBootstrap {
|
||||
MeteoriteStructure.CONFIGURED_INSTANCE);
|
||||
}
|
||||
|
||||
private static void addMeteoriteWorldGen(Biome b) {
|
||||
private static void addMeteoriteWorldGen(Identifier id, Biome b, Set<String> biomeBlacklist) {
|
||||
if (!AEConfig.instance().isFeatureEnabled(AEFeature.METEORITE_WORLD_GEN)) {
|
||||
AELog.debug("Not generating meteorites in %s because the feature is disabled", id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (b.getCategory() == Biome.Category.THEEND || b.getCategory() == Biome.Category.NETHER) {
|
||||
AELog.debug("Not generating meteorites in %s because it's of category %s", id, b.getCategory());
|
||||
return;
|
||||
}
|
||||
|
||||
if (biomeBlacklist.contains(id.toString())) {
|
||||
AELog.debug("Not generating meteorites in %s because the biome is blacklisted in the config", id);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -91,14 +115,24 @@ public final class AppEngBootstrap {
|
||||
modifier.addStructureFeature(MeteoriteStructure.CONFIGURED_INSTANCE);
|
||||
}
|
||||
|
||||
private static void addQuartzWorldGen(Biome b, ConfiguredFeature<?, ?> quartzOre,
|
||||
ConfiguredFeature<?, ?> chargedQuartz) {
|
||||
private static void addQuartzWorldGen(Identifier id, Biome b, ConfiguredFeature<?, ?> quartzOre,
|
||||
ConfiguredFeature<?, ?> chargedQuartz, Set<String> biomeBlacklist) {
|
||||
if (!AEConfig.instance().isFeatureEnabled(AEFeature.CERTUS_QUARTZ_WORLD_GEN)) {
|
||||
AELog.debug("Not generating quartz-ore in %s because the feature is disabled", id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (b.getCategory() == Biome.Category.THEEND || b.getCategory() == Biome.Category.NETHER) {
|
||||
AELog.debug("Not generating quartz ore in %s because it's of category %s", id, b.getCategory());
|
||||
return;
|
||||
}
|
||||
|
||||
if (biomeBlacklist.contains(id.toString())) {
|
||||
AELog.debug("Not generating quartz-ore in %s because the biome is blacklisted in the config", id);
|
||||
return;
|
||||
}
|
||||
|
||||
BiomeModifier modifier = new BiomeModifier(b);
|
||||
|
||||
modifier.addFeature(GenerationStep.Feature.UNDERGROUND_ORES, quartzOre);
|
||||
|
||||
if (AEConfig.instance().isFeatureEnabled(AEFeature.CHARGED_CERTUS_ORE)) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user